From 4d11078cb0b6ab94a692d5b650f72da67ad0ab0a Mon Sep 17 00:00:00 2001 From: Branden Moore Date: Thu, 3 Mar 2022 15:26:11 -0600 Subject: [PATCH 001/367] Initial Import of GHPC Frontend --- frontend/.gitignore | 22 + frontend/README.md | 29 + frontend/cli/ghpcfe-cli.py | 236 + frontend/cli/utils.py | 63 + frontend/deploy.sh | 169 + frontend/docs/AppEngine-Notes.md | 69 + frontend/docs/BJM-Notes.md | 158 + frontend/docs/ClusterCommandControl.md | 68 + frontend/docs/Database design.md | 99 + .../templates/bootstrap_compute.sh | 31 + .../templates/bootstrap_controller.sh | 32 + .../templates/bootstrap_login.sh | 31 + .../filesystem_tf/gcp_filestore/main.tf | 32 + .../filesystem_tf/gcp_filestore/variables.tf | 21 + .../filesystem_tf/gcp_filestore/versions.tf | 18 + .../clusters/ansible_setup/ansible.cfg | 6 + .../clusters/ansible_setup/compute.yaml | 10 + .../clusters/ansible_setup/controller.yaml | 12 + .../clusters/ansible_setup/login.yaml | 10 + .../roles/c2_daemon/files/ghpcfe_c2.service | 12 + .../roles/c2_daemon/files/ghpcfe_c2daemon.py | 700 + .../roles/c2_daemon/tasks/main.yaml | 47 + .../c2_daemon/templates/ghpcfe_c2.yaml.j2 | 5 + .../roles/dev_env/tasks/main.yaml | 22 + .../roles/spack_install/tasks/main.yaml | 54 + .../roles/spack_setup/tasks/main.yaml | 30 + .../clusters/ansible_setup/vars.yaml | 2 + .../gcs_bucket/webserver/startup.sh | 229 + .../infrastructure_files/vpc_tf/GCP/main.tf | 74 + .../vpc_tf/GCP/subnet.tf.template | 12 + .../vpc_tf/GCP/variables.tf | 11 + .../vpc_tf/GCP/versions.tf | 18 + .../workbench_tf/google/main.tf | 232 + .../workbench_tf/google/orgpolicy.tf | 74 + .../workbench_tf/google/outputs.tf | 35 + .../workbench_tf/google/provider.tf | 6 + .../workbench_tf/google/variables.tf | 159 + .../workbench_tf/google/versions.tf | 24 + frontend/requirements.txt | 67 + frontend/tf/main.tf | 216 + frontend/tf/outputs.tf | 4 + frontend/tf/provider.tf | 10 + frontend/tf/variables.tf | 81 + frontend/tf/versions.tf | 14 + frontend/website/.gitignore | 2 + frontend/website/ghpcfe/__init__.py | 0 frontend/website/ghpcfe/admin.py | 131 + frontend/website/ghpcfe/apps.py | 24 + .../ghpcfe/cluster_manager/__init__.py | 0 frontend/website/ghpcfe/cluster_manager/c2.py | 319 + .../ghpcfe/cluster_manager/cloud_info.py | 407 + .../ghpcfe/cluster_manager/clusterinfo.py | 570 + .../cluster_manager/create_workbench.py | 48 + .../cluster_manager/destroy_workbench.py | 42 + .../ghpcfe/cluster_manager/filesystem.py | 151 + .../ghpcfe/cluster_manager/pause_cluster.py | 40 + .../website/ghpcfe/cluster_manager/spack.py | 41 + .../ghpcfe/cluster_manager/start_workbench.py | 34 + .../website/ghpcfe/cluster_manager/utils.py | 238 + .../cluster_manager/validate_credential.py | 52 + .../website/ghpcfe/cluster_manager/vpc.py | 170 + .../ghpcfe/cluster_manager/workbenchinfo.py | 188 + frontend/website/ghpcfe/forms.py | 490 + .../commands/custom_startup_command.py | 56 + .../commands/seed_workbench_presets.py | 59 + frontend/website/ghpcfe/models.py | 1060 + frontend/website/ghpcfe/permissions.py | 26 + frontend/website/ghpcfe/serializers.py | 105 + frontend/website/ghpcfe/signals.py | 45 + .../website/ghpcfe/static/css/jquery-ui.css | 1311 ++ frontend/website/ghpcfe/static/css/styles.css | 29 + .../ghpcfe/static/examples/namd_apoa1.sh | 28 + .../ghpcfe/static/examples/namd_stmv.sh | 29 + .../examples/openfoam_motorbike_meshing.sh | 39 + .../examples/openfoam_motorbike_solving.sh | 46 + .../ghpcfe/static/examples/run_hpcc.py | 176 + .../website/ghpcfe/static/examples/run_hpl.py | 178 + .../ghpcfe/static/examples/wrf_12km.sh | 41 + .../ghpcfe/static/examples/wrf_2.5km.sh | 44 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../website/ghpcfe/static/img/GCP_logo.png | Bin 0 -> 21838 bytes .../website/ghpcfe/static/img/application.png | Bin 0 -> 29071 bytes .../website/ghpcfe/static/img/checkmark.png | Bin 0 -> 169 bytes .../website/ghpcfe/static/img/cluster.png | Bin 0 -> 378407 bytes .../website/ghpcfe/static/img/credential.png | Bin 0 -> 66924 bytes .../website/ghpcfe/static/img/loading.gif | Bin 0 -> 79152 bytes .../ghpcfe/static/img/main-application.png | Bin 0 -> 11370 bytes .../ghpcfe/static/img/main-cluster.png | Bin 0 -> 5391 bytes .../ghpcfe/static/img/main-credential.png | Bin 0 -> 4957 bytes .../website/ghpcfe/static/img/main-job.png | Bin 0 -> 3719 bytes .../website/ghpcfe/static/img/placeholder.png | Bin 0 -> 7983 bytes .../ghpcfe/static/img/status-completed.png | Bin 0 -> 745 bytes .../ghpcfe/static/img/status-configured.png | Bin 0 -> 893 bytes .../ghpcfe/static/img/status-deleted.png | Bin 0 -> 747 bytes .../ghpcfe/static/img/status-error.png | Bin 0 -> 620 bytes .../ghpcfe/static/img/status-paused.png | Bin 0 -> 772 bytes .../ghpcfe/static/img/status-ready.png | Bin 0 -> 901 bytes .../ghpcfe/static/img/unknown_user.png | Bin 0 -> 1611 bytes .../ghpcfe/static/img/white-application.png | Bin 0 -> 914 bytes .../ghpcfe/static/img/white-benchmark.png | Bin 0 -> 3462 bytes .../ghpcfe/static/img/white-cluster.png | Bin 0 -> 1603 bytes .../ghpcfe/static/img/white-credential.png | Bin 0 -> 1038 bytes .../ghpcfe/static/img/white-filesystem.png | Bin 0 -> 1389 bytes .../ghpcfe/static/img/white-hamburger.png | Bin 0 -> 274 bytes .../website/ghpcfe/static/img/white-home.png | Bin 0 -> 765 bytes .../website/ghpcfe/static/img/white-job.png | Bin 0 -> 688 bytes .../ghpcfe/static/img/white-network.png | Bin 0 -> 17051 bytes .../ghpcfe/static/img/white-servers.png | Bin 0 -> 17346 bytes .../ghpcfe/static/img/workbench-white.png | Bin 0 -> 5527 bytes .../ghpcfe/static/js/bootstrap.bundle.js | 7663 +++++++ .../ghpcfe/static/js/bootstrap.bundle.js.map | 1 + .../ghpcfe/static/js/bootstrap.bundle.min.js | 7 + .../static/js/bootstrap.bundle.min.js.map | 1 + .../website/ghpcfe/static/js/bootstrap.esm.js | 5023 +++++ .../ghpcfe/static/js/bootstrap.esm.js.map | 1 + .../ghpcfe/static/js/bootstrap.esm.min.js | 7 + .../ghpcfe/static/js/bootstrap.esm.min.js.map | 1 + .../website/ghpcfe/static/js/bootstrap.js | 5053 +++++ .../website/ghpcfe/static/js/bootstrap.js.map | 1 + .../website/ghpcfe/static/js/bootstrap.min.js | 7 + .../ghpcfe/static/js/bootstrap.min.js.map | 1 + .../website/ghpcfe/static/js/jquery-ui.js | 18706 ++++++++++++++++ .../website/ghpcfe/static/js/jquery.cookie.js | 114 + .../ghpcfe/static/js/jquery.formset.js | 250 + .../ghpcfe/templates/account/update_form.html | 28 + .../templates/application/check_delete.html | 17 + .../templates/application/create_form.html | 76 + .../ghpcfe/templates/application/detail.html | 55 + .../templates/application/edit_form.html | 47 + .../ghpcfe/templates/application/list.html | 91 + .../ghpcfe/templates/application/log.html | 53 + .../application/spack_create_form.html | 114 + .../ghpcfe/templates/base_generic.html | 133 + .../templates/benchmark/create_form.html | 28 + .../ghpcfe/templates/benchmark/detail.html | 50 + .../ghpcfe/templates/benchmark/list.html | 45 + .../templates/cluster/check_delete.html | 14 + .../templates/cluster/check_destroy.html | 61 + .../ghpcfe/templates/cluster/cost.html | 12 + .../ghpcfe/templates/cluster/create_form.html | 106 + .../ghpcfe/templates/cluster/detail.html | 103 + .../ghpcfe/templates/cluster/list.html | 145 + .../website/ghpcfe/templates/cluster/log.html | 60 + .../ghpcfe/templates/cluster/update_form.html | 180 + .../templates/cluster/user_auth_gcp.html | 117 + .../templates/credential/check_delete.html | 14 + .../templates/credential/create_form.html | 28 + .../ghpcfe/templates/credential/detail.html | 11 + .../ghpcfe/templates/credential/list.html | 33 + .../templates/credential/select_form.html | 43 + .../templates/credential/update_form.html | 27 + .../website/ghpcfe/templates/document.html | 169 + .../templates/filesystem/check_delete.html | 14 + .../templates/filesystem/check_destroy.html | 40 + .../filesystem/filestore_create_form.html | 92 + .../filesystem/filestore_detail.html | 64 + .../filesystem/filestore_update_form.html | 93 + .../filesystem/impl_select_form.html | 32 + .../ghpcfe/templates/filesystem/list.html | 121 + frontend/website/ghpcfe/templates/index.html | 76 + .../ghpcfe/templates/job/confirm_delete.html | 18 + .../ghpcfe/templates/job/create_form.html | 233 + .../website/ghpcfe/templates/job/detail.html | 57 + .../website/ghpcfe/templates/job/list.html | 81 + .../website/ghpcfe/templates/job/log.html | 46 + .../ghpcfe/templates/job/rerun_form.html | 233 + .../ghpcfe/templates/job/select_cluster.html | 35 + .../credential_dropdown_list_options.html | 4 + .../ghpcfe/templates/vpc/check_delete.html | 14 + .../ghpcfe/templates/vpc/check_destroy.html | 19 + .../ghpcfe/templates/vpc/create_form.html | 66 + .../website/ghpcfe/templates/vpc/detail.html | 124 + .../ghpcfe/templates/vpc/import_form.html | 80 + .../website/ghpcfe/templates/vpc/list.html | 126 + .../ghpcfe/templates/vpc/update_form.html | 72 + .../ghpcfe/templates/vpc/virtual_subnet.html | 40 + .../templates/workbench/check_delete.html | 14 + .../templates/workbench/check_destroy.html | 21 + .../templates/workbench/create_form.html | 83 + .../ghpcfe/templates/workbench/detail.html | 44 + .../ghpcfe/templates/workbench/list.html | 148 + frontend/website/ghpcfe/tests.py | 17 + frontend/website/ghpcfe/urls.py | 174 + frontend/website/ghpcfe/views/__init__.py | 28 + frontend/website/ghpcfe/views/applications.py | 266 + frontend/website/ghpcfe/views/asyncview.py | 100 + frontend/website/ghpcfe/views/benchmarks.py | 76 + frontend/website/ghpcfe/views/clusters.py | 680 + frontend/website/ghpcfe/views/credentials.py | 144 + frontend/website/ghpcfe/views/filesystems.py | 255 + frontend/website/ghpcfe/views/gcpfilestore.py | 132 + frontend/website/ghpcfe/views/jobs.py | 322 + frontend/website/ghpcfe/views/users.py | 57 + frontend/website/ghpcfe/views/view_utils.py | 100 + frontend/website/ghpcfe/views/vpc.py | 458 + frontend/website/ghpcfe/views/workbench.py | 219 + frontend/website/manage.py | 22 + frontend/website/nginx.conf | 56 + .../templates/registration/logged_out.html | 6 + .../website/templates/registration/login.html | 46 + .../registration/password_reset_complete.html | 6 + .../registration/password_reset_confirm.html | 29 + .../registration/password_reset_done.html | 5 + .../registration/password_reset_email.html | 3 + .../registration/password_reset_form.html | 13 + frontend/website/website/__init__.py | 0 frontend/website/website/asgi.py | 16 + frontend/website/website/settings.py | 197 + frontend/website/website/urls.py | 44 + frontend/website/website/wsgi.py | 16 + 214 files changed, 54034 insertions(+) create mode 100644 frontend/.gitignore create mode 100644 frontend/README.md create mode 100644 frontend/cli/ghpcfe-cli.py create mode 100644 frontend/cli/utils.py create mode 100755 frontend/deploy.sh create mode 100644 frontend/docs/AppEngine-Notes.md create mode 100644 frontend/docs/BJM-Notes.md create mode 100644 frontend/docs/ClusterCommandControl.md create mode 100644 frontend/docs/Database design.md create mode 100644 frontend/infrastructure_files/cluster_startup/templates/bootstrap_compute.sh create mode 100644 frontend/infrastructure_files/cluster_startup/templates/bootstrap_controller.sh create mode 100644 frontend/infrastructure_files/cluster_startup/templates/bootstrap_login.sh create mode 100644 frontend/infrastructure_files/filesystem_tf/gcp_filestore/main.tf create mode 100644 frontend/infrastructure_files/filesystem_tf/gcp_filestore/variables.tf create mode 100644 frontend/infrastructure_files/filesystem_tf/gcp_filestore/versions.tf create mode 100644 frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/ansible.cfg create mode 100644 frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/compute.yaml create mode 100644 frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/controller.yaml create mode 100644 frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/login.yaml create mode 100644 frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/c2_daemon/files/ghpcfe_c2.service create mode 100644 frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/c2_daemon/files/ghpcfe_c2daemon.py create mode 100644 frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/c2_daemon/tasks/main.yaml create mode 100644 frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/c2_daemon/templates/ghpcfe_c2.yaml.j2 create mode 100644 frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/dev_env/tasks/main.yaml create mode 100644 frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/spack_install/tasks/main.yaml create mode 100644 frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/spack_setup/tasks/main.yaml create mode 100644 frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/vars.yaml create mode 100644 frontend/infrastructure_files/gcs_bucket/webserver/startup.sh create mode 100644 frontend/infrastructure_files/vpc_tf/GCP/main.tf create mode 100644 frontend/infrastructure_files/vpc_tf/GCP/subnet.tf.template create mode 100644 frontend/infrastructure_files/vpc_tf/GCP/variables.tf create mode 100644 frontend/infrastructure_files/vpc_tf/GCP/versions.tf create mode 100644 frontend/infrastructure_files/workbench_tf/google/main.tf create mode 100644 frontend/infrastructure_files/workbench_tf/google/orgpolicy.tf create mode 100644 frontend/infrastructure_files/workbench_tf/google/outputs.tf create mode 100644 frontend/infrastructure_files/workbench_tf/google/provider.tf create mode 100644 frontend/infrastructure_files/workbench_tf/google/variables.tf create mode 100644 frontend/infrastructure_files/workbench_tf/google/versions.tf create mode 100644 frontend/requirements.txt create mode 100644 frontend/tf/main.tf create mode 100644 frontend/tf/outputs.tf create mode 100644 frontend/tf/provider.tf create mode 100644 frontend/tf/variables.tf create mode 100644 frontend/tf/versions.tf create mode 100644 frontend/website/.gitignore create mode 100644 frontend/website/ghpcfe/__init__.py create mode 100644 frontend/website/ghpcfe/admin.py create mode 100644 frontend/website/ghpcfe/apps.py create mode 100644 frontend/website/ghpcfe/cluster_manager/__init__.py create mode 100644 frontend/website/ghpcfe/cluster_manager/c2.py create mode 100644 frontend/website/ghpcfe/cluster_manager/cloud_info.py create mode 100644 frontend/website/ghpcfe/cluster_manager/clusterinfo.py create mode 100644 frontend/website/ghpcfe/cluster_manager/create_workbench.py create mode 100644 frontend/website/ghpcfe/cluster_manager/destroy_workbench.py create mode 100644 frontend/website/ghpcfe/cluster_manager/filesystem.py create mode 100644 frontend/website/ghpcfe/cluster_manager/pause_cluster.py create mode 100644 frontend/website/ghpcfe/cluster_manager/spack.py create mode 100644 frontend/website/ghpcfe/cluster_manager/start_workbench.py create mode 100644 frontend/website/ghpcfe/cluster_manager/utils.py create mode 100644 frontend/website/ghpcfe/cluster_manager/validate_credential.py create mode 100644 frontend/website/ghpcfe/cluster_manager/vpc.py create mode 100644 frontend/website/ghpcfe/cluster_manager/workbenchinfo.py create mode 100644 frontend/website/ghpcfe/forms.py create mode 100644 frontend/website/ghpcfe/management/commands/custom_startup_command.py create mode 100644 frontend/website/ghpcfe/management/commands/seed_workbench_presets.py create mode 100644 frontend/website/ghpcfe/models.py create mode 100644 frontend/website/ghpcfe/permissions.py create mode 100644 frontend/website/ghpcfe/serializers.py create mode 100644 frontend/website/ghpcfe/signals.py create mode 100644 frontend/website/ghpcfe/static/css/jquery-ui.css create mode 100644 frontend/website/ghpcfe/static/css/styles.css create mode 100644 frontend/website/ghpcfe/static/examples/namd_apoa1.sh create mode 100644 frontend/website/ghpcfe/static/examples/namd_stmv.sh create mode 100644 frontend/website/ghpcfe/static/examples/openfoam_motorbike_meshing.sh create mode 100644 frontend/website/ghpcfe/static/examples/openfoam_motorbike_solving.sh create mode 100755 frontend/website/ghpcfe/static/examples/run_hpcc.py create mode 100755 frontend/website/ghpcfe/static/examples/run_hpl.py create mode 100644 frontend/website/ghpcfe/static/examples/wrf_12km.sh create mode 100644 frontend/website/ghpcfe/static/examples/wrf_2.5km.sh create mode 100644 frontend/website/ghpcfe/static/fonts/glyphicons-halflings-regular.eot create mode 100644 frontend/website/ghpcfe/static/fonts/glyphicons-halflings-regular.svg create mode 100644 frontend/website/ghpcfe/static/fonts/glyphicons-halflings-regular.ttf create mode 100644 frontend/website/ghpcfe/static/fonts/glyphicons-halflings-regular.woff create mode 100644 frontend/website/ghpcfe/static/fonts/glyphicons-halflings-regular.woff2 create mode 100644 frontend/website/ghpcfe/static/img/GCP_logo.png create mode 100644 frontend/website/ghpcfe/static/img/application.png create mode 100644 frontend/website/ghpcfe/static/img/checkmark.png create mode 100644 frontend/website/ghpcfe/static/img/cluster.png create mode 100644 frontend/website/ghpcfe/static/img/credential.png create mode 100644 frontend/website/ghpcfe/static/img/loading.gif create mode 100644 frontend/website/ghpcfe/static/img/main-application.png create mode 100644 frontend/website/ghpcfe/static/img/main-cluster.png create mode 100644 frontend/website/ghpcfe/static/img/main-credential.png create mode 100644 frontend/website/ghpcfe/static/img/main-job.png create mode 100644 frontend/website/ghpcfe/static/img/placeholder.png create mode 100644 frontend/website/ghpcfe/static/img/status-completed.png create mode 100644 frontend/website/ghpcfe/static/img/status-configured.png create mode 100644 frontend/website/ghpcfe/static/img/status-deleted.png create mode 100644 frontend/website/ghpcfe/static/img/status-error.png create mode 100644 frontend/website/ghpcfe/static/img/status-paused.png create mode 100644 frontend/website/ghpcfe/static/img/status-ready.png create mode 100644 frontend/website/ghpcfe/static/img/unknown_user.png create mode 100644 frontend/website/ghpcfe/static/img/white-application.png create mode 100644 frontend/website/ghpcfe/static/img/white-benchmark.png create mode 100644 frontend/website/ghpcfe/static/img/white-cluster.png create mode 100644 frontend/website/ghpcfe/static/img/white-credential.png create mode 100644 frontend/website/ghpcfe/static/img/white-filesystem.png create mode 100644 frontend/website/ghpcfe/static/img/white-hamburger.png create mode 100644 frontend/website/ghpcfe/static/img/white-home.png create mode 100644 frontend/website/ghpcfe/static/img/white-job.png create mode 100644 frontend/website/ghpcfe/static/img/white-network.png create mode 100644 frontend/website/ghpcfe/static/img/white-servers.png create mode 100644 frontend/website/ghpcfe/static/img/workbench-white.png create mode 100644 frontend/website/ghpcfe/static/js/bootstrap.bundle.js create mode 100644 frontend/website/ghpcfe/static/js/bootstrap.bundle.js.map create mode 100644 frontend/website/ghpcfe/static/js/bootstrap.bundle.min.js create mode 100644 frontend/website/ghpcfe/static/js/bootstrap.bundle.min.js.map create mode 100644 frontend/website/ghpcfe/static/js/bootstrap.esm.js create mode 100644 frontend/website/ghpcfe/static/js/bootstrap.esm.js.map create mode 100644 frontend/website/ghpcfe/static/js/bootstrap.esm.min.js create mode 100644 frontend/website/ghpcfe/static/js/bootstrap.esm.min.js.map create mode 100644 frontend/website/ghpcfe/static/js/bootstrap.js create mode 100644 frontend/website/ghpcfe/static/js/bootstrap.js.map create mode 100644 frontend/website/ghpcfe/static/js/bootstrap.min.js create mode 100644 frontend/website/ghpcfe/static/js/bootstrap.min.js.map create mode 100644 frontend/website/ghpcfe/static/js/jquery-ui.js create mode 100644 frontend/website/ghpcfe/static/js/jquery.cookie.js create mode 100644 frontend/website/ghpcfe/static/js/jquery.formset.js create mode 100644 frontend/website/ghpcfe/templates/account/update_form.html create mode 100644 frontend/website/ghpcfe/templates/application/check_delete.html create mode 100644 frontend/website/ghpcfe/templates/application/create_form.html create mode 100644 frontend/website/ghpcfe/templates/application/detail.html create mode 100644 frontend/website/ghpcfe/templates/application/edit_form.html create mode 100644 frontend/website/ghpcfe/templates/application/list.html create mode 100644 frontend/website/ghpcfe/templates/application/log.html create mode 100644 frontend/website/ghpcfe/templates/application/spack_create_form.html create mode 100644 frontend/website/ghpcfe/templates/base_generic.html create mode 100644 frontend/website/ghpcfe/templates/benchmark/create_form.html create mode 100644 frontend/website/ghpcfe/templates/benchmark/detail.html create mode 100644 frontend/website/ghpcfe/templates/benchmark/list.html create mode 100644 frontend/website/ghpcfe/templates/cluster/check_delete.html create mode 100644 frontend/website/ghpcfe/templates/cluster/check_destroy.html create mode 100644 frontend/website/ghpcfe/templates/cluster/cost.html create mode 100644 frontend/website/ghpcfe/templates/cluster/create_form.html create mode 100644 frontend/website/ghpcfe/templates/cluster/detail.html create mode 100644 frontend/website/ghpcfe/templates/cluster/list.html create mode 100644 frontend/website/ghpcfe/templates/cluster/log.html create mode 100644 frontend/website/ghpcfe/templates/cluster/update_form.html create mode 100644 frontend/website/ghpcfe/templates/cluster/user_auth_gcp.html create mode 100644 frontend/website/ghpcfe/templates/credential/check_delete.html create mode 100644 frontend/website/ghpcfe/templates/credential/create_form.html create mode 100644 frontend/website/ghpcfe/templates/credential/detail.html create mode 100644 frontend/website/ghpcfe/templates/credential/list.html create mode 100644 frontend/website/ghpcfe/templates/credential/select_form.html create mode 100644 frontend/website/ghpcfe/templates/credential/update_form.html create mode 100644 frontend/website/ghpcfe/templates/document.html create mode 100644 frontend/website/ghpcfe/templates/filesystem/check_delete.html create mode 100644 frontend/website/ghpcfe/templates/filesystem/check_destroy.html create mode 100644 frontend/website/ghpcfe/templates/filesystem/filestore_create_form.html create mode 100644 frontend/website/ghpcfe/templates/filesystem/filestore_detail.html create mode 100644 frontend/website/ghpcfe/templates/filesystem/filestore_update_form.html create mode 100644 frontend/website/ghpcfe/templates/filesystem/impl_select_form.html create mode 100644 frontend/website/ghpcfe/templates/filesystem/list.html create mode 100644 frontend/website/ghpcfe/templates/index.html create mode 100644 frontend/website/ghpcfe/templates/job/confirm_delete.html create mode 100644 frontend/website/ghpcfe/templates/job/create_form.html create mode 100644 frontend/website/ghpcfe/templates/job/detail.html create mode 100644 frontend/website/ghpcfe/templates/job/list.html create mode 100644 frontend/website/ghpcfe/templates/job/log.html create mode 100644 frontend/website/ghpcfe/templates/job/rerun_form.html create mode 100644 frontend/website/ghpcfe/templates/job/select_cluster.html create mode 100644 frontend/website/ghpcfe/templates/utility/credential_dropdown_list_options.html create mode 100644 frontend/website/ghpcfe/templates/vpc/check_delete.html create mode 100644 frontend/website/ghpcfe/templates/vpc/check_destroy.html create mode 100644 frontend/website/ghpcfe/templates/vpc/create_form.html create mode 100644 frontend/website/ghpcfe/templates/vpc/detail.html create mode 100644 frontend/website/ghpcfe/templates/vpc/import_form.html create mode 100644 frontend/website/ghpcfe/templates/vpc/list.html create mode 100644 frontend/website/ghpcfe/templates/vpc/update_form.html create mode 100644 frontend/website/ghpcfe/templates/vpc/virtual_subnet.html create mode 100644 frontend/website/ghpcfe/templates/workbench/check_delete.html create mode 100644 frontend/website/ghpcfe/templates/workbench/check_destroy.html create mode 100644 frontend/website/ghpcfe/templates/workbench/create_form.html create mode 100644 frontend/website/ghpcfe/templates/workbench/detail.html create mode 100644 frontend/website/ghpcfe/templates/workbench/list.html create mode 100644 frontend/website/ghpcfe/tests.py create mode 100644 frontend/website/ghpcfe/urls.py create mode 100644 frontend/website/ghpcfe/views/__init__.py create mode 100644 frontend/website/ghpcfe/views/applications.py create mode 100644 frontend/website/ghpcfe/views/asyncview.py create mode 100644 frontend/website/ghpcfe/views/benchmarks.py create mode 100644 frontend/website/ghpcfe/views/clusters.py create mode 100644 frontend/website/ghpcfe/views/credentials.py create mode 100644 frontend/website/ghpcfe/views/filesystems.py create mode 100644 frontend/website/ghpcfe/views/gcpfilestore.py create mode 100644 frontend/website/ghpcfe/views/jobs.py create mode 100644 frontend/website/ghpcfe/views/users.py create mode 100644 frontend/website/ghpcfe/views/view_utils.py create mode 100644 frontend/website/ghpcfe/views/vpc.py create mode 100644 frontend/website/ghpcfe/views/workbench.py create mode 100755 frontend/website/manage.py create mode 100644 frontend/website/nginx.conf create mode 100644 frontend/website/templates/registration/logged_out.html create mode 100644 frontend/website/templates/registration/login.html create mode 100644 frontend/website/templates/registration/password_reset_complete.html create mode 100644 frontend/website/templates/registration/password_reset_confirm.html create mode 100644 frontend/website/templates/registration/password_reset_done.html create mode 100644 frontend/website/templates/registration/password_reset_email.html create mode 100644 frontend/website/templates/registration/password_reset_form.html create mode 100644 frontend/website/website/__init__.py create mode 100644 frontend/website/website/asgi.py create mode 100644 frontend/website/website/settings.py create mode 100644 frontend/website/website/urls.py create mode 100644 frontend/website/website/wsgi.py diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000000..dc77c0fd70 --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,22 @@ +/clusters/ +fs/ +vpcs/ +runs/ +myvenv/ +__pycache__ +website/ghpcfe/migrations/ +.*.swp +*.sqlite3 +bin/ +lib/ +share/ +run/ +configuration.yaml +website/static/ +workbenches/ +key1 +key2 +.terraform/ +.terraform.lock.hcl +terraform.tfstate* +terraform.tfvars diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000000..30286bbd34 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,29 @@ +# Multi-platform HPC Application System + +This is a web front-end for HPC applications on GCP. The system enables admin users to manage the life cycles of HPC clusters and install applications. It also allows users to prepare and submit HPC jobs, and run benchmarks. This application is built upon the Django framework. + +### Deployment + +This system can be deployed on GCP using the following procedures. + +A user is handed with the deployment script `deploy.sh` together with deployment key files that grant access to some private GitHub repositories. In the future, when the system becomes mature enough and is made public, the key files will no longer be necessary. + +Run `deploy.sh` interactively on any Linux based client machines, or from a GCP cloud shell. The script will prompt to collect the following information from the user: + +* Login details for the superuser of the web application. +* Name, region and instance type of the compute engine virtual machine to host the web application. +* An SSH key for the admin user to gain access to the server. + +The hosting VM will then be created and configured automatically. The whole process takes approxiately 15 minutes. + +### Post-deployment Configuations + +After the deployment, the web application requires some additional configurations. + + - The site must be associated with a domain name. This is required to allow user access via Google authentication. + - For a production deployment, an SSL certificate should be obtained for the domain to support secure connections. + - The deployment script created a firewall rule to restrict access to the site from the Internet. Relax or remove the firewall rule for production. + - After setting up the domain name, visit the hosting GCP project and register this web application (in GCP console, create an OAuth 2.0 credential under the *APIs and Services* section). Update the *Authorised JavaScript origins* to the full domain name and *Authorised redirect URIs* fields to `/accounts/google/login/callback/`. Note the *Client ID* and *Client secret*. + - SSH into the server and edit the Django settings at `/opt/gcluster/c398_MultiCloud_Benchmarking/website/website/settings.py` by adding the domain name to the *ALLOWED_HOSTS* list. + - The website should be fully functional now. Open it in a browser and log in using the superuser account created earlier. Update the Django social application database table at `https:///admin/socialaccount/socialapp/1/change/`, replacing the two PLACEHOLDERs by the *Client ID* and *Client secret* to complete the set up. + diff --git a/frontend/cli/ghpcfe-cli.py b/frontend/cli/ghpcfe-cli.py new file mode 100644 index 0000000000..990ba5ff01 --- /dev/null +++ b/frontend/cli/ghpcfe-cli.py @@ -0,0 +1,236 @@ +# Copyright 2022 Google LLC +# +# 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. + +import click +import requests +import sys +import yaml +import json +from pathlib import Path + +import utils + + +def unified_error_handling(func): + def func_wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except requests.HTTPError as e: + status_code = e.response.status_code + print(e) + print("------") + if status_code==404: + print("The server has returned an HTTP 404 error, which normally indicates a non-existing/invisible resource, e.g., requesting information with an invalid resource ID.") + elif status_code==403: + print("The server has returned an HTTP 403 error, which normally indicates a permission problem, e.g., current user has no permission to access the requested resource.") + else: + print("The server has returned an HTTP " + str(status_code) + " error.") + return None + except: + print("------") + print("Unexpected error:", sys.exc_info()[0]) + raise + return func_wrapper + + +@click.group("top-level") +def cli(): + pass + +@cli.command("config") +def config(): + """Initialise this application. + + Perform a one-time initialisation of this application. + Configurations are saved in $HOME/.ghpcfe/config file. + """ + print("Configuration file will be written at $HOME/.ghpcfe/config") + print() + server = input("Enter the URL of the server hosting the HPC application system: ") + try: + response = requests.get(server, timeout=10) + except requests.ConnectionError as exception: + print("URL appears to be invalid. Please double check it and try again.") + sys.exit(1) + api_key = input("Enter the API key associated with your user account: ") + try: + if len(api_key) != 40: + raise ValueError('Invalid length.') + value = int(api_key, 16) + except ValueError as exception: + print("The API key should be a 40-digit hexadecimal string.") + print("It can be found from the associated website.") + sys.exit(2) + config_data = { + 'config': { + 'server': { + 'url': server, + 'accessKey': api_key + } + } + } + config_dir = str(Path.home()) + "/.ghpcfe" + p = Path(config_dir) + p.mkdir(parents=True, exist_ok=True) + filepath = p / 'config' + with filepath.open('w+') as file: + yaml.dump(config_data, file, default_flow_style=False) + + +# credential management + +@cli.group("credential") +def credential(): + """Manage credentials. + + Manage cloud credentials used with this system. + """ + pass + +@credential.command(name="list", short_help="List all existing credentials.") +@unified_error_handling +def credential_list(): + """List all existing credentials.""" + config = utils.load_config() + ret = utils.get_model_state(config, 'credentials') + parsed = json.loads(ret) + utils.print_json(json.dumps(parsed)) + +@credential.command(name="add", short_help="Add/register a credential to the system.") +@click.option("-n", "--name", required=True, type=click.STRING) +@click.option("-f", "--credential_file", required=True, type=click.File(mode='r')) +def credential_add(name, credential_file): + """Add/register a credential to the system.""" + config = utils.load_config() + credential = credential_file.read() + url = f"{config['server']['url']}/api/credential-validate" + data = {"cloud_provider": "GCP", "detail": credential} + headers = {"Authorization": f"Token {config['server']['accessKey']}"} + response = requests.post(url, data=data, headers=headers) + parsed = json.loads(response.text) + if parsed['validated']: + data['name'] = name + ret = utils.model_create(config, 'credentials', data) + parsed = json.loads(ret) + utils.print_json(json.dumps(parsed)) + else: + print("Failed to validate this credential on GCP") + sys.exit(3) + +@credential.command(name="delete", short_help="Delete a credential from the system.") +def credential_delete(): + """Delete a credential from the system.""" + pass + + +# cluster management + +@cli.group("cluster") +def cluster(): + """Manage clusters. + + Manage the life cycles of clusters in this system. + """ + pass + +@cluster.command(name="list", short_help="List all existing clusters.") +@unified_error_handling +def cluster_list(): + """List all existing clusters.""" + config = utils.load_config() + ret = utils.get_model_state(config, 'clusters') + # keep only selected fields returned from API in list view + keys = ("cloud_region", "head_node_internal_ip", "cloud_credential", "advanced_networking", "ansible_branch", "cloud_vpc", "cloud_subnet", "homedirs", "spackdir", "mount_points") + parsed = json.loads(ret) + for cluster in parsed: + for key in keys: + del cluster[key] + utils.print_json(json.dumps(parsed)) + +@cluster.command(name="show", short_help="Show details of an existing cluster.") +@click.option('--id', required=True, type=click.INT) +@unified_error_handling +def cluster_show(id): + """Show details of an existing cluster.""" + config = utils.load_config() + ret = utils.get_model_state(config, 'clusters', id) + parsed = json.loads(ret) + utils.print_json(json.dumps(parsed)) + + +@cluster.command(name="create", short_help="Create a new cluster.") +@click.option("-n", "--name", required=True, type=click.STRING) +@click.option("-s", "--subnet", required=True, type=click.STRING) +def cluster_create(name, subnet): + """Create a new cluster.""" + print(f"cluster {name} created.") + +@cluster.command(name="destroy", short_help="Destroy a cluster.") +def cluster_destroy(): + """Destroy a cluster.""" + pass + + +# application management + +@cli.group("application") +def application(): + """Manage applications. + + Manage application installations on clusters. + """ + pass + +@application.command(name="list", short_help="List all applications.") +def application_list(): + click.echo('List all existing applications.') + +@application.command(name="show", short_help="Show details of an application.") +def application_show(): + click.echo('Show details of an application.') + +@application.command(name="spack-install", short_help="Install a Spack application.") +def application_spack_install(): + """Install a Spack application.""" + pass + + +# job management + +@cli.group("job") +def job(): + """Manage jobs. + + Manage jobs to run applications on clusters. + """ + pass + +@job.command(name="list", short_help="List all existing jobs.") +def job_list(): + """List all existing jobs.""" + pass + +@job.command(name="show", short_help="Show details of an existing job.") +def job_show(): + """Show details of an existing job.""" + pass + +@job.command(name="submit", short_help="Submit a job to run a specified application on a cluster.") +def job_submit(): + """Submit a job to run a specified application on a cluster.""" + pass + + +if __name__ == '__main__': + cli() diff --git a/frontend/cli/utils.py b/frontend/cli/utils.py new file mode 100644 index 0000000000..8d4e6f5426 --- /dev/null +++ b/frontend/cli/utils.py @@ -0,0 +1,63 @@ +# Copyright 2022 Google LLC +# +# 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. + +from pathlib import Path +import yaml +import requests +import json + +g_config = { + 'server': {}, + 'loaded': False +} + +def load_config(): + global g_config + if not g_config['loaded']: + config_file = str(Path.home()) + "/.ghpcfe/config" + p = Path(config_file) + if p.is_file(): + with p.open('r') as f: + g_config.update(yaml.safe_load(f)['config']) + g_config['loaded'] = True + else: + print("Please first initialise this application by 'python naghpc.py config'.") + return g_config + + +def get_model_state(config, table, key=None): + url = f"{config['server']['url']}/api/{table}/" + if key: + url += f"{key}/" + headers = {"Authorization": f"Token {config['server']['accessKey']}"} + resp = requests.get(url, headers=headers) + if not resp.ok: + resp.raise_for_status() + state = resp.json() + return json.dumps(state) + + +def model_create(config, table, data): + url = f"{config['server']['url']}/api/{table}/" + headers = {"Authorization": f"Token {config['server']['accessKey']}"} + resp = requests.post(url, data=data, headers=headers) + if not resp.ok: + resp.raise_for_status() + state = resp.json() + return json.dumps(state) + + +def print_json(json_str): + parsed = json.loads(json_str) + print(json.dumps(parsed, indent=4)) diff --git a/frontend/deploy.sh b/frontend/deploy.sh new file mode 100755 index 0000000000..73c38a8d2d --- /dev/null +++ b/frontend/deploy.sh @@ -0,0 +1,169 @@ +#!/bin/bash +# Copyright 2022 Google LLC +# +# 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. + +# Exit on any errors +set -e + +cat <<+ +Welcome to the deployment of the Google HPC Frontend. + +This script will ask a short series of questions to configure the frontend +before deployment. + +As this deployment creates many GCP resources, plenty of permissions are +required. Owner or Editor of the hosting GCP project can deploy without +any problem. A workable set of GCP roles for successful deployment includes: + +* Compute Admin +* Storage Admin +* Pub/Sub Admin +* Create Service Accounts, Delete Service Accounts, Service Account User + ++ + +# Check for terraform +if ! command -v terraform &> /dev/null +then + echo "Please install or make sure is in your \$PATH, terraform, version 0.13 or higher" + exit 1 +fi + +if ! command -v gsutil &> /dev/null +then + echo "Please install or make sure is in your \$PATH, gsutil, part of the Google Cloud Tools" + exit 1 +fi + + +# GCP project to deploy +while [ -z "${project_id}" ] ; +do + read -p "GCP Project Name: " project_id + if [ -z "${project_id}" ]; + then + echo "This cannot be left blank" + echo "" + fi +done + +read -p " Enter a cloud zone [europe-west4-a]: " zone +zone=${zone:-europe-west4-a} +region=${zone%-*} +read -p "Deployment name [lower-case letters, numbers, no spaces]: " deployment_name + +echo "" +echo "Please select deployment method of server software:" +echo " 1) Use a copy of the code from this computer" +echo " 2) Clone the git repo when server deploys" +read -p " Please choose one of the above options: " deploy_choice +if [ "${deploy_choice}" == "1" ]; +then + deployment="tarball" +elif [ "${deploy_choice}" == "2" ]; +then + deployment="git" + read -p "For Git clones, please specify the path to the deployment key: " deploy_key + if [ ! -r "${deploy_key}" ]; + then + echo "Deployment key file cannot be read." + exit 1 + fi + deploy_key=$(realpath "${deploy_key}") +else + echo "Invalid selection" + exit 1 +fi + +echo "" +echo "If you specify a DNS hostname, the server will attempt to acquire a TLS" +echo "Certificate from LetsEncrypt. If no hostname is specified, the server" +echo "will use standard, unencrypted HTTP. This is NOT RECOMMENDED." +read -p " Please enter the DNS hostname of the new webserver, or just hit enter for none: " hostname + +# Collect Django admin user information +echo "" +echo "To create an admin user for this web application:" +read -p " choose a username: " django_superuser_username +read -p " set an initial password for this user: " django_superuser_password +read -p " supply this user's email address: " django_superuser_email + +# Collect deployment files +if [ "${deployment}" == "tarball" ] ; +then + tar -cz -f tf/deployment.tar.gz --exclude=tf/ ../../hpc-toolkit 2>/dev/null +fi + +cd tf + +# Create Terraform setup +cat > terraform.tfvars <<+ +project_id = "${project_id}" +region = "${region}" +zone = "${zone}" + +deployment_name = "${deployment_name}" + +django_su_username = "${django_superuser_username}" +django_su_email = "${django_superuser_email}" +django_su_password = "${django_superuser_password}" + +deployment_mode = "${deployment}" + +extra_labels = { + creator = "${USER}" +} ++ + +if [ -n "${hostname}" ] +then + echo "webserver_hostname = \"${hostname}\"" >> terraform.tfvars +fi + +if [ "${deployment}" == "git" ]; then + echo "Will clone Hpc-Toolkit from github.com/${REPO_FORK:-GoogleCloudPlatform}.git branch ${REPO_BRANCH:-main}." + echo "Set REPO_BRANCH and REPO_FORK environment variables to override" + + echo "repo_branch = \"${REPO_BRANCH:-main}\"" >> terraform.tfvars + echo "repo_fork = \"${REPO_FORK:-GoogleCloudPlatform}\"" >> terraform.tfvars + echo "deployment_key = \"${deploy_key}\"" >> terraform.tfvars +fi + +echo "" +echo "" +echo "terraform.tfvars file has been created in the 'tf' directory." +echo "If you wish additional customization, please edit that file before continuing" +echo "" +read -r -p " Are you ready to deploy? [y/N]: " ready +case "$ready" in + [Yy]* ) break;; + * ) echo "exiting." ; exit;; +esac + +terraform init +terraform apply -auto-approve +echo "" +echo "Deployment in process. Initialization should take about 15 minutes." +echo "After that time, please point your web browser to the above server_ip." +if [ -n "${hostname}" ] +then + echo "and update your DNS record to point '${hostname}' to that IP." +fi + +echo "" +echo "To terminate this deployment, please make sure any resources created" +echo "by the FrontEnd have been destroyed, then run 'terraform destroy' from the" +echo "'tf' directory" +echo "" + diff --git a/frontend/docs/AppEngine-Notes.md b/frontend/docs/AppEngine-Notes.md new file mode 100644 index 0000000000..d400abb974 --- /dev/null +++ b/frontend/docs/AppEngine-Notes.md @@ -0,0 +1,69 @@ +# Moving to AppEngine + +## Benefits +* Increased reliance on GCP products +* Working towards a "Deployment" model +* TLS provided +* DNS provided - Useful for Google Login + + +## Useful Links: +* [Django in AppEngine Flexible Environment](https://cloud.google.com/python/django/flexible-environment) +* [App Engine Custom Runtime](https://cloud.google.com/appengine/docs/flexible/custom-runtimes) +* [Docker for Custom runtimes](https://cloud.google.com/appengine/docs/flexible/custom-runtimes/build) +* [Django and Docker](https://docs.docker.com/compose/django/) +* [Google Secrets Manager](https://cloud.google.com/secret-manager/docs/how-to) + +## Challenges + +1. Database + * Simply migrate to CloudSQL - can use a local CloudSQL Proxy to access same DB from development machines. +1. Invoking Terraform binaries + * Can use AppEngine "Flexible Environment" With the "Custom Runtime" Docker container, which can contain Terraform dependencies +1. Storage of TF state / vars files + * Consider storing in DB, and syncing with scratch space (`/tmp/`) as needed + * May need to consider locking via DB to prevent multiple simultaneous TF actions on the same cluster + * Consider storing in Cloud Storage rather than DB + * TF State is ~ 50KB + * Would enable storage of cluster log files +1. SSH key management + * Currently create an SSH key per cluster to allow "citc" access. + * Can have just 1 SSH key for the deployment - stored in Google Secrets Manager + * Deployed app would download the SSH private key and use it for connecting to clusters. + * Clusters would all need to be created using this same key +1. AppEngine scaling / weekly restarts + * Should be OK (aka, Django piece stateless), provided: + * Use CloudSQL + * TF State/Vars stored in DB + * SSH keys stored + + +## Changes Required: +### Additions +* Docker file +* Deployment / installation scripting + * Include creating SSH key secret + +### Django code + +Probably very little. + +### Django DB model + +May need to incorporate some state currently stored on disk (Terraform state / vars) + +### Backend Scripts + +#### Cluster Creation/Destruction +* Need to sync tfvars and tfstate with stable storage + * Stage from stable storage, run in scratch space, sync to stable storage +* Sync logs to stable storage? +* Re-use project-wide SSH key +* Need to install project scripts to cluster (Not stored open-source.) + +#### Install/Run scripts +* Rather than drive from management node, install scripts on cluster + * Management node will simply `ssh citc@ run_job ` + * `run_job` will then query the DB via API (back to management) to get required info, build SLURM submit script, etc.. Invoke job as user +* Some scripts need to be able to be run as unprivledged users (ie, update DB at end of job run) + diff --git a/frontend/docs/BJM-Notes.md b/frontend/docs/BJM-Notes.md new file mode 100644 index 0000000000..f944142bb1 --- /dev/null +++ b/frontend/docs/BJM-Notes.md @@ -0,0 +1,158 @@ +# Notes + + - OSC OpenOnDemand - doesn't really seem like the right fit. More focused on web-app front-end to clusters. + + - CitC supports Filestore/EFS (I think...) + - CitC supports multiple instance types in the "cluster" via SLURM + - `limits.yaml` sets your acceptable quota - need to investigate how this corresponds to SLURM Partitions (or some other mechanism to pick instance types at submission time) + - `-C FEATURE` to srun can be used to limit to nodes with particular 'features' set. (ie: `--constraint="intel"`) [Link](https://slurm.schedmd.com/srun.html#OPT_constraint) + - `./ansible/roles/slurm/files/update_config.py` sets features: + - `shape={shape}` (shape-name from `limits.yaml`) + - `ad={ad}` + - `arch={arch}` (x86_64, aarch64) + - **SUFFICIENT TO SUBMIT JOBS WITH -C shape=\** + + +- CitC + - config steps + - login update - centos@ -> Update ~citc/.ssh/authorized_keys + - set limits.yaml + - install spack into `/mnt/shared/spack` + - update `compute_image_extra.sh` to make sourcing spack part of login (`/etc/profile.d/spack` ?) + - `sudo /usr/local/bin/run-packer` + - `sudo /usr/local/bin/run-packer aarch64` (on AWS for graviton2) +- + + + +# DEMO FOR AWS + +~~~bash +$ terraform apply -auto-approve aws +#... <~3 minute wait> +ManagementPublicIP = 3.129.60.142 +cluster_id = smooth-termite +$ ssh -i ~/.ssh/aws-key centos@3.129.60.142 +The authenticity of host '3.129.60.142 (3.129.60.142)' can't be established. +ECDSA key fingerprint is SHA256:qqZ8PvlmJmCkzgq2FjxUsdbcbLXAsZnE2mbUEh5jwxE. +Are you sure you want to continue connecting (yes/no)? yes + +[centos@mgmt ~]$ sudo su -l citc +[citc@mgmt ~]$ sudo tail -f /root/ansible-pull.log +#... <~18 minute wait for ansible/packer build> +[citc@mgmt ~]$ cat > limits.yaml <<+ +> t3a.medium: 4 +> t4g.2xlarge: 4 +> + +> # Above needs to be chosen by user somehow + +[citc@mgmt ~]$ finish +[citc@mgmt ~]$ mkdir /mnt/shared/spack +[citc@mgmt ~]$ sudo git clone --depth 1 --branch v0.16.0 https://github.com/spack/spack.git /mnt/shared/spack +[citc@mgmt ~]$ chown -R citc:citc /mnt/shared/spack +[citc@mgmt ~]$ cat >> compute_image_extra.sh < VM_COUNT: the number of VM instances to include in that policy. For compact policies, you **must** apply the policy to exactly this number of instances. + +also + +> Compact: +> +> * **Up to 22 instances** in each policy +> * Applies to a fixed number of instances +> * Support **only for C2** machine types + +(emphasis is mine). + + +### Implementation conclusions from above + +1. Don't try to have Terraform create the placement groups, unless at TF time, we know the max size of the cluster. + - Could make this part of the `finish` call (`/usr/local/bin/update_config`) to create placement groups based off `limits.yaml` + - Would need to manage cleanup of these, somehow. (delete all that match a name (`${cluster_id}-placement-${shape}`), create new ones?) +1. Create placement groups on a per-instance-type basis +1. Make the `start_node` method become a `start_nodes` method, and support starting multiple instances with a single invocation of `startnode` from SLURM (it can pass a list of nodes) +1. `start_nodes` applies the resource policy/placement group if appropriate. diff --git a/frontend/docs/ClusterCommandControl.md b/frontend/docs/ClusterCommandControl.md new file mode 100644 index 0000000000..84a72f5b00 --- /dev/null +++ b/frontend/docs/ClusterCommandControl.md @@ -0,0 +1,68 @@ +# Command and Control of Clusters +Previous incarnations of this Frontend relied on the frontend webserver instance being able to SSH directly to clusters in order to performance command and control (C2) operations. When clusters were created, an admin user was set that would accept a public ssh key for which the webserver owned the private key. This was largely straightfoward, and worked quite well. The clusters were also able to make HTTP API queries to the webserver. + +This works well in the case where webserver and clusters all have public IP addresses, and are able to receive inbound requests, but it breaks down in the case where a user may wish to have the compute clusters not be directly exposed to the public internet. + +The new approach is based around [Google PubSub](https://cloud.google.com/pubsub/). The webserver and clusters now no longer directly communicate via SSH and HTTP, but rather send messages via Google Cloud. This offers the advantage of supporting clusters that are not publicly accessible, and removes the reliance on SSH connections between webserver and clusters. + +## PubSub details + +During deployment of a new Frontend system, a new Google PubSub Topic will be created. This centralized topic is used for all command and control traffice between the Frontend webserver and the client clusters. Individual Subscriptions are created for each cluster controller, as well as for the Frontend itself. The Frontend creates a new subscription for each cluster, and informs the cluster that it is to use the newly-created subscription. + +![](https://cloud.google.com/pubsub/images/wp_flow.svg) + +### Message Delivery + +Each [subscription is filtered](https://cloud.google.com/pubsub/docs/filtering) based off of a message attribute. Messages to each Cluster **MUST** have an attribute `target=cluster_X` where `X` is the Cluster's unique ID. Messages to the Frontend **MUST NOT** have a `target` attribute. + +By using filtering in this way, and having a 1:1 mapping between Subscription and Recipient, we guarantee that the messages being sent are received by only the intended recipient. + +### Message Schema + +Beyond the filtering attribute requirements previously discussed, the form of the messages are as follows: + +#### Common Attributes: + + * `command` - The command being sent as part of the message + * `source` - The identity of the sender - corresponds to the `target` attribute. This is how the Frontend identifies which cluster sent the message + +#### Common Message Data: + + * `ackid` - A UUID generated by the system to identify a command/response pair. + +Each command will have additional data in the Message Data, specific to that command's requirements. + +#### Commands: + + * `ACK` - Acknowledges a previous command, signals that the command is complete + * `UPDATE` - Acknowledges a previous command, but signals that the command is not yet complete. Can be sent in response to other commands multiple times, to be finally followed by an `ACK` + * `PING`, `PONG` - Testing commands. Not typically used + * `CLUSTER_STATUS` - Cluster command to Frontend to indicate a change in the status of the cluster. For example, to signal that the cluster has finished initialization and is ready for jobs. + * `SYNC` - Command to cluster to synchronize with the Frontend, including updating Log Files, and potentially other activities in the future (such as setting user permissions). + * `SPACK_INSTALL` - Install a Spack package + * `RUN_JOB` - Submit a job on behalf of a user to SLURM + * `REGISTER_USER_GCS` - Begin the process to register a user's GCS credentials with `gsutil`. + + +### Cluster C2 Daemon + +During startup of a cluster, a Daemon is installed which creates a Streaming Pull thread to Subscribe to the Cluster's Subscription. This daemon is responsible for responding to C2 messages and following through on the message's requests, including submitting jobs to SLURM to install Spack packages, and run user's jobs. + + +### Security + +The C2 topic is created at deployment time, as well as the subscription for the Frontend. Topic creation permission is then no longer required by the Service Accounts of the Frontend or the Clusters. + +When a Cluster is created, a new Service Account is created for that Cluster. This Service Account is then granted `pubsub.subscriber` permissions to the C2 Topic, and `pubsub.publisher` permissions to that cluster's own Subscription. The Service Accounts for the clusters are created without any Google PubSub IAM permissions, so these policy bindings on the topic and subscription are the only PubSub IAM permissions granted to the cluster's service accounts. + +Sadly, the Frontend's Service Account must have either the role of `pubsub.admin` or a custom role, set at the project level. This is because creating subscriptions and setting IAM Policy Bindings are actions done at the project level, rather than attached to the topic. + +By setting IAM policy bindings, we are able to grant permissions to service accounts which are associated with clusters which are in projects other than the base project where the Frontend resides. + +For example, if the Frontend is in GCP Project `Alpha`, the C2 Topic will also be in Project `Alpha`. If a cluster is then created in project `Beta`, the Frontend will grant the cluster's Service Account IAM permissions within the `Alpha` project. + +## Data Storage + +Previous systems relied on the Frontend webserver using SSH to download log files from the clusters to display to users. With the PubSub architecture, this needed to change. Clusters now automatically upload job logs to a GCS bucket, which is specified at cluster creation time. The Cluster's Service Account is granted ObjectAdmin permissions in order to create and update Log files in the GCS bucket. + +The Frontend webserver now displays log files from the GCS bucket, rather than copying them from the clusters via SSH. diff --git a/frontend/docs/Database design.md b/frontend/docs/Database design.md new file mode 100644 index 0000000000..06bcb9aa10 --- /dev/null +++ b/frontend/docs/Database design.md @@ -0,0 +1,99 @@ +# Database design + +[Ning] I've added comments to the doc based on my understanding of Django +framework. The autoincrement id fields are not necessary as they are handled +automatically. + +## User Table +(Note, use Google auth APIs - we don't want to do password management, etc) + + - `user_id` - key, autoincrement + - `username` - Name of user + +[Ning] Django's default User model contains username, email, password, +first_name, and last_name fields - should be sufficient for this project. We +derive from it to create a custom user model (but not adding any new field) to +facilitate future development. + +## User Access Table +Provides a mapping of which users have access to which clusters. [Ning] user A +could use a cluster created by user B if permission is given. This +relationship is a fairly straight-forward. Therefore it is added to the +Cluster table as a 'authorised users' field. In practice, Django generates an +extra table any way to handle such many-to-many relationship. + + - `user_id` - key into User Table + - `cluster_id` - key into Cluster Table + +## [Ning] Credential table +Save users cloud credentials. It is fairly complex to programmatically set up cloud credentials (e.g. create a service account on GCP and assign it sufficient permissions to allow working VMs as HPC clusters). We ask user to generate the credentials, either from command line or via web consoles, and copy/paste the credential details to the web form. It is fairly simple to validate credentials. + + - `name` - name of the credential + - `owner` - who owns this credential + - `cloud_provider` - Which provider + - `detail` - text of the credential (e.g. for GCP in JSON format) + - `validated` - flag whether this credential is validated + +## Cluster Table +[Ning] A user can have one cluster per cloud provider. Each cluster can have +multiple node types. + + - `cluster_id` - key, autoincrement? + - `name` - name of the cluster + - `internal_name` - cluster name generated by CitC + - `cloud_provider` - Which provider + - `credentials` - key into Credential table + - `instance_types` - VM instance types ('shape:count,shape:count...') [ning] constraints of node types can be imposed by 'Cluster in the cloud'. It is not easy to include the 'count' values in this database table. A separate table 'ClusterInstanceType' can be used. + - `region` - Cloud region + - `zone` - Cloud zone + - `headnode_ip` - Cluster Head Node IP addr + - `status` - [Ning] current status of the cluster, e.g. ready, stopped, deleted, as can be updated by the backend + +## Cluste Intance Type Table + - `cluster` - key into Cluster table + - `instanace_type` - key into MachineType table + - `count` - maximum number of such node type to use in the cluster + +## Benchmark Table + +[Ning] A benchmark is an unique combination of an application binary and an +input dataset, e.g. a OpenFOAM v7 compiled by xxx complier with yyy MPI library +running the MotorBike 22 million dataset. + + - `bench_id` - key, autoincrement? + - `name` - Common name of benchmark + dataset + - `app_name` - Name of benchmark application + - `dataset` - key into Dataset table + - `script_dir` - directory of target scripts [Ning] we can use the unique ID field in a directory structure when working with data files (both inputs and results) + +## Benchmark Results Table + +[Ning] This represents a single run of a benchamrk - run-time settings and +results can be saved in this table. + + - `run_id` - key, autoincrement? + - `bench_id` - key into Benchmark table + - `cluster_id` - key into Cluster table + - `instance_types` - Type of VM instance + - `arch` - Architecture of the processors (some machine type may have multiple architectures) + - `nnodes` - Number of Nodes used + - `ranks_per_node` - Number of MPI ranks per node + - `threads_per_rank` - Number of threads per MPI rank [Ning] reserved for future use to support hybrid code + - `state` - "Waiting, Installing, Preparing, Running, Finished, Error", etc. + - `log text` - Truncated Output from running the job [Ning] may be better to store logs in files, using unique file names containing the ID of this benchmark. + - `result_units` - Units for results (seconds, itrs/sec, etc) + - `result_value` - Benchmark results value + - `runtime` - Benchmark result runtime (may duplicate `result_value` in some cases) + +## [Ning] Dataset Table + +This represents a single input dataset. One dataset may be used by multiple +benchmarks (two applications, or different versions of the same application +can can use the same dataset); one application installation can run mutiple +dataset. This table can take care of such logic. + +## [Ning] Other tables + +In Django, it is fairly easy to create additional models to represent small +objects such as machine types, cloud providers, compilers, MPI libraries. We +benefit from Django's admin site to easily manage these fields. diff --git a/frontend/infrastructure_files/cluster_startup/templates/bootstrap_compute.sh b/frontend/infrastructure_files/cluster_startup/templates/bootstrap_compute.sh new file mode 100644 index 0000000000..7ad78a8922 --- /dev/null +++ b/frontend/infrastructure_files/cluster_startup/templates/bootstrap_compute.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +BUCKET={{ server_bucket }} +CLUSTER_ID={{ cluster.id }} +SPACK_DIR={{ spack_dir }} + +echo "This is the startup script for the compute nodes on cluster ${CLUSTER_ID}" + +# Install ansible +# Download ansible playbook from GCS bucket +# Set up our facts file +# Run ansible for controller + +set -x +set -e +yum install -y ansible + +cd /tmp +gsutil -m cp -r gs://${BUCKET}/clusters/ansible_setup /tmp +cd /tmp/ansible_setup + +# Set up facts file +mkdir facts.d +cat > facts.d/ghpcfe.fact < facts.d/ghpcfe.fact < facts.d/ghpcfe.fact < 150: # 300 seconds + logger.error("Wait timed out - 5 minutes passed!") + response['status'] = 'Wait timed out - 5 minutes passed!' + send_message('ACK', response) + child.terminate(force=True) + _c2_ackMap.pop(ackid) + return + + # Remove our callback, now that we have our verify key + _c2_ackMap.pop(ackid) + + child.expect('Enter the authorization code:') + child.sendline(my_verify_key) + child.expect(pexpect.EOF) + child.wait() + child.close() + response['exit_status'] = child.exitstatus + response['status'] = 'Success' if child.exitstatus == 0 else 'Failure' + send_message('ACK', response) + + except Exception as ex: + logger.error("Failed to configure User's GCS creds.", exc_info=ex) + send_message('ACK', response) + pass + +# Other Callbacks + +def cb_ping(message): + logger.info(f"Received PING") + if 'id' in message: + logger.info(f" PING id {id}. Sending ACK") + pid = message['id'] + send_message('PONG', {'id': pid}) + + +def cb_pong(message): + logger.info(f"Received PONG!") + if 'id' in message: + logger.info(f" PING id {id}.") + + +def cb_ack(message): + ackid = message.get('ackid', None) + logger.info(f"Received ACK to message {ackid}!") + try: + cb = _c2_ackMap.pop[ackid] + logger.info(f"Calling final callback for ACK id {ackid}") + cb(message) + except KeyError: + pass + + +def cb_update(message): + ackid = message.get('ackid', None) + logger.info(f"Received UPDATE to message {ackid}!") + try: + cb = _c2_ackMap[ackid] + logger.info("Calling callback for UPDATE") + cb(message) + except KeyError: + logger.warning("No registered Update Callback for this ID") + + +callback_map = { + 'ACK': cb_ack, + 'PING': cb_ping, + 'PONG': cb_pong, + 'SYNC': cb_sync, + 'UPDATE': cb_update, + 'SPACK_INSTALL': cb_spack_install, + 'RUN_JOB': cb_run_job, + 'REGISTER_USER_GCS': cb_register_user_gcs, +} + + +def callback(message): + logger.info(f"Received {message.data!r}.") + cmd = message.attributes.get('command', None) + if cmd in callback_map: + callback_map[cmd](json.loads(message.data)) + else: + logger.warning("No Command attribute in the message. Discarding") + message.ack() + + +if __name__ == "__main__": + + streaming_pull_future = subscriber.subscribe(config['subscription_path'], callback=callback) + logger.info(f"Listening for messages on {config['subscription_path']}..\n") + + send_message('CLUSTER_STATUS', { + 'message': "Cluster C2 Daemon started", + # Mark the cluster as now running + 'status': 'r', + }) + + # Wrap subscriber in a 'with' block to automatically call close() when done. + with subscriber: + try: + # When `timeout` is not set, result() will block indefinitely, + # unless an exception is encountered first. + streaming_pull_future.result() + + except Exception as exc: + logger.error('Received exception. Shutting down.', exc_info=exc) + streaming_pull_future.cancel() # Trigger the shutdown. + streaming_pull_future.result() # Block until the shutdown is complete. + + thread_pool.shutdown() + + send_message('CLUSTER_STATUS', { + 'message': "Cluster C2 Daemon stopping", + }) + diff --git a/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/c2_daemon/tasks/main.yaml b/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/c2_daemon/tasks/main.yaml new file mode 100644 index 0000000000..0108589e41 --- /dev/null +++ b/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/c2_daemon/tasks/main.yaml @@ -0,0 +1,47 @@ +--- +- name: Upgrade PIP3 + pip: + executable: pip3 + name: pip + state: latest + +- name: Install FE C&C Dependencies + pip: + executable: pip3 + name: + - requests + - pexpect + - google-cloud-storage + - google-cloud-pubsub + +- name: Enable su to OS Login + lineinfile: + path: /etc/pam.d/su + line: session [success=ok default=ignore] pam_mkhomedir.so + state: present + insertafter: EOF + +- name: Install FE C&C Daemon + copy: + src: ghpcfe_c2daemon.py + dest: /usr/local/sbin/ghpcfe_c2daemon.py + mode: 0755 + +- name: Install FE C&C Daemon Config + template: + src: ghpcfe_c2.yaml.j2 + dest: /usr/local/etc/ghpcfe_c2.yaml + mode: 0755 + +- name: Install FE C&C service file + copy: + src: ghpcfe_c2.service + dest: /etc/systemd/system/ghpcfe_c2.service + +- name: Start FE C&C Daemon + systemd: + daemon_reload: yes + state: started + name: ghpcfe_c2 + enabled: yes + masked: no diff --git a/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/c2_daemon/templates/ghpcfe_c2.yaml.j2 b/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/c2_daemon/templates/ghpcfe_c2.yaml.j2 new file mode 100644 index 0000000000..02393cbb6e --- /dev/null +++ b/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/c2_daemon/templates/ghpcfe_c2.yaml.j2 @@ -0,0 +1,5 @@ +topic_path: {{ ansible_local.ghpcfe.config.fec2_topic }} +subscription_path: {{ ansible_local.ghpcfe.config.fec2_subscription }} +cluster_id: {{ ansible_local.ghpcfe.config.cluster_id }} +cluster_bucket: {{ ansible_local.ghpcfe.config.cluster_bucket }} +spack_path: {{ ansible_local.ghpcfe.config.spack_dir }} diff --git a/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/dev_env/tasks/main.yaml b/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/dev_env/tasks/main.yaml new file mode 100644 index 0000000000..31fdc5afeb --- /dev/null +++ b/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/dev_env/tasks/main.yaml @@ -0,0 +1,22 @@ +--- +- name: Install CentOS Software Collections + yum: + name: centos-release-scl +- name: Install Dev Tools + yum: + name: + - devtoolset-9 + - devtoolset-11 + - cmake + - python2-devel + - python36-devel + + +- name: Add DevTools to default shells + copy: + dest: /etc/profile.d/98-devtools.sh + content: | + . /opt/rh/devtoolset-11/enable + owner: root + mode: 0755 + force: no diff --git a/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/spack_install/tasks/main.yaml b/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/spack_install/tasks/main.yaml new file mode 100644 index 0000000000..c83296d706 --- /dev/null +++ b/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/spack_install/tasks/main.yaml @@ -0,0 +1,54 @@ +--- +- name: Create Spack Directory + file: + path: "{{ spack_dir }}" + owner: root + group: root + state: directory + mode: 0755 + +- name: Clone Spack + git: + repo: https://github.com/spack/spack.git + dest: "{{ spack_dir }}" + version: v0.17.1 + depth: 1 + +- name: Apply Global Spack configurations + command: "{{ spack_dir }}/bin/spack config --scope site add config:db_lock_timeout:30" + + +- name: Init Spack DB + command: "{{ spack_dir }}/bin/spack reindex" + +- name: Determine Slurm version + shell: "/usr/local/bin/scontrol --version | awk '{print $2}' | tr '.' '-'" + register: slurm_version_cmd +- set_fact: + slurm_version={{ slurm_version_cmd.stdout }} +- name: Write Slurm Package file + copy: + dest: /tmp/spack_pkg.yml + content: | + packages: + slurm: + externals: + - spec: slurm@{{ slurm_version_cmd.stdout }} + prefix: /usr/local + buildable: false +- name: Spack import Slurm + command: "{{ spack_dir }}/bin/spack config --scope site add -f /tmp/spack_pkg.yml" +- name: Remove temporary file + file: + path: /tmp/spack_pkg.yml + state: absent + +- name: Set MPI provider preferences + command: "{{ spack_dir }}/bin/spack config --scope site add 'packages:all:providers:mpi:[intel-mpi,intel-oneapi-mpi,openmpi,mpich]'" + +- name: Set OpenMPI default options + command: "{{ spack_dir }}/bin/spack config --scope site add packages:openmpi:variants:'+pmi +legacylaunchers schedulers=slurm fabrics=auto'" + +- name: Set MPICH default options + command: "{{ spack_dir }}/bin/spack config --scope site add packages:mpich:variants:'+slurm netmod=tcp'" + diff --git a/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/spack_setup/tasks/main.yaml b/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/spack_setup/tasks/main.yaml new file mode 100644 index 0000000000..67cde7b1dd --- /dev/null +++ b/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/roles/spack_setup/tasks/main.yaml @@ -0,0 +1,30 @@ +--- +- name: Spack config externals + shell: | + module load openmpi + {{ spack_dir }}/bin/spack external find --scope=system --not-buildable + +- name: Spack mark cmake as buildable + command: "{{ spack_dir }}/bin/spack config --scope system add packages:cmake:buildable:true" + +- name: Spack mark python as buildable + command: "{{ spack_dir }}/bin/spack config --scope system add packages:python:buildable:true" + +- name: Spack mark OpenMPI as buildable + command: "{{ spack_dir }}/bin/spack config --scope system add packages:openmpi:buildable:true" + +- name: Spack mark GCC as buildable + command: "{{ spack_dir }}/bin/spack config --scope system add packages:gcc:buildable:true" + +- name: Spack Find DevTool compiler + command: "{{ spack_dir }}/bin/spack compiler find --scope system /opt/rh/devtoolset-11/root/usr/bin" + + +- name: Add Spack to default shells + copy: + dest: /etc/profile.d/99-spack.sh + content: | + . {{ spack_dir }}/share/spack/setup-env.sh + owner: root + mode: 0755 + force: no diff --git a/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/vars.yaml b/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/vars.yaml new file mode 100644 index 0000000000..608f25c545 --- /dev/null +++ b/frontend/infrastructure_files/gcs_bucket/clusters/ansible_setup/vars.yaml @@ -0,0 +1,2 @@ +--- +spack_dir: "{{ ansible_local.ghpcfe.config.spack_dir }}" diff --git a/frontend/infrastructure_files/gcs_bucket/webserver/startup.sh b/frontend/infrastructure_files/gcs_bucket/webserver/startup.sh new file mode 100644 index 0000000000..28e8513ccf --- /dev/null +++ b/frontend/infrastructure_files/gcs_bucket/webserver/startup.sh @@ -0,0 +1,229 @@ +#!/bin/bash +# Copyright 2022 Google LLC +# +# 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. + + +# Startup script to prepare a new VM to host the web application for the +# Multi-platform HPC Application System + +# based on a CentOS 8 system + +# obtain metadata of this server +GCP_PROJECT=$(curl --silent --show-error http://metadata.google.internal/computeMetadata/v1/project/project-id -H "Metadata-Flavor: Google") +SERVER_IP_ADDRESS=$(curl --silent --show-error http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip -H "Metadata-Flavor: Google") +SERVER_HOSTNAME=$(curl --silent --fail http://metadata/computeMetadata/v1/instance/attributes/hostname -H "Metadata-Flavor: Google") +config_bucket=$(curl --silent --show-error http://metadata/computeMetadata/v1/instance/attributes/webserver-config-bucket -H "Metadata-Flavor: Google") +c2_topic=$(curl --silent --show-error http://metadata/computeMetadata/v1/instance/attributes/ghpcfe-c2-topic -H "Metadata-Flavor: Google") +deploy_mode=$(curl --silent --show-error http://metadata/computeMetadata/v1/instance/attributes/deploy_mode -H "Metadata-Flavor: Google") + +# Exit if deployment already exists to stop startup script running on reboots +if [[ -d /opt/gcluster/hpc-toolkit ]] +then + printf "It appears gcluster has already been deployed. Exiting...\n" + exit 0; +fi + +printf "####################\n#### Installing required packages\n####################\n" +dnf install -y epel-release +dnf update -y --security +dnf config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo +dnf install --best -y google-cloud-sdk nano make gcc python38-devel unzip git \ + rsync nginx bind-utils policycoreutils-python-utils \ + terraform packer supervisor python3-certbot-nginx +curl --silent --show-error --location https://github.com/mikefarah/yq/releases/download/v4.13.4/yq_linux_amd64 --output /usr/local/bin/yq +chmod +x /usr/local/bin/yq +curl --silent --show-error --location https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.linux.x86_64.tar.xz --output /tmp/shellcheck.tar.xz +tar xfa /tmp/shellcheck.tar.xz --strip=1 --directory /usr/local/bin + +# donwload configuration file +gsutil cp "gs://${config_bucket}/webserver/config" /tmp/config +gsutil rm "gs://${config_bucket}/webserver/config" + +# load configurations +DJANGO_USERNAME=$(/usr/local/bin/yq e '.django_username' /tmp/config) +DJANGO_PASSWORD=$(/usr/local/bin/yq e '.django_password' /tmp/config) +DJANGO_EMAIL=$(/usr/local/bin/yq e '.django_email' /tmp/config) +GOOGLE_CLIENT_ID=$(/usr/local/bin/yq e '.google_client_id' /tmp/config) +GOOGLE_CLIENT_SECRET=$(/usr/local/bin/yq e '.google_client_secret' /tmp/config) +repo_fork=$(/usr/local/bin/yq e '.git_fork' /tmp/config) +repo_branch=$(/usr/local/bin/yq e '.git_branch' /tmp/config) +# 'yq' does not handle multi-line string properly, need to restore the correct key format +TMP=$(/usr/local/bin/yq e '.deploy_key1' /tmp/config) +TMP2=$(echo "$TMP" | sed 's/ /\n/g') +DEPLOY_KEY1=$(echo "$TMP2" | sed -z 's/\nOPENSSH\nPRIVATE\nKEY/ OPENSSH PRIVATE KEY/g') +rm -f /tmp/config + +#install go from golang as repo version is too low for hpc-toolkit +curl --silent --show-error --location https://golang.org/dl/go1.17.3.linux-amd64.tar.gz --output /tmp/go1.17.3.linux-amd64.tar.gz +rm -rf /usr/local/go && tar -C /usr/local -xzf /tmp/go1.17.3.linux-amd64.tar.gz + +#Add path entry for Go binaries to bashrc for all users (only works on future logins) +echo 'export PATH=$PATH:/usr/local/go/bin:~/go/bin' >> /etc/bashrc + +printf "\n####################\n#### Creating firewall & SELinux rules\n####################\n" +printf "Adding rule for port 22 (ssh): " +firewall-cmd --permanent --add-port=22/tcp +printf "Adding rule for port 80: " +firewall-cmd --permanent --add-port=80/tcp +printf "Adding rule for port 443: " +firewall-cmd --permanent --add-port=443/tcp +printf "Reloading firewall: " +firewall-cmd --reload +setsebool httpd_can_network_connect on -P + +printf "\n####################\n#### Create gcluster user & create deployment key\n####################\n" +printf "Adding gcluster user...\n" +useradd -r -m -d /opt/gcluster gcluster + +if [ "${deploy_mode}" == "git" ]; +then + printf "Adding deployment keys..\n" + mkdir -p /opt/gcluster/.ssh + + echo "$DEPLOY_KEY1" > /opt/gcluster/.ssh/gcluster-ghdeploy-20211109 + sed -i -e :a -e '/^\n*$/{$d;N;ba' -e '}' /opt/gcluster/.ssh/gcluster-ghdeploy-20211109 + chmod 700 /opt/gcluster/.ssh/ghpc-ghdeploy-20211109 + cat >> /opt/gcluster/.ssh/config <<+ + +host github.com + hostname github.com + IdentityFile ~/.ssh/ghpc-ghdeploy-20211109 + StrictHostKeyChecking=accept-new ++ + chown -R /opt/gcluster/.ssh + + fetch_hpc_toolkit="git clone -b \"${repo_branch}\" git@github.com:${repo_fork}/hpc-toolkit.git" + +elif [ "${deploy_mode}" == "tarball" ]; +then + printf "\n####################\n#### Download web application files\n####################\n" + gsutil cp "gs://${config_bucket}/webserver/deployment.tar.gz" /tmp/deployment.tar.gz + + fetch_hpc_toolkit="tar xfz /tmp/deployment.tar.gz" +fi + + +#Clean up anything we may have missed +chown gcluster:gcluster -R /opt/gcluster + +# run the following as 'gcluster' user +sudo su - gcluster -c /bin/bash < configuration.yaml + echo " server:" >> configuration.yaml + echo " domain_name: \"${SERVER_HOSTNAME:-${SERVER_IP_ADDRESS}}\"" >> configuration.yaml + echo " host_type: \"GCP\"" >> configuration.yaml + echo " gcp_project: \"$GCP_PROJECT\"" >> configuration.yaml + echo " gcs_bucket: \"${config_bucket}\"" >> configuration.yaml + echo " c2_topic: \"${c2_topic}\"" >> configuration.yaml + + printf "\nInitalising Django environments...\n" + mkdir /opt/gcluster/run + pushd website + python manage.py makemigrations + python manage.py migrate + printf "\nCreating django super user..." + DJANGO_SUPERUSER_PASSWORD=$DJANGO_PASSWORD python manage.py createsuperuser --username $DJANGO_USERNAME --email $DJANGO_EMAIL --noinput + printf "\nInitialise Django db" + python manage.py custom_startup_command $GOOGLE_CLIENT_ID $GOOGLE_CLIENT_SECRET + printf "\nSet up static contents..." + python manage.py collectstatic + python manage.py seed_workbench_presets + popd + + printf "\nUpdating Django settings.py...\n" + sed -e "s/SERVER_IP/$SERVER_IP_ADDRESS/g" -e "s/SERVER_NAME/$SERVER_HOSTNAME/g" -i website/website/settings.py + if [ -n "${SERVER_HOSTNAME}" ] ; then + sed "s/SERVER_NAME/$SERVER_HOSTNAME/g" -i website/nginx.conf + else + # No server name set, remove the entry + sed "/SERVER_NAME/d" -i website/nginx.conf + fi + +EOF + +printf "Creating supervisord service..." +echo "[program:gcluster-uvicorn-background] +process_name=%(program_name)s_%(process_num)02d +directory=/opt/gcluster/hpc-toolkit/frontend/website +command=/opt/gcluster/django-env/bin/uvicorn website.asgi:application --reload --host 127.0.0.1 --port 8001 +autostart=true +autorestart=true +user=gcluster +redirect_stderr=true +stdout_logfile=/opt/gcluster/run/supvisor.log" > /etc/supervisord.d/gcluster.ini + +printf "Creating systemd service..." +echo "[Unit] +Description=GCluster: The GCP HPC Cluster deployment tool +Requires=supervisord.service + + +[Service] +Type=forking +ExecStart=/usr/sbin/nginx -p /opt/gcluster/run/ -c /opt/gcluster/hpc-toolkit/frontend/website/nginx.conf +ExecStop=/usr/sbin/nginx -p /opt/gcluster/run/ -c /opt/gcluster/hpc-toolkig/frontend/website/nginx.conf -s stop +PIDFile=/opt/gcluster/run/nginx.pid +Restart=no + + +[Install] +WantedBy=default.target" > /etc/systemd/system/gcluster.service + +printf "Reloading systemd and starting service..." +setenforce 0 +systemctl daemon-reload +systemctl start gcluster.service +systemctl status gcluster.service + + +# IF we have a hostname, configure for TLS +if [ -n "${SERVER_HOSTNAME}" ] ; then + printf "Installing LetsEncrypt Certificate" + /usr/bin/certbot --nginx --nginx-server-root=/opt/gcluster/hpc-toolkit/frontend/website -m ${DJANGO_EMAIL} --agree-tos -d ${SERVER_HOSTNAME} + + printf "Installing Cron entry to keep Cert up to date" + tmpcron=$(mktemp) + crontab -l root > "${tmpcron}" 2>/dev/null + echo "0 12 * * * /usr/bin/certbot renew --quiet" >> "${tmpcron}" + crontab -u root "${tmpcron}" + rm "${tmpcron}" +fi + diff --git a/frontend/infrastructure_files/vpc_tf/GCP/main.tf b/frontend/infrastructure_files/vpc_tf/GCP/main.tf new file mode 100644 index 0000000000..fcad1363b8 --- /dev/null +++ b/frontend/infrastructure_files/vpc_tf/GCP/main.tf @@ -0,0 +1,74 @@ + +resource "random_pet" "vpc_name" { + length = 2 + separator = "-" + keepers = { } +} + +locals { + vpc_key = random_pet.vpc_name.id +} + +# VPC Creation +resource "google_compute_network" "network" { + name = "${local.vpc_key}-network" + project = var.project + auto_create_subnetworks = false +} + + +resource "google_compute_router" "network_router" { + name = "${local.vpc_key}-compute-router" + region = var.region + project = var.project + network = google_compute_network.network.name +} + +resource "google_compute_router_nat" "network_nat" { + name = "${local.vpc_key}-nat" + project = var.project + router = google_compute_router.network_router.name + region = google_compute_router.network_router.region + nat_ip_allocate_option = "AUTO_ONLY" + source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES" + log_config { + enable = true + filter = "ERRORS_ONLY" + } +} + + + +# Firewalls - allow all internal, allow ssh from external + +resource "google_compute_firewall" "firewall_allow_ssh" { + name = "${local.vpc_key}-firewall-ssh" + network = google_compute_network.network.name + project = var.project + source_ranges = ["0.0.0.0/0"] + allow { + protocol = "tcp" + ports = ["22"] + } +} + + +resource "google_compute_firewall" "firewall_internal" { + name = "${local.vpc_key}-firewall-internal" + network = google_compute_network.network.name + project = var.project + source_ranges = ["10.0.0.0/8"] + allow { + protocol = "tcp" + ports = ["0-65535"] + } + allow { + protocol = "udp" + ports = ["0-65535"] + } + allow { protocol = "icmp" } +} + +output "vpc_id" { + value = google_compute_network.network.name +} diff --git a/frontend/infrastructure_files/vpc_tf/GCP/subnet.tf.template b/frontend/infrastructure_files/vpc_tf/GCP/subnet.tf.template new file mode 100644 index 0000000000..c5b604f341 --- /dev/null +++ b/frontend/infrastructure_files/vpc_tf/GCP/subnet.tf.template @@ -0,0 +1,12 @@ + +resource "google_compute_subnetwork" "subnet_{SUBNET_ID}" { + name = "${local.vpc_key}-subnet-{SUBNET_ID}" + region = var.region + project = var.project + ip_cidr_range = "{CIDR_TEXT}" + network = google_compute_network.network.name +} + +output "subnet-{SUBNET_ID}" { + value = google_compute_subnetwork.subnet_{SUBNET_ID}.name +} diff --git a/frontend/infrastructure_files/vpc_tf/GCP/variables.tf b/frontend/infrastructure_files/vpc_tf/GCP/variables.tf new file mode 100644 index 0000000000..f6e7645818 --- /dev/null +++ b/frontend/infrastructure_files/vpc_tf/GCP/variables.tf @@ -0,0 +1,11 @@ +variable "project" { +} + +variable "region" { +} + +variable "zone" { +} + +variable "credentials" { +} diff --git a/frontend/infrastructure_files/vpc_tf/GCP/versions.tf b/frontend/infrastructure_files/vpc_tf/GCP/versions.tf new file mode 100644 index 0000000000..6aba7451bd --- /dev/null +++ b/frontend/infrastructure_files/vpc_tf/GCP/versions.tf @@ -0,0 +1,18 @@ +terraform { + required_providers { + google = { + source = "hashicorp/google" + version = ">= 3.54" + } + } + + required_version = ">= 0.12.20" +} + + +provider "google" { + credentials = file(var.credentials) + project = var.project + region = var.region + zone = var.zone +} diff --git a/frontend/infrastructure_files/workbench_tf/google/main.tf b/frontend/infrastructure_files/workbench_tf/google/main.tf new file mode 100644 index 0000000000..d76830020b --- /dev/null +++ b/frontend/infrastructure_files/workbench_tf/google/main.tf @@ -0,0 +1,232 @@ +/** + * Copyright 2021 Google LLC + * + * 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. + */ + +locals { + random_id = var.random_id != null ? var.random_id : random_id.default.hex + project = (var.create_project + ? try(module.project_radlab_ds_analytics.0, null) + : try(data.google_project.existing_project.0, null) + ) + region = join("-", [split("-", var.zone)[0], split("-", var.zone)[1]]) + + network = ( + var.create_network + ? try(module.vpc_ai_notebook.0.network.network, null) + : try(data.google_compute_network.default.0, null) + ) + + subnet = ( + var.create_network + ? try(module.vpc_ai_notebook.0.subnets["${local.region}/${var.subnet_name}"], null) + : try(data.google_compute_subnetwork.default.0, null) + ) + + notebook_sa_project_roles = [ + "roles/compute.instanceAdmin", + "roles/notebooks.admin", + "roles/bigquery.user", + "roles/storage.objectViewer" + ] + + project_services = var.enable_services ? [ + "compute.googleapis.com", + "bigquery.googleapis.com", + "notebooks.googleapis.com", + "bigquerystorage.googleapis.com" + ] : [] +} + +resource "random_id" "default" { + byte_length = 2 +} + +##################### +# ANALYTICS PROJECT # +##################### + +data "google_project" "existing_project" { + count = var.create_project ? 0 : 1 + project_id = var.project_name +} + +module "project_radlab_ds_analytics" { + count = var.create_project ? 1 : 0 + source = "terraform-google-modules/project-factory/google" + version = "~> 11.0" + + name = format("%s-%s", var.project_name, local.random_id) + random_project_id = false + folder_id = var.folder_id + billing_account = var.billing_account_id + org_id = var.organization_id + + activate_apis = [] +} + +resource "google_project_service" "enabled_services" { + for_each = toset(local.project_services) + project = local.project.project_id + service = each.value + disable_dependent_services = true + disable_on_destroy = true + + depends_on = [ + module.project_radlab_ds_analytics + ] +} + +data "google_compute_network" "default" { + count = var.create_network ? 0 : 1 + project = local.project.project_id + name = var.network_name +} + +data "google_compute_subnetwork" "default" { + count = var.create_network ? 0 : 1 + project = local.project.project_id + name = var.subnet_name + region = local.region +} + +module "vpc_ai_notebook" { + count = var.create_network ? 1 : 0 + source = "terraform-google-modules/network/google" + version = "~> 3.0" + + project_id = local.project.project_id + network_name = var.network_name + routing_mode = "GLOBAL" + description = "VPC Network created via Terraform" + + subnets = [ + { + subnet_name = var.subnet_name + subnet_ip = var.ip_cidr_range + subnet_region = local.region + description = "Subnetwork inside *vpc-analytics* VPC network, created via Terraform" + subnet_private_access = true + } + ] + + firewall_rules = [ + { + name = "fw-ai-notebook-allow-internal" + description = "Firewall rule to allow traffic on all ports inside *vpc-analytics* VPC network." + priority = 65534 + ranges = ["10.0.0.0/8"] + direction = "INGRESS" + + allow = [{ + protocol = "tcp" + ports = ["0-65535"] + }] + } + ] + + depends_on = [ + google_project_service.enabled_services + ] +} + +resource "google_service_account" "sa_p_notebook" { + project = local.project.project_id + account_id = format("sa-p-notebook-%s", local.random_id) + display_name = "Notebooks in trusted environment" +} + +resource "google_project_iam_member" "sa_p_notebook_permissions" { + for_each = toset(local.notebook_sa_project_roles) + project = local.project.project_id + member = "serviceAccount:${google_service_account.sa_p_notebook.email}" + role = each.value +} + +resource "google_service_account_iam_member" "sa_ai_notebook_user_iam" { + for_each = var.trusted_users + member = each.value + role = "roles/iam.serviceAccountUser" + service_account_id = google_service_account.sa_p_notebook.id +} + +resource "google_project_iam_binding" "ai_notebook_user_role1" { + project = local.project.project_id + members = var.trusted_users + role = "roles/notebooks.admin" +} + +resource "google_project_iam_binding" "ai_notebook_user_role2" { + project = local.project.project_id + members = var.trusted_users + role = "roles/viewer" +} + +resource "google_notebooks_instance" "ai_notebook" { + count = var.notebook_count + project = local.project.project_id + name = "notebooks-instance-${local.random_id}-${count.index}" + location = var.zone + machine_type = var.machine_type + + vm_image { + project = var.image_project + image_family = var.image_family + } + + service_account = google_service_account.sa_p_notebook.email + + install_gpu_driver = false + boot_disk_type = var.boot_disk_type + boot_disk_size_gb = var.boot_disk_size_gb + + no_public_ip = false + no_proxy_access = false + + network = local.network.self_link + subnet = local.subnet.self_link + + post_startup_script = "https://github.com/GoogleCloudPlatform/rad-lab/blob/main/modules/data_science/scripts/build/samplenotebook.sh" + + labels = { + module = "data-science" + } + + metadata = { + terraform = "true" + proxy-mode = "mail" + } + depends_on = [time_sleep.wait_120_seconds] +} + +resource "google_storage_bucket" "user_scripts_bucket" { + project = local.project.project_id + name = join("", ["user-scripts-notebooks-instance-", local.random_id]) + location = "US" + force_destroy = true + uniform_bucket_level_access = true + + cors { + origin = ["http://user-scripts"] + method = ["GET", "HEAD", "PUT", "POST", "DELETE"] + response_header = ["*"] + max_age_seconds = 3600 + } +} + +resource "google_storage_bucket_iam_binding" "binding" { + bucket = google_storage_bucket.user_scripts_bucket.name + role = "roles/storage.admin" + members = var.trusted_users +} \ No newline at end of file diff --git a/frontend/infrastructure_files/workbench_tf/google/orgpolicy.tf b/frontend/infrastructure_files/workbench_tf/google/orgpolicy.tf new file mode 100644 index 0000000000..e93ba9e395 --- /dev/null +++ b/frontend/infrastructure_files/workbench_tf/google/orgpolicy.tf @@ -0,0 +1,74 @@ +/** + * Copyright 2021 Google LLC + * + * 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. + */ + + +resource "google_project_organization_policy" "external_ip_policy" { + count = var.set_external_ip_policy ? 1 : 0 + constraint = "compute.vmExternalIpAccess" + project = local.project.project_id + + list_policy { + allow { + all = true + } + } + depends_on = [ + module.project_radlab_ds_analytics + ] +} + +resource "google_project_organization_policy" "shielded_vm_policy" { + count = var.set_shielded_vm_policy ? 1 : 0 + constraint = "compute.requireShieldedVm" + project = local.project.project_id + + boolean_policy { + enforced = false + } + depends_on = [ + module.project_radlab_ds_analytics + ] +} + +resource "google_project_organization_policy" "trustedimage_project_policy" { + count = var.set_trustedimage_project_policy ? 1 : 0 + constraint = "compute.trustedImageProjects" + project = local.project.project_id + + list_policy { + allow { + values = [ + "is:projects/deeplearning-platform-release", + ] + } + } + + depends_on = [ + module.project_radlab_ds_analytics + ] +} + +resource "time_sleep" "wait_120_seconds" { + count = var.set_trustedimage_project_policy || var.set_shielded_vm_policy || var.set_external_ip_policy ? 1 : 0 + + depends_on = [ + google_project_organization_policy.external_ip_policy, + google_project_organization_policy.shielded_vm_policy, + google_project_organization_policy.trustedimage_project_policy + ] + + create_duration = "120s" +} \ No newline at end of file diff --git a/frontend/infrastructure_files/workbench_tf/google/outputs.tf b/frontend/infrastructure_files/workbench_tf/google/outputs.tf new file mode 100644 index 0000000000..98f6dcaaca --- /dev/null +++ b/frontend/infrastructure_files/workbench_tf/google/outputs.tf @@ -0,0 +1,35 @@ +/** + * Copyright 2021 Google LLC + * + * 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. + */ + +output "deployment_id" { + description = "RADLab Module Deployment ID" + value = local.random_id +} + +output "project-radlab-ds-analytics-id" { + description = "Analytics Project ID" + value = local.project.project_id +} + +output "notebooks-instance-names" { + description = "Notebook Instance Names" + value = join(", ", google_notebooks_instance.ai_notebook[*].name) +} + +output "user-scripts-bucket-uri" { + description = "User Script Bucket URI" + value = google_storage_bucket.user_scripts_bucket.self_link +} \ No newline at end of file diff --git a/frontend/infrastructure_files/workbench_tf/google/provider.tf b/frontend/infrastructure_files/workbench_tf/google/provider.tf new file mode 100644 index 0000000000..2cf3bca7bb --- /dev/null +++ b/frontend/infrastructure_files/workbench_tf/google/provider.tf @@ -0,0 +1,6 @@ +provider "google" { + credentials = file(var.credentials) + region = var.region + zone = var.zone + project = var.project +} diff --git a/frontend/infrastructure_files/workbench_tf/google/variables.tf b/frontend/infrastructure_files/workbench_tf/google/variables.tf new file mode 100644 index 0000000000..2a974577df --- /dev/null +++ b/frontend/infrastructure_files/workbench_tf/google/variables.tf @@ -0,0 +1,159 @@ +/** + * Copyright 2021 Google LLC + * + * 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. + */ + +variable "billing_account_id" { + description = "Billing Account associated to the GCP Resources" + type = string + default = "" +} + +variable "boot_disk_size_gb" { + description = "The size of the boot disk in GB attached to this instance" + type = number + default = 100 +} + +variable "boot_disk_type" { + description = "Disk types for notebook instances" + type = string + default = "PD_SSD" +} + +variable "create_network" { + description = "If the module has to be deployed in an existing network, set this variable to false." + type = bool + default = false +} + +variable "create_project" { + description = "Set to true if the module has to create a project. If you want to deploy in an existing project, set this variable to false." + type = bool + default = false +} + +variable "enable_services" { + description = "Enable the necessary APIs on the project. When using an existing project, this can be set to false." + type = bool + default = false +} + +variable "folder_id" { + description = "Folder ID where the project should be created. It can be skipped if already setting organization_id. Leave blank if the project should be created directly underneath the Organization node. " + type = string + default = "" +} + +variable "image_family" { + description = "Image of the AI notebook." + type = string + default = "tf-latest-cpu" +} + +variable "image_project" { + description = "Google Cloud project where the image is hosted." + type = string + default = "deeplearning-platform-release" +} + +variable "ip_cidr_range" { + description = "Unique IP CIDR Range for AI Notebooks subnet" + type = string + default = "10.142.190.0/24" +} + +variable "machine_type" { + description = "Type of VM you would like to spin up" + type = string + default = "n1-standard-1" +} + +variable "network_name" { + description = "Name of the network to be created." + type = string + default = "ai-notebook" +} + +variable "notebook_count" { + description = "Number of AI Notebooks requested" + type = string + default = "1" +} + +variable "organization_id" { + description = "Organization ID where GCP Resources need to get spin up. It can be skipped if already setting folder_id" + type = string + default = "" +} + +variable "project_name" { + description = "Project name or ID, if it's an existing project." + type = string + default = "gcluster-discovery" +} +variable "random_id" { + description = "Adds a suffix of 4 random characters to the `project_id`" + type = string + default = null +} + +variable "set_external_ip_policy" { + description = "Enable org policy to allow External (Public) IP addresses on virtual machines." + type = bool + default = false +} + +variable "set_shielded_vm_policy" { + description = "Apply org policy to disable shielded VMs." + type = bool + default = false +} + +variable "set_trustedimage_project_policy" { + description = "Apply org policy to set the trusted image projects." + type = bool + default = false +} + +variable "subnet_name" { + description = "Name of the subnet where to deploy the Notebooks." + type = string + default = "subnet-ai-notebook" +} + +variable "trusted_users" { + description = "The list of trusted users." + type = set(string) + default = [] +} + + +variable "zone" { + description = "Cloud Zone associated to the AI Notebooks" + type = string + default = "us-east4-c" +} + +variable "credentials" { + default = "" +} + +variable "region" { + default = "" +} + +variable "project" { + default = "" +} \ No newline at end of file diff --git a/frontend/infrastructure_files/workbench_tf/google/versions.tf b/frontend/infrastructure_files/workbench_tf/google/versions.tf new file mode 100644 index 0000000000..5ad984971b --- /dev/null +++ b/frontend/infrastructure_files/workbench_tf/google/versions.tf @@ -0,0 +1,24 @@ +/** + * Copyright 2021 Google LLC + * + * 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. + */ + +terraform { + required_version = "~> 1.0" + + required_providers { + google = ">= 3.87.0" + google-beta = ">= 3.87.0" + } +} \ No newline at end of file diff --git a/frontend/requirements.txt b/frontend/requirements.txt new file mode 100644 index 0000000000..55ab68e55f --- /dev/null +++ b/frontend/requirements.txt @@ -0,0 +1,67 @@ +archspec==0.1.3 +argcomplete==2.0.0 +asgiref==3.5.0 +astroid==2.9.3 +cachetools==5.0.0 +certifi==2021.10.8 +cffi==1.15.0 +charset-normalizer==2.0.12 +click==7.1.2 +cryptography==36.0.1 +defusedxml==0.7.1 +Django==3.2.12 +django-allauth==0.48.0 +django-extensions==3.1.5 +djangorestframework==3.13.1 +google-api-core==2.5.0 +google-api-python-client==2.37.0 +google-auth==2.6.0 +google-auth-httplib2==0.1.0 +google-cloud-billing==1.4.1 +google-cloud-core==2.2.2 +google-cloud-pubsub==2.9.0 +google-cloud-storage==2.1.0 +google-crc32c==1.3.0 +google-resumable-media==2.2.1 +googleapis-common-protos==1.54.0 +grpc-google-iam-v1==0.12.3 +grpcio==1.43.0 +grpcio-status==1.43.0 +h11==0.13.0 +httplib2==0.20.4 +idna==3.3 +isort==5.10.1 +lazy-object-proxy==1.7.1 +libcst==0.4.1 +mccabe==0.6.1 +mypy-extensions==0.4.3 +oauthlib==3.2.0 +platformdirs==2.5.0 +pre-commit==2.17.0 +proto-plus==1.20.1 +protobuf==3.19.4 +pyasn1==0.4.8 +pyasn1-modules==0.2.8 +pycparser==2.21 +PyJWT==2.3.0 +pylint==2.12.2 +pylint-django==2.5.0 +pylint-plugin-utils==0.7 +pyparsing==3.0.7 +python3-openid==3.2.0 +pytz==2021.3 +PyYAML==6.0 +requests==2.27.1 +requests-oauthlib==1.3.1 +rsa==4.8 +six==1.16.0 +sqlparse==0.4.2 +toml==0.10.2 +typing-inspect==0.7.1 +typing_extensions==4.1.1 +uritemplate==4.1.1 +urllib3==1.26.8 +uvicorn==0.17.4 +wrapt==1.13.3 +xmltodict==0.12.0 +yq==2.13.0 diff --git a/frontend/tf/main.tf b/frontend/tf/main.tf new file mode 100644 index 0000000000..b093939015 --- /dev/null +++ b/frontend/tf/main.tf @@ -0,0 +1,216 @@ +# Create Service Account +# Create bucket +# Upload files + +# Create PubSub topic +# Create VPC and subnet +# Create VM instance + +locals { + sa_roles = [ + "storage.objectAdmin", + "logging.logWriter", + "monitoring.metricWriter", + "cloudtrace.agent", + "pubsub.admin" + ] + + deploy_key1 = var.deployment_key != "" ? file(var.deployment_key) : "" + + server_config_file = <<-EOT +django_username: "${var.django_su_username}" +django_password: "${var.django_su_password}" +django_email: "${var.django_su_email}" +deploy_key1: "${local.deploy_key1}" +git_branch: "${var.repo_branch}" +git_fork: "${var.repo_fork}" +google_client_id: PLACEHOLDER +google_client_secret: PLACEHOLDER +EOT + + default_labels = { + ghpcfe_id = var.deployment_name, + } + labels = merge(var.extra_labels, local.default_labels) +} + + +module "service_account" { + source = "terraform-google-modules/service-accounts/google" + version = "~> 4.1" + + description = "Service Account for GHPC Open Frontend" + names = ["fe-service-account"] + prefix = var.deployment_name + project_id = var.project_id + project_roles = [for role in local.sa_roles : "${var.project_id}=>roles/${role}"] +} + +module "control_bucket" { + source = "terraform-google-modules/cloud-storage/google" + version = "~> 2.2" + + project_id = var.project_id + names = ["storage"] + prefix = var.deployment_name + force_destroy = { + storage = true + } + location = var.region + storage_class = "STANDARD" + set_admin_roles = true + admins = ["serviceAccount:${module.service_account.email}"] + set_storage_admin_roles = true + storage_admins = ["serviceAccount:${module.service_account.email}"] + labels = local.labels +} + +resource "null_resource" "uploader" { + depends_on = [module.control_bucket.bucket] + # Upload files + provisioner "local-exec" { + command = "gsutil -m cp -r ../infrastructure_files/gcs_bucket/* ${module.control_bucket.bucket.url}/" + } +} + +# Also upload our deployment tarball +resource "google_storage_bucket_object" "deployment_file" { + count = var.deployment_mode == "tarball" ? 1 : 0 + name = "webserver/deployment.tar.gz" + bucket = module.control_bucket.bucket.name + source = "deployment.tar.gz" + metadata = { } +} + +resource "google_storage_bucket_object" "config_file" { + name = "webserver/config" + bucket = module.control_bucket.bucket.name + content = local.server_config_file + metadata = { } +} + + + +module "pubsub" { + source = "terraform-google-modules/pubsub/google" + version = "~> 1.8" + + topic = var.deployment_name + project_id = var.project_id + grant_token_creator = false + topic_labels = local.labels + subscription_labels = local.labels + + pull_subscriptions = [ + { + name = "${var.deployment_name}-c2resp" + filter = "NOT attributes:target" + } + ] +} + + +resource "google_compute_network" "hosting-vpc" { + + project = var.project_id + name = "${var.deployment_name}-network" + auto_create_subnetworks = false + +} + + +resource "google_compute_subnetwork" "hosting-subnetwork" { + + name = "${var.deployment_name}-subnetwork" + ip_cidr_range = "10.2.0.0/28" + region = var.region + network = google_compute_network.hosting-vpc.name + +} + + +resource "google_compute_firewall" "allow-http-rule" { + + project = var.project_id + name = "${var.deployment_name}-allow-http" + network = google_compute_network.hosting-vpc.name + + allow { + protocol = "tcp" + ports = ["80"] + } + + source_tags = ["http-server"] + source_ranges = ["0.0.0.0/0"] + +} + + +resource "google_compute_firewall" "allow-https-rule" { + + project = var.project_id + name = "${var.deployment_name}-allow-https" + network = google_compute_network.hosting-vpc.name + + allow { + protocol = "tcp" + ports = ["443"] + } + + source_tags = ["https-server"] + source_ranges = ["0.0.0.0/0"] + +} + + +resource "google_compute_instance" "server_vm" { + + name = "${var.deployment_name}-server" + machine_type = var.server_instance_type + zone = var.zone + + hostname = var.webserver_hostname != "" ? var.webserver_hostname : null + + metadata = { + startup-script-url = "${module.control_bucket.bucket.url}/webserver/startup.sh", + webserver-config-bucket = module.control_bucket.bucket.name, + ghpcfe-c2-topic = module.pubsub.topic, + hostname = var.webserver_hostname + deploy_mode = var.deployment_mode + # TODO: SSH Keys + } + + service_account { + email = module.service_account.email + scopes = [ + "storage-full", + "logging-write", + "monitoring-write", + "trace", + "service-control", + "service-management", + "pubsub" + ] + } + scheduling { + on_host_maintenance = "MIGRATE" + } + + labels = local.labels + tags = ["http-server", "https-server"] + + boot_disk { + initialize_params { + image = "projects/rocky-linux-cloud/global/images/rocky-linux-8-v20220126" + size = 30 + type = "pd-ssd" + } + } + + network_interface { + subnetwork = google_compute_subnetwork.hosting-subnetwork.name + access_config { + } + } + +} diff --git a/frontend/tf/outputs.tf b/frontend/tf/outputs.tf new file mode 100644 index 0000000000..a5c4d75a81 --- /dev/null +++ b/frontend/tf/outputs.tf @@ -0,0 +1,4 @@ +output "server_ip" { + description = "Webserver IP Address" + value = google_compute_instance.server_vm.network_interface[0].access_config[0].nat_ip +} diff --git a/frontend/tf/provider.tf b/frontend/tf/provider.tf new file mode 100644 index 0000000000..6b76e8ac4e --- /dev/null +++ b/frontend/tf/provider.tf @@ -0,0 +1,10 @@ +provider "google" { + project = var.project_id + zone = var.zone + region = var.region +} +provider "google-beta" { + project = var.project_id + zone = var.zone + region = var.region +} diff --git a/frontend/tf/variables.tf b/frontend/tf/variables.tf new file mode 100644 index 0000000000..eca073f278 --- /dev/null +++ b/frontend/tf/variables.tf @@ -0,0 +1,81 @@ +variable "project_id" { + type = string +} + +variable "region" { + type = string +} + +variable "zone" { + type = string +} + +variable "deployment_name" { + description = "Base \"name\" for the deployment." + type = string +} + +variable "webserver_hostname" { + description = "DNS Hostname for the webserver" + default = "" + type = string +} + +variable "django_su_username" { + description = "DJango Admin SuperUser username" + type = string + default = "admin" +} + +variable "django_su_password" { + description = "DJango Admin SuperUser password" + type = string + sensitive = true +} + +variable "django_su_email" { + description = "DJango Admin SuperUser email" + type = string +} + +variable "server_instance_type" { + default = "e2-standard-2" + type = string +} + +variable "deployment_mode" { + type = string + description = "Use a tarball of this directory, or download from git to deploy the server. Must be either 'tarball' or 'git'" + default = "tarball" + validation { + condition = var.deployment_mode == "tarball" || var.deployment_mode == "git" + error_message = "The variable 'deployment_mode' must be either 'tarball' or 'git'." + } +} + +variable "ssh_key" { + description = "admin SSH Key to add to the webserver instance" + default = "~/.ssh/id_rsa.pub" + type = string +} + +variable "repo_branch" { + default = "main" + type = string +} + +variable "repo_fork" { + default = "GoogleCloudPlatform" + type = string +} + +variable "deployment_key" { + default = "" + type = string +} + + +variable "extra_labels" { + type = map + default = {} +} diff --git a/frontend/tf/versions.tf b/frontend/tf/versions.tf new file mode 100644 index 0000000000..42881bff0e --- /dev/null +++ b/frontend/tf/versions.tf @@ -0,0 +1,14 @@ +terraform { + required_version = ">= 0.13" + + required_providers { + google = { + source = "hashicorp/google" + version = "~> 3.0" + } + google-beta = { + source = "hashicorp/google-beta" + version = "~> 3.0" + } + } +} diff --git a/frontend/website/.gitignore b/frontend/website/.gitignore new file mode 100644 index 0000000000..43ae0e2a6c --- /dev/null +++ b/frontend/website/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +*.py[cod] diff --git a/frontend/website/ghpcfe/__init__.py b/frontend/website/ghpcfe/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/website/ghpcfe/admin.py b/frontend/website/ghpcfe/admin.py new file mode 100644 index 0000000000..5ab9e3c90a --- /dev/null +++ b/frontend/website/ghpcfe/admin.py @@ -0,0 +1,131 @@ +# Copyright 2022 Google LLC +# +# 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. + +""" admin.py """ + +from django.contrib import admin +from django.contrib.auth.admin import UserAdmin +from .models import * +from .forms import UserCreationForm, UserChangeForm + +class UserAdmin(UserAdmin): + """ Custom UserAdmin """ + add_form = UserCreationForm + form = UserChangeForm + model = User + list_display = ('username', 'first_name', 'last_name', 'email', 'is_staff', 'is_active',) + list_filter = ('email', 'is_staff', 'is_active',) + ordering = ('username',) + readonly_fields = ('last_login', 'date_joined', 'unix_id',) + + fieldsets = ( + (None, {'fields': ('username', 'password',)}), + ('Personal info', {'fields': ('first_name', 'last_name', 'email',)}), + ('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'roles',)}), + ('Important dates', {'fields': ('last_login', 'date_joined')}), + ('Identity', {'fields': ('unix_id', 'ssh_key',)}), + ) + + + +class MountPointInline(admin.TabularInline): + """ To enable inline editing of instance types on cluster admin page """ + model = MountPoint + extra = 1 + +class ClusterPartitionInline(admin.TabularInline): + """ To enable inline editing of instance types on cluster admin page """ + model = ClusterPartition + extra = 1 + + +class FilesystemExportInline(admin.TabularInline): + """ To enable inline editing of instance types on cluster admin page """ + model = FilesystemExport + extra = 1 + + +class VirtualNetworkAdmin(admin.ModelAdmin): + """ Custom ModelAdmin for VirtualNetwork model """ + list_display = ('id', 'name', 'cloud_region', 'cloud_id', 'cloud_state') + + + +class VirtualSubnetAdmin(admin.ModelAdmin): + """ Custom ModelAdmin for VirtualSubnet model """ + list_display = ('id', 'name', 'cloud_zone', 'cloud_id', '_vpc_name', 'cloud_state') + + + def _vpc_name(self, obj): + return obj.vpc.name + _vpc_name.short_description = 'VPC' + + +class FilesystemAdmin(admin.ModelAdmin): + """ Custom ModelAdmin for Filesystem model """ + inlines = (FilesystemExportInline,) + + list_display = ('id', 'name', 'impl_type', 'cloud_zone', 'cloud_id', 'subnet', 'cloud_state') + + + +class ClusterAdmin(admin.ModelAdmin): + """ Custom ModelAdmin for Cluster model """ + inlines = (MountPointInline,ClusterPartitionInline) + list_display = ('id', 'name', 'cloud_zone', '_controller_node', 'status') + + def _controller_node(self, obj): + if obj.controller_node: + return obj.controller_node.public_ip if obj.controller_node.public_ip else obj.controller_node.internal_ip + else: + return "" + _controller_node.short_description = "Controller Node IP" + + + +class ApplicationAdmin(admin.ModelAdmin): + """ Custom ModelAdmin for Application model """ + list_display = ('id', 'name', 'spack_spec', 'install_loc', 'compiler', 'mpi', 'status') + + +class JobAdmin(admin.ModelAdmin): + """ Custom ModelAdmin for Job model """ + list_display = ('id', 'get_name', 'partition', 'number_of_nodes', 'ranks_per_node', 'threads_per_rank', 'status') + + def get_name(self, obj): + return obj.application.name + get_name.short_description = 'Aplication' #Renames column head + +# Register your models here. +admin.site.register(Application, ApplicationAdmin) +admin.site.register(ApplicationInstallationLocation) +admin.site.register(VirtualNetwork, VirtualNetworkAdmin) +admin.site.register(VirtualSubnet, VirtualSubnetAdmin) +admin.site.register(Cluster, ClusterAdmin) +admin.site.register(ClusterPartition) +admin.site.register(ComputeInstance) +admin.site.register(Credential) +admin.site.register(Job, JobAdmin) +admin.site.register(MachineType) +admin.site.register(InstanceType) +admin.site.register(Benchmark) +admin.site.register(Role) +admin.site.register(User, UserAdmin) +admin.site.register(Filesystem, FilesystemAdmin) +admin.site.register(FilesystemExport) +admin.site.register(MountPoint) +admin.site.register(Workbench) +admin.site.register(WorkbenchPreset) + + diff --git a/frontend/website/ghpcfe/apps.py b/frontend/website/ghpcfe/apps.py new file mode 100644 index 0000000000..93578f0675 --- /dev/null +++ b/frontend/website/ghpcfe/apps.py @@ -0,0 +1,24 @@ +# Copyright 2022 Google LLC +# +# 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. + +from django.apps import AppConfig +from .cluster_manager import c2 + +class ghpcfeConfig(AppConfig): + name = 'ghpcfe' + default_auto_field = 'django.db.models.AutoField' + + def ready(self): + import ghpcfe.signals + c2.startup() diff --git a/frontend/website/ghpcfe/cluster_manager/__init__.py b/frontend/website/ghpcfe/cluster_manager/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/website/ghpcfe/cluster_manager/c2.py b/frontend/website/ghpcfe/cluster_manager/c2.py new file mode 100644 index 0000000000..2513cf56fd --- /dev/null +++ b/frontend/website/ghpcfe/cluster_manager/c2.py @@ -0,0 +1,319 @@ +# Copyright 2022 Google LLC +# +# 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. + +from google.cloud import pubsub +from google.api_core.exceptions import AlreadyExists +import json, uuid + +# Note: We can't import Models here, because this module gets run as part of +# startup, and the Models haven't yet been created. +# Instead, import Models in the Callback Functions as appropriate + +from . import utils + +import logging +logger = logging.getLogger(__name__) + + +# Current design: +# 1 topic for our overall system +# Subscription for FE is set with a filter of messages WITHOUT a "target" +# attribute. Subscriptions for Clusters each have a filter for a "target" +# attribute that matches the cluster's ID. (ideally, should rather be +# something less guessable, like a hash or a unique key.) + + + + +# Message data should be json-encoded. +# Message attributes are to be used by the C2-infrastructure - data for the wider use +# Messages should have the following attributes: +# * target={subscription_name} (or no target, to come to FE) +# * command=('ping', 'sub_job', etc...) +# If no 'target' (aka, coming from the clusters: +# * source={cluster_id} - Who sent it? + + +# Command with reponse callback +# +# Commands that require a response should encode a unique key as a message +# field ('ackid'). +# When receiver finishes the command, they should then send an ACK with that +# same 'ackid', and any associated data. + + + + +_c2_callbackMap = {} + + +def c2_ping(message, source_id): + # Expect source_id in the form of 'cluster_{id}' + logger.info(f"Received PING from cluster {source_id}") + if 'id' in message: + logger.info(f" PING id {id}. Sending ACK") + pid = message['id'] + _c2State.send_message('PONG', {'id': pid}, target=source_id) + return True + +def c2_pong(message, source_id): + # Expect source_id in the form of 'cluster_{id}' + logger.info(f"Received PONG from cluster {source_id}") + if 'id' in message: + logger.info(f" PING id {id}.") + return True + + + +_c2_ackMap = {} +# Difference between UPDATE and ACK: ACK removes the callback, UPDATE leaves it in place +def cb_ack(message, source_id): + ackid = message.get('ackid', None) + logger.info(f"Received ACK to message {ackid} from {source_id}!") + if not ackid: + logger.error("No ackid in ACK. Ignoring") + return True + try: + cb = _c2_ackMap.pop(ackid) + logger.info("Calling Callback registered for this ACK") + cb(message) + except KeyError: + logger.warning("No Callback registered for the ACK") + pass + + return True + +# Difference between UPDATE and ACK: ACK removes the callback, UPDATE leaves it in place +def cb_update(message, source_id): + ackid = message.get('ackid', None) + logger.info(f"Received UPDATE to message {ackid} from {source_id}!") + if not ackid: + logger.error("No ackid in UPDATE. Ignoring") + return True + try: + cb = _c2_ackMap[ackid] + logger.info("Calling Callback registered for this UPDATE") + cb(message) + except KeyError: + logger.warning("No Callback registered for the UPDATE") + pass + + return True + + +def cb_cluster_status(message, source_id): + from ..models import Cluster + try: + cid = message['cluster_id'] + if f"cluster_{cid}" != source_id: + raise ValueError("Message comes from {source_id}, but claims cluster {cid}. Ignoring message") + + cluster = Cluster.objects.get(pk=cid) + logger.info(f"Cluster Status message for {cluster.id}: {message['message']}") + new_status = message.get('status', None) + if new_status: + cluster.status = new_status + cluster.save() + except Exception as ex: + logger.error(f"Cluster Status Callback error!", exc_info=ex) + return True + + + + +def _c2_respCB(message): + logger.debug(f"Received {message}.") + + cmd = message.attributes.get('command', None) + try: + source = message.attributes.get('source', None) + if not source: + logger.error("Message had no Source ID") + + callback = _c2_callbackMap[cmd] + if callback(json.loads(message.data), source_id=source): + message.ack() + else: + message.nack() + return + except KeyError: + if cmd: + logger.error(f"Message command {cmd} associated with it, but No such command known. Discarding") + else: + logger.error("Message has no command associated with it. Discarding") + message.ack() + + + + + +class _C2State: + def __init__(self): + self._pubClient = None + self._subClient = None + self._streaming_pull_future = None + self._project_id = None + self._topic = None + self._topic_path = None + + + @property + def subClient(self): + if not self._subClient: + self._subClient = pubsub.SubscriberClient() + return self._subClient + + @property + def pubClient(self): + if not self._pubClient: + self._pubClient = pubsub.PublisherClient() + return self._pubClient + + + def startup(self): + conf = utils.load_config() + self._project_id = conf['server']['gcp_project'] + self._topic = conf['server']['c2_topic'] + self._topic_path = self.pubClient.topic_path(self._project_id, self._topic) + + sub_path = self.get_or_create_subscription("c2resp", filter_target=False) + + self._streaming_pull_future = self.subClient.subscribe(sub_path, callback=_c2_respCB) + # TODO... Figure out hot to "cleanly" shut down + + + def get_subscription_path(self, sub_id): + sub_id = f"{self._topic}-{sub_id}" + return self.subClient.subscription_path(self._project_id, sub_id) + + def get_or_create_subscription(self, sub_id, filter_target=True, service_account=None): + sub_path = self.get_subscription_path(sub_id) + + request = {'name': sub_path, + 'topic': self._topic_path + } + if filter_target: + request['filter'] = f'attributes.target="{sub_id}"' + else: + request['filter'] = f'NOT attributes:target' + + try: + # Create subscription if it doesn't already exist + self.subClient.create_subscription(request=request) + logger.info(f"PubSub Subscription created") + + if service_account: + self.setup_service_account(sub_id, service_account) + + except AlreadyExists: + logger.info(f"PubSub Subscription {sub_path} already exists") + pass + logger.info(f"Returning subscription {sub_path}") + return sub_path + + + def setup_service_account(self, sub_id, service_account): + sub_path = self.get_subscription_path(sub_id) + # Need to set 2 policies. One on the subscription, to allow + # access to subscribe one on the main topic, to allow + # publication (c2 response) + + policy = self.subClient.get_iam_policy(request={"resource": sub_path}) + policy.bindings.add(role='roles/pubsub.subscriber', members=[f"serviceAccount:{service_account}"]) + policy = self.subClient.set_iam_policy(request={"resource": sub_path, "policy": policy}) + + policy = self.pubClient.get_iam_policy(request={"resource": self._topic_path}) + policy.bindings.add(role='roles/pubsub.publisher', members=[f"serviceAccount:{service_account}"]) + policy = self.pubClient.set_iam_policy(request={"resource": self._topic_path, "policy": policy}) + + + def delete_subscription(self, sub_id, service_account): + sub_path = self.get_subscription_path(sub_id) + self.subClient.delete_subscription(request={"subscription": sub_path}) + if service_account: + # TODO: Remove IAM permission from topic + #policy = self.pubClient.get_iam_policy(request={"resource": sub_path}) + #policy.bindings.remove(role='roles/pubsub.publisher', members=[f"serviceAccount:{service_account}"]) + #policy = self.pubClient.set_iam_policy(request={"resource": sub_path, "policy": policy}) + pass + + + def send_message(self, command, message, target, extra_attrs={}): + # TODO: If we want loopback, need to make 'target' optional, + # or change up our filters + # TODO: Consider if we want to keep the futures or not + self.pubClient.publish(self._topic_path, bytes(json.dumps(message), 'utf-8'), target=target, command=command, **extra_attrs) + + +_c2State = None + + + + +def get_cluster_sub_id(cluster_id): + return f"cluster_{cluster_id}" + +def get_cluster_subscription_path(cluster_id): + return _c2State.get_subscription_path(get_cluster_sub_id(cluster_id)) + + +def create_cluster_subscription(cluster_id): + return _c2State.get_or_create_subscription(get_cluster_sub_id(cluster_id), filter_target=True) + + +def add_cluster_subscription_service_account(cluster_id, service_account): + return _c2State.setup_service_account(get_cluster_sub_id(cluster_id), service_account) + + +def delete_cluster_subscription(cluster_id, service_account=None): + return _c2State.delete_subscription(get_cluster_sub_id(cluster_id), service_account=service_account) + +def get_topic_path(): + return _c2State._topic_path + + + +def startup(): + global _c2State + if _c2State: + logger.error("ERROR: C&C PubSub already started!") + return + + _c2State = _C2State() + _c2State.startup() +# Difference between UPDATE and ACK: ACK removes the callback, UPDATE leaves it in place + register_command('ACK', cb_ack) + register_command('UPDATE', cb_update) + register_command('PING', c2_ping) + register_command('PONG', c2_pong) + register_command('CLUSTER_STATUS', cb_cluster_status) + + +def send_command(cluster_id, cmd, data, onResponse=None): + if onResponse: + data['ackid'] = str(uuid.uuid4()) + _c2_ackMap[data['ackid']] = onResponse + _c2State.send_message(command=cmd, message=data, target=get_cluster_sub_id(cluster_id)) + return data['ackid'] + +def send_update(cluster_id, comm_id, data): + # comm_id is result from `send_command()` + data['ackid'] = comm_id + _c2State.send_message(command='UPDATE', message=data, target=get_cluster_sub_id(cluster_id)) + + +def register_command(command_id, callback): + _c2_callbackMap[command_id] = callback + + diff --git a/frontend/website/ghpcfe/cluster_manager/cloud_info.py b/frontend/website/ghpcfe/cluster_manager/cloud_info.py new file mode 100644 index 0000000000..5f0fbcac99 --- /dev/null +++ b/frontend/website/ghpcfe/cluster_manager/cloud_info.py @@ -0,0 +1,407 @@ +# Copyright 2022 Google LLC +# +# 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. + + +import json +from google.oauth2 import service_account +from google.cloud import storage as gcs +from google.cloud.billing_v1.services import cloud_catalog +import google.cloud.exceptions +import googleapiclient.discovery + +import configparser +from collections import defaultdict +import archspec.cpu + +import logging +logger = logging.getLogger(__name__) + + +gcp_machine_table = defaultdict(lambda: defaultdict(lambda: 'x86_64'), { + # General Purpose + 'e2': defaultdict(lambda: "x86_64"), + 'n2': defaultdict(lambda: "cascadelake"), + 'n2d': defaultdict(lambda: "zen2"), + 'n1': defaultdict(lambda: "x86_64"), + # Compute Optimized + 'c2': defaultdict(lambda: "cascadelake"), + 'c2d': defaultdict(lambda: "zen2"), # TODO: Should be zen3, but CentOS7 doesn't have a new enough kernel to recognize as such. + 't2d': defaultdict(lambda: "zen2"), # TODO: Should be zen3, but CentOS7 doesn't have a new enough kernel to recognize as such. + # Memory Optimized + 'm2': defaultdict(lambda: "cascadelake"), + 'm1': defaultdict(lambda: "broadwell", {'megamem': 'skylake_avx512', 'ultramem': 'broadwell'}), + # Accelerated + 'a2': defaultdict(lambda: "cascadelake"), + }) + + + +def _get_arch_for_node_type_gcp(instance, default='x86_64'): + (family, group, size) = instance.split('-') + return gcp_machine_table[family][group] + + +def _get_gcp_client(credentials, service="compute", api_version="v1"): + credInfo = json.loads(credentials) + creds = service_account.Credentials.from_service_account_info(credInfo) + return ( + credInfo["project_id"], + googleapiclient.discovery.build(service, api_version, credentials=creds, cache_discovery=False) + ) + +def _get_gcp_machine_types(credentials, region, zone): + (project, client) = _get_gcp_client(credentials) + + req = client.machineTypes().list(project=project, zone=zone, + filter="isSharedCpu=False") + + resp = req.execute() + if "items" not in resp: + return [] + + return { + mt["name"]: { + "name": mt["name"], + "family": mt["name"].split('-')[0], + "memory": mt["memoryMb"], + "vCPU": mt["guestCpus"], + "arch": _get_arch_for_node_type_gcp(mt["name"], default="x86_64") + } + for mt in resp["items"] + } + + + + +def get_machine_types(cloudProvider, credentials, region, zone): + if cloudProvider == "GCP": + return _get_gcp_machine_types(credentials, region, zone) + else: + raise Exception("Unsupport Cloud Provider") + + +class MachineFamily(): + def __init__(self, name = None): + self.name = name + self.members = [] + self.arch_family = None + + @property + def common_arch(self): + return get_common_arch([m["arch"] for m in self.members]) + + def addMember(self, machineInfo): + memberArch = archspec.cpu.TARGETS[machineInfo["arch"]] + if not self.name: + self.name = machineInfo["family"] + if not self.arch_family: + self.arch_family = memberArch.family + elif self.arch_family != memberArch.family: + raise Exception(f"Mismatched architectures! {self.arch_family.name} != {memberArch.family.name}") + self.members.append(machineInfo) + + +def get_machine_families(cloudProvider, credentials, region, zone): + """ From list of machines, produce a family info array """ + machines = get_machine_types(cloudProvider, credentials, region, zone) + families = defaultdict(MachineFamily) + [families[m["family"]].addMember(m) for m in machines.values()] + return families.values() + + +def _get_arch_ancestry(arch): + ancestry = {arch.name} + for p in arch.parents: + ancestry.update(_get_arch_ancestry(p)) + return ancestry + +def get_common_arch(archs): + archs = [archspec.cpu.TARGETS[a] for a in archs] + commonSet = set.intersection(*[_get_arch_ancestry(a) for a in archs]) + if not commonSet: + return None + return max([archspec.cpu.TARGETS[a] for a in commonSet]).name + +def get_arch_ancestry(archName): + arch = archspec.cpu.TARGETS[archName] + res = [archName] + if arch.family != arch: + for x in arch.parents: + res.extend(get_arch_ancestry(x.name)) + return res + +def get_arch_family(arch): + return archspec.cpu.TARGETS[arch].family.name + +def sort_architectures(archNames): + archs = [archspec.cpu.TARGETS[a] for a in archNames] + return [x.name for x in sorted(archs)] + + + +def _get_gcp_region_zone_info(credentials): + (project, client) = _get_gcp_client(credentials) + + req = client.zones().list(project=project) + results = defaultdict(list) + while req is not None: + resp = req.execute() + for zone in resp['items']: + region = '-'.join(zone["name"].split('-')[:-1]) + results[region].append(zone["name"]) + req = client.zones().list_next(previous_request=req, previous_response=resp) + return results + +def get_region_zone_info(cloudProvider, credentials): + if cloudProvider == "GCP": + return _get_gcp_region_zone_info(credentials) + else: + raise Exception("Unsupport Cloud Provider") + + + +def _get_gcp_subnets(credentials): + (project, client) = _get_gcp_client(credentials) + + req = client.subnetworks().listUsable(project=project) + results = req.execute() + entries = results['items'] + subnets = [] + for entry in entries: + # subnet in the form of https://www.googleapis.com/compute/v1/projects//regions//subnetworks/ + tokens = entry['subnetwork'].split("/") + region = tokens[8] + subnet = tokens[10] + # vpc in the form of https://www.googleapis.com/compute/v1/projects//global/networks/ + tokens = entry['network'].split("/") + vpc = tokens[9] + # cidr in standard form xxx.xxx.xxx.xxx/yy + cidr = entry['ipCidrRange'] + subnets.append([vpc, region, subnet, cidr]) + return subnets + + +def get_subnets(cloudProvider, credentials): + if cloudProvider == "GCP": + return _get_gcp_subnets(credentials) + else: + raise Exception("Unsupport Cloud Provider") + + +_gcp_services_list = None +_gcp_compute_sku_list = None + +def _get_gcp_instance_pricing(credentials, region, zone, instance_type): + global _gcp_services_list + global _gcp_compute_sku_list + + creds = service_account.Credentials.from_service_account_info(json.loads(credentials)) + catalog = cloud_catalog.CloudCatalogClient(credentials=creds) + # Step one: Find the Compute Engine service + if not _gcp_services_list: + _gcp_services_list = [x for x in catalog.list_services() if "Compute Engine" == x.display_name] + services = _gcp_services_list + if len(services) != 1: + raise Exception("Did not find Compute Engine Service") + # Step two: Get all the SKUs associated with the Compute Engine service + if not _gcp_compute_sku_list: + _gcp_compute_sku_list = [x for x in catalog.list_skus(parent=services[0].name)] + skus = [x for x in _gcp_compute_sku_list if region in x.service_regions] + # To zero'th degree, pricing for an instance is made up of: + # # cores * Price/PerCore of instance semi-family + # # GB RAM * Price/GBhr of instance semi-family + # THESE ARE TODO + # # Disk Storage - We'll just assume a 20GB disk - that's what we're currently getting + + + # Google's Billing API has SKUs, but the SKUs don't map to anything - you + # can't get SKU info from the actual products. We have to look up sku's + # with pricing info, and try to map the SKU's description to the actual + # Compute infrastructure we're using. We do have to look at the + # "description" field, which feels hazardous and liable to change + + def get_disk_price(disk_size, skus): + def disk_sku_filter(elem): + if elem.category.resource_family != "Storage": + return False + if elem.category.resource_group != "PDStandard": + return False + if region not in elem.service_regions: + return False + if not elem.description.startswith("Storage PD Capacity"): + # Filter out 'Regional Storage PD Capacity...' + return False + return True + disk_sku = [x for x in skus if disk_sku_filter(x)] + if len(disk_sku) != 1: + raise Exception("Failed to find singular appropriate disk") + disk_price_expression = disk_sku[0].pricing_info[0].pricing_expression + unit_price = disk_price_expression.tiered_rates[0].unit_price.nanos * 1e-9 + disk_cost_per_month = disk_size * unit_price + disk_cost_per_hr = disk_cost_per_month / (24*30) + return disk_cost_per_hr + + def get_cpu_price(num_cores, instance_type, skus): + instance_description_mapper = { + 'e2': 'E2 Instance Core', + 'n2d': 'N2D AMD Instance Core', + 'c2': 'Compute optimized Core', + 'c2d': 'C2D AMD Instance Core', + 't2d': 'T2D AMD Instance Core', + 'a2': 'A2 Instance Core', + 'm1': 'Memory-optimized Instance Core', # ?? + 'm2': 'Memory Optimized Upgrade Premium for Memory-optimized Instance Core', # ?? + 'n2': 'N2 Instance Core', + 'n1': 'Custom Instance Core', #?? + } + instance_class = instance_type.split('-')[0] + if instance_class not in instance_description_mapper.keys(): + raise NotImplementedError(f"Do not yet have a price mapping for instance type {instance_type}") + + def cpu_sku_filter(elem): + if elem.category.resource_family != "Compute": + return False + if elem.category.resource_group != "CPU": + return False + if elem.category.usage_type != "OnDemand": + return False + if region not in elem.service_regions: + return False + if "Sole Tenancy" in elem.description: + return False + if not elem.description.startswith(instance_description_mapper[instance_class]): + return False + return True + cpu_sku = [x for x in skus if cpu_sku_filter(x)] + if len(cpu_sku) != 1: + raise Exception("Failed to find singular appropriate cpu billing") + cpu_price_expression = cpu_sku[0].pricing_info[0].pricing_expression + unit_price = cpu_price_expression.tiered_rates[0].unit_price.nanos * 1e-9 + cpu_price_per_hr = num_cores * unit_price + return cpu_price_per_hr + + def get_mem_price(num_gb, instance_type, skus): + instance_description_mapper = { + 'e2': 'E2 Instance Ram', + 'n2d': 'N2D AMD Instance Ram', + 'c2': 'Compute optimized Ram', + 'c2d': 'C2D AMD Instance Ram', + 't2d': 'T2D AMD Instance Ram', + 'a2': 'A2 Instance Ram', + 'm1': 'Memory-optimized Instance Ram', # ?? + 'n2': 'N2 Instance Ram', + } + # TODO: Deal with 'Extended Instance Ram' + instance_class = instance_type.split('-')[0] + if instance_class not in instance_description_mapper.keys(): + raise NotImplementedError(f"Do not yet have a price mapping for instance type {instance_type}") + + def mem_sku_filter(elem): + if elem.category.resource_family != "Compute": + return False + if elem.category.resource_group != "RAM": + return False + if elem.category.usage_type != "OnDemand": + return False + if region not in elem.service_regions: + return False + if "Sole Tenancy" in elem.description: + return False + if not elem.description.startswith(instance_description_mapper[instance_class]): + return False + return True + mem_sku = [x for x in skus if mem_sku_filter(x)] + if len(mem_sku) != 1: + raise Exception("Failed to find singular appropriate RAM billing") + mem_price_expression = mem_sku[0].pricing_info[0].pricing_expression + unit_price = mem_price_expression.tiered_rates[0].unit_price.nanos * 1e-9 + ram_price_per_hr = num_gb * unit_price + return ram_price_per_hr + + machine = _get_gcp_machine_types(credentials, region, zone)[instance_type] + return get_cpu_price(machine["vCPU"], instance_type, skus) + get_mem_price(machine["memory"]/1024, instance_type, skus) + get_disk_price(20.0, skus) + + + +def get_instance_pricing(cloudProvider, credentials, region, zone, instance_type): + """ Return price per hour for an instance """ + if cloudProvider == "GCP": + return _get_gcp_instance_pricing(credentials, region, zone, instance_type) + else: + raise Exception("Unsupport Cloud Provider") + + + +def gcs_apply_bucket_acl(bucket, account, permission="roles/storage.objectViewer"): + + logger.info(f"Attempting to grant {permission} to gs://{bucket}/ for user {account}") + client = gcs.Client() + try: + gcs_bucket = client.get_bucket(bucket) + policy = gcs_bucket.get_iam_policy() + for binding in policy.bindings: + if binding['role'] == permission: + binding['members'].add(account) + break + else: + policy.bindings.append({'role': permission, 'members': set(account)}) + + gcs_bucket.set_iam_policy(policy) + + except Exception as exc: + logger.error("Failed to apply GCS Policy", exc_info=exc) + + +def gcs_upload_file(bucket, path, contents, extra_acl=[]): + logger.info(f"Attempting to upload to gs://{bucket}/{path if path else''}") + client = gcs.Client() + gcs_bucket = client.bucket(bucket) + blob = gcs_bucket.blob(path) + blob.upload_from_string(contents) + for acl in extra_acl: + if acl.get('user') and acl.get('permission'): + if permission in ['OWNER', 'READER', 'WRITER']: + blob.acl.user(user).grant(permission) + blob.acl.save() + client.close() + +def gcs_fetch_file(bucket, paths): + client = gcs.Client() + gcs_bucket = client.bucket(bucket) + results = {} + for path in paths: + try: + logger.debug(f"Attempting to download from gs://{bucket}/{path if path else ''}") + blob = gcs_bucket.blob(path) + results[path] = blob.download_as_text() + except google.cloud.exceptions.NotFound as nf: + logger.info("Attempt failed (Not Found) to download {path}", exc_info=nf) + client.close() + return results + +def gcs_get_blob(bucket, path): + """Returns a blob object - it may or may not exist""" + client = gcs.Client() + gcs_bucket = client.bucket(bucket) + return gcs_bucket.blob(path) + + +def get_gcp_workbench_region_zone_info(credentials, service="notebooks", api_version="v1"): + + (project, nb) = _get_gcp_client(credentials, service, api_version) + request = nb.projects().locations().list(name=f'projects/{project}') + result = request.execute() + locations = [x['locationId'] for x in result['locations']] + return locations + diff --git a/frontend/website/ghpcfe/cluster_manager/clusterinfo.py b/frontend/website/ghpcfe/cluster_manager/clusterinfo.py new file mode 100644 index 0000000000..64882a9a10 --- /dev/null +++ b/frontend/website/ghpcfe/cluster_manager/clusterinfo.py @@ -0,0 +1,570 @@ +#!/usr/bin/env python3 +# Copyright 2022 Google LLC +# +# 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. + + +# To create a cluster, we need: +# 1) Know which Cloud Provider & region/zone/project +# 2) Know authentication credentials +# 3) Know an "ID Number" or name - for directory to store state info + +# 1 - Supplied via commandline +# 2 - Supplied via... Env vars / commandline? +# 3 - Supplied via commandline + + + +import argparse +from pathlib import Path +import os, shutil, sys +import subprocess +import json + +from . import utils +from . import cloud_info +from . import c2 + +from google.api_core.exceptions import PermissionDenied as GCPPermissionDenied + +from django.template import engines as template_engines + +import logging +logger = logging.getLogger(__name__) + + +from ..models import Cluster, ApplicationInstallationLocation, \ + ComputeInstance, InstanceType + +class ClusterInfo: + """ Expected process: + +ClusterInfo object - represent a cluster +- Call prepare() + - This will create the directory, dump a YAML file for GHPC +- Call update() + - This will dump a new YAML file +- Call start_cluster() + - Calls ghpc to create Terraform + - Initializes Terraform + - Applies Terraform +""" + + def __init__(self, cluster): + self.config = utils.load_config() + self.ghpc_path = self.config["baseDir"].parent / 'ghpc' + + self.cluster = cluster + self.cluster_dir = self.config["baseDir"] / 'clusters' / f'cluster_{self.cluster.id}' + + + def prepare(self, credentials): + self._create_cluster_dir() + self._set_credentials(credentials) + self.update() + + def update(self): + self._prepare_ghpc_yaml() + self._prepare_bootstrap_gcs() + + def start_cluster(self): + self.cluster.cloud_state = 'nm' + self.cluster.status = 'c' + self.cluster.save() + + try: + self._run_ghpc() + self._initialize_terraform() + self._apply_terraform() + except Exception as e: + self.cluster.status = 'e' + self.cluster.cloud_status = 'nm' + self.cluster.save() + raise + + def stop_cluster(self): + self._destroy_terraform() + + def get_cluster_access_key(self): + return self.cluster.get_access_key() + + + + def _create_cluster_dir(self): + self.cluster_dir.mkdir(parents=True) + + def _get_credentials_file(self): + return self.cluster_dir / 'cloud_credentials' + + def _set_credentials(self, creds=None): + credfile = self._get_credentials_file() + if not creds: + # pull from DB + creds = self.cluster.cloud_credential.detail + with credfile.open('w') as fp: + fp.write(creds) + + # Create SSH Keys + self._create_ssh_key(self.cluster_dir) + + + def _create_ssh_key(self, tgtDir): + #ssh-keygen -t rsa -f /.ssh/id_rsa -N "" + sshdir = tgtDir / '.ssh' + sshdir.mkdir(mode = 0o711) + + priv_key_file = sshdir / 'id_rsa' + pub_key_file = sshdir / 'id_rsa.pub' + + subprocess.run(["ssh-keygen", + "-t", "rsa", + "-f", priv_key_file.as_posix(), + "-N", "", + "-C", "citc@mgmt"], + check=True) + + + + + def _prepare_ghpc_filesystems(self): + yaml = [] + refs = [] + for (count, mp) in enumerate(self.cluster.mount_points.order_by('mount_order')): + storage_id = f"mount_num_{count}" + ip = "'$controller'" if mp.export in self.cluster.shared_fs.exports.all() else mp.export.server_name + yaml.append(f""" + - source: resources/file-system/pre-existing-network-storage + kind: terraform + id: {storage_id} + settings: + server_ip: {ip} + remote_mount: {mp.export.export_name} + local_mount: {mp.mount_path} + mount_options: {mp.mount_options} + fs_type: {mp.fstype_name} +""") + refs.append(storage_id) + + return ("\n\n".join(yaml), refs) + + def _prepare_ghpc_partitions(self, part_uses): + # TODO: Eventually should have actual "partitions" in the Model, with a name, etc + yaml = [] + refs = [] + uses_str = self._yaml_refs_to_uses(part_uses) + for (count, part) in enumerate(self.cluster.partitions.all()): + part_id = f"partition_{count}" + image_str = f"image: {part.image}\n" if part.image else "" + yaml.append(f""" + - source: resources/third-party/compute/SchedMD-slurm-on-gcp-partition + kind: terraform + id: {part_id} + settings: + partition_name: {part.name} + subnetwork_name: {self.cluster.subnet.cloud_id} + max_node_count: {part.max_node_count} + machine_type: {part.machine_type.name} + enable_placement: {part.enable_placement} + image_hyperthreads: {part.enable_hyperthreads} + exclusive: {part.enable_placement or not part.enable_node_reuse} + {image_str} + use: +{uses_str} +""") + if part.image: + yaml.append(" image: {part.image}\n") + + refs.append(part_id) + + return ("\n\n".join(yaml), refs) + + def _yaml_refs_to_uses(self, use_list): + return "\n".join([f" - {x}" for x in use_list]) + + + def _prepare_ghpc_yaml(self): + ymlFile = self.cluster_dir / 'cluster.yaml' + project_id = json.loads(self.cluster.cloud_credential.detail)["project_id"] + + (filesystems_yaml, filesystems_references) = self._prepare_ghpc_filesystems() + (partitions_yaml, partitions_references) = self._prepare_ghpc_partitions(["hpc_network"] + filesystems_references) + + controller_uses = self._yaml_refs_to_uses(["hpc_network"] + partitions_references + filesystems_references) + login_uses = self._yaml_refs_to_uses(["hpc_network"] + filesystems_references + ["slurm_controller"]) + + controller_sa = f"{self.cluster.cloud_id}-service-acct" + # TODO: Determine if these all should be different, and if so, add to resource to be created + # Note though, that at the moment, GHPC won't let us unpack output + # variables, so we can't index properly. + # for now, just use the singular access, and only create a single acct + #compute_sa = controller_sa + #login_sa = controller_sa + + startup_bucket = self.config["server"]["gcs_bucket"] + with ymlFile.open('w') as f: + f.write(f""" +blueprint_name: {self.cluster.name} + +vars: + project_id: {project_id} + deployment_name: {self.cluster.name} + region: {self.cluster.cloud_region} + zone: {self.cluster.cloud_zone} + +resource_groups: +- group: primary + resources: + - source: resources/network/pre-existing-vpc + kind: terraform + settings: + network_name: {self.cluster.subnet.vpc.cloud_id} + subnetwork_name: {self.cluster.subnet.cloud_id} + id: hpc_network + +{filesystems_yaml} + + - source: resources/project/service-account + kind: terraform + id: hpc_service_account + settings: + project_id: {project_id} + names: [ {controller_sa} ] + project_roles: + - compute.instanceAdmin.v1 + - iam.serviceAccountUser + - monitoring.metricWriter + - logging.logWriter + - storage.objectAdmin + - pubsub.publisher + - pubsub.subscriber + +{partitions_yaml} + + - source: resources/third-party/scheduler/SchedMD-slurm-on-gcp-controller + kind: terraform + id: slurm_controller + settings: + login_node_count: {self.cluster.num_login_nodes} + controller_service_account: $(hpc_service_account.email) + controller_startup_script: | + #!/bin/bash + echo "******************************************** CALLING CONTROLLER STARTUP" + gsutil cp gs://{startup_bucket}/clusters/{self.cluster.id}/bootstrap_controller.sh - | bash + compute_node_service_account: $(hpc_service_account.email) + compute_node_scopes: + - https://www.googleapis.com/auth/monitoring.write + - https://www.googleapis.com/auth/logging.write + - https://www.googleapis.com/auth/devstorage.read_write + - https://www.googleapis.com/auth/pubsub + compute_startup_script: | + #!/bin/bash + gsutil cp gs://{startup_bucket}/clusters/{self.cluster.id}/bootstrap_compute.sh - | bash + use: +{controller_uses} + + - source: resources/third-party/scheduler/SchedMD-slurm-on-gcp-login-node + kind: terraform + id: slurm_login + settings: + subnetwork_name: {self.cluster.subnet.cloud_id} + login_service_account: $(hpc_service_account.email) + login_scopes: + - https://www.googleapis.com/auth/monitoring.write + - https://www.googleapis.com/auth/logging.write + - https://www.googleapis.com/auth/devstorage.read_write + login_startup_script: | + #!/bin/bash + echo "******************************************** CALLING LOGIN STARTUP" + gsutil cp gs://{startup_bucket}/clusters/{self.cluster.id}/bootstrap_login.sh - | bash + use: +{login_uses} + +""") + + def _prepare_bootstrap_gcs(self): + template_dir = self.config["baseDir"] / 'infrastructure_files' / 'cluster_startup' / 'templates' + engine = template_engines['django'] + for templ in ["controller", "login", "compute"]: + template_fn = template_dir / f"bootstrap_{templ}.sh" + with open(template_fn, 'r') as fp: + tstr = fp.read() + template = engine.from_string(tstr) + # TODO: Add to context any other things we may need in the startup script + rendered_file = template.render(context={ + 'server_bucket': self.config["server"]["gcs_bucket"], + 'cluster': self.cluster, + 'spack_dir': self.cluster.spackdir, + 'fec2_topic': c2.get_topic_path(), + 'fec2_subscription': c2.get_cluster_subscription_path(self.cluster.id), + }) + blobpath = f"clusters/{self.cluster.id}/{template_fn.name}" + cloud_info.gcs_upload_file(self.config["server"]["gcs_bucket"], blobpath, rendered_file) + + + def _initialize_terraform(self): + tfDir = self.get_terraform_dir() + extraEnv = {'GOOGLE_APPLICATION_CREDENTIALS': self._get_credentials_file()} + try: + logger.info("Invoking Terraform Init") + utils.run_terraform(tfDir, "init") + utils.run_terraform(tfDir, "validate", extraEnv=extraEnv) + logger.info("Invoking Terraform Plan") + utils.run_terraform(tfDir, "plan", extraEnv=extraEnv) + except subprocess.CalledProcessError as cpe: + logger.error("Terraform exec failed", exc_info=cpe) + if cpe.stdout: + logger.info(f" STDOUT:\n{cpe.stdout.decode('utf-8')}\n") + if cpe.stderr: + logger.info(f" STDERR:\n{cpe.stderr.decode('utf-8')}\n") + raise + + def _run_ghpc(self): + tgtDir = self.cluster_dir + try: + logger.info("Invoking ghpc create") + log_out_fn = tgtDir / f"ghpc_create_log.stdout" + log_err_fn = tgtDir / f"ghpc_create_log.stderr" + with log_out_fn.open('wb') as log_out: + with log_err_fn.open('wb') as log_err: + subprocess.run([self.ghpc_path.as_posix(), 'create', 'cluster.yaml'], + cwd=tgtDir, + stdout=log_out, stderr=log_err, + check=True) + except subprocess.CalledProcessError as cpe: + logger.error("ghpc exec failed", exc_info=cpe) + # No logs from stdout/err - get dumped to files + raise + + + def _get_tf_state_resource(self, state, filters): + """Given a Terraform State json file, look for the Resource that matches each entry + in the supplied filters dictionary. Returns each match""" + def matches(x): + try: + for k,v in filters.items(): + if x[k] != v: + return False + return True + except KeyError: + return False + return [x for x in filter(matches, state["resources"])] + + def _create_model_instances_from_tf_state(self, state, filters): + tf_nodes = self._get_tf_state_resource(state, filters)[0]["instances"] + def model_from_tf(tf): + ciKwargs = { + 'id': None, + 'cloud_credential': self.cluster.cloud_credential, + 'cloud_state': 'm', + 'cloud_region': self.cluster.cloud_region, + 'cloud_zone': self.cluster.cloud_zone, + } + + try: + ciKwargs['cloud_id'] = tf["attributes"]["name"] + instance_type_name = tf["attributes"]["machine_type"] + ciKwargs['instance_type'] = InstanceType.objects.get(name=instance_type_name) + except (KeyError): + pass + + try: + nic = tf["attributes"]["network_interface"][0] + ciKwargs['internal_ip'] = nic["network_ip"] + ciKwargs['public_ip'] = nic["access_config"][0]["nat_ip"] + except (KeyError, IndexError): + pass + + try: + service_acct = tf["attributes"]["service_account"][0] + ciKwargs['service_account'] = service_acct["email"] + except (KeyError, IndexError): + pass + + return ComputeInstance(**ciKwargs) + return [model_from_tf(instance) for instance in tf_nodes] + + def _get_service_accounts(self, tf_state): +# TODO: Once we're creating service accounts, can pull them from those resources +# At the moment, pull from controller & login instances. This misses "compute" +# nodes, but they're going to just be the same as controller & login until +# we start setting them. + #filters = {'module': "module.hpc_service_account.module.service_accounts", + # 'name': 'service_accounts'} + #sa_accounts = self._get_tf_state_resource(tf_state, filters)[0]["instances"] + #ctrl_sa = sa_accounts[*]['attributes']['email'] where * defined by attributes-account_id + + filters = {'module': "module.slurm_controller.module.slurm_cluster_controller", + 'name': 'controller_node'} + tf_node = self._get_tf_state_resource(tf_state, filters)[0]["instances"][0] + ctrl_sa = tf_node["attributes"]["service_account"][0]["email"] + + filters = {'module': "module.slurm_login.module.slurm_cluster_login_node", + 'name': 'login_node'} + tf_node = self._get_tf_state_resource(tf_state, filters)[0]["instances"][0] + login_sa = tf_node["attributes"]["service_account"][0]["email"] + + return {'controller': ctrl_sa, + 'login': login_sa, + 'compute': login_sa} + + + def _apply_service_account_permissions(self, service_accounts): + # Need to give permission for all instances to download startup scripts + # Need to give ability to upload job log files to bucket + # TODO: Figure out who exactly will do this. For now, grant to all. + all_sas = set(service_accounts.values()) + bucket = self.config["server"]["gcs_bucket"] + for sa in all_sas: + cloud_info.gcs_apply_bucket_acl(bucket, f'serviceAccount:{sa}', permission='roles/storage.objectAdmin') + + # Give Command & Control access + try: + c2.add_cluster_subscription_service_account(self.cluster.id, service_accounts['controller']) + except GCPPermissionDenied: + logger.warning("Permission Denied attempting to add IAM permissions for service account to PubSub Subscription/Topic. Command and Control may not work. Please grant the role of pubsub.admin to FrontEnd service account.") + if self.cluster.project_id != self.config["server"]["gcp_project"]: + logger.error("Cluster project differs from FrontEnd project. C&C will not work.") + + def _apply_terraform(self): + tfDir = self.get_terraform_dir() + + # Create C&C Subscription + c2.create_cluster_subscription(self.cluster.id) + + + extraEnv = {'GOOGLE_APPLICATION_CREDENTIALS': self._get_credentials_file()} + try: + logger.info("Invoking Terraform Apply") + (log_out, log_err) = utils.run_terraform(tfDir, "apply", extraEnv=extraEnv) + + # Look for Management and Login Nodes in TF state file + stateFile = tfDir / 'terraform.tfstate' + with stateFile.open('r') as statefp: + state = json.load(statefp) + + # Apply Perms to the service accounts + service_accounts = self._get_service_accounts(state) + self._apply_service_account_permissions(service_accounts) + + # Cluster is now being initialized + self.cluster.internal_name = self.cluster.name + self.cluster.cloud_state = 'm' + + # Cluster initialization is now running. + self.cluster.status = 'i' + self.cluster.save() + + mgmtNodes = self._create_model_instances_from_tf_state(state, { + 'module': "module.slurm_controller.module.slurm_cluster_controller", + "name": "controller_node"}) + if len(mgmtNodes) != 1: + logger.warning(f"Found {len(mgmtNodes)} management nodes, rather than the 1 expected!") + if len(mgmtNodes): + node = mgmtNodes[0] + node.save() + utils.add_host_to_server_firewall(node.public_ip) + self.cluster.controller_node = node + logger.info(f"Created cluster at (mgmt) {node.public_ip if node.public_ip else node.internal_ip}") + + + loginNodes = self._create_model_instances_from_tf_state(state, { + 'module': "module.slurm_login.module.slurm_cluster_login_node", + "name": "login_node"}) + if len(loginNodes) != self.cluster.num_login_nodes: + logger.warning(f"Found {len(loginNodes)} login nodes, rather than the {self.cluster.num_login_nodes} expected!") + for lnode in loginNodes: + lnode.cluster_login = self.cluster + lnode.save() + utils.add_host_to_server_firewall(lnode.public_ip) + logger.info(f"Created login at {lnode.public_ip if lnode.public_ip else lnode.internal_ip}") + + # Set up Spack Install location + self._configure_spack_install_loc() + + self.cluster.save() + + + except subprocess.CalledProcessError as cpe: + # We can error during provisioning, in which case Terraform + # doesn't tear things down. Run a `destroy`, just in case + self._destroy_terraform() + raise + + + def _destroy_terraform(self): + tfDir = self.get_terraform_dir() + extraEnv = {'GOOGLE_APPLICATION_CREDENTIALS': self._get_credentials_file()} + try: + logger.info("Invoking Terraform destroy") + self.cluster.status = 't' + self.cluster.cloud_status = 'dm' + self.cluster.save() + + #utils.remove_host_from_server_firewall(self.cluster.XXXX) + utils.run_terraform(tfDir, 'destroy', extraEnv=extraEnv) + + controller_sa = self.cluster.controller_node.service_account + + self.cluster.controller_node.delete() + self.cluster.login_nodes.all().delete() + # Refresh so our python object gets the SET_NULL's from the above deletes + self.cluster = Cluster.objects.get(id=self.cluster.id) + + self.cluster.status = 'd' + self.cluster.cloud_status = 'xm' + self.cluster.save() + + c2.delete_cluster_subscription(self.cluster.id, controller_sa) + except subprocess.CalledProcessError as cpe: + logger.error("Terraform destroy failed", exc_info=cpe) + if cpe.stdout: + logger.info(f" STDOUT:\n{cpe.stdout.decode('utf-8')}\n") + if cpe.stderr: + logger.info(f" STDERR:\n{cpe.stderr.decode('utf-8')}\n") + raise + + + + def _configure_spack_install_loc(self): + """Configures the spack_install field. + Could point to an existing install, if paths match appropriately, + otherwise, create a new DB entry. + """ + cluster_spack_dir = self.cluster.spackdir + # Find the mount point that best matches our spack dir + spack_mp = None + for mp in self.cluster.mount_points.order_by('mount_order'): + if cluster_spack_dir.startswith(mp.mount_path): + spack_mp = mp + + if not spack_mp: + logger.error(f"Unable to find a mount_point matching out spack path {cluster_spack_dir}") + return + + partial_path = cluster_spack_dir[len(spack_mp.mount_path)+1:] + # Now we have a Mount Point, Find app Install locs with that MP's export + possible_apps = ApplicationInstallationLocation.objects.filter(fs_export=spack_mp.export).filter(path=partial_path) + if possible_apps: + self.cluster.spack_install = possible_apps[0] + else: + # Need to create a new entry + self.cluster.spack_install = ApplicationInstallationLocation(fs_export=spack_mp.export, path=partial_path) + self.cluster.spack_install.save() + self.cluster.save() + + + + def get_terraform_dir(self): + return self.cluster_dir / self.cluster.name / 'primary' + + diff --git a/frontend/website/ghpcfe/cluster_manager/create_workbench.py b/frontend/website/ghpcfe/cluster_manager/create_workbench.py new file mode 100644 index 0000000000..7a186c641a --- /dev/null +++ b/frontend/website/ghpcfe/cluster_manager/create_workbench.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# Copyright 2022 Google LLC +# +# 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. + + +# To create a cluster, we need: +# 1) Know which Cloud Provider & region/zone/project +# 2) Know authentication credentials +# 3) Know an "ID Number" or name - for directory to store state info + +# 1 - Supplied via commandline +# 2 - Supplied via... Env vars / commandline? +# 3 - Supplied via commandline + + + +import argparse +import sys + +from . import utils +from .workbenchinfo import WorkbenchInfo + + +def update_workbench_terraform(workbench): + wi = WorkbenchInfo(workbench) + wi.prepare_terraform_vars() + return 0 + +def create_workbench(workbench, token, credentials=None): + utils.load_config(accessKey=token) # TODO: allow custom path? + + workbench_info = WorkbenchInfo(workbench) + + # workbench files being created + workbench_info.create_workbench_dir(credentials) + + return 0 diff --git a/frontend/website/ghpcfe/cluster_manager/destroy_workbench.py b/frontend/website/ghpcfe/cluster_manager/destroy_workbench.py new file mode 100644 index 0000000000..7c79c9ce39 --- /dev/null +++ b/frontend/website/ghpcfe/cluster_manager/destroy_workbench.py @@ -0,0 +1,42 @@ +# Copyright 2022 Google LLC +# +# 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. + +import argparse + +from .utils import run_terraform, load_config + + +def destroy_workbench(workbench, token): + ''' + Destroy a workbench. + + Parameters: + args - an object with the following members: + 'workbench_id' - id # of the compute workbench + 'accessKey' - DB access key + ''' + + config = load_config() + + workbench.status = 't' + workbench.cloud_status = 'dm' + workbench.save() + workbench_dir = config["baseDir"] / 'workbenches' / f'workbench_{workbench.id}' + + print("running destroy workbench " + str(workbench.id)) + run_terraform(workbench_dir / 'terraform' / 'google', 'destroy') + workbench.status = 'd' + workbench.cloud_status = 'xm' + workbench.save() + diff --git a/frontend/website/ghpcfe/cluster_manager/filesystem.py b/frontend/website/ghpcfe/cluster_manager/filesystem.py new file mode 100644 index 0000000000..9b59331b61 --- /dev/null +++ b/frontend/website/ghpcfe/cluster_manager/filesystem.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +# Copyright 2022 Google LLC +# +# 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. + + + +import argparse +from pathlib import Path +import os, shutil, sys, subprocess +import json +import logging +logger = logging.getLogger(__name__) + +from ..models import * + +from . import utils + + +def write_filestore_yaml(fs: GCPFilestoreFilesystem, tgtDir: Path) -> None: + ymlFile = tgtDir / 'filesystem.yaml' + project_id = json.loads(fs.cloud_credential.detail)["project_id"] + # Get first (only) export + export_name = fs.exports.first().export_name + + with ymlFile.open('w') as f: + f.write(f""" +blueprint_name: {fs.name} + +vars: + project_id: {project_id} + deployment_name: {fs.name} + region: {fs.cloud_region} + zone: {fs.cloud_zone} + +resource_groups: +- group: primary + resources: + - source: resources/file-system/filestore + kind: terraform + id: {fs.name} + settings: + filestore_share_name: {export_name[1:]} + network_name: {fs.subnet.vpc.cloud_id} + zone: {fs.cloud_zone} + size_gb: {fs.capacity} + filestore_tier: {fs.get_performance_tier_display()} + outputs: + - network_storage +""") + + + +def update_filesystem(fs: Filesystem) -> None: + return create_filesystem(fs) + + +def create_filesystem(fs: Filesystem) -> None: + tgtDir = _base_dir_for_fs(fs) + if not tgtDir.is_dir(): + tgtDir.mkdir(parents=True) + + # Create creds file + with _get_credentials_file(fs).open('w') as fp: + fp.write(fs.cloud_credential.detail) + fp.write("\n") + + # Convert to our native type + Impl = FilesystemImpl(fs.impl_type) + if Impl == FilesystemImpl.GCPFILESTORE: + fs = fs.gcpfilestorefilesystem + write_filestore_yaml(fs, tgtDir) + else: + raise NotImplementedError("No support yet for this filesystem") + + +def _run_ghpc(tgtDir: Path) -> None: + ghpc_path = utils.load_config()["baseDir"] / 'dependencies' / 'hpc-toolkit' / 'ghpc' + + try: + logger.info("Invoking ghpc create") + log_out_fn = tgtDir / f"ghpc_create_log.stdout" + log_err_fn = tgtDir / f"ghpc_create_log.stderr" + with log_out_fn.open('wb') as log_out: + with log_err_fn.open('wb') as log_err: + subprocess.run([ghpc_path.as_posix(), 'create', 'filesystem.yaml'], + cwd=tgtDir, + stdout=log_out, stderr=log_err, + check=True) + except subprocess.CalledProcessError as cpe: + logger.error("ghpc exec failed", exc_info=cpe) + # No logs from stdout/err - get dumped to files + raise + +def start_filesystem(fs: Filesystem) -> None: + """Effectively, just 'terraform apply'""" + fs.status = 'cm' + fs.save() + try: + _run_ghpc(_base_dir_for_fs(fs)) + extraEnv = {'GOOGLE_APPLICATION_CREDENTIALS': _get_credentials_file(fs)} + tgtDir = _tf_dir_for_fs(fs) + utils.run_terraform(tgtDir, "init") + utils.run_terraform(tgtDir, "plan", extraEnv=extraEnv) + logger.info(f"Invoking terraform apply for fs {fs.id}") + utils.run_terraform(tgtDir, "apply", extraEnv=extraEnv) + logger.info(f"terraform apply complete, getting status for fs {fs.id}") + (out_fn, err_fn) = utils.run_terraform(tgtDir, "output", arguments=["-json"]) + with out_fn.open('r') as outputfp: + results = json.load(outputfp) + data = results[f'network_storage_{fs.name}']['value'] + fs.cloud_id = f'network_storage_{fs.name}' + fs.hostname_or_ip = data['server_ip'] + fs.cloud_state = 'm' + fs.save() + except subprocess.CalledProcessError as cpe: + fs.cloud_state = 'nm' + fs.save() + logger.error("Terraform apply failed", exc_info=cpe) + if cpe.stdout: + logger.info(f" STDOUT:\n{cpe.stdout.decode('utf-8')}\n") + if cpe.stderr: + logger.info(f" STDERR:\n{cpe.stderr.decode('utf-8')}\n") + raise + + +def destroy_filesystem(fs: Filesystem) -> None: + tgtDir = _tf_dir_for_fs(fs) + extraEnv = {'GOOGLE_APPLICATION_CREDENTIALS': _get_credentials_file(fs)} + utils.run_terraform(tgtDir, "destroy", extraEnv=extraEnv) + + +def _base_dir_for_fs(fs: Filesystem) -> Path: + config = utils.load_config() + return config["baseDir"] / 'fs' / f'fs_{fs.id}' + +def _tf_dir_for_fs(fs: Filesystem) -> Path: + return _base_dir_for_fs(fs) / f'{fs.name}' / 'primary' + +def _get_credentials_file(fs: Filesystem) -> Path: + return _base_dir_for_fs(fs) / 'cloud_credentials' diff --git a/frontend/website/ghpcfe/cluster_manager/pause_cluster.py b/frontend/website/ghpcfe/cluster_manager/pause_cluster.py new file mode 100644 index 0000000000..53ae9d03b7 --- /dev/null +++ b/frontend/website/ghpcfe/cluster_manager/pause_cluster.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +# Copyright 2022 Google LLC +# +# 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. + + +import configparser + +from .utils import load_cluster_info, run_terraform + + +def pause_cluster(args): + ''' + Pause or un-pause a cluster. + + Parameters: + args - an object with the following members: + 'cluster_id' - id # of the compute cluster + 'accessKey' - key to update database [not really used ?] + ''' + load_cluster_info(args) + + if args.cloud == "google": + raise NotImplementedError("Pausing on GCP not yet implemented") + #pause_cluster_gcp(args) + else: + raise NotImplementedError(f"Pausing on {args.cloud} not yet implemented") + + run_terraform(args.cluster_dir / 'terraform' / args.cloud, 'refresh') + diff --git a/frontend/website/ghpcfe/cluster_manager/spack.py b/frontend/website/ghpcfe/cluster_manager/spack.py new file mode 100644 index 0000000000..a58dbeb039 --- /dev/null +++ b/frontend/website/ghpcfe/cluster_manager/spack.py @@ -0,0 +1,41 @@ +# Copyright 2022 Google LLC +# +# 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. + +from pathlib import Path +from . import utils +import sys + +spack_prefix = utils.g_baseDir / 'dependencies' / 'spack' +spack_path_lib = spack_prefix / 'lib' / 'spack' +spack_external_libs = spack_path_lib / 'external' + +sys.path.insert(0, spack_path_lib.as_posix()) +sys.path.insert(0, spack_external_libs.as_posix()) + +import spack.main +import spack.repo +import spack.version + +def get_package_list(): + return spack.repo.all_package_names() + +def get_package_info(names): + pkgs = [spack.repo.get(name) for name in names] + return ({'name': pkg.name, + 'latest_version': str(spack.version.VersionList(pkg.versions).preferred()), + 'versions': [str(v) for v in reversed(sorted(pkg.versions))], + 'variants': [k for k,v in pkg.variants.items()], + 'description': pkg.format_doc() + } for pkg in pkgs) + diff --git a/frontend/website/ghpcfe/cluster_manager/start_workbench.py b/frontend/website/ghpcfe/cluster_manager/start_workbench.py new file mode 100644 index 0000000000..7df0024f40 --- /dev/null +++ b/frontend/website/ghpcfe/cluster_manager/start_workbench.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# Copyright 2022 Google LLC +# +# 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. + + +import argparse +import sys + + +from . import utils +from .workbenchinfo import WorkbenchInfo + + +def start_workbench(workbench, token): + workbench.cloud_state = 'nm' + workbench.status = 'c' + workbench.save() + utils.load_config(accessKey=token) # TODO: allow custom path? + wi = WorkbenchInfo(workbench) + wi.initialize_terraform() + wi.run_terraform() + workbench.cloud_state = 'm' + workbnch.save() diff --git a/frontend/website/ghpcfe/cluster_manager/utils.py b/frontend/website/ghpcfe/cluster_manager/utils.py new file mode 100644 index 0000000000..3ad5fe7622 --- /dev/null +++ b/frontend/website/ghpcfe/cluster_manager/utils.py @@ -0,0 +1,238 @@ +# Copyright 2022 Google LLC +# +# 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. + +from pathlib import Path +import json, os, subprocess +import requests +import yaml +import copy + +#TODO = Make some form of global config file +g_baseDir = Path( __file__ ).resolve().parent.parent.parent.parent +g_config = { + 'baseDir': g_baseDir, + 'server': {}, + 'loaded': False +} + + + +def load_config(configFile=g_baseDir/'configuration.yaml', accessKey=None): + global g_config + def _pathify(var): + global g_config + if var in g_config: + if type(g_config[var]) is not Path: + g_config[var] = Path(g_config[var]) + + if not g_config['loaded']: + + with configFile.open('r') as f: + g_config.update(yaml.safe_load(f)['config']) + + # Convert certain entries to appropriate types + _pathify('baseDir') + + if accessKey: + g_config["server"]["accessKey"] = accessKey + elif "C398_API_AUTHENTICATION_TOKEN" in os.environ: + g_config["server"]["accessKey"] = os.environ["C398_API_AUTHENTICATION_TOKEN"] + + g_config['loaded'] = True + + if accessKey and (("accessKey" not in g_config["server"]) or (accessKey != g_config["server"]["accessKey"])): + cfg = copy.deepcopy(g_config) + cfg["server"]["accessKey"] = accessKey + return cfg + + return g_config + + +def _parse_tfvars(filename): + res = dict() + with open(filename, 'r') as fp: + lines = [x for x in fp] + + lnum = 0 + multi_line_terminator = None + + while lnum < len(lines): + line = lines[lnum] + lnum += 1 + if multi_line_terminator: + if line.startswith(multi_line_terminator): + multi_line_terminator = None + res[current_key] = current_value + else: + current_value += line + else: + line = line.strip() + if line.startswith('#'): + continue + line = line.split('=', maxsplit=1) + if len(line) != 2: + # Not sure what to do when it's not x=y... skip? + continue + (current_key, current_value) = [x.strip() for x in line] + + if current_value.startswith('<<'): + multi_line_terminator=current_value[2:] + current_value = "" + continue + + res[current_key] = current_value.strip(' " " ') + + return res + + +def add_host_to_server_firewall(newHost): + if not newHost: + return + config = load_config() + + if "firewall" not in config["server"]: + return + if not config["server"]["firewall"].get("update", False): + return + firewallName = config["server"]["firewall"].get("name", None) + if not firewallName: + return + if config["server"].get("host_type", None) == "GCP": + project = config["server"].get("gcp_project", None) + if project: + # Only support GCP at the moment + try: + import googleapiclient.discovery + gcloud = googleapiclient.discovery.build("compute", "v1", cache_discovery=False) + existingFW = gcloud.firewalls().get(project=project, firewall=firewallName).execute() + patch = {'sourceRanges': existingFW["sourceRanges"]} + patch['sourceRanges'].append(f"{newHost}/32") + res = gcloud.firewalls().patch(project=project, firewall=firewallName, body=patch).execute() + except Exception as e: + # TODO: Log + raise + +def remove_host_from_server_firewall(tgtHost): + config = load_config() + + if "firewall" not in config["server"]: + return + if not config["server"]["firewall"].get("update", False): + return + firewallName = config["server"]["firewall"].get("name", None) + if not firewallName: + return + if config["server"].get("host_type", None) == "GCP": + project = config["server"].get("gcp_project", None) + if project: + # Only support GCP at the moment + try: + import googleapiclient.discovery + gcloud = googleapiclient.discovery.build("compute", "v1", cache_discovery=False) + existingFW = gcloud.firewalls().get(project=project, firewall=firewallName).execute() + patch = {'sourceRanges': [x for x in existingFW["sourceRanges"] if x != f"{tgtHost}/32"]} + gcloud.firewalls().patch(project=project, firewall=firewallName, body=patch).execute() + except Exception as e: + # TODO: Log + raise + + + +def load_cluster_info(args): + load_config(accessKey=args.accessKey) + args.cluster_dir = g_baseDir / 'clusters' / f'cluster_{args.cluster_id}' + if not args.cluster_dir.is_dir(): + raise FileExistsError(f"Cluster ID {args.cluster_id} does not exist") + + if 'cloud' not in args: + for c in ["google"]: + d = args.cluster_dir / 'terraform' / c + if d.is_dir(): + args.cloud = c + break + else: + raise FileExistsError(f"Unable to determine Cloud type of Cluster Dir {args.cluster_dir.as_posix()}") + + stateFile = args.cluster_dir / 'terraform' / args.cloud / 'terraform.tfstate' + with stateFile.open('r') as statefp: + state = json.load(statefp) + args.cluster_ip = state["outputs"]["ManagementPublicIP"]["value"] + args.cluster_name = state["outputs"]["cluster_id"]["value"] + args.tf_state = state + + args.cluster_vars = _parse_tfvars(args.cluster_dir / 'terraform' / args.cloud / 'terraform.tfvars') + + + +def rsync_dir(sourceDir, targetDir, args, log_dir, log_name='rsync_log', source_is_remote=False, rsync_opts=[]): + """ + Requires 'args.cluster_dir' and 'args.cluster_ip' + """ + ssh_key = args.cluster_dir / '.ssh' / 'id_rsa' + ssh_args = f"ssh -i {ssh_key.as_posix()}" + + remote_str = f"citc@{args.cluster_ip}:" + + src_dir = f'{(remote_str if source_is_remote else "")}{sourceDir.as_posix()}/' + tgt_dir = f'{(remote_str if not source_is_remote else "")}{targetDir.as_posix()}' + + rsync_ssh = f"ssh -i {ssh_key.as_posix()}" + rsync_cmd = ["rsync", "-az", "--copy-unsafe-links", "-e", ssh_args] + rsync_cmd.extend(rsync_opts) + rsync_cmd.extend([src_dir, tgt_dir]) + + newEnv = os.environ.copy() + # Don't have terraform try to re-use any existing SSH agent + # It has its own keys + if "SSH_AUTH_SOCK" in newEnv: + del newEnv["SSH_AUTH_SOCK"] + + + try: + subprocess.run(rsync_cmd, env=newEnv, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True) + except subprocess.CalledProcessError as cpe: + if cpe.stdout: + with open(log_dir / f"{log_name}.stdout", 'wb') as log_out: + log_out.write(cpe.stdout) + if cpe.stderr: + with open(log_dir / f"{log_name}.stderr", 'wb') as log_err: + log_err.write(cpe.stderr) + raise + + + +def run_terraform(tgtDir, command, arguments=[], extraEnv={}): + cmdline = ["terraform", command, "-no-color"] + cmdline.extend(arguments) + if command in ["apply", "destroy"]: + cmdline.append("-auto-approve") + + log_out_fn = tgtDir / f"terraform_{command}_log.stdout" + log_err_fn = tgtDir / f"terraform_{command}_log.stderr" + + newEnv = os.environ.copy() + # Don't have terraform try to re-use any existing SSH agent + # It has its own keys + if "SSH_AUTH_SOCK" in newEnv: + del newEnv["SSH_AUTH_SOCK"] + newEnv.update(extraEnv) + + with log_out_fn.open('wb') as log_out: + with log_err_fn.open('wb') as log_err: + proc = subprocess.run(cmdline, cwd=tgtDir, env=newEnv, + stdout=log_out, stderr=log_err, check=True) + + return (log_out_fn, log_err_fn) + + diff --git a/frontend/website/ghpcfe/cluster_manager/validate_credential.py b/frontend/website/ghpcfe/cluster_manager/validate_credential.py new file mode 100644 index 0000000000..39a5132155 --- /dev/null +++ b/frontend/website/ghpcfe/cluster_manager/validate_credential.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# Copyright 2022 Google LLC +# +# 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. + + +import json +import warnings +from google.oauth2 import service_account + +def validate_credential(cloud_provider, credential_detail): + """ communicate with a cloud provider to validate a credential """ + + validated = False + if cloud_provider == 'GCP': + validated = _validate_credential_gcp(credential_detail) + + return validated + + + +def _validate_credential_gcp(credential_detail): + + # catch errors for incorrect format + try: + info = json.loads(credential_detail) + except Exception as ex: + print(ex) + return False + + # I've seen different error conditions, including a warning to indicate + # corrupted private key. Need to catch that but not other harmless warnings. + warnings.simplefilter('ignore', ResourceWarning) + warnings.simplefilter('error', UserWarning) + try: + credentials = service_account.Credentials.from_service_account_info(info) + except Exception as ex: + print('Invalid private key in the credential information') + print(ex) + return False + + return True diff --git a/frontend/website/ghpcfe/cluster_manager/vpc.py b/frontend/website/ghpcfe/cluster_manager/vpc.py new file mode 100644 index 0000000000..2c5352b6b7 --- /dev/null +++ b/frontend/website/ghpcfe/cluster_manager/vpc.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python3 +# Copyright 2022 Google LLC +# +# 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. + + + +import argparse +from pathlib import Path +import os, shutil, sys, subprocess +import json + +from ..models import VirtualNetwork, VirtualSubnet + +from . import utils + + +def create_vpc(vpc: VirtualNetwork) -> None: + + # create working directory and copy in TerraForm templates + tgtDir = _tf_dir_for_vpc(vpc.id) + if not tgtDir.parent.is_dir(): + tgtDir.parent.mkdir(parents=True) + shutil.copytree(_tf_source_dir_for_vpc("GCP"), tgtDir) + + # create credential file + with open(tgtDir / 'cloud_credentials', 'w') as fp: + fp.write(vpc.cloud_credential.detail) + fp.write("\n") + + project_id = json.loads(vpc.cloud_credential.detail)["project_id"] + + # create Terraform variable definition file + with open(tgtDir / 'terraform.tfvars', 'w') as fp: + fp.write(f""" +region = "{vpc.cloud_region}" +zone = "{vpc.cloud_zone}" +project = "{project_id}" +credentials = "cloud_credentials" +""") + + if not vpc.is_managed: + # If VPC is not managed by us, don't create it, use a TF data provider + mainTF = tgtDir / 'main.tf' + mainTF.unlink() + generate_vpc_tf_datablock(vpc, tgtDir) + try: + utils.run_terraform(tgtDir, "init") + utils.run_terraform(tgtDir, "validate") + utils.run_terraform(tgtDir, "plan") + except subprocess.CalledProcessError as cpe: + logger.error("Terraform exec failed", exc_info=cpe) + if cpe.stdout: + logger.info(f" STDOUT:\n{cpe.stdout.decode('utf-8')}\n") + if cpe.stderr: + logger.info(f" STDERR:\n{cpe.stderr.decode('utf-8')}\n") + raise + + +def start_vpc(vpc: VirtualNetwork) -> None: + """Effectively, just 'terraform apply'""" + tgtDir = _tf_dir_for_vpc(vpc.id) + try: + utils.run_terraform(tgtDir, "apply") + stateFile = tgtDir / 'terraform.tfstate' + with stateFile.open('r') as statefp: + state = json.load(statefp) + if vpc.is_managed: + vpc.cloud_id = state["outputs"]["vpc_id"]["value"] + vpc.save() + for subnet in vpc.subnets.all(): + if subnet.is_managed: + subnet.cloud_id = state["outputs"][f"subnet-{subnet.id}"]["value"] + subnet.cloud_state = 'm' + subnet.save() + except subprocess.CalledProcessError as cpe: + logger.error("Terraform apply failed", exc_info=cpe) + if cpe.stdout: + logger.info(f" STDOUT:\n{cpe.stdout.decode('utf-8')}\n") + if cpe.stderr: + logger.info(f" STDERR:\n{cpe.stderr.decode('utf-8')}\n") + raise + + +def destroy_vpc(vpc: VirtualNetwork) -> None: + tgtDir = _tf_dir_for_vpc(vpc.id) + utils.run_terraform(tgtDir, "destroy") + vpc.cloud_state = 'xm' + vpc.save() + + +def create_subnet(subnet: VirtualSubnet) -> None: + """Create a new Subnet in an existing VPC + Uses adds a subnet file to the VPC TF directory. + If no VPC TF directory exists, create one importing a + data resource for the VPC itself. + """ + tgtDir = _tf_dir_for_vpc(subnet.vpc.id) + if not tgtDir.is_dir(): + create_vpc(subnet.vpc) + template = tgtDir / 'subnet.tf.template' + with open(template, 'r') as fp: + templateStr = fp.read() + templateStr = templateStr.replace("{SUBNET_ID}", str(subnet.id)) + templateStr = templateStr.replace("{CIDR_TEXT}", str(subnet.cidr)) + fname = tgtDir / f'subnet-{subnet.id}.tf' + with open(fname, 'w') as fp: + fp.write(templateStr) + + +def delete_subnet(subnet: VirtualSubnet) -> None: + """Removes the subnet from the VPC""" + tgtDir = _tf_dir_for_vpc(subnet.vpc.id) + fname = tgtDir / f'subnet-{subnet.id}.tf' + if fname.exists(): + fname.unlink() + + +def generate_vpc_tf_datablock(vpc: VirtualNetwork, tgtDir: Path) -> Path: + outFile = tgtDir / 'vpc.tf' + if "GCP" in vpc.cloud_provider: + dstype = "google_compute_network" + key = "name" + else: + raise NotImplementedError(f"Cloud Provider {vpc.cloud_provider} not yet implmeneted") + with outFile.open('w') as fp: + fp.write(f""" +data {dstype} "the_vpc" {{ + {key} = {vpc.cloud_id} +}} + +""") + return outFile + + +def generate_subnet_tf_datablock(subnet: VirtualSubnet, tgtDir: Path) -> Path: + outFile = tgtDir / f"subnet-{subnet.id}.tf" + if "GCP" in subnet.cloud_provider: + dstype = "google_compute_subnetwork" + key = "name" + else: + raise NotImplementedError(f"Cloud Provider {vpc.cloud_provider} not yet implmeneted") + with outFile.open('w') as fp: + fp.write(f""" +data {dstype} "subnet_{subnet.id}" {{ + {key} = {subnet.cloud_id} +}} + +""") + return outFile + + +def _tf_dir_for_vpc(vpc_id: int) -> Path: + config = utils.load_config() + return config["baseDir"] / 'vpcs' / f'vpc_{vpc_id}' + + +def _tf_source_dir_for_vpc(cloud: str) -> Path: + config = utils.load_config() + return config["baseDir"] / 'infrastructure_files' / 'vpc_tf' / cloud diff --git a/frontend/website/ghpcfe/cluster_manager/workbenchinfo.py b/frontend/website/ghpcfe/cluster_manager/workbenchinfo.py new file mode 100644 index 0000000000..5c9a66389f --- /dev/null +++ b/frontend/website/ghpcfe/cluster_manager/workbenchinfo.py @@ -0,0 +1,188 @@ +#!/usr/bin/env python3 +# Copyright 2022 Google LLC +# +# 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. + + +# To create a workbench, we need: +# 1) Know which Cloud Provider & region/zone/project +# 2) Know authentication credentials +# 3) Know an "ID Number" or name - for directory to store state info + +# 1 - Supplied via commandline +# 2 - Supplied via... Env vars / commandline? +# 3 - Supplied via commandline + +import argparse +import os, shutil, sys +import subprocess +import json +import os.path as path +from datetime import datetime +from datetime import timedelta + +from . import utils +class WorkbenchInfo: + + def __init__(self, workbench): + self.config = utils.load_config() + + self.workbench = workbench + self.workbench_dir = self.config["baseDir"] / 'workbenches' / f'workbench_{self.workbench.id}' + + self.cloud_dir = "google" + + def create_workbench_dir(self, credentials): + self.workbench_dir.mkdir(parents=True) + + self.set_credentials(credentials) + self.copy_terraform() + self.prepare_terraform_vars() + + def get_credentials_file(self): + return self.workbench_dir / 'cloud_credentials' + + def set_credentials(self, creds=None): + credfile = self.get_credentials_file() + if not creds: + # pull from DB + creds = self.workbench.cloud_credential.detail + with credfile.open('w') as fp: + fp.write(creds) + + def copy_terraform(self): + tfDir = self.workbench_dir / 'terraform' + shutil.copytree(self.config["baseDir"] / 'infrastructure_files' / 'workbench_tf' / self.cloud_dir, tfDir / self.cloud_dir ) + #shutil.copytree(self.config["baseDir"] / 'infrastructure_files' / 'workbench_tf' / 'common-files' , tfDir / 'common-files' ) + return tfDir + + def prepare_terraform_vars(self): + region = self.workbench.cloud_region + zone = self.workbench.cloud_zone + vpc = self.workbench.subnet.vpc.cloud_id + subnet = self.workbench.subnet.cloud_id + + # Cloud-specific Terraform changes + project = json.loads(self.workbench.cloud_credential.detail)["project_id"] + + users = self.workbench.trusted_users.all() + trusted_user_tfvalue = "" + i = 0 + for user in users: + if i != 0: + trusted_user_tfvalue = trusted_user_tfvalue + "," + i = 1 + trusted_user_tfvalue = trusted_user_tfvalue + "\"user:" + user.email + "\"" + + csp_info = f""" +region = "{region}" +zone = "{zone}" +project_name = "{project}" +credentials = "{self.get_credentials_file().resolve().as_posix()}" +subnet_name = "{subnet}" +machine_type = "{self.workbench.machine_type}" +boot_disk_type = "{self.workbench.boot_disk_type}" +boot_disk_size_gb = "{self.workbench.boot_disk_capacity}" +trusted_users = [{trusted_user_tfvalue}] +image_family = "{self.workbench.image_family}" +""" +# pkeys_str = b"\n".join(self._get_ssh_keys()).decode('utf-8') + tfvars = self.workbench_dir / 'terraform' / self.cloud_dir / 'terraform.tfvars' + with tfvars.open('w') as f: + f.write(f""" +{csp_info} +""") + + + def get_workbench_access_key(self): + return self.workbench.get_access_key() + + def initialize_terraform(self): + tfDir = self.workbench_dir / 'terraform' + try: + print("Invoking Terraform Init") + utils.run_terraform(tfDir / self.cloud_dir, "init") + utils.run_terraform(tfDir / self.cloud_dir, "validate") + print("Invoking Terraform Plan") + utils.run_terraform(tfDir / self.cloud_dir, "plan") + except subprocess.CalledProcessError as cpe: + if cpe.stdout: + print(cpe.stdout.decode('utf-8')) + if cpe.stderr: + print(cpe.stderr.decode('utf-8')) + raise + + + def run_terraform(self): + tfDir = self.workbench_dir / 'terraform' + try: + print("Invoking Terraform Apply") + (log_out, log_err) = utils.run_terraform(tfDir / self.cloud_dir, "apply") + # Look for Management Public IP in terraform.tfstate + stateFile = tfDir / self.cloud_dir / 'terraform.tfstate' + with stateFile.open('r') as statefp: + state = json.load(statefp) + workbench_name = state["outputs"]["workbench_id"]["value"] + print(f"Created workbench {workbench_name}, url not available yet") + # workbench is now being initialized + self.workbench.internal_name = workbench_name + self.workbench.cloud_state = 'm' + self.workbench.status = 'i' + + self.workbench.save() + # Ansible is now running... Probably 15-30 minutes or so + + + except subprocess.CalledProcessError as cpe: + # We can error during provisioning, in which case Terraform + # doesn't tear things down. Run a `desotry`, just in case + try: + utils.run_terraform(tfDir / self.cloud_dir, 'destroy') + except subprocess.CalledProcessError as cpe2: + pass + if cpe.stdout: + print(cpe.stdout.decode('utf-8')) + if cpe.stderr: + print(cpe.stderr.decode('utf-8')) + raise + + def get_workbench_proxy_uri(self): + # set terraform dir + tfDir = self.workbench_dir / 'terraform' + try: + stateFile = tfDir / self.cloud_dir / 'terraform.tfstate' + if os.path.exists(stateFile): + file_time = datetime.utcfromtimestamp(os.path.getmtime(stateFile)) + check_time = datetime.utcnow() - timedelta(seconds=60) + + if file_time < check_time: + (log_out, log_err) = utils.run_terraform(tfDir / self.cloud_dir, "apply", ["-refresh-only"]) + + with stateFile.open('r') as statefp: + state = json.load(statefp) + + self.workbench.proxy_uri = state["resources"][3]["instances"][0]["attributes"]["proxy_uri"] + if state["resources"][3]["instances"][0]["attributes"]["state"] == "ACTIVE": + self.workbench.status = 'r' + + self.workbench.save() + + + except subprocess.CalledProcessError as cpe: + # We can error during provisioning, in which case Terraform + # doesn't tear things down. Run a `desotry`, just in case + if cpe.stdout: + print(cpe.stdout.decode('utf-8')) + if cpe.stderr: + print(cpe.stderr.decode('utf-8')) + raise diff --git a/frontend/website/ghpcfe/forms.py b/frontend/website/ghpcfe/forms.py new file mode 100644 index 0000000000..29b59b5ab2 --- /dev/null +++ b/frontend/website/ghpcfe/forms.py @@ -0,0 +1,490 @@ +# Copyright 2022 Google LLC +# +# 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. + +""" forms.py """ + +from django import forms +from django.forms import ValidationError, modelformset_factory, inlineformset_factory +from django.contrib.auth.forms import UserCreationForm, UserChangeForm +from django.utils.safestring import mark_safe +from .cluster_manager import validate_credential, cloud_info +from .models import * +import json + +class UserCreationForm(UserCreationForm): + """ Custom UserCreationForm """ + + class Meta(UserCreationForm): + model = User + fields = ('email',) + + +class UserUpdateForm(UserChangeForm): + """ Custom form for updating user account """ + + password = None + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['ssh_key'].label = "SSH key" + + class Meta: + model = User + fields = ('email','ssh_key',) + widgets = { + 'email': forms.TextInput(attrs={'class': 'form-control'}), + 'ssh_key': forms.Textarea(attrs={'class': 'form-control'}), + } + + +class CredentialForm(forms.ModelForm): + """ Custom form for Credential model implementing additional validation """ + + class Meta: + model = Credential + + fields = ('name', 'detail') + + widgets = { + 'name': forms.TextInput(attrs={'class': 'form-control'}), + 'detail': forms.Textarea(attrs={'class': 'form-control'}), + } + + def clean(self): + super().clean() + + # validate the credential details with cloud platform + detail = self.cleaned_data['detail'] + validated = validate_credential.validate_credential("GCP", detail) + if not validated: + raise ValidationError('Credential cannot be validated.') + + +class ClusterForm(forms.ModelForm): + """ Custom form for Cluster model implementing option filtering """ + + def clean(self): + super().clean() + # TODO - validate 'region' and 'zone' + + def _get_creds(self, kwargs): + # We do this, because on Create views, there isn't an instance, so we + # set the creds via the 'initial' data field. On Updates, there is + # an object, so pull from there + if 'cloud_credential' in kwargs['initial']: + creds = kwargs['initial']['cloud_credential'] + else: + creds = self.instance.cloud_credential + return creds + + def __init__(self, *args, **kwargs): + + zone_choices = None + if 'zone_choices' in kwargs: + zone_choices = kwargs.pop('zone_choices') + + super().__init__(*args, **kwargs) + credential = self._get_creds(kwargs) + + self.fields['subnet'].queryset = VirtualSubnet.objects.filter(cloud_credential=credential) + if zone_choices: + # We set this on the widget, because we will be changing the + # widget's field in the template via javascript + self.fields['cloud_zone'].widget.choices = zone_choices + + if 'n' not in self.instance.cloud_state: + # Need to disable certain widgets + self.fields['subnet'].disabled = True + self.fields['cloud_zone'].disabled = True + self.fields['spackdir'].disabled = True + + class Meta: + model = Cluster + + fields = ('name', 'subnet', 'cloud_zone', 'cloud_credential', 'authorised_users', 'spackdir', 'num_login_nodes') + + widgets = { + 'name': forms.TextInput(attrs={'class': 'form-control'}), + 'cloud_credential': forms.Select(attrs={'class': 'form-control', 'disabled': True}), + 'subnet': forms.Select(attrs={'class': 'form-control'}), + 'cloud_zone': forms.Select(attrs={'class': 'form-control'}), + } + + + + +class ClusterMountPointForm(forms.ModelForm): + """ Form for Cluster Mount points """ + class Meta: + model = MountPoint + fields = ('export', 'mount_order', 'mount_path', 'mount_options') + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + for field in self.fields: + self.fields[field].widget.attrs.update({'class': 'form-control'}) + +class ClusterPartitionForm(forms.ModelForm): + """ Form for Cluster Paritions """ + class Meta: + model = ClusterPartition + fields = ('name', 'machine_type', 'image', 'max_node_count', 'enable_placement', 'enable_hyperthreads', 'enable_node_reuse') + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + for field in self.fields: + self.fields[field].widget.attrs.update({'class': 'form-control'}) + if self.fields[field].help_text: + self.fields[field].widget.attrs.update({'title': self.fields[field].help_text}) + + def clean(self): + cleaned_data = super().clean() + if cleaned_data['enable_placement'] and cleaned_data['machine_type'].family.name not in ['c2', 'c2d']: + raise ValidationError('Placement Groups are only valid for C2 and C2D instance types') + return cleaned_data + + +class WorkbenchForm(forms.ModelForm): + """ Custom form for Workbench model implementing option filtering """ + + def clean(self): + cleaned_data = super().clean() + subnet = cleaned_data.get("subnet") + + if subnet.cloud_zone not in self.workbench_zones: + validation_error_message = "Network " + subnet.vpc.cloud_id + " has an invalid region & zone for Vertex AI Workbenches: " + subnet.cloud_zone + ". Please see Workbench Documentation for more infromation on region availability, try" + raise forms.ValidationError(mark_safe(validation_error_message)) + + #validate user has an email address that we can pass to GCP + users = cleaned_data.get("trusted_users") + for user in users: + if not user.email: + raise forms.ValidationError("Trusted User has no email address") + + def __init__(self, user, *args, **kwargs): + has_creds = 'cloud_credential' in kwargs + if has_creds: + credential = kwargs.pop('cloud_credential') + kwargs['initial']['cloud_credential'] = credential + super().__init__(*args, **kwargs) + if not has_creds: + credential = self.instance.cloud_credential + self.fields['subnet'].queryset = VirtualSubnet.objects.filter(cloud_credential=credential) + self.workbench_zones = cloud_info.get_gcp_workbench_region_zone_info(credential.detail) + if 'n' not in self.instance.cloud_state: + #Need to disable certain widgets + self.fields['subnet'].disabled = True + #Pull instance types from cloud_info + instance_types = cloud_info.get_machine_types("GCP", credential.detail, "europe-west4", "europe-west4-a") + #set variables for retrieving instance types for dropdown menu + choices_list = [] + instance_list = [] + category = "" + #Populate dropdown menu with preset instance_types from WorkbenchPresets + for preset in WorkbenchPreset.objects.order_by('category').values(): + #if category variable has changed from last loop then append instances to overall choices list as tuple and clear instance_list + if category != preset['category']: + if category: + choices_list.append((category,tuple(instance_list))) + instance_list = [] + #set category to current value and append preset to dropdown menu list + category = preset['category'] + instance_list.append((preset['machine_type'],preset['name'])) + #append final preset instance type from loop + choices_list.append((category,tuple(instance_list))) + category = "" + if Role.CLUSTERADMIN in [x.id for x in user.roles.all()]: + for instance_type in sorted(instance_types): + #if family variable has changed from last loop then append instances to overall choices list as tuple and clear instance_list + if category != instance_types[instance_type]['family']: + if category: + choices_list.append((category,tuple(instance_list))) + instance_list = [] + #save family of current instance + category = instance_types[instance_type]['family'] + #create instance string for displaying to user + instance_string = instance_types[instance_type]['name'] + " - " + str(instance_types[instance_type]['vCPU']) + "x " + instance_types[instance_type]['arch'] + " vCPUs with " + str(instance_types[instance_type]['memory']) + " Memory" + #append tuple to instance list + instance_list.append((instance_types[instance_type]['name'],instance_string)) + #append final preset instance type from loop + choices_list.append((category,tuple(instance_list))) + self.fields['machine_type'].widget.choices = choices_list + + class Meta: + model = Workbench + + fields = ('name', 'subnet', 'cloud_credential', 'trusted_users', 'machine_type', 'boot_disk_type', 'boot_disk_capacity', 'image_family') + + widgets = { + 'name': forms.TextInput(attrs={'class': 'form-control'}), + 'cloud_credential': forms.Select(attrs={'class': 'form-control', 'disabled': True}), + 'subnet': forms.Select(attrs={'class': 'form-control'}), + 'machine_type': forms.Select(attrs={'class': 'form-control'}), + } + +class ApplicationEditForm(forms.ModelForm): + """ Custom form for application model """ + + class Meta: + model = Application + + fields = ('name', 'description') + + widgets = { + 'name': forms.TextInput(attrs={'class': 'form-control'}), + 'description': forms.Textarea(attrs={'class': 'form-control'}), + 'load_command': forms.TextInput(attrs={'class': 'form-control'}), + } + + def clean(self): + super().clean() + + # Validate selected instance types with each other, and 'install instance' + common_arch = cloud_info.get_common_arch([x.cpu_arch for x in self.cleaned_data['instance_type']]) + if not common_arch: + raise ValidationError('Selected Instance Types have incompatible architectures.') + + if self.instance.installed_architecture: + install_arch = self.instance.installed_architecture + for t in self.cleaned_data['instance_type']: + common = cloud_info.get_common_arch([install_arch, t.cpu_arch]) + if not common or common != install_arch: + raise ValidationError(f'Application installed for {install_arch} not valid on {t.cpu_arch} ({t.name})') + + +class ApplicationForm(forms.ModelForm): + """ Custom form for application model """ + + class Meta: + model = Application + + fields = ('install_loc', 'name', 'version', 'description', 'load_command') + + widgets = { + 'install_loc': forms.Select(attrs={'class': 'form-control', 'disabled': True}), + 'name': forms.TextInput(attrs={'class': 'form-control'}), + 'version': forms.TextInput(attrs={'class': 'form-control'}), + 'description': forms.Textarea(attrs={'class': 'form-control'}), + 'load_command': forms.TextInput(attrs={'class': 'form-control'}), + } + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + def clean(self): + super().clean() + + # Validate selected instance types with each other, and 'install instance' + common_arch = cloud_info.get_common_arch([x.cpu_arch for x in self.cleaned_data['instance_type']]) + if not common_arch: + raise ValidationError('Instance Types have incompatible architectures.') + + if self.cleaned_data['installed_architecture']: + tgt = self.cleaned_data['installed_architecture'] + if cloud_info.get_common_arch([tgt, common_arch]) != tgt: + raise ValidationError('Install instance architecture does not match run instance types') + + +class SpackApplicationForm(forms.ModelForm): + """ Custom form for application model """ + + class Meta: + model = Application + + fields = ('cluster', 'spack_name', 'name', 'version', 'spack_spec', 'description', 'install_partition') + + widgets = { + 'cluster': forms.Select(attrs={'class': 'form-control', 'disabled': True}), + 'spack_name': forms.TextInput(attrs={'class': 'form-control'}), + 'name': forms.TextInput(attrs={'class': 'form-control'}), + 'spack_spec': forms.TextInput(attrs={'class': 'form-control'}), + 'version': forms.Select(attrs={'class': 'form-control'}), + 'description': forms.Textarea(attrs={'class': 'form-control'}), + 'install_partition': forms.Select(attrs={'class': 'form-control'}), + } + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + cluster = kwargs['initial']['cluster'] + self.fields['install_partition'].queryset = cluster.partitions + + + +class JobForm(forms.ModelForm): + """ Custom form for job model """ + + class Meta: + model = Job + + fields = ('name', 'application', 'cluster', 'partition', 'number_of_nodes', 'ranks_per_node', \ + 'threads_per_rank', 'wall_clock_time_limit', 'run_script', 'cleanup_choice', \ + 'input_data', 'result_data', 'benchmark') + + widgets = { + 'name': forms.TextInput(attrs={'class': 'form-control'}), + 'application': forms.HiddenInput(), + 'cluster': forms.Select(attrs={'class': 'form-control', 'disabled': True}), + 'partition': forms.Select(attrs={'class': 'form-control'}), + 'number_of_nodes': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}), + 'ranks_per_node': forms.NumberInput(attrs={'class': 'form-control', 'min': '1'}), + 'threads_per_rank': forms.NumberInput(attrs={'class': 'form-control', 'min': '1', 'readonly': True}), + 'wall_clock_time_limit': forms.NumberInput(attrs={'class': 'form-control', 'min': '0'}), + 'run_script': forms.URLInput(attrs={'class': 'form-control'}), + 'input_data': forms.URLInput(attrs={'class': 'form-control'}), + 'result_data': forms.URLInput(attrs={'class': 'form-control'}), + 'cleanup_choice': forms.Select(attrs={'class': 'form-control'}), + 'benchmark': forms.Select(attrs={'class': 'form-control'}), + } + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + cluster = kwargs['initial']['cluster'] + self.fields['partition'].queryset = cluster.partitions + + +class BenchmarkForm(forms.ModelForm): + """ Custom form for benchmark model """ + + class Meta: + model = Benchmark + + fields = ('name', 'description') + widgets = { + 'name': forms.TextInput(attrs={'class': 'form-control'}), + 'description': forms.Textarea(attrs={'class': 'form-control'}), + } + + +class VPCForm(forms.ModelForm): + """ Custom form for VPC model implementing option filtering """ + + def clean(self): + super().clean() + # TODO - validate 'region' and 'zone' + + def __init__(self, *args, **kwargs): + if 'cloud_credential' in kwargs: + cloud_credential = kwargs.pop('cloud_credential') + kwargs['initial']['cloud_credential'] = cloud_credential + super().__init__(*args, **kwargs) + + class Meta: + model = VirtualNetwork + + fields = ('name', 'cloud_credential', 'cloud_region', 'cloud_zone') + + widgets = { + 'name': forms.TextInput(attrs={'class': 'form-control'}), + 'cloud_credential': forms.Select(attrs={'class': 'form-control', 'disabled': True}), + 'cloud_region': forms.Select(attrs={'class': 'form-control'}), + 'cloud_zone': forms.Select(attrs={'class': 'form-control'}), + } + + +class VPCImportForm(forms.ModelForm): + + subnets = forms.MultipleChoiceField(widget=forms.SelectMultiple(attrs={'class': 'form-control', 'disabled': True})) + vpc = forms.ChoiceField(widget=forms.Select(attrs={'class': 'form-control', 'onchange': 'vpcSelected()'})) + + def clean(self): + super().clean() + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['subnets'].choices = kwargs['initial']['subnets'] + self.fields['vpc'].choices = kwargs['initial']['vpc'] + + class Meta: + model = VirtualNetwork + + fields = ('name', 'cloud_credential') + + widgets = { + 'name': forms.TextInput(attrs={'class': 'form-control'}), + 'cloud_credential': forms.Select(attrs={'class': 'form-control', 'disabled': True}), + } + + +class VirtualSubnetForm(forms.ModelForm): + """ Form for VirtualSubnet model to be embedded """ + + class Meta: + model = VirtualSubnet + + fields = ('name', 'cidr') + #widgets = { + # #'instance_type': forms.Select(attrs={'class': 'form-control'}), + # 'max_vCPU': forms.NumberInput(attrs={'min': '1'}), + #} + + +class FilestoreForm(forms.ModelForm): + """ Custom form for GCP Filestoremodel implementing option filtering """ + + share_name = forms.CharField(label='Export Name', + max_length=16, + validators=[ + RegexValidator( + regex='^/[-a-zA-Z0-9_]{1,16}', + message="Share must start with a '/' and be no more than 16 characters long, with no spaces"), + ] + ) + + def _get_creds(self, kwargs): + # We do this, because on Create views, there isn't an instance, so we + # set the creds via the 'initial' data field. On Updates, there is + # an object, so pull from there + if 'cloud_credential' in kwargs['initial']: + creds = kwargs['initial']['cloud_credential'] + else: + creds = self.instance.cloud_credential + return creds + + def __init__(self, *args, **kwargs): + + zone_choices = None + if 'zone_choices' in kwargs: + zone_choices = kwargs.pop('zone_choices') + + super().__init__(*args, **kwargs) + + creds = self._get_creds(kwargs) + + self.fields['subnet'].queryset = VirtualSubnet.objects.filter(cloud_credential=creds) + if zone_choices: + # We set this on the widget, because we will be changing the + # widget's field in the template via javascript + self.fields['cloud_zone'].widget.choices = zone_choices + + if 'n' not in self.instance.cloud_state: + # Need to disable certain widgets + self.fields['subnet'].disabled = True + self.fields['cloud_zone'].disabled = True + self.fields['share_name'].disabled = True + self.fields['performance_tier'].disabled = True + + class Meta: + model = GCPFilestoreFilesystem + + fields = ('name', 'subnet', 'cloud_zone', 'cloud_credential', 'capacity', 'performance_tier') + + widgets = { + 'name': forms.TextInput(attrs={'class': 'form-control'}), + 'cloud_credential': forms.Select(attrs={'class': 'form-control', 'disabled': True}), + 'subnet': forms.Select(attrs={'class': 'form-control'}), + 'capacity': forms.NumberInput(attrs={'min': 1024, 'default':1024}), + 'share_name': forms.TextInput(attrs={'class': 'form-control'}), + 'cloud_zone': forms.Select(attrs={'class': 'form-control'}), + } + diff --git a/frontend/website/ghpcfe/management/commands/custom_startup_command.py b/frontend/website/ghpcfe/management/commands/custom_startup_command.py new file mode 100644 index 0000000000..88bfef416d --- /dev/null +++ b/frontend/website/ghpcfe/management/commands/custom_startup_command.py @@ -0,0 +1,56 @@ +# Copyright 2022 Google LLC +# +# 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. + +from django.core.management.base import BaseCommand, CommandError +from ghpcfe.models import Role, User +from rest_framework.authtoken.models import Token +from django.contrib.sites.models import Site +from allauth.socialaccount.models import SocialApp +import yaml + +class Command(BaseCommand): + help = 'My custom startup command' + + def add_arguments(self, parser): + parser.add_argument('client_id', type=str, help='Client ID',) + parser.add_argument('secret', type=str, help='Client secret key',) + + def handle(self, *args, **kwargs): + client_id = kwargs['client_id'] + secret = kwargs['secret'] + try: + # one-off database initialisation + records = Role.objects.all() + if not records: + roles = [] + # populate Role table + for role in Role.ROLE_CHOICES: + Role.objects.create(id=role[0]) + roles.append(role[0]) + # give the super user all the roles + user = User.objects.get(pk=1) + user.roles.set(roles, clear=True) + # initialise database for Google social login + with open('../configuration.yaml', 'r') as file: + config = yaml.safe_load(file) + domain_name = config['config']['server']['domain_name'] + site = Site.objects.get(pk=1) + site.name = domain_name + site.domain = domain_name + site.save() + socialapp = SocialApp(provider="google", name="Google API", client_id=client_id, key='', secret=secret) + socialapp.save() + socialapp.sites.add(site) + except: + raise CommandError('Initalization failed.') diff --git a/frontend/website/ghpcfe/management/commands/seed_workbench_presets.py b/frontend/website/ghpcfe/management/commands/seed_workbench_presets.py new file mode 100644 index 0000000000..1e8f8a6ffc --- /dev/null +++ b/frontend/website/ghpcfe/management/commands/seed_workbench_presets.py @@ -0,0 +1,59 @@ +# Copyright 2022 Google LLC +# +# 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. + +from django.core.management.base import BaseCommand, CommandError +from ghpcfe.models import WorkbenchPreset + +class Command(BaseCommand): + help = 'Seeds default presets into the workbench preset model so normal users an create workbenches of an approved machine type' + + # def add_arguments(self, parser): + # parser.add_argument('poll_ids', nargs='+', type=int) + + def handle(self, *args, **options): + self.stdout.write("Populating Workbench Presets...", ending='\n') + + #create small preset + wbpreset1 = WorkbenchPreset() + wbpreset1.name = "Small - 1x core with 3840 Memory" + wbpreset1.machine_type = 'n1-standard-1' + wbpreset1.category = 'Recommended' + wbpreset1.save() + self.stdout.write(str(wbpreset1) + ", Machine Type: " + wbpreset1.machine_type + ", Category: " + wbpreset1.category, ending='\n') + + #create medium preset + wbpreset2 = WorkbenchPreset() + wbpreset2.name = "Medium - 2x cores with 7680 Memory" + wbpreset2.machine_type = 'n1-standard-2' + wbpreset2.category = 'Recommended' + wbpreset2.save() + self.stdout.write(str(wbpreset2) + ", Machine Type: " + wbpreset2.machine_type + ", Category: " + wbpreset2.category, ending='\n') + + #create large preset + wbpreset3 = WorkbenchPreset() + wbpreset3.name = "Large - 4x cores with 15360 Memory" + wbpreset3.machine_type = 'n1-standard-4' + wbpreset3.category = 'Recommended' + wbpreset3.save() + self.stdout.write(str(wbpreset3) + ", Machine Type: " + wbpreset3.machine_type + ", Category: " + wbpreset3.category, ending='\n') + + #create X-large preset + wbpreset4 = WorkbenchPreset() + wbpreset4.name = "X-Large - 8x cores with 30720 Memory" + wbpreset4.machine_type = 'n1-standard-8' + wbpreset4.category = 'Recommended' + wbpreset4.save() + self.stdout.write(str(wbpreset4) + ", Machine Type: " + wbpreset4.machine_type + ", Category: " + wbpreset4.category, ending='\n') + + self.stdout.write("Completed populating Workbench PResets", ending='\n') diff --git a/frontend/website/ghpcfe/models.py b/frontend/website/ghpcfe/models.py new file mode 100644 index 0000000000..c9933ab59f --- /dev/null +++ b/frontend/website/ghpcfe/models.py @@ -0,0 +1,1060 @@ +# Copyright 2022 Google LLC +# +# 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. + +""" models.py """ + +import itertools +import json +from django.db import models +from django.contrib.auth.models import AbstractUser +from django.core.validators import MinValueValidator +from django.db.models.signals import post_save +from django.dispatch import receiver +from django.conf import settings +from django.core.validators import RegexValidator +from rest_framework.authtoken.models import Token +from allauth.socialaccount.models import SocialAccount + +CLOUD_RESOURCE_MGMT_STATUS = ( + ('i', 'Imported'), # Use an existing resource created outside this system + ('nm', 'New'), # Just defined, managed + ('cm', 'Creating'), # In the process of creating, managed + ('m', 'Managed/Running'), # Created, operational, managed + ('dm', 'Destroying'), # In the process of deleting, managed + ('xm', 'Destroyed'), # Deleted, managed +) + +# Create your models here. + +class Role(models.Model): + """ Model representing different user roles """ + CLUSTERADMIN = 1 + NORMALUSER = 2 + VIEWER = 3 + ROLE_CHOICES = ( + (CLUSTERADMIN, 'cluster administrator'), + (NORMALUSER, 'normal user'), + (VIEWER, 'viewer'), + ) + id = models.PositiveSmallIntegerField( + choices = ROLE_CHOICES, + primary_key = True, + ) + + def __str__(self): + return self.get_id_display() + + +class User(AbstractUser): + """ A custom User model extending the base Django one """ + + roles = models.ManyToManyField(Role) + ssh_key = models.TextField( + max_length = 3072, + help_text = 'If required, provide your public key to SSH into the cluster head node', + blank = True, + null = True, + ) + # this field is set automatically from the post_save signal + unix_id = models.PositiveIntegerField( + validators = [MinValueValidator(1000)], + help_text = "Unix ID for the user on the clusters and fileystems", + blank = True, + null = True, + ) + + def get_avatar_url(self): + """ If using social login, return the Google profile picture if available """ + url = "/static/img/unknown_user.png" + # SocialAccount table has 'extra_data' field containing the URL to extract + if SocialAccount.objects.filter(user=self.id).exists(): + extra_data = SocialAccount.objects.get(user=self.id).extra_data + json_data = json.dumps(extra_data) + data = json.loads(json_data) + url = data["picture"] + return url + + def has_viewer_role(self): + if self.roles.filter(id=3).exists(): + return True + else: + return False + + def has_normaluser_role(self): + if self.roles.filter(id=2).exists(): + return True + else: + return False + + def has_admin_role(self): + if self.roles.filter(id=1).exists(): + return True + else: + return False + + +@receiver(post_save, sender=settings.AUTH_USER_MODEL) +def user_post_save(sender, instance=None, created=False, **kwargs): + """ Initialise certain information for new users """ + if created: + # generate API token + Token.objects.create(user=instance) + # assign a UNIX ID to this user + instance.unix_id = instance.id + 9999 + instance.save() + # by default set new user to 'ordinary user' + if instance.id > 1: + instance.roles.set([Role.NORMALUSER]) + + +class Credential(models.Model): + """ Model reprenseting a credential on a cloud platform """ + + name = models.CharField( + max_length = 30, + help_text = 'Enter a name for this credential, e.g. My GCP credential', + ) + owner = models.ForeignKey( + User, + help_text = 'Who owns this credential?', + on_delete = models.RESTRICT, + ) + detail = models.TextField( + max_length = 4000, + help_text = 'Obtain the credential detail and copy/paste it into this text field.', + ) + + def __str__(self): + return self.name + + +class MachineType(models.Model): + """ Model representing a virtual machine family on a cloud platform """ + + name = models.CharField( + max_length = 30, + help_text = 'Enter a valid machine type', + unique=True, + ) + cpu_arch = models.CharField( + max_length = 16, + help_text = 'Processor architecture' + ) + + def __str__(self): + return self.name + + +class InstanceType(models.Model): + """ Model represent individual instance types/sizes """ + name = models.CharField( + max_length=30, + help_text = 'Instance Type/Size Name', + unique=True + ) + family = models.ForeignKey( + MachineType, + on_delete = models.RESTRICT, + ) + num_vCPU = models.PositiveIntegerField( + validators = [MinValueValidator(1)], + help_text = 'Number of vCPU for this size' + ) + + @property + def cpu_arch(self): + return self.family.cpu_arch + + def __str__(self): + return self.name + + +class CloudResource(models.Model): + """ The base class of all cloud resource """ + cloud_credential = models.ForeignKey( + Credential, + help_text = 'Choose the credential to use with this cloud resource', + on_delete = models.RESTRICT, + ) + cloud_id = models.CharField( + max_length = 4096, + help_text = 'Cloud Resource id (GCP name, etc...)', + blank = True, + null = True, + ) + cloud_state = models.CharField( + max_length = 2, + choices = CLOUD_RESOURCE_MGMT_STATUS, + default = 'nm', + help_text = "Current state of this cloud resource", + ) + cloud_region = models.CharField( + max_length = 30, + help_text = 'The region of this cloud resource', + ) + cloud_zone = models.CharField( + max_length = 30, + help_text = 'The zone of this cloud resource', + blank = True, + null = True, + ) + + @property + def project_id(self): + if self.cloud_credential: + credInfo = json.loads(self.cloud_credential.detail) + return credInfo.get("project_id", None) + return None + + @property + def is_managed(self): + return 'm' in self.cloud_state + + +class VirtualNetwork(CloudResource): + """ Model representing a virtual network (VPC) in the cloud """ + name = models.CharField( + max_length = 64, + help_text = 'Name for the virtual network', + ) + + def __str__(self): + return self.name + + def in_use(self): + for wb in Workbench.objects.all(): + if self == wb.subnet.vpc: + #print(vpc) + return True + + for cluster in Cluster.objects.all(): + if self == cluster.subnet.vpc: + return True + + for fs in Filesystem.objects.all(): + if self == fs.subnet.vpc:# + return True + + return False + + +class VirtualSubnet(CloudResource): + """ Model representing a subnet in the cloud """ + name = models.CharField( + max_length = 64, + help_text = 'Name for the virtual subnet', + ) + vpc = models.ForeignKey( + VirtualNetwork, + related_name = 'subnets', + help_text = 'The VPC to which this subnet belongs', + on_delete = models.CASCADE, + ) + cidr = models.CharField( + max_length=18, + help_text = 'CIDR for this subnet', + ) + + def __str__(self): + return f"{self.vpc.cloud_id} - {self.vpc.name} - {self.name}" + + +FILESYSTEM_TYPES = ( + (' ', "none"), + ('n', "nfs"), + ('l', "lustre"), + ('d', "daos"), + ('b', 'beegfs'), +) + +class FilesystemImpl(models.IntegerChoices): + BUILT_IN = 0, 'Cluster Built-in' + GCPFILESTORE = 1, 'GCP Filestore' + + +class Filesystem(CloudResource): + """ Model representing a file system in the cloud """ + name = models.CharField( + max_length = 40, + help_text = 'Enter a name for the file system', + ) + internal_name = models.CharField( + max_length = 40, + help_text = 'name generated by system (not to be set by user)', + blank = True, + null = True, + ) + subnet = models.ForeignKey( + VirtualSubnet, + related_name = 'filesystems', + help_text = 'Subnet within which the cluster resides', + on_delete = models.RESTRICT, + ) + impl_type = models.PositiveIntegerField( + choices = FilesystemImpl.choices, + blank = False, + ) + fstype = models.CharField( + max_length = 1, + choices = FILESYSTEM_TYPES, + help_text = 'Type of Filesystem (NFS, Lustre, etc)', + ) + + @property + def fstype_name(self): + return dict(FILESYSTEM_TYPES).get(self.fstype) + + hostname_or_ip = models.CharField( + max_length = 128, + help_text = "Hostname or IP address of Filesystem server", + null = True, + blank = True, + ) + + def __str__(self): + return self.name + + +class FilesystemExport(models.Model): + """ Model representing a file system export """ + # mount -t : /mnt + + filesystem = models.ForeignKey( + Filesystem, + related_name = 'exports', + on_delete = models.CASCADE + ) + @property + def fstype(self): + return self.filesystem.fstype + + @property + def fstype_name(self): + return self.filesystem.fstype_name + + @property + def server_name(self): + return self.filesystem.hostname_or_ip + + export_name = models.CharField( + max_length=256, + help_text = "An export from NFS, or name of FS for Lustre, etc.", + ) + + @property + def source_string(self): + if self.server_name: + return f"{self.server_name}:{self.export_name}" + else: + return f"{self.export_name}" + + def __str__(self): + return f"{self.export_name} on {self.filesystem}" + + +class MountPoint(models.Model): + """ Model representing a mount point """ + export = models.ForeignKey( + FilesystemExport, + related_name = '+', + on_delete = models.CASCADE, + ) + + cluster = models.ForeignKey( + "Cluster", + related_name = "mount_points", + on_delete = models.CASCADE, + ) + + @property + def fstype(self): + return self.export.fstype + + @property + def fstype_name(self): + return self.export.fstype_name + + @property + def mount_source(self): + return self.export.source_string + + mount_order = models.PositiveIntegerField( + help_text = 'Mounts are mounted in numerically increasing order', + default = 0, + ) + + mount_options = models.CharField( + max_length = 128, + help_text = "Mount options (passed to mount -o)", + blank = True, + ) + + mount_path = models.CharField( + max_length = 4096, + help_text = "Path on which to mount this filesystem", + ) + + def __str__(self): + return f"{self.mount_path} on {self.cluster}" + + +class Cluster(CloudResource): + """ Model representing a cluster """ + + name = models.CharField( + max_length = 40, + help_text = 'Enter a name for the cluster', + ) + owner = models.ForeignKey( + User, + related_name = 'owner', + help_text = 'Who owns this cluster?', + on_delete = models.RESTRICT, + ) + subnet = models.ForeignKey( + VirtualSubnet, + related_name = 'clusters', + help_text = 'Subnet within which the cluster resides', + on_delete = models.RESTRICT, + ) + authorised_users = models.ManyToManyField( + User, + related_name = 'authorised_users', + help_text = 'Select other users authorised to use this cluster', + ) + CLUSTER_STATUS = ( + ('n', 'Cluster is being newly configured by user'), + ('c', 'Cluster is being created'), + ('i', 'Cluster is being initialised'), + ('r', 'Cluster is ready for jobs'), + ('s', 'Cluster is stopped (can be restarted)'), + ('t', 'Cluster is terminating'), + ('e', 'Cluster deployment has failed'), + ('d', 'Cluster has been deleted'), + ) + status = models.CharField( + max_length = 1, + choices = CLUSTER_STATUS, + default = 'n', + help_text = 'Status of this cluster', + ) + spackdir = models.CharField( + max_length = 4096, + verbose_name = "Spack directory", + default = "/opt/cluster/spack", + help_text = 'Specify where Spack install applications on the cluster', + ) + shared_fs = models.ForeignKey( + Filesystem, + on_delete = models.RESTRICT, + related_name = '+', + ) + spack_install = models.ForeignKey( + 'ApplicationInstallationLocation', + on_delete = models.SET_NULL, + related_name = 'clusters_using', + null = True, + blank = True, + ) + controller_node = models.OneToOneField( + 'ComputeInstance', + on_delete = models.SET_NULL, + null = True, + blank = True, + ) + num_login_nodes = models.PositiveIntegerField( + validators = [MinValueValidator(0)], + help_text = 'The number of login nodes to create', + default = 1, + ) + def get_access_key(self): + return Token.objects.get(user=self.owner) + + def __str__(self): + """String for representing the Model object.""" + return f"Cluster '{self.name}'" + + +class ComputeInstance(CloudResource): + cluster_login = models.ForeignKey( + Cluster, + related_name = "login_nodes", + unique = False, + null = True, + blank = True, + on_delete = models.CASCADE, + ) + internal_ip = models.GenericIPAddressField( + protocol = 'IPv4', + blank = True, + null = True, + ) + public_ip = models.GenericIPAddressField( + protocol = 'IPv4', + blank = True, + null = True, + ) + instance_type = models.ForeignKey( + InstanceType, + related_name = '+', + # Probably shouldn't ever be not set, but we don't *require* it for anything yet. + on_delete = models.SET_NULL, + null = True, + blank = True, + ) + service_account = models.EmailField( + max_length = 512, + null = True, + blank = True, + default = "", + ) + + +class ClusterPartition(models.Model): +# TODO - SlurmGCP allows subnet & zone specification on Partition + name = models.CharField( + max_length = 80, + help_text = 'Partition name' + ) + cluster = models.ForeignKey( + Cluster, + related_name = "partitions", + on_delete = models.CASCADE, + ) + machine_type = models.ForeignKey( + InstanceType, + related_name = '+', + on_delete = models.RESTRICT, + ) + image = models.CharField( + max_length = 4096, + help_text = 'OS Image path', + blank = True, + ) + max_node_count = models.PositiveIntegerField( + validators = [MinValueValidator(1)], + help_text = 'The maximum number of nodes in the partition', + default = 2, + ) + enable_placement = models.BooleanField( + default = True, + help_text = 'Enable Placement Groups (currently only valid for C2 and C2D instances)' + ) + enable_hyperthreads = models.BooleanField( + default = False, + help_text = 'Enable Hyprethreads (SMT)' + ) + enable_node_reuse = models.BooleanField( + default = True, + help_text = 'Enable nodes to be re-used for multiple jobs. (Disabled when Placement Groups are used.)' + ) + + @property + def vCPU_per_node(self): + return machine_type.num_vCPU // (1 if self.enable_hyperthreads else 2) + + + def __str__(self): + return self.name + + + + +class ApplicationInstallationLocation(models.Model): + fs_export = models.ForeignKey( + FilesystemExport, + on_delete = models.CASCADE, + help_text = 'Filestore on which the application resides' + ) + path = models.CharField( + max_length = 2048, + help_text = 'Directory in the filestore where application resides' + ) + @property + def filesystem(self): + return self.fs_export.filesystem + + +class Application(models.Model): + """ Model representing a particular binary installation of an application. """ + + name = models.CharField( + max_length = 30, + help_text = 'Enter an application name', + ) + description = models.TextField( + max_length = 4000, + help_text = '(Optional) description of this application', + blank = True, + null = True, + ) + version = models.CharField( + max_length = 30, + help_text = '(Optional) which version of this application', + blank = True, + null = True, + ) + # We store both the cluster and the installation location + # This allows us to track which cluster was used to perform the installation + cluster = models.ForeignKey( + Cluster, + help_text = 'Which cluster was used to install the application', + on_delete = models.CASCADE, + ) + install_loc = models.ForeignKey( + ApplicationInstallationLocation, + help_text = 'Location of the application installation', + on_delete = models.CASCADE, + ) + install_partition = models.ForeignKey( + ClusterPartition, + help_text = 'Cluster partition on which the installation job will be run', + on_delete = models.RESTRICT, + blank = True, + null = True, + ) + spack_name = models.CharField( + max_length = 30, + help_text = 'Name of the application in Spack', + blank = True, + null = True, + ) + spack_spec = models.CharField( + max_length = 200, + help_text = 'Spack spec that refers to this particular build configuration', + blank = True, + null = True, + ) + spack_hash = models.CharField( + max_length=32, + help_text = 'Hash of the Spack installation of the application package', + blank = True, + null = True, + ) + installed_architecture = models.CharField( + max_length = 128, + help_text = 'CPU architecture of installed package', + blank = True, + null = True, + ) + load_command = models.CharField( + max_length = 200, + help_text = \ + "Commands to load the application package, e.g. 'spack load xxx' or 'module load yyy'", + blank = True, + null = True, + ) + compiler = models.CharField( + max_length = 40, + help_text = "Which compiler was used to build this application", + blank = True, + null = True, + ) + mpi = models.CharField( + max_length = 40, + help_text = "Which MPI library was this application built against", + blank = True, + null = True, + ) + APPLICATION_INSTALLATION_STATUS = ( + ('n', 'Application is being newly configured'), + ('p', 'Application installation is being prepared'), + ('q', 'Application installation is in job queue'), + ('i', 'Application is being installed'), + ('r', 'Application successfully installed and ready to run'), + ('e', 'Application installation completed in error'), + ('x', 'Hosting cluster has been destroyed'), + ) + status = models.CharField( + max_length = 1, + choices = APPLICATION_INSTALLATION_STATUS, + default = 'n', + help_text = 'Status of this application installation', + ) + + def __str__(self): + """String for representing the Model object.""" + return f'{self.name} - {self.get_status_display()}' + + +class Benchmark(models.Model): + """ Model representing a benchmark """ + + name = models.CharField( + max_length = 30, + help_text = 'Enter a name of this benchmark', + ) + description = models.TextField( + max_length = 4000, + help_text = 'Enter a description of this benchmark', + ) + + def __str__(self): + """String for representing the Benchmark object.""" + return self.name + + +class Job(models.Model): + """ Model representing a single run of an application """ + + application = models.ForeignKey( + Application, + help_text = 'Which application installation to use?', + on_delete = models.RESTRICT, + ) + cluster = models.ForeignKey( + Cluster, + help_text = 'Which cluster was used for this job', + on_delete = models.SET_NULL, + null = True, + ) + name = models.CharField( + max_length = 40, + help_text = 'Enter a job name', + ) + date_time_submission = models.DateTimeField( + blank = True, + null = True, + auto_now_add=True, + ) + user = models.ForeignKey( + User, + help_text = 'Who owns this job?', + on_delete = models.CASCADE, + ) + partition = models.ForeignKey( + ClusterPartition, + help_text = 'Cluster partition on which the job will be run', + on_delete = models.CASCADE, + ) + number_of_nodes = models.PositiveIntegerField( + validators = [MinValueValidator(1)], + help_text = 'The number of nodes to use', + ) + ranks_per_node = models.PositiveIntegerField( + validators = [MinValueValidator(1)], + help_text = 'The number of MPI ranks per node', + ) + threads_per_rank = models.PositiveIntegerField( + validators = [MinValueValidator(1)], + default = 1, + help_text = 'The number of threads per MPI rank (for hybrid jobs)', + ) + wall_clock_time_limit = models.PositiveIntegerField( + validators = [MinValueValidator(0)], + default = 0, + help_text = 'The wall clock time limit of this job (in minutes)', + blank = True, + null = True, + ) + run_script = models.CharField( + max_length = 8192, + help_text= \ + 'The URL to the job script (a shell script or a tarball containing run.sh). Or the raw script', + ) + # adpated from Django's URL validation regex + import re + ul = '\u00a1-\uffff' + hostname_re = r'[a-z' + ul + r'0-9](?:[a-z' + ul + r'0-9-]{0,61}[a-z' + ul + r'0-9])?' + domain_re = r'(?:\.(?!-)[a-z' + ul + r'0-9-]{1,63}(? .ui-controlgroup-item { + float: left; + margin-left: 0; + margin-right: 0; +} +.ui-controlgroup > .ui-controlgroup-item:focus, +.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus { + z-index: 9999; +} +.ui-controlgroup-vertical > .ui-controlgroup-item { + display: block; + float: none; + width: 100%; + margin-top: 0; + margin-bottom: 0; + text-align: left; +} +.ui-controlgroup-vertical .ui-controlgroup-item { + box-sizing: border-box; +} +.ui-controlgroup .ui-controlgroup-label { + padding: .4em 1em; +} +.ui-controlgroup .ui-controlgroup-label span { + font-size: 80%; +} +.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item { + border-left: none; +} +.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item { + border-top: none; +} +.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content { + border-right: none; +} +.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content { + border-bottom: none; +} + +/* Spinner specific style fixes */ +.ui-controlgroup-vertical .ui-spinner-input { + + /* Support: IE8 only, Android < 4.4 only */ + width: 75%; + width: calc( 100% - 2.4em ); +} +.ui-controlgroup-vertical .ui-spinner .ui-spinner-up { + border-top-style: solid; +} + +.ui-checkboxradio-label .ui-icon-background { + box-shadow: inset 1px 1px 1px #ccc; + border-radius: .12em; + border: none; +} +.ui-checkboxradio-radio-label .ui-icon-background { + width: 16px; + height: 16px; + border-radius: 1em; + overflow: visible; + border: none; +} +.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon, +.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon { + background-image: none; + width: 8px; + height: 8px; + border-width: 4px; + border-style: solid; +} +.ui-checkboxradio-disabled { + pointer-events: none; +} +.ui-datepicker { + width: 17em; + padding: .2em .2em 0; + display: none; +} +.ui-datepicker .ui-datepicker-header { + position: relative; + padding: .2em 0; +} +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-next { + position: absolute; + top: 2px; + width: 1.8em; + height: 1.8em; +} +.ui-datepicker .ui-datepicker-prev-hover, +.ui-datepicker .ui-datepicker-next-hover { + top: 1px; +} +.ui-datepicker .ui-datepicker-prev { + left: 2px; +} +.ui-datepicker .ui-datepicker-next { + right: 2px; +} +.ui-datepicker .ui-datepicker-prev-hover { + left: 1px; +} +.ui-datepicker .ui-datepicker-next-hover { + right: 1px; +} +.ui-datepicker .ui-datepicker-prev span, +.ui-datepicker .ui-datepicker-next span { + display: block; + position: absolute; + left: 50%; + margin-left: -8px; + top: 50%; + margin-top: -8px; +} +.ui-datepicker .ui-datepicker-title { + margin: 0 2.3em; + line-height: 1.8em; + text-align: center; +} +.ui-datepicker .ui-datepicker-title select { + font-size: 1em; + margin: 1px 0; +} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { + width: 45%; +} +.ui-datepicker table { + width: 100%; + font-size: .9em; + border-collapse: collapse; + margin: 0 0 .4em; +} +.ui-datepicker th { + padding: .7em .3em; + text-align: center; + font-weight: bold; + border: 0; +} +.ui-datepicker td { + border: 0; + padding: 1px; +} +.ui-datepicker td span, +.ui-datepicker td a { + display: block; + padding: .2em; + text-align: right; + text-decoration: none; +} +.ui-datepicker .ui-datepicker-buttonpane { + background-image: none; + margin: .7em 0 0 0; + padding: 0 .2em; + border-left: 0; + border-right: 0; + border-bottom: 0; +} +.ui-datepicker .ui-datepicker-buttonpane button { + float: right; + margin: .5em .2em .4em; + cursor: pointer; + padding: .2em .6em .3em .6em; + width: auto; + overflow: visible; +} +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { + float: left; +} + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { + width: auto; +} +.ui-datepicker-multi .ui-datepicker-group { + float: left; +} +.ui-datepicker-multi .ui-datepicker-group table { + width: 95%; + margin: 0 auto .4em; +} +.ui-datepicker-multi-2 .ui-datepicker-group { + width: 50%; +} +.ui-datepicker-multi-3 .ui-datepicker-group { + width: 33.3%; +} +.ui-datepicker-multi-4 .ui-datepicker-group { + width: 25%; +} +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { + border-left-width: 0; +} +.ui-datepicker-multi .ui-datepicker-buttonpane { + clear: left; +} +.ui-datepicker-row-break { + clear: both; + width: 100%; + font-size: 0; +} + +/* RTL support */ +.ui-datepicker-rtl { + direction: rtl; +} +.ui-datepicker-rtl .ui-datepicker-prev { + right: 2px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next { + left: 2px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-prev:hover { + right: 1px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next:hover { + left: 1px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane { + clear: right; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button { + float: left; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, +.ui-datepicker-rtl .ui-datepicker-group { + float: right; +} +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { + border-right-width: 0; + border-left-width: 1px; +} + +/* Icons */ +.ui-datepicker .ui-icon { + display: block; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; + left: .5em; + top: .3em; +} +.ui-dialog { + position: absolute; + top: 0; + left: 0; + padding: .2em; + outline: 0; +} +.ui-dialog .ui-dialog-titlebar { + padding: .4em 1em; + position: relative; +} +.ui-dialog .ui-dialog-title { + float: left; + margin: .1em 0; + white-space: nowrap; + width: 90%; + overflow: hidden; + text-overflow: ellipsis; +} +.ui-dialog .ui-dialog-titlebar-close { + position: absolute; + right: .3em; + top: 50%; + width: 20px; + margin: -10px 0 0 0; + padding: 1px; + height: 20px; +} +.ui-dialog .ui-dialog-content { + position: relative; + border: 0; + padding: .5em 1em; + background: none; + overflow: auto; +} +.ui-dialog .ui-dialog-buttonpane { + text-align: left; + border-width: 1px 0 0 0; + background-image: none; + margin-top: .5em; + padding: .3em 1em .5em .4em; +} +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { + float: right; +} +.ui-dialog .ui-dialog-buttonpane button { + margin: .5em .4em .5em 0; + cursor: pointer; +} +.ui-dialog .ui-resizable-n { + height: 2px; + top: 0; +} +.ui-dialog .ui-resizable-e { + width: 2px; + right: 0; +} +.ui-dialog .ui-resizable-s { + height: 2px; + bottom: 0; +} +.ui-dialog .ui-resizable-w { + width: 2px; + left: 0; +} +.ui-dialog .ui-resizable-se, +.ui-dialog .ui-resizable-sw, +.ui-dialog .ui-resizable-ne, +.ui-dialog .ui-resizable-nw { + width: 7px; + height: 7px; +} +.ui-dialog .ui-resizable-se { + right: 0; + bottom: 0; +} +.ui-dialog .ui-resizable-sw { + left: 0; + bottom: 0; +} +.ui-dialog .ui-resizable-ne { + right: 0; + top: 0; +} +.ui-dialog .ui-resizable-nw { + left: 0; + top: 0; +} +.ui-draggable .ui-dialog-titlebar { + cursor: move; +} +.ui-draggable-handle { + -ms-touch-action: none; + touch-action: none; +} +.ui-resizable { + position: relative; +} +.ui-resizable-handle { + position: absolute; + font-size: 0.1px; + display: block; + -ms-touch-action: none; + touch-action: none; +} +.ui-resizable-disabled .ui-resizable-handle, +.ui-resizable-autohide .ui-resizable-handle { + display: none; +} +.ui-resizable-n { + cursor: n-resize; + height: 7px; + width: 100%; + top: -5px; + left: 0; +} +.ui-resizable-s { + cursor: s-resize; + height: 7px; + width: 100%; + bottom: -5px; + left: 0; +} +.ui-resizable-e { + cursor: e-resize; + width: 7px; + right: -5px; + top: 0; + height: 100%; +} +.ui-resizable-w { + cursor: w-resize; + width: 7px; + left: -5px; + top: 0; + height: 100%; +} +.ui-resizable-se { + cursor: se-resize; + width: 12px; + height: 12px; + right: 1px; + bottom: 1px; +} +.ui-resizable-sw { + cursor: sw-resize; + width: 9px; + height: 9px; + left: -5px; + bottom: -5px; +} +.ui-resizable-nw { + cursor: nw-resize; + width: 9px; + height: 9px; + left: -5px; + top: -5px; +} +.ui-resizable-ne { + cursor: ne-resize; + width: 9px; + height: 9px; + right: -5px; + top: -5px; +} +.ui-progressbar { + height: 2em; + text-align: left; + overflow: hidden; +} +.ui-progressbar .ui-progressbar-value { + margin: -1px; + height: 100%; +} +.ui-progressbar .ui-progressbar-overlay { + background: url("data:image/gif;base64,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"); + height: 100%; + filter: alpha(opacity=25); /* support: IE8 */ + opacity: 0.25; +} +.ui-progressbar-indeterminate .ui-progressbar-value { + background-image: none; +} +.ui-selectable { + -ms-touch-action: none; + touch-action: none; +} +.ui-selectable-helper { + position: absolute; + z-index: 100; + border: 1px dotted black; +} +.ui-selectmenu-menu { + padding: 0; + margin: 0; + position: absolute; + top: 0; + left: 0; + display: none; +} +.ui-selectmenu-menu .ui-menu { + overflow: auto; + overflow-x: hidden; + padding-bottom: 1px; +} +.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup { + font-size: 1em; + font-weight: bold; + line-height: 1.5; + padding: 2px 0.4em; + margin: 0.5em 0 0 0; + height: auto; + border: 0; +} +.ui-selectmenu-open { + display: block; +} +.ui-selectmenu-text { + display: block; + margin-right: 20px; + overflow: hidden; + text-overflow: ellipsis; +} +.ui-selectmenu-button.ui-button { + text-align: left; + white-space: nowrap; + width: 14em; +} +.ui-selectmenu-icon.ui-icon { + float: right; + margin-top: 0; +} +.ui-slider { + position: relative; + text-align: left; +} +.ui-slider .ui-slider-handle { + position: absolute; + z-index: 2; + width: 1.2em; + height: 1.2em; + cursor: default; + -ms-touch-action: none; + touch-action: none; +} +.ui-slider .ui-slider-range { + position: absolute; + z-index: 1; + font-size: .7em; + display: block; + border: 0; + background-position: 0 0; +} + +/* support: IE8 - See #6727 */ +.ui-slider.ui-state-disabled .ui-slider-handle, +.ui-slider.ui-state-disabled .ui-slider-range { + filter: inherit; +} + +.ui-slider-horizontal { + height: .8em; +} +.ui-slider-horizontal .ui-slider-handle { + top: -.3em; + margin-left: -.6em; +} +.ui-slider-horizontal .ui-slider-range { + top: 0; + height: 100%; +} +.ui-slider-horizontal .ui-slider-range-min { + left: 0; +} +.ui-slider-horizontal .ui-slider-range-max { + right: 0; +} + +.ui-slider-vertical { + width: .8em; + height: 100px; +} +.ui-slider-vertical .ui-slider-handle { + left: -.3em; + margin-left: 0; + margin-bottom: -.6em; +} +.ui-slider-vertical .ui-slider-range { + left: 0; + width: 100%; +} +.ui-slider-vertical .ui-slider-range-min { + bottom: 0; +} +.ui-slider-vertical .ui-slider-range-max { + top: 0; +} +.ui-sortable-handle { + -ms-touch-action: none; + touch-action: none; +} +.ui-spinner { + position: relative; + display: inline-block; + overflow: hidden; + padding: 0; + vertical-align: middle; +} +.ui-spinner-input { + border: none; + background: none; + color: inherit; + padding: .222em 0; + margin: .2em 0; + vertical-align: middle; + margin-left: .4em; + margin-right: 2em; +} +.ui-spinner-button { + width: 1.6em; + height: 50%; + font-size: .5em; + padding: 0; + margin: 0; + text-align: center; + position: absolute; + cursor: default; + display: block; + overflow: hidden; + right: 0; +} +/* more specificity required here to override default borders */ +.ui-spinner a.ui-spinner-button { + border-top-style: none; + border-bottom-style: none; + border-right-style: none; +} +.ui-spinner-up { + top: 0; +} +.ui-spinner-down { + bottom: 0; +} +.ui-tabs { + position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ + padding: .2em; +} +.ui-tabs .ui-tabs-nav { + margin: 0; + padding: .2em .2em 0; +} +.ui-tabs .ui-tabs-nav li { + list-style: none; + float: left; + position: relative; + top: 0; + margin: 1px .2em 0 0; + border-bottom-width: 0; + padding: 0; + white-space: nowrap; +} +.ui-tabs .ui-tabs-nav .ui-tabs-anchor { + float: left; + padding: .5em 1em; + text-decoration: none; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active { + margin-bottom: -1px; + padding-bottom: 1px; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor, +.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor, +.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor { + cursor: text; +} +.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor { + cursor: pointer; +} +.ui-tabs .ui-tabs-panel { + display: block; + border-width: 0; + padding: 1em 1.4em; + background: none; +} +.ui-tooltip { + padding: 8px; + position: absolute; + z-index: 9999; + max-width: 300px; +} +body .ui-tooltip { + border-width: 2px; +} +/* Component containers +----------------------------------*/ +.ui-widget { + font-family: Arial,Helvetica,sans-serif; + font-size: 1em; +} +.ui-widget .ui-widget { + font-size: 1em; +} +.ui-widget input, +.ui-widget select, +.ui-widget textarea, +.ui-widget button { + font-family: Arial,Helvetica,sans-serif; + font-size: 1em; +} +.ui-widget.ui-widget-content { + border: 1px solid #c5c5c5; +} +.ui-widget-content { + border: 1px solid #dddddd; + background: #ffffff; + color: #333333; +} +.ui-widget-content a { + color: #333333; +} +.ui-widget-header { + border: 1px solid #dddddd; + background: #e9e9e9; + color: #333333; + font-weight: bold; +} +.ui-widget-header a { + color: #333333; +} + +/* Interaction states +----------------------------------*/ +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default, +.ui-button, + +/* We use html here because we need a greater specificity to make sure disabled +works properly when clicked or hovered */ +html .ui-button.ui-state-disabled:hover, +html .ui-button.ui-state-disabled:active { + border: 1px solid #c5c5c5; + background: #f6f6f6; + font-weight: normal; + color: #454545; +} +.ui-state-default a, +.ui-state-default a:link, +.ui-state-default a:visited, +a.ui-button, +a:link.ui-button, +a:visited.ui-button, +.ui-button { + color: #454545; + text-decoration: none; +} +.ui-state-hover, +.ui-widget-content .ui-state-hover, +.ui-widget-header .ui-state-hover, +.ui-state-focus, +.ui-widget-content .ui-state-focus, +.ui-widget-header .ui-state-focus, +.ui-button:hover, +.ui-button:focus { + border: 1px solid #cccccc; + background: #ededed; + font-weight: normal; + color: #2b2b2b; +} +.ui-state-hover a, +.ui-state-hover a:hover, +.ui-state-hover a:link, +.ui-state-hover a:visited, +.ui-state-focus a, +.ui-state-focus a:hover, +.ui-state-focus a:link, +.ui-state-focus a:visited, +a.ui-button:hover, +a.ui-button:focus { + color: #2b2b2b; + text-decoration: none; +} + +.ui-visual-focus { + box-shadow: 0 0 3px 1px rgb(94, 158, 214); +} +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active, +a.ui-button:active, +.ui-button:active, +.ui-button.ui-state-active:hover { + border: 1px solid #003eff; + background: #007fff; + font-weight: normal; + color: #ffffff; +} +.ui-icon-background, +.ui-state-active .ui-icon-background { + border: #003eff; + background-color: #ffffff; +} +.ui-state-active a, +.ui-state-active a:link, +.ui-state-active a:visited { + color: #ffffff; + text-decoration: none; +} + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, +.ui-widget-content .ui-state-highlight, +.ui-widget-header .ui-state-highlight { + border: 1px solid #dad55e; + background: #fffa90; + color: #777620; +} +.ui-state-checked { + border: 1px solid #dad55e; + background: #fffa90; +} +.ui-state-highlight a, +.ui-widget-content .ui-state-highlight a, +.ui-widget-header .ui-state-highlight a { + color: #777620; +} +.ui-state-error, +.ui-widget-content .ui-state-error, +.ui-widget-header .ui-state-error { + border: 1px solid #f1a899; + background: #fddfdf; + color: #5f3f3f; +} +.ui-state-error a, +.ui-widget-content .ui-state-error a, +.ui-widget-header .ui-state-error a { + color: #5f3f3f; +} +.ui-state-error-text, +.ui-widget-content .ui-state-error-text, +.ui-widget-header .ui-state-error-text { + color: #5f3f3f; +} +.ui-priority-primary, +.ui-widget-content .ui-priority-primary, +.ui-widget-header .ui-priority-primary { + font-weight: bold; +} +.ui-priority-secondary, +.ui-widget-content .ui-priority-secondary, +.ui-widget-header .ui-priority-secondary { + opacity: .7; + filter:Alpha(Opacity=70); /* support: IE8 */ + font-weight: normal; +} +.ui-state-disabled, +.ui-widget-content .ui-state-disabled, +.ui-widget-header .ui-state-disabled { + opacity: .35; + filter:Alpha(Opacity=35); /* support: IE8 */ + background-image: none; +} +.ui-state-disabled .ui-icon { + filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */ +} + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { + width: 16px; + height: 16px; +} +.ui-icon, +.ui-widget-content .ui-icon { + background-image: url("images/ui-icons_444444_256x240.png"); +} +.ui-widget-header .ui-icon { + background-image: url("images/ui-icons_444444_256x240.png"); +} +.ui-state-hover .ui-icon, +.ui-state-focus .ui-icon, +.ui-button:hover .ui-icon, +.ui-button:focus .ui-icon { + background-image: url("images/ui-icons_555555_256x240.png"); +} +.ui-state-active .ui-icon, +.ui-button:active .ui-icon { + background-image: url("images/ui-icons_ffffff_256x240.png"); +} +.ui-state-highlight .ui-icon, +.ui-button .ui-state-highlight.ui-icon { + background-image: url("images/ui-icons_777620_256x240.png"); +} +.ui-state-error .ui-icon, +.ui-state-error-text .ui-icon { + background-image: url("images/ui-icons_cc0000_256x240.png"); +} +.ui-button .ui-icon { + background-image: url("images/ui-icons_777777_256x240.png"); +} + +/* positioning */ +.ui-icon-blank { background-position: 16px 16px; } +.ui-icon-caret-1-n { background-position: 0 0; } +.ui-icon-caret-1-ne { background-position: -16px 0; } +.ui-icon-caret-1-e { background-position: -32px 0; } +.ui-icon-caret-1-se { background-position: -48px 0; } +.ui-icon-caret-1-s { background-position: -65px 0; } +.ui-icon-caret-1-sw { background-position: -80px 0; } +.ui-icon-caret-1-w { background-position: -96px 0; } +.ui-icon-caret-1-nw { background-position: -112px 0; } +.ui-icon-caret-2-n-s { background-position: -128px 0; } +.ui-icon-caret-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -65px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -65px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 1px -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-on { background-position: -96px -144px; } +.ui-icon-radio-off { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, +.ui-corner-top, +.ui-corner-left, +.ui-corner-tl { + border-top-left-radius: 3px; +} +.ui-corner-all, +.ui-corner-top, +.ui-corner-right, +.ui-corner-tr { + border-top-right-radius: 3px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-left, +.ui-corner-bl { + border-bottom-left-radius: 3px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-right, +.ui-corner-br { + border-bottom-right-radius: 3px; +} + +/* Overlays */ +.ui-widget-overlay { + background: #aaaaaa; + opacity: .3; + filter: Alpha(Opacity=30); /* support: IE8 */ +} +.ui-widget-shadow { + -webkit-box-shadow: 0px 0px 5px #666666; + box-shadow: 0px 0px 5px #666666; +} diff --git a/frontend/website/ghpcfe/static/css/styles.css b/frontend/website/ghpcfe/static/css/styles.css new file mode 100644 index 0000000000..de76a0fec0 --- /dev/null +++ b/frontend/website/ghpcfe/static/css/styles.css @@ -0,0 +1,29 @@ +.sidebar-nav { + margin-top: 20px; + padding: 0; + list-style: none; +} + +.navbar-nav > .active > a { + border-bottom: 2px solid white +} + +#pageloader +{ + background: rgba( 255, 255, 255, 0.8 ); + display: none; + height: 100%; + position: fixed; + width: 100%; + z-index: 9999; +} + +#pageloader img +{ + left: 50%; + margin-left: -32px; + margin-top: -32px; + position: absolute; + top: 50%; +} + diff --git a/frontend/website/ghpcfe/static/examples/namd_apoa1.sh b/frontend/website/ghpcfe/static/examples/namd_apoa1.sh new file mode 100644 index 0000000000..048099f44b --- /dev/null +++ b/frontend/website/ghpcfe/static/examples/namd_apoa1.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# CHANGES REQUIRED TO SPACK PACKAGE FOR CHARMPP +# https://github.com/spack/spack/issues/18535 +# then... +# spack install namd @2.15a1 fftw=mkl ^charmpp backend=mpi arch=cascadelake +# +# ALSO, the NAMD package assumes that 'intel-mkl' sets up include directories like Spack expects +# It does not. +# Just yum install fftw-devel so that it can find an fftw3.h header... + +# Reference: https://software.intel.com/content/www/us/en/develop/articles/recipe-build-and-run-namd-on-intel-xeon-processors-on-single-node.html + +curl -O http://www.ks.uiuc.edu/Research/namd/utilities/apoa1.tar.gz +tar xfz apoa1.tar.gz +sed -i -e '/numsteps/s/500/1000/' apoa1/apoa1.namd +sed -i -e "/outputtiming/a\\outputenergies 600" apoa1/apoa1.namd + +GET_PERF="\$2==\"Benchmark\"{n++; s+=log(\$8); }END{print 1/exp(s/n)}" + +# Run 1 rank per host +mpirun -N 1 -np ${SLURM_JOB_NUM_NODES} namd2 +p ${SLURM_CPUS_ON_NODE} +ppn ${SLURM_CPUS_ON_NODE} +setcpuaffinity ./apoa1/apoa1.namd > namd-apoa1.log 2>&1 +res=$? + +if [[ "$res" == 0 ]]; then + kpi=$(awk "${GET_PERF}" < namd-apoa1.log) + echo "{\"result_unit\": \"ns/day\", \"result_value\": $kpi}" > kpi.json +fi diff --git a/frontend/website/ghpcfe/static/examples/namd_stmv.sh b/frontend/website/ghpcfe/static/examples/namd_stmv.sh new file mode 100644 index 0000000000..f913f140ee --- /dev/null +++ b/frontend/website/ghpcfe/static/examples/namd_stmv.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# CHANGES REQUIRED TO SPACK PACKAGE FOR CHARMPP +# https://github.com/spack/spack/issues/18535 +# then... +# spack install namd @2.15a1 fftw=mkl ^charmpp backend=mpi arch=cascadelake +# +# ALSO, the NAMD package assumes that 'intel-mkl' sets up include directories like Spack expects +# It does not. +# Just yum install fftw-devel so that it can find an fftw3.h header... + +# Reference: https://software.intel.com/content/www/us/en/develop/articles/recipe-build-and-run-namd-on-intel-xeon-processors-on-single-node.html + +curl -O http://www.ks.uiuc.edu/Research/namd/utilities/stmv.tar.gz +tar xfz stmv.tar.gz +sed -i -e '/numsteps/s/500/1000/' stmv/stmv.namd +sed -i -e '/outputEnergies/s/20/600/' stmv/stmv.namd +sed -i -e 's/;.*$//' stmv/stmv.namd + +GET_PERF="\$2==\"Benchmark\"{n++; s+=log(\$8); }END{print 1/exp(s/n)}" + +# Run 1 rank per host +mpirun -N 1 -np ${SLURM_JOB_NUM_NODES} namd2 +p ${SLURM_CPUS_ON_NODE} +ppn ${SLURM_CPUS_ON_NODE} +setcpuaffinity ./stmv/stmv.namd > namd-stmv.log 2>&1 +res=$? + +if [[ "$res" == 0 ]]; then + kpi=$(awk "${GET_PERF}" < namd-stmv.log) + echo "{\"result_unit\": \"ns/day\", \"result_value\": $kpi}" > kpi.json +fi diff --git a/frontend/website/ghpcfe/static/examples/openfoam_motorbike_meshing.sh b/frontend/website/ghpcfe/static/examples/openfoam_motorbike_meshing.sh new file mode 100644 index 0000000000..f3558dc53f --- /dev/null +++ b/frontend/website/ghpcfe/static/examples/openfoam_motorbike_meshing.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +BLOCKMESH_DIMENSIONS="100 40 40" # 22 million case +#BLOCKMESH_DIMENSIONS="130 52 52" # 42 million case +NTASKS=32 # number of processes for meshing +DECOMPOSE="8 2 2" # mesh decomposition + +# Copy case from OpenFOAM tutorial +cp -r $FOAM_TUTORIALS/incompressible/simpleFoam/motorBike . +cd motorBike + +# Customise settings +foamDictionary -entry castellatedMeshControls.maxGlobalCells -set 200000000 system/snappyHexMeshDict +foamDictionary -entry blocks -set "( hex ( 0 1 2 3 4 5 6 7 ) ( $BLOCKMESH_DIMENSIONS ) simpleGrading ( 1 1 1 ) )" system/blockMeshDict +foamDictionary -entry numberOfSubdomains -set $NTASKS system/decomposeParDict +foamDictionary -entry hierarchicalCoeffs.n -set "( $DECOMPOSE )" system/decomposeParDict + +# Copy and prepare geometry +cp $FOAM_TUTORIALS/resources/geometry/motorBike.obj.gz constant/triSurface/ +surfaceFeatures 2>&1 | tee log.surfaceFeatures + +# Generate and decompise base mesh +blockMesh 2>&1 | tee log.blockMesh +decomposePar -copyZero 2>&1 | tee log.decomposePar + +# Run mesh generation in parallel +mpirun snappyHexMesh -parallel -overwrite 2>&1 | tee log.snappyHexMesh + +# Reconstruct into a single mesh - it will be decomposed again when running solver +reconstructParMesh -constant 2>&1 | tee log.reconstructParMesh +rm -rf ./processor* +renumberMesh -constant -overwrite 2>&1 | tee log.renumberMesh + +# Clean up +rm -rf ./processor* +cd .. +tar cvf motorBike.tar motorBike +bzip2 motorBike.tar +rm -rf motorBike diff --git a/frontend/website/ghpcfe/static/examples/openfoam_motorbike_solving.sh b/frontend/website/ghpcfe/static/examples/openfoam_motorbike_solving.sh new file mode 100644 index 0000000000..c1c4a9f7c6 --- /dev/null +++ b/frontend/website/ghpcfe/static/examples/openfoam_motorbike_solving.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Mesh was previously generated and saved. Refer to the separate meshing script. +tar xvf motorBike.tar.bz2 +cd motorBike +NODES=${SLURM_JOB_NUM_NODES} +PPN=${SLURM_CPUS_ON_NODE} # or underpopulate if needed +NTASKS=$(($NODES*$PPN)) + +# Customise settings to decompose the mesh +foamDictionary -entry numberOfSubdomains -set $NTASKS system/decomposeParDict +foamDictionary -entry method -set multiLevel system/decomposeParDict +foamDictionary -entry multiLevelCoeffs -set "{}" system/decomposeParDict +foamDictionary -entry scotchCoeffs -set "{}" system/decomposeParDict +foamDictionary -entry multiLevelCoeffs.level0 -set "{}" system/decomposeParDict +foamDictionary -entry multiLevelCoeffs.level0.numberOfSubdomains -set $NODES system/decomposeParDict +foamDictionary -entry multiLevelCoeffs.level0.method -set scotch system/decomposeParDict +foamDictionary -entry multiLevelCoeffs.level1 -set "{}" system/decomposeParDict +foamDictionary -entry multiLevelCoeffs.level1.numberOfSubdomains -set $PPN system/decomposeParDict +foamDictionary -entry multiLevelCoeffs.level1.method -set scotch system/decomposeParDict + +# Customise solver algorithms +foamDictionary -entry solvers.p.nPreSweeps -set 0 system/fvSolution +foamDictionary -entry solvers.p.nPostSweeps -set 2 system/fvSolution +foamDictionary -entry solvers.p.cacheAgglomeration -set on system/fvSolution +foamDictionary -entry solvers.p.agglomerator -set faceAreaPair system/fvSolution +foamDictionary -entry solvers.p.nCellsInCoarsestLevel -set 10 system/fvSolution +foamDictionary -entry solvers.p.mergeLevels -set 1 system/fvSolution +foamDictionary -entry relaxationFactors.equations.U -set 0.7 system/fvSolution +foamDictionary -entry relaxationFactors.fields -add "{}" system/fvSolution +foamDictionary -entry relaxationFactors.fields.p -set 0.3 system/fvSolution + +# Decompose the mesh +decomposePar -copyZero 2>&1 | tee log.decomposeParMultiLevel + +# Run the solver +foamDictionary -entry writeInterval -set 1000 system/controlDict +foamDictionary -entry runTimeModifiable -set "false" system/controlDict +foamDictionary -entry functions -set "{}" system/controlDict +foamDictionary -entry endTime -set 250 system/controlDict +mpirun potentialFoam -parallel 2>&1 | tee log.potentialFoam +mpirun simpleFoam -parallel 2>&1 | tee log.simpleFoam + +# Extract the total execution time as KPI +cd - +echo '{"result_unit": "seconds", "result_value": '$(tail -n 5 motorBike/log.simpleFoam | head -n1 | awk '{print $3}')'}' > kpi.json diff --git a/frontend/website/ghpcfe/static/examples/run_hpcc.py b/frontend/website/ghpcfe/static/examples/run_hpcc.py new file mode 100755 index 0000000000..fbf5141bc1 --- /dev/null +++ b/frontend/website/ghpcfe/static/examples/run_hpcc.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python3 + +import sys +from functools import reduce +from math import sqrt +from argparse import ArgumentParser, ArgumentTypeError +from multiprocessing import cpu_count +from pathlib import Path + +def lcm(a, b): + # This doesn't work on python2... Should get updated at some point + from math import gcd + l = abs(a*b) // gcd(a, b) + return l + +def lcm_array(arr): + return reduce((lambda x,y: lcm(x, y)), arr) + + +def write_HPL_input(N, NB, PQ_Grids, outputfile='hpccinf.txt'): +# Problem sizes (Line 6) +# https://icl.utk.edu/hpl/faq/index.html#122 +# Memory per Rank... ~sqrt(MpR/8 *.75) 'div by 8 to get # doubles' +#N = [1000 10000 10000] + + +# Block sizes (Line 8) +# https://icl.utk.edu/hpl/faq/index.html#124 +#NB = [32 44 48 64 .. 256] + + +# Ps and Qs +# https://icl.utk.edu/hpl/faq/index.html#125 +# 1:k, with k in [1..3] range +# depends on # ranks... P*Q = #numRanks used +#PQ_Grids = [(2, 2), (P, Q)...] + + hpl_input = { + 'numN': len(N), + 'Ns': " ".join([str(n) for n in N]), + 'numNB': len(NB), + 'NBs': " ".join([str(nb) for nb in NB]), + 'numPQ': len(PQ_Grids), + 'Ps': " ".join([str(int(x[0])) for x in PQ_Grids]), + 'Qs': " ".join([str(int(x[1])) for x in PQ_Grids]) + } + + + hpl_template="""HPLinpack benchmark input file +Innovative Computing Laboratory, University of Tennessee +HPL.out output file name (if any) +8 device out (6=stdout,7=stderr,file) +{numN} # of problems sizes (N) +{Ns} Ns +{numNB} # of NBs +{NBs} NBs +0 PMAP process mapping (0=Row-,1=Column-major) +{numPQ} # of process grids (P x Q) +{Ps} Ps +{Qs} Qs +16.0 threshold +1 # of panel fact +2 PFACTs (0=left, 1=Crout, 2=Right) +1 # of recursive stopping criterium +4 NBMINs (>= 1) +1 # of panels in recursion +2 NDIVs +1 # of recursive panel fact. +1 RFACTs (0=left, 1=Crout, 2=Right) +1 # of broadcast +1 BCASTs (0=1rg,1=1rM,2=2rg,3=2rM,4=Lng,5=LnM) +1 # of lookahead depth +1 DEPTHs (>=0) +2 SWAP (0=bin-exch,1=long,2=mix) +64 swapping threshold +0 L1 in (0=transposed,1=no-transposed) form +0 U in (0=transposed,1=no-transposed) form +1 Equilibration (0=no,1=yes) +8 memory alignment in double (> 0) +### This line (no. 32) is ignored (it serves as a separator). ###### +0 Number of additional problem sizes for PTRANS +1200 10000 30000 values of N +0 number of additional blocking sizes for PTRANS +40 9 8 13 13 20 16 32 64 values of NB +""" + + with open(outputfile, 'w') as fp: + fp.write(hpl_template.format(**hpl_input)) + + +def mem_per_core(): + from multiprocessing import cpu_count + nCPU = cpu_count() + + MemTotal = None + with open("/proc/meminfo", 'r') as fp: + for line in fp: + info = line.split() + if 'MemTotal:' == info[0]: + MemTotal = int(info[1]) / 1024 + break + if not MemTotal: + raise Exception('Unable to determine system memory. Please specify --mem_per_rank') + + return int(MemTotal / nCPU) + + +def calculate_N(nRanks, MemPerRank, memWeight): + totalMemInBytes = MemPerRank * nRanks * (memWeight / 100.) * 1024*1024 + totalDoubles = totalMemInBytes / 8 + nSize = int(sqrt(totalDoubles)) + # TODO: Maybe round something "human" + return nSize + + +def parse_ratio(string): + try: + (p,q) = [int(x) for x in string.split(':')] + return [p, q] + except: + msg = "%r should be of format : (ie, '1:2')"%string + raise ArgumentTypeError(msg) + +def estimate_PQ(nRanks): + factors = [(x, int(nRanks/x)) for x in range(2, int(sqrt(nRanks))+1) if nRanks%x == 0] + if len(factors) == 0: + factors = [(1, nRanks)] + + return factors[-1] + + + +def create_input(ranks, mem_weight): + + N = calculate_N(ranks, mem_per_core(), mem_weight) + NB = [ 128, 160, 192, 256] # Some "reasonable" numbers + LCM = lcm_array(NB) + factor = int(N / LCM) + if factor%2: + factor -=1 + N = [int(LCM * factor)] + + PQ = [estimate_PQ(ranks)] + + write_HPL_input(N, NB, PQ) + + + +def parse_hpl_out(outFile): + with outFile.open('r') as fp: + for line in fp: + line = line.strip() + v = line.split('=') + if len(v) == 2: + if v[0] == 'HPL_Tflops': + return {'result_unit': 'Tflops', 'result_value': v[1]} + return None + + + +if __name__ == '__main__': + import os, subprocess, json + + nranks=int(os.environ.get("SLURM_NTASKS", 1)) + + create_input(nranks, mem_weight=25.0) + # Now, run HPL itself + subprocess.run(["mpirun", "hpcc"]) + + outFile = Path('./hpccoutf.txt') + if outFile.exists(): + # Create KPI.json + kpi = parse_hpl_out(outFile) + if kpi: + with open('kpi.json', 'w') as fp: + fp.write(json.dumps(kpi)) diff --git a/frontend/website/ghpcfe/static/examples/run_hpl.py b/frontend/website/ghpcfe/static/examples/run_hpl.py new file mode 100755 index 0000000000..eeabf2ac41 --- /dev/null +++ b/frontend/website/ghpcfe/static/examples/run_hpl.py @@ -0,0 +1,178 @@ +#!/usr/bin/env python3 + +import sys +from functools import reduce +from math import sqrt +from argparse import ArgumentParser, ArgumentTypeError +from multiprocessing import cpu_count +from pathlib import Path + +def lcm(a, b): + # This doesn't work on python2... Should get updated at some point + from math import gcd + l = abs(a*b) // gcd(a, b) + return l + +def lcm_array(arr): + return reduce((lambda x,y: lcm(x, y)), arr) + + +def write_HPL_input(N, NB, PQ_Grids, outputfile='HPL.dat'): +# Problem sizes (Line 6) +# https://icl.utk.edu/hpl/faq/index.html#122 +# Memory per Rank... ~sqrt(MpR/8 *.75) 'div by 8 to get # doubles' +#N = [1000 10000 10000] + + +# Block sizes (Line 8) +# https://icl.utk.edu/hpl/faq/index.html#124 +#NB = [32 44 48 64 .. 256] + + +# Ps and Qs +# https://icl.utk.edu/hpl/faq/index.html#125 +# 1:k, with k in [1..3] range +# depends on # ranks... P*Q = #numRanks used +#PQ_Grids = [(2, 2), (P, Q)...] + + hpl_input = { + 'numN': len(N), + 'Ns': " ".join([str(n) for n in N]), + 'numNB': len(NB), + 'NBs': " ".join([str(nb) for nb in NB]), + 'numPQ': len(PQ_Grids), + 'Ps': " ".join([str(int(x[0])) for x in PQ_Grids]), + 'Qs': " ".join([str(int(x[1])) for x in PQ_Grids]) + } + + + hpl_template="""HPLinpack benchmark input file +Innovative Computing Laboratory, University of Tennessee +HPL.out output file name (if any) +8 device out (6=stdout,7=stderr,file) +{numN} # of problems sizes (N) +{Ns} Ns +{numNB} # of NBs +{NBs} NBs +0 PMAP process mapping (0=Row-,1=Column-major) +{numPQ} # of process grids (P x Q) +{Ps} Ps +{Qs} Qs +16.0 threshold +1 # of panel fact +2 PFACTs (0=left, 1=Crout, 2=Right) +1 # of recursive stopping criterium +4 NBMINs (>= 1) +1 # of panels in recursion +2 NDIVs +1 # of recursive panel fact. +1 RFACTs (0=left, 1=Crout, 2=Right) +1 # of broadcast +1 BCASTs (0=1rg,1=1rM,2=2rg,3=2rM,4=Lng,5=LnM) +1 # of lookahead depth +1 DEPTHs (>=0) +2 SWAP (0=bin-exch,1=long,2=mix) +64 swapping threshold +0 L1 in (0=transposed,1=no-transposed) form +0 U in (0=transposed,1=no-transposed) form +1 Equilibration (0=no,1=yes) +8 memory alignment in double (> 0) +""" + + with open(outputfile, 'w') as fp: + fp.write(hpl_template.format(**hpl_input)) + + +def mem_per_core(): + from multiprocessing import cpu_count + nCPU = cpu_count() + + MemTotal = None + with open("/proc/meminfo", 'r') as fp: + for line in fp: + info = line.split() + if 'MemTotal:' == info[0]: + MemTotal = int(info[1]) / 1024 + break + if not MemTotal: + raise Exception('Unable to determine system memory. Please specify --mem_per_rank') + + return int(MemTotal / nCPU) + + +def calculate_N(nRanks, MemPerRank, memWeight): + totalMemInBytes = MemPerRank * nRanks * (memWeight / 100.) * 1024*1024 + totalDoubles = totalMemInBytes / 8 + nSize = int(sqrt(totalDoubles)) + # TODO: Maybe round something "human" + return nSize + + +def parse_ratio(string): + try: + (p,q) = [int(x) for x in string.split(':')] + return [p, q] + except: + msg = "%r should be of format : (ie, '1:2')"%string + raise ArgumentTypeError(msg) + +def estimate_PQ(nRanks): + factors = [(x, int(nRanks/x)) for x in range(2, int(sqrt(nRanks))+1) if nRanks%x == 0] + if len(factors) == 0: + factors = [(1, nRanks)] + + return factors[-1] + + + +def create_input(ranks, mem_weight): + + N = calculate_N(ranks, mem_per_core(), mem_weight) + NB = [ 128, 160, 192, 256] # Some "reasonable" numbers + LCM = lcm_array(NB) + factor = int(N / LCM) + if factor%2: + factor -=1 + N = [int(LCM * factor)] + + PQ = [estimate_PQ(ranks)] + + write_HPL_input(N, NB, PQ) + + + +def parse_hpl_out(outFile): + results=[] + with outFile.open('r') as fp: + line = fp.readline() + while line: + line = line.strip() + if ['T/V', 'N', 'NB', 'P', 'Q', 'Time', 'Gflops'] == line.split(): + # Skip the next line (all '-----'), and get our data + fp.readline() + line = fp.readline().strip() + vals = line.split() + results.append(float(vals[-1])) + line = fp.readline() + if len(results) > 0: + return {'result_unit': 'Gflops', 'result_value': max(results)} + return None + + + +if __name__ == '__main__': + import os, subprocess, json + + nranks=int(os.environ.get("SLURM_NTASKS", 1)) + + create_input(nranks, mem_weight=25.0) + # Now, run HPL itself + subprocess.run(["mpirun", "xhpl"]) + + outFile = Path('./HPL.out') + if outFile.exists(): + # Create KPI.json + kpi = parse_hpl_out(outFile) + if kpi: + with open('kpi.json', 'w') as fp: + fp.write(json.dumps(kpi)) diff --git a/frontend/website/ghpcfe/static/examples/wrf_12km.sh b/frontend/website/ghpcfe/static/examples/wrf_12km.sh new file mode 100644 index 0000000000..d3e855e6fd --- /dev/null +++ b/frontend/website/ghpcfe/static/examples/wrf_12km.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Spack doesn't place much into the environment for WRF +# But it does add to CMAKE_PREFIX_PATH +# Extract the package info from that +spack_hash=$(echo $CMAKE_PREFIX_PATH | sed -e 's/:/\n/g' |sort | uniq| awk -F- '/wrf-3.9.1.1/{print $NF}') +wrf_home=$(spack location -i /${spack_hash}) + +bench_dir=bench_12km + +# SHOULD HAVE DOWNLOAD: +# gs://mcbench/datasets/WRFv3/bench_12km + +if [ ! -d "${bench_dir}" ]; then + print "Failed to launch - no ${bench_dir} dir!" + exit 1 +fi + +if [ ! -x "$wrf_home/main/wrf.exe" ]; then + print "Failed to launch - could not find wrf.exe" + exit 1 +fi + +cd ${bench_dir} +ln -s $wrf_home/main/wrf.exe +ln -s $wrf_home/run/RRTM_DATA + +mpirun ./wrf.exe +res=$? + +cd - +cp ${bench_dir}/namelist.* . +cp ${bench_dir}/rsl.* . +rm -rf "${bench_dir}" + +if [[ "$res" == 0 ]]; then + # Produce kpi.json + simSecPerSec=$(grep 'Timing for main' rsl.error.0000 | awk '{SUM += $9} END {print 10800./SUM}') + echo "{\"result_unit\": \"simSecPerSec\", \"result_value\": $simSecPerSec}" > kpi.json +fi + diff --git a/frontend/website/ghpcfe/static/examples/wrf_2.5km.sh b/frontend/website/ghpcfe/static/examples/wrf_2.5km.sh new file mode 100644 index 0000000000..cd7fe7df60 --- /dev/null +++ b/frontend/website/ghpcfe/static/examples/wrf_2.5km.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# Spack doesn't place much into the environment for WRF +# But it does add to CMAKE_PREFIX_PATH +# Extract the package info from that +spack_hash=$(echo $CMAKE_PREFIX_PATH | sed -e 's/:/\n/g' |sort | uniq| awk -F- '/wrf-3.9.1.1/{print $NF}') +wrf_home=$(spack location -i /${spack_hash}) + +bench_dir=bench_2.5km + +# SHOULD HAVE DOWNLOAD: +# gs://mcbench/datasets/WRFv3/bench_2.5km + +if [ ! -d "${bench_dir}" ]; then + print "Failed to launch - no ${bench_dir} dir!" + exit 1 +fi + +if [ ! -x "$wrf_home/main/wrf.exe" ]; then + print "Failed to launch - could not find wrf.exe" + exit 1 +fi + +cd ${bench_dir} +ln -s $wrf_home/main/wrf.exe +ln -s $wrf_home/run/RRTM_DATA +ln -s $wrf_home/run/VEGPARM.TBL +ln -s $wrf_home/run/SOILPARM.TBL +ln -s $wrf_home/run/GENPARM.TBL + +mpirun ./wrf.exe +res=$? + +cd - +cp ${bench_dir}/namelist.* . +cp ${bench_dir}/rsl.* . +rm -rf "${bench_dir}" + +if [[ "$res" == 0 ]]; then + # Produce kpi.json + simSecPerSec=$(grep 'Timing for main' rsl.error.0000 | awk '{SUM += $9} END {print 10800./SUM}') + echo "{\"result_unit\": \"simSecPerSec\", \"result_value\": $simSecPerSec}" > kpi.json +fi + diff --git a/frontend/website/ghpcfe/static/fonts/glyphicons-halflings-regular.eot b/frontend/website/ghpcfe/static/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000000000000000000000000000000000000..b93a4953fff68df523aa7656497ee339d6026d64 GIT binary patch literal 20127 zcma%hV{j!vx9y2-`@~L8?1^pLwlPU2wr$&<*tR|KBoo`2;LUg6eW-eW-tKDb)vH%` z^`A!Vd<6hNSRMcX|Cb;E|1qflDggj6Kmr)xA10^t-vIc3*Z+F{r%|K(GyE^?|I{=9 zNq`(c8=wS`0!RZy0g3{M(8^tv41d}oRU?8#IBFtJy*9zAN5dcxqGlMZGL>GG%R#)4J zDJ2;)4*E1pyHia%>lMv3X7Q`UoFyoB@|xvh^)kOE3)IL&0(G&i;g08s>c%~pHkN&6 z($7!kyv|A2DsV2mq-5Ku)D#$Kn$CzqD-wm5Q*OtEOEZe^&T$xIb0NUL}$)W)Ck`6oter6KcQG9Zcy>lXip)%e&!lQgtQ*N`#abOlytt!&i3fo)cKV zP0BWmLxS1gQv(r_r|?9>rR0ZeEJPx;Vi|h1!Eo*dohr&^lJgqJZns>&vexP@fs zkPv93Nyw$-kM5Mw^{@wPU47Y1dSkiHyl3dtHLwV&6Tm1iv{ve;sYA}Z&kmH802s9Z zyJEn+cfl7yFu#1^#DbtP7k&aR06|n{LnYFYEphKd@dJEq@)s#S)UA&8VJY@S2+{~> z(4?M();zvayyd^j`@4>xCqH|Au>Sfzb$mEOcD7e4z8pPVRTiMUWiw;|gXHw7LS#U< zsT(}Z5SJ)CRMXloh$qPnK77w_)ctHmgh}QAe<2S{DU^`!uwptCoq!Owz$u6bF)vnb zL`bM$%>baN7l#)vtS3y6h*2?xCk z>w+s)@`O4(4_I{L-!+b%)NZcQ&ND=2lyP+xI#9OzsiY8$c)ys-MI?TG6 zEP6f=vuLo!G>J7F4v|s#lJ+7A`^nEQScH3e?B_jC&{sj>m zYD?!1z4nDG_Afi$!J(<{>z{~Q)$SaXWjj~%ZvF152Hd^VoG14rFykR=_TO)mCn&K$ z-TfZ!vMBvnToyBoKRkD{3=&=qD|L!vb#jf1f}2338z)e)g>7#NPe!FoaY*jY{f)Bf>ohk-K z4{>fVS}ZCicCqgLuYR_fYx2;*-4k>kffuywghn?15s1dIOOYfl+XLf5w?wtU2Og*f z%X5x`H55F6g1>m~%F`655-W1wFJtY>>qNSdVT`M`1Mlh!5Q6#3j={n5#za;!X&^OJ zgq;d4UJV-F>gg?c3Y?d=kvn3eV)Jb^ zO5vg0G0yN0%}xy#(6oTDSVw8l=_*2k;zTP?+N=*18H5wp`s90K-C67q{W3d8vQGmr zhpW^>1HEQV2TG#8_P_0q91h8QgHT~8=-Ij5snJ3cj?Jn5_66uV=*pq(j}yHnf$Ft;5VVC?bz%9X31asJeQF2jEa47H#j` zk&uxf3t?g!tltVP|B#G_UfDD}`<#B#iY^i>oDd-LGF}A@Fno~dR72c&hs6bR z2F}9(i8+PR%R|~FV$;Ke^Q_E_Bc;$)xN4Ti>Lgg4vaip!%M z06oxAF_*)LH57w|gCW3SwoEHwjO{}}U=pKhjKSZ{u!K?1zm1q? zXyA6y@)}_sONiJopF}_}(~}d4FDyp|(@w}Vb;Fl5bZL%{1`}gdw#i{KMjp2@Fb9pg ziO|u7qP{$kxH$qh8%L+)AvwZNgUT6^zsZq-MRyZid{D?t`f|KzSAD~C?WT3d0rO`0 z=qQ6{)&UXXuHY{9g|P7l_nd-%eh}4%VVaK#Nik*tOu9lBM$<%FS@`NwGEbP0&;Xbo zObCq=y%a`jSJmx_uTLa{@2@}^&F4c%z6oe-TN&idjv+8E|$FHOvBqg5hT zMB=7SHq`_-E?5g=()*!V>rIa&LcX(RU}aLm*38U_V$C_g4)7GrW5$GnvTwJZdBmy6 z*X)wi3=R8L=esOhY0a&eH`^fSpUHV8h$J1|o^3fKO|9QzaiKu>yZ9wmRkW?HTkc<*v7i*ylJ#u#j zD1-n&{B`04oG>0Jn{5PKP*4Qsz{~`VVA3578gA+JUkiPc$Iq!^K|}*p_z3(-c&5z@ zKxmdNpp2&wg&%xL3xZNzG-5Xt7jnI@{?c z25=M>-VF|;an2Os$Nn%HgQz7m(ujC}Ii0Oesa(y#8>D+P*_m^X##E|h$M6tJr%#=P zWP*)Px>7z`E~U^2LNCNiy%Z7!!6RI%6fF@#ZY3z`CK91}^J$F!EB0YF1je9hJKU7!S5MnXV{+#K;y zF~s*H%p@vj&-ru7#(F2L+_;IH46X(z{~HTfcThqD%b{>~u@lSc<+f5#xgt9L7$gSK ziDJ6D*R%4&YeUB@yu@4+&70MBNTnjRyqMRd+@&lU#rV%0t3OmouhC`mkN}pL>tXin zY*p)mt=}$EGT2E<4Q>E2`6)gZ`QJhGDNpI}bZL9}m+R>q?l`OzFjW?)Y)P`fUH(_4 zCb?sm1=DD0+Q5v}BW#0n5;Nm(@RTEa3(Y17H2H67La+>ptQHJ@WMy2xRQT$|7l`8c zYHCxYw2o-rI?(fR2-%}pbs$I%w_&LPYE{4bo}vRoAW>3!SY_zH3`ofx3F1PsQ?&iq z*BRG>?<6%z=x#`NhlEq{K~&rU7Kc7Y-90aRnoj~rVoKae)L$3^z*Utppk?I`)CX&& zZ^@Go9fm&fN`b`XY zt0xE5aw4t@qTg_k=!-5LXU+_~DlW?53!afv6W(k@FPPX-`nA!FBMp7b!ODbL1zh58 z*69I}P_-?qSLKj}JW7gP!la}K@M}L>v?rDD!DY-tu+onu9kLoJz20M4urX_xf2dfZ zORd9Zp&28_ff=wdMpXi%IiTTNegC}~RLkdYjA39kWqlA?jO~o1`*B&85Hd%VPkYZT z48MPe62;TOq#c%H(`wX5(Bu>nlh4Fbd*Npasdhh?oRy8a;NB2(eb}6DgwXtx=n}fE zx67rYw=(s0r?EsPjaya}^Qc-_UT5|*@|$Q}*|>V3O~USkIe6a0_>vd~6kHuP8=m}_ zo2IGKbv;yA+TBtlCpnw)8hDn&eq?26gN$Bh;SdxaS04Fsaih_Cfb98s39xbv)=mS0 z6M<@pM2#pe32w*lYSWG>DYqB95XhgAA)*9dOxHr{t)er0Xugoy)!Vz#2C3FaUMzYl zCxy{igFB901*R2*F4>grPF}+G`;Yh zGi@nRjWyG3mR(BVOeBPOF=_&}2IWT%)pqdNAcL{eP`L*^FDv#Rzql5U&Suq_X%JfR_lC!S|y|xd5mQ0{0!G#9hV46S~A` z0B!{yI-4FZEtol5)mNWXcX(`x&Pc*&gh4k{w%0S#EI>rqqlH2xv7mR=9XNCI$V#NG z4wb-@u{PfQP;tTbzK>(DF(~bKp3;L1-A*HS!VB)Ae>Acnvde15Anb`h;I&0)aZBS6 z55ZS7mL5Wp!LCt45^{2_70YiI_Py=X{I3>$Px5Ez0ahLQ+ z9EWUWSyzA|+g-Axp*Lx-M{!ReQO07EG7r4^)K(xbj@%ZU=0tBC5shl)1a!ifM5OkF z0w2xQ-<+r-h1fi7B6waX15|*GGqfva)S)dVcgea`lQ~SQ$KXPR+(3Tn2I2R<0 z9tK`L*pa^+*n%>tZPiqt{_`%v?Bb7CR-!GhMON_Fbs0$#|H}G?rW|{q5fQhvw!FxI zs-5ZK>hAbnCS#ZQVi5K0X3PjL1JRdQO+&)*!oRCqB{wen60P6!7bGiWn@vD|+E@Xq zb!!_WiU^I|@1M}Hz6fN-m04x=>Exm{b@>UCW|c8vC`aNbtA@KCHujh^2RWZC}iYhL^<*Z93chIBJYU&w>$CGZDRcHuIgF&oyesDZ#&mA;?wxx4Cm#c0V$xYG?9OL(Smh}#fFuX(K;otJmvRP{h ze^f-qv;)HKC7geB92_@3a9@MGijS(hNNVd%-rZ;%@F_f7?Fjinbe1( zn#jQ*jKZTqE+AUTEd3y6t>*=;AO##cmdwU4gc2&rT8l`rtKW2JF<`_M#p>cj+)yCG zgKF)y8jrfxTjGO&ccm8RU>qn|HxQ7Z#sUo$q)P5H%8iBF$({0Ya51-rA@!It#NHN8MxqK zrYyl_&=}WVfQ?+ykV4*@F6)=u_~3BebR2G2>>mKaEBPmSW3(qYGGXj??m3L zHec{@jWCsSD8`xUy0pqT?Sw0oD?AUK*WxZn#D>-$`eI+IT)6ki>ic}W)t$V32^ITD zR497@LO}S|re%A+#vdv-?fXsQGVnP?QB_d0cGE+U84Q=aM=XrOwGFN3`Lpl@P0fL$ zKN1PqOwojH*($uaQFh8_)H#>Acl&UBSZ>!2W1Dinei`R4dJGX$;~60X=|SG6#jci} z&t4*dVDR*;+6Y(G{KGj1B2!qjvDYOyPC}%hnPbJ@g(4yBJrViG1#$$X75y+Ul1{%x zBAuD}Q@w?MFNqF-m39FGpq7RGI?%Bvyyig&oGv)lR>d<`Bqh=p>urib5DE;u$c|$J zwim~nPb19t?LJZsm{<(Iyyt@~H!a4yywmHKW&=1r5+oj*Fx6c89heW@(2R`i!Uiy* zp)=`Vr8sR!)KChE-6SEIyi(dvG3<1KoVt>kGV=zZiG7LGonH1+~yOK-`g0)r#+O|Q>)a`I2FVW%wr3lhO(P{ksNQuR!G_d zeTx(M!%brW_vS9?IF>bzZ2A3mWX-MEaOk^V|4d38{1D|KOlZSjBKrj7Fgf^>JyL0k zLoI$adZJ0T+8i_Idsuj}C;6jgx9LY#Ukh;!8eJ^B1N}q=Gn4onF*a2vY7~`x$r@rJ z`*hi&Z2lazgu{&nz>gjd>#eq*IFlXed(%$s5!HRXKNm zDZld+DwDI`O6hyn2uJ)F^{^;ESf9sjJ)wMSKD~R=DqPBHyP!?cGAvL<1|7K-(=?VO zGcKcF1spUa+ki<`6K#@QxOTsd847N8WSWztG~?~ z!gUJn>z0O=_)VCE|56hkT~n5xXTp}Ucx$Ii%bQ{5;-a4~I2e|{l9ur#*ghd*hSqO= z)GD@ev^w&5%k}YYB~!A%3*XbPPU-N6&3Lp1LxyP@|C<{qcn&?l54+zyMk&I3YDT|E z{lXH-e?C{huu<@~li+73lMOk&k)3s7Asn$t6!PtXJV!RkA`qdo4|OC_a?vR!kE_}k zK5R9KB%V@R7gt@9=TGL{=#r2gl!@3G;k-6sXp&E4u20DgvbY$iE**Xqj3TyxK>3AU z!b9}NXuINqt>Htt6fXIy5mj7oZ{A&$XJ&thR5ySE{mkxq_YooME#VCHm2+3D!f`{) zvR^WSjy_h4v^|!RJV-RaIT2Ctv=)UMMn@fAgjQV$2G+4?&dGA8vK35c-8r)z9Qqa=%k(FU)?iec14<^olkOU3p zF-6`zHiDKPafKK^USUU+D01>C&Wh{{q?>5m zGQp|z*+#>IIo=|ae8CtrN@@t~uLFOeT{}vX(IY*;>wAU=u1Qo4c+a&R);$^VCr>;! zv4L{`lHgc9$BeM)pQ#XA_(Q#=_iSZL4>L~8Hx}NmOC$&*Q*bq|9Aq}rWgFnMDl~d*;7c44GipcpH9PWaBy-G$*MI^F0 z?Tdxir1D<2ui+Q#^c4?uKvq=p>)lq56=Eb|N^qz~w7rsZu)@E4$;~snz+wIxi+980O6M#RmtgLYh@|2}9BiHSpTs zacjGKvwkUwR3lwTSsCHlwb&*(onU;)$yvdhikonn|B44JMgs*&Lo!jn`6AE>XvBiO z*LKNX3FVz9yLcsnmL!cRVO_qv=yIM#X|u&}#f%_?Tj0>8)8P_0r0!AjWNw;S44tst zv+NXY1{zRLf9OYMr6H-z?4CF$Y%MdbpFIN@a-LEnmkcOF>h16cH_;A|e)pJTuCJ4O zY7!4FxT4>4aFT8a92}84>q0&?46h>&0Vv0p>u~k&qd5$C1A6Q$I4V(5X~6{15;PD@ ze6!s9xh#^QI`J+%8*=^(-!P!@9%~buBmN2VSAp@TOo6}C?az+ALP8~&a0FWZk*F5N z^8P8IREnN`N0i@>O0?{i-FoFShYbUB`D7O4HB`Im2{yzXmyrg$k>cY6A@>bf7i3n0 z5y&cf2#`zctT>dz+hNF&+d3g;2)U!#vsb-%LC+pqKRTiiSn#FH#e!bVwR1nAf*TG^ z!RKcCy$P>?Sfq6n<%M{T0I8?p@HlgwC!HoWO>~mT+X<{Ylm+$Vtj9};H3$EB}P2wR$3y!TO#$iY8eO-!}+F&jMu4%E6S>m zB(N4w9O@2=<`WNJay5PwP8javDp~o~xkSbd4t4t8)9jqu@bHmJHq=MV~Pt|(TghCA}fhMS?s-{klV>~=VrT$nsp7mf{?cze~KKOD4 z_1Y!F)*7^W+BBTt1R2h4f1X4Oy2%?=IMhZU8c{qk3xI1=!na*Sg<=A$?K=Y=GUR9@ zQ(ylIm4Lgm>pt#%p`zHxok%vx_=8Fap1|?OM02|N%X-g5_#S~sT@A!x&8k#wVI2lo z1Uyj{tDQRpb*>c}mjU^gYA9{7mNhFAlM=wZkXcA#MHXWMEs^3>p9X)Oa?dx7b%N*y zLz@K^%1JaArjgri;8ptNHwz1<0y8tcURSbHsm=26^@CYJ3hwMaEvC7 z3Wi-@AaXIQ)%F6#i@%M>?Mw7$6(kW@?et@wbk-APcvMCC{>iew#vkZej8%9h0JSc? zCb~K|!9cBU+))^q*co(E^9jRl7gR4Jihyqa(Z(P&ID#TPyysVNL7(^;?Gan!OU>au zN}miBc&XX-M$mSv%3xs)bh>Jq9#aD_l|zO?I+p4_5qI0Ms*OZyyxA`sXcyiy>-{YN zA70%HmibZYcHW&YOHk6S&PQ+$rJ3(utuUra3V0~@=_~QZy&nc~)AS>v&<6$gErZC3 zcbC=eVkV4Vu0#}E*r=&{X)Kgq|8MGCh(wsH4geLj@#8EGYa})K2;n z{1~=ghoz=9TSCxgzr5x3@sQZZ0FZ+t{?klSI_IZa16pSx6*;=O%n!uXVZ@1IL;JEV zfOS&yyfE9dtS*^jmgt6>jQDOIJM5Gx#Y2eAcC3l^lmoJ{o0T>IHpECTbfYgPI4#LZq0PKqnPCD}_ zyKxz;(`fE0z~nA1s?d{X2!#ZP8wUHzFSOoTWQrk%;wCnBV_3D%3@EC|u$Ao)tO|AO z$4&aa!wbf}rbNcP{6=ajgg(`p5kTeu$ji20`zw)X1SH*x zN?T36{d9TY*S896Ijc^!35LLUByY4QO=ARCQ#MMCjudFc7s!z%P$6DESz%zZ#>H|i zw3Mc@v4~{Eke;FWs`5i@ifeYPh-Sb#vCa#qJPL|&quSKF%sp8*n#t?vIE7kFWjNFh zJC@u^bRQ^?ra|%39Ux^Dn4I}QICyDKF0mpe+Bk}!lFlqS^WpYm&xwIYxUoS-rJ)N9 z1Tz*6Rl9;x`4lwS1cgW^H_M*)Dt*DX*W?ArBf?-t|1~ge&S}xM0K;U9Ibf{okZHf~ z#4v4qc6s6Zgm8iKch5VMbQc~_V-ZviirnKCi*ouN^c_2lo&-M;YSA>W>>^5tlXObg zacX$k0=9Tf$Eg+#9k6yV(R5-&F{=DHP8!yvSQ`Y~XRnUx@{O$-bGCksk~3&qH^dqX zkf+ZZ?Nv5u>LBM@2?k%k&_aUb5Xjqf#!&7%zN#VZwmv65ezo^Y4S#(ed0yUn4tFOB zh1f1SJ6_s?a{)u6VdwUC!Hv=8`%T9(^c`2hc9nt$(q{Dm2X)dK49ba+KEheQ;7^0) ziFKw$%EHy_B1)M>=yK^=Z$U-LT36yX>EKT zvD8IAom2&2?bTmX@_PBR4W|p?6?LQ+&UMzXxqHC5VHzf@Eb1u)kwyfy+NOM8Wa2y@ zNNDL0PE$F;yFyf^jy&RGwDXQwYw6yz>OMWvJt98X@;yr!*RQDBE- zE*l*u=($Zi1}0-Y4lGaK?J$yQjgb+*ljUvNQ!;QYAoCq@>70=sJ{o{^21^?zT@r~hhf&O;Qiq+ ziGQQLG*D@5;LZ%09mwMiE4Q{IPUx-emo*;a6#DrmWr(zY27d@ezre)Z1BGZdo&pXn z+);gOFelKDmnjq#8dL7CTiVH)dHOqWi~uE|NM^QI3EqxE6+_n>IW67~UB#J==QOGF zp_S)c8TJ}uiaEiaER}MyB(grNn=2m&0yztA=!%3xUREyuG_jmadN*D&1nxvjZ6^+2 zORi7iX1iPi$tKasppaR9$a3IUmrrX)m*)fg1>H+$KpqeB*G>AQV((-G{}h=qItj|d zz~{5@{?&Dab6;0c7!!%Se>w($RmlG7Jlv_zV3Ru8b2rugY0MVPOOYGlokI7%nhIy& z-B&wE=lh2dtD!F?noD{z^O1~Tq4MhxvchzuT_oF3-t4YyA*MJ*n&+1X3~6quEN z@m~aEp=b2~mP+}TUP^FmkRS_PDMA{B zaSy(P=$T~R!yc^Ye0*pl5xcpm_JWI;@-di+nruhqZ4gy7cq-)I&s&Bt3BkgT(Zdjf zTvvv0)8xzntEtp4iXm}~cT+pi5k{w{(Z@l2XU9lHr4Vy~3ycA_T?V(QS{qwt?v|}k z_ST!s;C4!jyV5)^6xC#v!o*uS%a-jQ6< z)>o?z7=+zNNtIz1*F_HJ(w@=`E+T|9TqhC(g7kKDc8z~?RbKQ)LRMn7A1p*PcX2YR zUAr{);~c7I#3Ssv<0i-Woj0&Z4a!u|@Xt2J1>N-|ED<3$o2V?OwL4oQ%$@!zLamVz zB)K&Ik^~GOmDAa143{I4?XUk1<3-k{<%?&OID&>Ud%z*Rkt*)mko0RwC2=qFf-^OV z=d@47?tY=A;=2VAh0mF(3x;!#X!%{|vn;U2XW{(nu5b&8kOr)Kop3-5_xnK5oO_3y z!EaIb{r%D{7zwtGgFVri4_!yUIGwR(xEV3YWSI_+E}Gdl>TINWsIrfj+7DE?xp+5^ zlr3pM-Cbse*WGKOd3+*Qen^*uHk)+EpH-{u@i%y}Z!YSid<}~kA*IRSk|nf+I1N=2 zIKi+&ej%Al-M5`cP^XU>9A(m7G>58>o|}j0ZWbMg&x`*$B9j#Rnyo0#=BMLdo%=ks zLa3(2EinQLXQ(3zDe7Bce%Oszu%?8PO648TNst4SMFvj=+{b%)ELyB!0`B?9R6aO{i-63|s@|raSQGL~s)9R#J#duFaTSZ2M{X z1?YuM*a!!|jP^QJ(hAisJuPOM`8Y-Hzl~%d@latwj}t&0{DNNC+zJARnuQfiN`HQ# z?boY_2?*q;Qk)LUB)s8(Lz5elaW56p&fDH*AWAq7Zrbeq1!?FBGYHCnFgRu5y1jwD zc|yBz+UW|X`zDsc{W~8m$sh@VVnZD$lLnKlq@Hg^;ky!}ZuPdKNi2BI70;hrpvaA4+Q_+K)I@|)q1N-H zrycZU`*YUW``Qi^`bDX-j7j^&bO+-Xg$cz2#i##($uyW{Nl&{DK{=lLWV3|=<&si||2)l=8^8_z+Vho-#5LB0EqQ3v5U#*DF7 zxT)1j^`m+lW}p$>WSIG1eZ>L|YR-@Feu!YNWiw*IZYh03mq+2QVtQ}1ezRJM?0PA< z;mK(J5@N8>u@<6Y$QAHWNE};rR|)U_&bv8dsnsza7{=zD1VBcxrALqnOf-qW(zzTn zTAp|pEo#FsQ$~*$j|~Q;$Zy&Liu9OM;VF@#_&*nL!N2hH!Q6l*OeTxq!l>dEc{;Hw zCQni{iN%jHU*C;?M-VUaXxf0FEJ_G=C8)C-wD!DvhY+qQ#FT3}Th8;GgV&AV94F`D ztT6=w_Xm8)*)dBnDkZd~UWL|W=Glu!$hc|1w7_7l!3MAt95oIp4Xp{M%clu&TXehO z+L-1#{mjkpTF@?|w1P98OCky~S%@OR&o75P&ZHvC}Y=(2_{ib(-Al_7aZ^U?s34#H}= zGfFi5%KnFVCKtdO^>Htpb07#BeCXMDO8U}crpe1Gm`>Q=6qB4i=nLoLZ%p$TY=OcP z)r}Et-Ed??u~f09d3Nx3bS@ja!fV(Dfa5lXxRs#;8?Y8G+Qvz+iv7fiRkL3liip}) z&G0u8RdEC9c$$rdU53=MH`p!Jn|DHjhOxHK$tW_pw9wCTf0Eo<){HoN=zG!!Gq4z4 z7PwGh)VNPXW-cE#MtofE`-$9~nmmj}m zlzZscQ2+Jq%gaB9rMgVJkbhup0Ggpb)&L01T=%>n7-?v@I8!Q(p&+!fd+Y^Pu9l+u zek(_$^HYFVRRIFt@0Fp52g5Q#I`tC3li`;UtDLP*rA{-#Yoa5qp{cD)QYhldihWe+ zG~zuaqLY~$-1sjh2lkbXCX;lq+p~!2Z=76cvuQe*Fl>IFwpUBP+d^&E4BGc{m#l%Kuo6#{XGoRyFc%Hqhf|%nYd<;yiC>tyEyk z4I+a`(%%Ie=-*n z-{mg=j&t12)LH3R?@-B1tEb7FLMePI1HK0`Ae@#)KcS%!Qt9p4_fmBl5zhO10n401 zBSfnfJ;?_r{%R)hh}BBNSl=$BiAKbuWrNGQUZ)+0=Mt&5!X*D@yGCSaMNY&@`;^a4 z;v=%D_!K!WXV1!3%4P-M*s%V2b#2jF2bk!)#2GLVuGKd#vNpRMyg`kstw0GQ8@^k^ zuqK5uR<>FeRZ#3{%!|4X!hh7hgirQ@Mwg%%ez8pF!N$xhMNQN((yS(F2-OfduxxKE zxY#7O(VGfNuLv-ImAw5+h@gwn%!ER;*Q+001;W7W^waWT%@(T+5k!c3A-j)a8y11t zx4~rSN0s$M8HEOzkcWW4YbKK9GQez2XJ|Nq?TFy;jmGbg;`m&%U4hIiarKmdTHt#l zL=H;ZHE?fYxKQQXKnC+K!TAU}r086{4m}r()-QaFmU(qWhJlc$eas&y?=H9EYQy8N$8^bni9TpDp zkA^WRs?KgYgjxX4T6?`SMs$`s3vlut(YU~f2F+id(Rf_)$BIMibk9lACI~LA+i7xn z%-+=DHV*0TCTJp~-|$VZ@g2vmd*|2QXV;HeTzt530KyK>v&253N1l}bP_J#UjLy4) zBJili9#-ey8Kj(dxmW^ctorxd;te|xo)%46l%5qE-YhAjP`Cc03vT)vV&GAV%#Cgb zX~2}uWNvh`2<*AuxuJpq>SyNtZwzuU)r@@dqC@v=Ocd(HnnzytN+M&|Qi#f4Q8D=h ziE<3ziFW%+!yy(q{il8H44g^5{_+pH60Mx5Z*FgC_3hKxmeJ+wVuX?T#ZfOOD3E4C zRJsj#wA@3uvwZwHKKGN{{Ag+8^cs?S4N@6(Wkd$CkoCst(Z&hp+l=ffZ?2m%%ffI3 zdV7coR`R+*dPbNx=*ivWeNJK=Iy_vKd`-_Hng{l?hmp=|T3U&epbmgXXWs9ySE|=G zeQ|^ioL}tveN{s72_&h+F+W;G}?;?_s@h5>DX(rp#eaZ!E=NivgLI zWykLKev+}sHH41NCRm7W>K+_qdoJ8x9o5Cf!)|qLtF7Izxk*p|fX8UqEY)_sI_45O zL2u>x=r5xLE%s|d%MO>zU%KV6QKFiEeo12g#bhei4!Hm+`~Fo~4h|BJ)%ENxy9)Up zOxupSf1QZWun=)gF{L0YWJ<(r0?$bPFANrmphJ>kG`&7E+RgrWQi}ZS#-CQJ*i#8j zM_A0?w@4Mq@xvk^>QSvEU|VYQoVI=TaOrsLTa`RZfe8{9F~mM{L+C`9YP9?OknLw| zmkvz>cS6`pF0FYeLdY%>u&XpPj5$*iYkj=m7wMzHqzZ5SG~$i_^f@QEPEC+<2nf-{ zE7W+n%)q$!5@2pBuXMxhUSi*%F>e_g!$T-_`ovjBh(3jK9Q^~OR{)}!0}vdTE^M+m z9QWsA?xG>EW;U~5gEuKR)Ubfi&YWnXV;3H6Zt^NE725*`;lpSK4HS1sN?{~9a4JkD z%}23oAovytUKfRN87XTH2c=kq1)O5(fH_M3M-o{{@&~KD`~TRot-gqg7Q2U2o-iiF}K>m?CokhmODaLB z1p6(6JYGntNOg(s!(>ZU&lzDf+Ur)^Lirm%*}Z>T)9)fAZ9>k(kvnM;ab$ptA=hoh zVgsVaveXbMpm{|4*d<0>?l_JUFOO8A3xNLQOh%nVXjYI6X8h?a@6kDe5-m&;M0xqx z+1U$s>(P9P)f0!{z%M@E7|9nn#IWgEx6A6JNJ(7dk`%6$3@!C!l;JK-p2?gg+W|d- ziEzgk$w7k48NMqg$CM*4O~Abj3+_yUKTyK1p6GDsGEs;}=E_q>^LI-~pym$qhXPJf z2`!PJDp4l(TTm#|n@bN!j;-FFOM__eLl!6{*}z=)UAcGYloj?bv!-XY1TA6Xz;82J zLRaF{8ayzGa|}c--}|^xh)xgX>6R(sZD|Z|qX50gu=d`gEwHqC@WYU7{%<5VOnf9+ zB@FX?|UL%`8EIAe!*UdYl|6wRz6Y>(#8x92$#y}wMeE|ZM2X*c}dKJ^4NIf;Fm zNwzq%QcO?$NR-7`su!*$dlIKo2y(N;qgH@1|8QNo$0wbyyJ2^}$iZ>M{BhBjTdMjK z>gPEzgX4;g3$rU?jvDeOq`X=>)zdt|jk1Lv3u~bjHI=EGLfIR&+K3ldcc4D&Um&04 z3^F*}WaxR(ZyaB>DlmF_UP@+Q*h$&nsOB#gwLt{1#F4i-{A5J@`>B9@{^i?g_Ce&O z<<}_We-RUFU&&MHa1#t56u_oM(Ljn7djja!T|gcxSoR=)@?owC*NkDarpBj=W4}=i1@)@L|C) zQKA+o<(pMVp*Su(`zBC0l1yTa$MRfQ#uby|$mlOMs=G`4J|?apMzKei%jZql#gP@IkOaOjB7MJM=@1j(&!jNnyVkn5;4lvro1!vq ztXiV8HYj5%)r1PPpIOj)f!>pc^3#LvfZ(hz}C@-3R(Cx7R427*Fwd!XO z4~j&IkPHcBm0h_|iG;ZNrYdJ4HI!$rSyo&sibmwIgm1|J#g6%>=ML1r!kcEhm(XY& zD@mIJt;!O%WP7CE&wwE3?1-dt;RTHdm~LvP7K`ccWXkZ0kfFa2S;wGtx_a}S2lslw z$<4^Jg-n#Ypc(3t2N67Juasu=h)j&UNTPNDil4MQMTlnI81kY46uMH5B^U{~nmc6+ z9>(lGhhvRK9ITfpAD!XQ&BPphL3p8B4PVBN0NF6U49;ZA0Tr75AgGw7(S=Yio+xg_ zepZ*?V#KD;sHH+15ix&yCs0eSB-Z%D%uujlXvT#V$Rz@$+w!u#3GIo*AwMI#Bm^oO zLr1e}k5W~G0xaO!C%Mb{sarxWZ4%Dn9vG`KHmPC9GWZwOOm11XJp#o0-P-${3m4g( z6~)X9FXw%Xm~&99tj>a-ri})ZcnsfJtc10F@t9xF5vq6E)X!iUXHq-ohlO`gQdS&k zZl})3k||u)!_=nNlvMbz%AuIr89l#I$;rG}qvDGiK?xTd5HzMQkw*p$YvFLGyQM!J zNC^gD!kP{A84nGosi~@MLKqWQNacfs7O$dkZtm4-BZ~iA8xWZPkTK!HpA5zr!9Z&+icfAJ1)NWkTd!-9`NWU>9uXXUr;`Js#NbKFgrNhTcY4GNv*71}}T zFJh?>=EcbUd2<|fiL+H=wMw8hbX6?+_cl4XnCB#ddwdG>bki* zt*&6Dy&EIPluL@A3_;R%)shA-tDQA1!Tw4ffBRyy;2n)vm_JV06(4Or&QAOKNZB5f(MVC}&_!B>098R{Simr!UG}?CW1Ah+X+0#~0`X)od zLYablwmFxN21L))!_zc`IfzWi`5>MxPe(DmjjO1}HHt7TJtAW+VXHt!aKZk>y6PoMsbDXRJnov;D~Ur~2R_7(Xr)aa%wJwZhS3gr7IGgt%@;`jpL@gyc6bGCVx!9CE7NgIbUNZ!Ur1RHror0~ zr(j$^yM4j`#c2KxSP61;(Tk^pe7b~}LWj~SZC=MEpdKf;B@on9=?_n|R|0q;Y*1_@ z>nGq>)&q!;u-8H)WCwtL&7F4vbnnfSAlK1mwnRq2&gZrEr!b1MA z(3%vAbh3aU-IX`d7b@q`-WiT6eitu}ZH9x#d&qx}?CtDuAXak%5<-P!{a`V=$|XmJ zUn@4lX6#ulB@a=&-9HG)a>KkH=jE7>&S&N~0X0zD=Q=t|7w;kuh#cU=NN7gBGbQTT z;?bdSt8V&IIi}sDTzA0dkU}Z-Qvg;RDe8v>468p3*&hbGT1I3hi9hh~Z(!H}{+>eUyF)H&gdrX=k$aB%J6I;6+^^kn1mL+E+?A!A}@xV(Qa@M%HD5C@+-4Mb4lI=Xp=@9+^x+jhtOc zYgF2aVa(uSR*n(O)e6tf3JEg2xs#dJfhEmi1iOmDYWk|wXNHU?g23^IGKB&yHnsm7 zm_+;p?YpA#N*7vXCkeN2LTNG`{QDa#U3fcFz7SB)83=<8rF)|udrEbrZL$o6W?oDR zQx!178Ih9B#D9Ko$H(jD{4MME&<|6%MPu|TfOc#E0B}!j^MMpV69D#h2`vsEQ{(?c zJ3Lh!3&=yS5fWL~;1wCZ?)%nmK`Eqgcu)O6rD^3%ijcxL50^z?OI(LaVDvfL0#zjZ z2?cPvC$QCzpxpt5jMFp05OxhK0F!Q`rPhDi5)y=-0C} zIM~ku&S@pl1&0=jl+rlS<4`riV~LC-#pqNde@44MB(j%)On$0Ko(@q?4`1?4149Z_ zZi!5aU@2vM$dHR6WSZpj+VboK+>u-CbNi7*lw4K^ZxxM#24_Yc`jvb9NPVi75L+MlM^U~`;a7`4H0L|TYK>%hfEfXLsu1JGM zbh|8{wuc7ucV+`Ys1kqxsj`dajwyM;^X^`)#<+a~$WFy8b2t_RS{8yNYKKlnv+>vB zX(QTf$kqrJ;%I@EwEs{cIcH@Z3|#^S@M+5jsP<^`@8^I4_8MlBb`~cE^n+{{;qW2q z=p1=&+fUo%T{GhVX@;56kH8K_%?X=;$OTYqW1L*)hzelm^$*?_K;9JyIWhsn4SK(| zSmXLTUE8VQX{se#8#Rj*lz`xHtT<61V~fb;WZUpu(M)f#;I+2_zR+)y5Jv?l`CxAinx|EY!`IJ*x9_gf_k&Gx2alL!hK zUWj1T_pk|?iv}4EP#PZvYD_-LpzU!NfcLL%fK&r$W8O1KH9c2&GV~N#T$kaXGvAOl)|T zuF9%6(i=Y3q?X%VK-D2YIYFPH3f|g$TrXW->&^Ab`WT z7>Oo!u1u40?jAJ8Hy`bv}qbgs8)cF0&qeVjD?e+3Ggn1Im>K77ZSpbU*08 zfZkIFcv?y)!*B{|>nx@cE{KoutP+seQU?bCGE`tS0GKUO3PN~t=2u7q_6$l;uw^4c zVu^f{uaqsZ{*a-N?2B8ngrLS8E&s6}Xtv9rR9C^b`@q8*iH)pFzf1|kCfiLw6u{Z%aC z!X^5CzF6qofFJgklJV3oc|Qc2XdFl+y5M9*P8}A>Kh{ zWRgRwMSZ(?Jw;m%0etU5BsWT-Dj-5F;Q$OQJrQd+lv`i6>MhVo^p*^w6{~=fhe|bN z*37oV0kji)4an^%3ABbg5RC;CS50@PV5_hKfXjYx+(DqQdKC^JIEMo6X66$qDdLRc z!YJPSKnbY`#Ht6`g@xGzJmKzzn|abYbP+_Q(v?~~ z96%cd{E0BCsH^0HaWt{y(Cuto4VE7jhB1Z??#UaU(*R&Eo+J`UN+8mcb51F|I|n*J zJCZ3R*OdyeS9hWkc_mA7-br>3Tw=CX2bl(=TpVt#WP8Bg^vE_9bP&6ccAf3lFMgr` z{3=h@?Ftb$RTe&@IQtiJfV;O&4fzh)e1>7seG; z=%mA4@c7{aXeJnhEg2J@Bm;=)j=O=cl#^NNkQ<{r;Bm|8Hg}bJ-S^g4`|itx)~!LN zXtL}?f1Hs6UQ+f0-X6&TBCW=A4>bU0{rv8C4T!(wD-h>VCK4YJk`6C9$by!fxOYw- zV#n+0{E(0ttq_#16B} ze8$E#X9o{B!0vbq#WUwmv5Xz6{(!^~+}sBW{xctdNHL4^vDk!0E}(g|W_q;jR|ZK< z8w>H-8G{%R#%f!E7cO_^B?yFRKLOH)RT9GJsb+kAKq~}WIF)NRLwKZ^Q;>!2MNa|} z-mh?=B;*&D{Nd-mQRcfVnHkChI=DRHU4ga%xJ%+QkBd|-d9uRI76@BT(bjsjwS+r) zvx=lGNLv1?SzZ;P)Gnn>04fO7Culg*?LmbEF0fATG8S@)oJ>NT3pYAXa*vX!eUTDF ziBrp(QyDqr0ZMTr?4uG_Nqs6f%S0g?h`1vO5fo=5S&u#wI2d4+3hWiolEU!=3_oFo zfie?+4W#`;1dd#X@g9Yj<53S<6OB!TM8w8})7k-$&q5(smc%;r z(BlXkTp`C47+%4JA{2X}MIaPbVF!35P#p;u7+fR*46{T+LR8+j25oduCfDzDv6R-hU{TVVo9fz?^N3ShMt!t0NsH)pB zRK8-S{Dn*y3b|k^*?_B70<2gHt==l7c&cT>r`C#{S}J2;s#d{M)ncW(#Y$C*lByLQ z&?+{dR7*gpdT~(1;M(FfF==3z`^eW)=5a9RqvF-)2?S-(G zhS;p(u~_qBum*q}On@$#08}ynd0+spzyVco0%G6;<-i5&016cV5UKzhQ~)fX03|>L z8ej+HzzgVr6_5ZUpa4HW0Ca!=r1%*}Oo;2no&Zz8DfR)L!@r<5 z2viSZpmvo5XqXyAz{Ms7`7kX>fnr1gi4X~7KpznRT0{Xc5Cfz@43PjBMBoH@z_{~( z(Wd}IPJ9hH+%)Fc)0!hrV+(A;76rhtI|YHbEDeERV~Ya>SQg^IvlazFkSK(KG9&{q zkPIR~EeQaaBmwA<20}mBO?)N$(z1@p)5?%}rM| zGF()~Z&Kx@OIDRI$d0T8;JX@vj3^2%pd_+@l9~a4lntZ;AvUIjqIZbuNTR6@hNJoV zk4F;ut)LN4ARuyn2M6F~eg-e#UH%2P;8uPGFW^vq1vj8mdIayFOZo(tphk8C7hpT~ z1Fv8?b_LNR3QD9J+!v=p%}# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/website/ghpcfe/static/fonts/glyphicons-halflings-regular.ttf b/frontend/website/ghpcfe/static/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1413fc609ab6f21774de0cb7e01360095584f65b GIT binary patch literal 45404 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 G`u_lkUM?>H literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/fonts/glyphicons-halflings-regular.woff2 b/frontend/website/ghpcfe/static/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..64539b54c3751a6d9adb44c8e3a45ba5a73b77f0 GIT binary patch literal 18028 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 literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/GCP_logo.png b/frontend/website/ghpcfe/static/img/GCP_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6f8b4ea0c8cbf220483aabf14f8257c615e59fd8 GIT binary patch literal 21838 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 Sat&y}a?RuhwA$!a%zprhLLp`V literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/application.png b/frontend/website/ghpcfe/static/img/application.png new file mode 100644 index 0000000000000000000000000000000000000000..0475eb94f5c16e6a6ba1b43812cf832da57ee2ef GIT binary patch literal 29071 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 ANdN!< literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/checkmark.png b/frontend/website/ghpcfe/static/img/checkmark.png new file mode 100644 index 0000000000000000000000000000000000000000..ad85a91027713d18ea4a3d7b7d22dfe540e38f5f GIT binary patch literal 169 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ΞPyzyGXCNp-4V}^M2ifg8oEnC?AvSf@} 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�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
    _DFz+G8)TW9Ne2dgcxBC;WhT5YVZn-H_Y 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 HD(wFNycyfN literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/credential.png b/frontend/website/ghpcfe/static/img/credential.png new file mode 100644 index 0000000000000000000000000000000000000000..dac22d4d965ea2eefc8a33250c8cc12d36a74688 GIT binary patch literal 66924 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 z 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 G(EkC{WqFqX literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/loading.gif b/frontend/website/ghpcfe/static/img/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..c58609f93c01385bd67592f8320b26cc3f4e223e GIT binary patch literal 79152 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

    {Rawwxdl|BWgKP9V19xL|OdI)ca)Y<~CWtDd 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 literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/main-credential.png b/frontend/website/ghpcfe/static/img/main-credential.png new file mode 100644 index 0000000000000000000000000000000000000000..82e49bc557a5f55519a15cc29cb24b032a530282 GIT binary patch literal 4957 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 literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/placeholder.png b/frontend/website/ghpcfe/static/img/placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..abbe8adb2800e3417d883f00c908a733313c684b GIT binary patch literal 7983 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

    6FME4R4>De z`#qSrF`{x*+_mD++fA5V!jsL}oJ_N`4MKscOG~e_2M(_+wFDpiP`KLC$kGwj(X95c zJNtt8ZItpYbhVZv5z2QK`weqtFIBwHld7rR@OI{4vTc663X1HtQW%ltUpFIUWt2=5!=m&~dk z`!C1opw&kWpSRSLQVj|EyAnH7(;6`mC_+I=obFRSk?rvnz0lLDc{mq3z1sCm!-0l| zxRXem>+WmP-8r7xCn}95+N!xaFS-hL4_SVsmX)mP;HJ?9t*?Nobx8UfY(Yx*IGrX;l9;EQ=R|!~W3j#7$uTkgUu2IjIZ(qr^ zVT^U8Uj~0aWItQ!UEp@xL8;ZDKBeHn($dc>6F=IJF&{TH>~@R4i=6!=_RUG<#A;dC z`HvAc5#vXner?!v{;@GpBEopOQ{dM9M*a7WiK%4`BfUibQSTv5zU|gItA)b0j%q^5 z(E5o-)>AEq&k_Pm*Dmh(tv?TU%68j*r87U#UH87!Xm;{By^y04%Hf(fT#KfRab+w*-oUjCadyUnDY_fS^;a~Q6>Ir9+S-&K6E#qKF{jOJVsLl4bt!MO#r@uU zsHvJD^Oow6r&jOGr?E?*eNr6sU3bQgj1*Va={pT><9bQCY{vy`VDEue+?GIA(^tZ( z(q_|i%tULMcf)3jc+ZCKeQ)ow)i*f*?a9%d`l0E%efnFo<-HbCR`rXU($(fJdI9R^ zd@6iQnLBHSZ1nFzdLNgR(zEii1{^>BIXm9cvVvTIXkHMP-vPfw}U%I z{dA)sK*b4Xe*Aa!vsxbaY#-0g&sPR+`dO?i`ja|ylI-Pb_w6efAM7jmXd%2CZLw-A zE0WOrNPliW!NBlwMDqVMyl!c1AM6%g#IBQ#^aZqSa-~_-dwkNhtKH znAuShN_PdHq+)POGaW_sb+A01h$Q;4`)PR zzfkpHQUtb>ssT$zV7sZO;r?)J4^;`y2*>tOrD0Myc7Q4lONL{IsKRi67$poNOx8Te z6T;8&fP!&~k&!ZX4Du(Hs_{+{E|vm0<~DQ2W9$=@V%sy$y-yTk!L3vt+#f>8!9-Cs z_wjJ}IWEvl3K$vGu|tr*RjDfPFyUgkhdE7@IpaO{4LXNsTWz+$v~Mn(cf1@f^fMe}e3wen}&KZ|bDsLXzEv4jh@dC&>F(m5_a5ykcx zq9Wm$u(2@AK{D|mP+C@a@L}3%20eu$0R@wK)OczH-BOrDvtVv{P>P{+TT}mWt|Jk} zN~@Yl$D~tw_5tw(#RJM$CS!(5K|(fGL<~=auu}$G&`vS~yeV%XjP3d?7e~BUvp7Jd z!q8(r{6%iIFwi|d+(7vffZpK(zo`w)ccnFw7fZPS1AQ-l%{c)ph9W6Yo1Zjage&Sx{BFy#sCvW8K7eE_UMHc>65OeJy)aN9^U(=3tN@B6 z77fH@=J30F;glnxeE9ktOtcVGqAE%xl0j(c8*cVqB!he19Cd`?ZlRk7->V75Bp7hf zdytH}Y~|>^P>IO%zoEU%VIyrn7$~L~iG(DIB#PAZG!6O!td@0TiAX;DVzvSgf=Uu4 zREXE@Sk!*yCUt%!gRE~ryG(Fb(9?o}PKyysNT3L!NN=A$gKmRRi)&;FkkVAPEKd+B zxh26*yl%^)_9}DK0lB&UAGAFL_gvj27^uUTlM*SpCsCxyrXpy7>1Q?Y7(j+LE-lR*;4CuzCI zQKXxOAE0{X@H3nr;(;C$V~b9wR{+>;#04EF z##TWFJpjN7qbAUwVr(&D=-L3T8gaOQ_QnHZ4|7<68czjNf3vTrP{2t&ym6Tbc0|An zqlf_&m-Y7*_!c-;0sJ+~<50FAU7ul%{9wP)zcBK_a+@ z5sNgnd~smj%H>Xh*>4Q)!)!2H41={i1kB*73D~m4RIRfiP#ZT=6UknHN);bU2RHi) zB|60m>>q(YRrP6o#msO*G4kg6T`N9+(a*(x^a?z|h?J!4jq>O0fW~@YsB)sstP|+Hq>OrN22p~4|cG7 zk6%9?-VEBsYJTQ~hh)2l6fJuX3K$TGL#gM~&lGiBINyHZjPTj>pVW(r)YZE#o+(lX p9qG$Ed?FP61JwT~(#4H@|E}-L0(MD6 zK~zY`t(84!6hRcnf4dhsKM)b3O|($FIDSHcL_sV)FbrrR8iXLGu^AB!cA`zJ(pZdk zdQnS3gqsv1cG^UYB2k8bBKSd&i%Kvlf_G<;S=lUm*||F(EbP2_`*!C4|G)PFny_wV znAQ@ZOfPU5I0BpiURy1f#RfEKLYX4)B<32jT9%S=A#QGS3xKM68aV@c4!l0UK zJMoLedW}$Kr@h_ZcH%cFzJdRNaa!V2Nk`B^VuUjFgzG2JZMCelbYh`Q^jb-5tpy6P z{pJ$Kir`&hD-RsDOU2VN#sD8vd?P}cT=esB-+9vv1plf#B`gozTSlHxCJ$@?>M7*T zS}m(WnLc1Ya5PN?&Z$m;Mb9CZ0O zQ7I~^g}|a`k$iR64}6A21jQD2%|`0@X0;p@%8UVLJq}R~g)&$zzW~pHJq?~2_rU?r z%3F++H<=OK=`^f85`T`azS&drRnHTbazc$`wfxZ8cV->13Ha`YW&9a){rDEpm63EF z=nsS{0|9Oju8Ih?S}w*$Qx|a8HL5HtS}mUjE6llvz{!~FH}J=GyPAWg=6n_48F1Zd bxd8AN+yb^+0a6~h00000NkvXXu0mjfjf6Vv literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/status-configured.png b/frontend/website/ghpcfe/static/img/status-configured.png new file mode 100644 index 0000000000000000000000000000000000000000..6649932293a40626c6a4ce258dcfe5bf8b3a0b89 GIT binary patch literal 893 zcmV-@1A_dCP)WFn||&y1k0})?0sVC~$$s%9Mer17#(0c-G3d7I?LT9RDKpB`-Kof90Pj!C=>;y)Wt>#&5D}WoWOw7>+wGt)MY8=;7 z24){%<^dF-*Qsh5nDxLLheHVb1SWDEyeOqZPHH7OZT%F;z!XMIZF>hC0$u>$Qb4~0 zAA#kLcY#)-GtO$Hp>p6+K_vZR%i%3hqLmm+Mw!ybp<}sOD{;mGl|TmA<^%g3Y1*ij z7>gb3{+>afH^rb@i5Rpd0tGnW0~MB2k5*z-2K~pIquS;-I z(CdIb)~h={&=Wm0#s?&n*Z_2-DJf<+C8QRU3~F_BSKD^g2Oa=hwG!PHleR2O!_+`d zO)0qrcnvJIwtNBZd3HS#>g~>Qb_k57T#+8IBqg@ZT8XEgqh`&(>3R52gn-ma^wkB% zIf2y91LzP?s+H)A+jAPQY&B>lb^)*Q05%SM1ukeMih;*T5qeo#q!764=s$oF;2^Lt z3*ZDW4155Fv=Sq;o-$=%?ng6M(uTDXD|1fxfgzJ}r@N=jcpmmB2VVY5o-;WaKK-P~8cxR9qG9 zrXa2a7ybb^DuPu|LX%ceTBB8)W?XoJH`lp$GNB(Ygk(<6ocErud(RC>K^T?+^1un8 z1RMvp0I{kxfLFjRU|J;lon|vgBNT}U!}4`tjC4E&P64q<<4;*KKes)Y@qo{0A%*lcP}IeJNzuIu+)&*a zZ}o;@c?38LG#xrkBNe`M#6}zCJn8&g0B*9*$gu&~Fw&LvCM^JGfPSM0)*9afqqzg$ zwzvvtibPGjPltht_9kD|G)@AyZPFjWu{HGcaZ>fxET#Lvl*7P0aNa|32Y6!1YHg%? zP%i`K0Xz#la}@&w(;m`Eecwd2jZ`=B2Jp>L8Uj9fs@m7%GkWy7NfpZ$X;H)2MJwfN zz#eaSjag^Wcs>Ap?Six}G8WsUBGG&&p60Y~vy#qfjqK`V@3nIpXiH@#Rl8daStXHF zcZ-FLhkO!hz&=a%(N}?UmZv+6fvZ!@0)v+9gOAkit$yI0XHrN)HG$OYY1Q(y&qM0V z>0r0vZF%}W%SocWebACue5Cfo*Xx<=nhsf#r!^nx3+uTE98NI49pclDX>V9J7PJ4~ zmP*(DC)LTl0bDX(I0B3$7~c)tb=-|6fK7&M3RvjrDI{Mjj9c1eU=-Nd#WWFUnCrj; dk?4x8@CPasx5exC_4EJ$002ovPDHLkV1ngTPI&+T literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/status-error.png b/frontend/website/ghpcfe/static/img/status-error.png new file mode 100644 index 0000000000000000000000000000000000000000..c214c4d21156452bcbd5c74f6309a022620b49aa GIT binary patch literal 620 zcmV-y0+aoTP)tHTi%Keh`!+VxHoSZx_IeAa6phY;XkjCP) z8UP*weL&9ti6-y_7!wKbSJW4qSpa^fW;np^EC62&6n+3M1oH2I2Pq1&3iz=I{1?zK zjhzFoRpj4DV-HJX8^GNp0VVhd@I0_S2YRKkUjU@BSAmPAyp_ftaat97jsue+0ipyy z58RIk{si;@ximH})i!`3;Iz+`+j_{iq@z-RUvvssO1wDlfdSyBhf@Gcf{O1^;AQLt zhJod6-rf~y?16}dhkzHcjfB(cGqAS}3#|hOMYFlt{pi_N5hsAhsV>;rriZ@*&8=`B zy{VgIz(gDH*V5R2;75xV%m9~?1W04&fh*g9TWRc|(+ZL2mHqb?odHIp0({X8;AR4R zNg8{+0Cg`sEx@Brt5sl^(@Fq*`?qEhI0^g?oj{>{DnZ1c(`rvqg6#K&R8H z{A_jtJ6gJ+qK6Z}?SP04pi3J2$7wYN%vZQ$zaLcRVsCZoiuV0000CaAH|kU={ue;}3~779rrsT3>}RFwP&Azi>A ziV8N`_$MfH#zGLHbBP8_p$2~-%AG|fXOY=svu3k<=f(XtH_P0-_nkLyzVlwdI&elI zwGGERff8^WIPAyUfd=pum<65zPk}k9?I(bxilS@CCi)0Sfir3sFacMZPKdD zyAY2?5I=8c)E;0O*h**NfTGlPK1w1M0i^)50nS5w0}cW6e-Us-^#CtB81^L0NNx8u zlQ5DPSO0@^fW6MB+f4%g+;;=lQx<*)dZo4jaA%GA$9}F4_?%*^?2HO7bjN%fa7MuGC$jJAv4E8RC5h%4NGHoepg36YK z*Y><{PWXoH;kN*)ITEM~;CYS&riHKJ^1?mgi^;_d ze{N)%TV8ox8(Hj0Z665#c)ZB4AbMT9PwtVgd=j%CI0(!HOQxSL{T64`4PY#VM9nWw60a{l8e3BAOi67=q7ew+ z=nAlZgA;E~YFk{@7f5Z9+SY&*!14w;Zukfui}na2R+cXSMPI#kTy%gVQrmaordJX0 zwINd5_dbE%bTaI~0jce)cy|;ewPv2s6mTYNt=iFg;GxuZ_+OgS0bm5U*rM}sU{Y#3 z6YsR!uH~FjW#Bw8=9Ar9xINBCs}<7D8>#i|5N3XLQEzX6C(n-#tI>Ip1?mf(%g3 z;I$3^mjRW)L0}h91uU1XUx6XuIdBgc_S$}qpD_~>%mU@i8lVHH2Ud|Cz5p+QHm~hS zCMANItd`$W<;+Fk6L2I4;Q%Xv!@#g|<^oU>Jv*%j>Yd?*wkT&Rfm=Wg`N3=8kk@uB z?u|tJzLhiOKrgV2{9+2I@Y;?>l}Nh*{p90F6Qn9>-!s3nBcH_Sw zj0DE{1rQEUtDNba76ZzewZO*$2>S&jfkm}f;XQQeCa^WbH`~K2NXJ~~ghsCbt1}#Q9XJu;`yweub+ag4k_1+y zS?uxJw#%VAfx8mbaa{G-Zcg*9SKuIgD_IB-1Nr<^GU`hfk} z-diC2JQFIEGwmT~du=Cyy}*50@Ald@du^veYk)hzh8*H%GLTLt9nL6co6QT#Nok`RGHlwdoOu8=0^h~rhtWWi_^6sg=JY0%GY!DgEH-}tHUrj-KGE-mL6_4tP^jom*=IxgLw%5745$}bGT40Z&TCseZ7%TI;bRdtyhk!b-?Ld4wN~9ajM4?Wg zNqV@sMtjO@dul$zX{|JnXLBJL$@9xz+rdmzav~RVlrxP$3$R17rZ{5hgbX$*ukE#L bMst9_z?Bm!2<+l<00000NkvXXu0mjfX3mSC literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/unknown_user.png b/frontend/website/ghpcfe/static/img/unknown_user.png new file mode 100644 index 0000000000000000000000000000000000000000..e086457b6de518615da24d79d97d92af3d856863 GIT binary patch literal 1611 zcmV-R2DJH!P)_{r30y>FVs^;^f`l;Mm#Q(9zS%%gw^W#lXSCy}rP@yS=x#y0x~rv$VGL_4ViH z=iJ=f&(F`o!os_|yS%->w6(Xfvb6mC{O|AY-QC^N($c`dz`eb{wY9gjw6?RewX(9b zva_|<*Vn;z>+Rs+;Qs#q^!4}b?C!(E#r^&Nz_xIl3-oC%V z#l^+w=;*k(xUsdkzP`Th?(VX(vfA3($H&L<^7Q8C>8!1FeL%;_mP9?CtNv#KzLo)z#M6@bUA?%F3~^ zvCq)b+1c6U=IGhl-1+(W(b3WO`1;7n%gfBpxw^dT>+QFseD{QmvG!olqB?Y6kL>gwv%)z$Fu@XXE6!^6Y#^Yi89<*~7|&d$!q z$jZFDyz}(-U3vg?;cxw!K4_0-hV`1ttj?CkdT_WJw%`~3d$^78BJ>*?v~ z@$vEK?Cg(_L`1G}Hn|NsB| z$NX;q0004WQchC}ho4=PN`X>y^Jm=u2|I!D^g@P89l3-1f?DF`p1!I33>9Svobzsg zgl7s>1VOIyuB~$os>L*P04yM28-N5*Q950K7geWiD2(%mQuQz`AClxTLGh+2M)f_4 z%O#}f10d6}5E5Vq{%hP`tue;tD+>K>+*tJe6aQ6G?Fmyl08xt4D*q|Wdr^3A$npv5Qvg^&7Kt0WXpZjL~(;x(9^<{H#^FKo7SAdC`w^Gt6#HfGnC;QZq|0|CihyvK) zTvXjNSq>`N_9VzbD+lj` z9lT>a>^SidbO7*yeF^}e=$}S)jxB~E>a#bw z5yp{_e|_oV08;5W<3Fe*WP7HjPGxEAm>j-jrH{=hGnBYb9%wOw0eZ@iR0G#fY|a%j z+7F6tuWli&065g=z-(k%%tE~>-CCJwW39+D$VDr_^V7A}cy$7>IvcMBrRlKI3#pF} z((rgbkkdn0boskMV|_Rsd#5w2+^BxgC`=C%gUP&v_h%!@Bm{``Lfp^#Ql_Td_V^Vy&rPlicSgD_RLw|Z{IO+{xEy{4%{%lTQ+tj%K zMf7zSIV0~*AIn~8EX1$qm8I&FB!DP96U;euCROPk5Tnn#kHgb?+tt{sH;N)?{+~I3@r9002ov JPDHLkV1mdD%?l88ajBA|soAdO(5!PeT|#y`Nq!iZRj zKT5H&5bQ+MLM_Bf6qUqS1b@f7Jd2x%guU6>nO!%Rn+FHS&YSPLswxSWr5#ql852v)C;V!GF+kh` ztw6w}Sj0qv%bI{Li(RMy9dQdp0$Rfjj;m@t!`!_Yi9V{Tvl-^d|0dw3Cx$qTcL7%m zT%{j@*Nd)o0Nc#}SIuxbfjfa)=&>z60`4a~To(CcaGDufMC4q;^7$xF=af$>*1XUdZ?gHOEGQpD~^2FvM zRdpP=Xo@6RWHm4>A|F!lF9Bl-k>CPJFPmkh3!!iiu*vfS^*ZSE0Xy-+!1Y-QWfE}DSa-4P&yc#{3kRK!G6|S6 z?$bs0#1}gK+Se~!vrF=0Q}z~ zGM9qy-Aa#cFcJ_6h=C9^4l#XRlnpAdmd4?uX`_>rsQh%e&o|@Fe6m3o13Ck|D#FRC<( ziR*x8z-*H^;+%*)PkDhOz2M^VL;|#xw@)4=vBRpm*+OO=*dKsDuBtOB`G{{@@2?vi0Uj;E z6{-|`UNDap@W9jyY-RDSz_8~Ba_L%+(rA!+M_ME5FT)P_rvmT?9Pn@Zg6ClbT>_OA o0r))*I^Lb3=msMJk%0D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 literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/white-cluster.png b/frontend/website/ghpcfe/static/img/white-cluster.png new file mode 100644 index 0000000000000000000000000000000000000000..a257a91edc0a14ad6e8672c22a78e672dcfd2fb4 GIT binary patch literal 1603 zcmV-J2E6%+P)Rv#R+!n^BJBoy*-{e$I1L9T0NcENIWR7vai>Yz z0ZcWsUnF6c*LSIw0$2|m3J72;umCt$=9r^^x$fm#B{i5?XBwBGiunLZS4nDfJ71mW z_pSch{IK5`m$!mGpjf?J;hNb#Nz+}c#!G56v%eztfuvr*B%p5yb1|UJ%(h8t0wx2e zYNlb5u8?$0(h*6`VKg8+dy<+ZtyOed>F-bU`th0oA)h_DKgmRVuhGF##%I05!H}r8B=1xW~*|Vwm6-pfR;jxCHi}1e^h806)ahz940Km;f4q zevbctO`^k|CV)%5JPULtu{!lM0VGZr1#nRS7X{EWDK~(M8ynQ;!`Ml~-X!{zWPvnJ4)wAJutZ0>noKkJuWGeC&X@+^rv5if}y37K8!KuiykS4GJ!XNCSYG6 z5pp1bM9Vavu~&crX0|wnCOif7jxqis;BHByBLSugBtD)A%t})P4QNS7`@XCMUt#0@ z?0u_$%&QRua44{ zYn?!^3eC$cX14hPAK)r?TGCk0xxM9y%EJY&-z2S(bbCGz>khC9*b$L=D#$#*9fj8G z{{Er80!fDfMLHVj>-!8zOU-OaAWfYup9BV_EPNP|*906a^ag%5vs3PnihcY5-~r%4 zuTLku1jJ5z^a7=_oQ(4KdCenmZUzCh5NV@i4;FpjO=!rDi%v%4?0@x3XsgIJ-%<}7KZ)}A>u#NL)0HbEQ2ZunS zR~CZD`2;b4cZVIlmnqm4?xM$g)a%}DDPl4K%boYAHWB| z(`I%?66U+EpVNJEvKllK*j*qHGhl~rs6OFs6~lBEn%P&9hS0soAYiYVwdbbq>ghgi zHo1y3yc`&5W(Pxf^0=qd2e}sQ39j`)WScEBT)53#Y3dhp%yLept3)>IKe%~B4eWe+ zSYHs6GEwYh7w1o2RExr7jaq;;F?~SztdyjgHGsP_N=2awBx}N!_l1Di=i zK~!ko?V3x76-N|?zyHqoh>jB_*(5|%5RAmvN`wqCSx6QlA}&l8;!Y6U_<*<&gk<9; zxDtFVLV^$iL%=*1Ch9_62!c4mL^mw}JoCJVSPsT&vo-cUZ0Hza8`aJ1D>1&l<}iG6rK+?4WtnG84r^u09SPU≫<+Ss!g0cMWoT41%LKU-A32HX$0#DrQ6{t9e~Qi0HlS%PbBrXu+1f4KJWoB7kDRNU<1H) zNq1Y^HhVA@p)wHw<>0z$yTUo@IthGH77sX-cZHWFFQe=q3mTAQ0X>q=mdVg;cTqoc zD8&M<7O@-K=6=DWGO6$|6_L(>i%0JVER*zCnN|?Y9cGkIuVwom>W7$N8KQp7RO&PU zygL>aa5@Hns@xd)Ted$1&QMKRQVYV}&lObun50X!fT?{A{8%C74@g=Yz9|~M#PBV! zg8B`Q#-5#0p2}Dz?VfLzGHG{$lgc#G5O9O~O_i;ZZZ~v(34dzEcAXvH=>Px#07*qo IM6N<$f|`TN@Bjb+ literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/white-filesystem.png b/frontend/website/ghpcfe/static/img/white-filesystem.png new file mode 100644 index 0000000000000000000000000000000000000000..2d6130904d75c93a9691e51d10da354e7552a5a2 GIT binary patch literal 1389 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yu_bxCyDx`7I;J! zGca%qgD@k*tT_@uLG}_)Usv|0>@p%8rpvzvDl#yz{PJ{h45_&F_U`SnI|@7w7au(R z|NrSr@37h1W}f`PJeRqaQ?N;(S)=06 zGVW{Bm(y| z|0-}asPCBEw|vKKIgbh2%^xq{uksOF$s%cMT>HIxiKB+&qNT6bUw0Ps5mY%XHBF~t zmreMcrz@l1)onhV<@#f$-L1}#yL63C-O70qQ9do!^WWy&+$Ifwhp#o2aaRrZ+|t)w zCG+3xO-4b_u60^X3!Hh2+y(k-95-1XmQXt}HDR{tZP}Av>u=?5Q#g!V$jYeBGX@B3$1tH0|NK7B|XIo)sAVWow$~0UaGb?_hVZk z<`ST6Ww(G?fQ3WF>VKk*T$PPX>qxb#}&{fYMMj`nwwDz7x}l^X@0-~ZasQD(20 zu)_w`Fq6nRKb>w!J?Z1WDZq4E}Q z+Q3tEoUdbZ#D*hUVrSB_nt0ACt-Q9l`&40S&*txu-4{BKbc8p5kvQM8DM#Bp?wW-4 z&D1$A+jlpw^m4HLwl8n)&D74&)MFhwM>|xntuQ=o^s{33@AkQxK0+#+be7DR&uiS% z_}sA}qlqIa<)qT?#6xFP^S|UDuGnpDDR;|5Ku7EN)ons8G7208c|jP(!HTZKU9JV` zF>K(X16(4Q%wzWNkX_BqSpVhr%w0VxEE|t7T|s0v0dScDD{DFrcX4mN)p*oc{?bH8 v21%CH=@U24PgLgc>VEWi1ETN(vJB?OFW6+;np{;C0}}Ui^>bP0l+XkKCnG$l literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/white-hamburger.png b/frontend/website/ghpcfe/static/img/white-hamburger.png new file mode 100644 index 0000000000000000000000000000000000000000..eefcf57110189fc40ab408663066554052851ca0 GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBU!3HExMD@7?DYhhUcNd2LAh=-f^2tCE&H|6f zVg?3oVGw3ym^DWND9B#o>Fdh=l$}*XK*r18lMyI1-_yl0B;(%OTL(Fr3>jE2p48IQ zc;UIltbbaTXxReU9qc#XAJzNEv!uah(gX*$N$ds7Hm9moGF}gAIM32@&nR#n0~3dW zgYAJBoBx$6mSXE$64I{S@hD>FTdMx3T&0qE`X$y4J_n-qFo&%_1XS6;@Rnirqo4Wi zlcYE3v;O!cVPKq{r&1a8$3B63&cDSQ=gOz< MUHx3vIVCg!0A1o+jQ{`u literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/white-home.png b/frontend/website/ghpcfe/static/img/white-home.png new file mode 100644 index 0000000000000000000000000000000000000000..2eed653625d3d4583df0fe925e756aa969a924b6 GIT binary patch literal 765 zcmV)-F zrM!ieQofV2uz5WT68Zkw+Dmp0C*y0N;F3KMvCyfW+ZlVN8e`$9J6n!!)?Kq1Ct?jnz<-)t@yI<^w3y8WQ7 zfjaEe@km|WRtdS_=l>Pfm=PTFO>h12Boy%o)MpM`4T*;T!({?_$ z)FuCVJ4C(UBcgJA6WCIaP5cQk5E0MvF*GEg@SbULy~*oPzXH>GRKS-~w&nFAzkuOTmjb7Ng|*fKU^cM2U;#b_MzTOBdIWd_ zoT*HKGBB&gAN>H<0{03g;9NxPt9MdgwkLlF-v4DY{8+#eFRA4$w%RArHTpxfA2?j}TOcO!WZBp2Js^5rK$-$cKoXDyBmqf4 v5|9KW0ZBj-kOU+FNk9^i1SA1TK$H0mTk&DxDxtdb00000NkvXXu0mjf6t`T( literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/white-job.png b/frontend/website/ghpcfe/static/img/white-job.png new file mode 100644 index 0000000000000000000000000000000000000000..c1b6fe9275e9793c8214b5566de044502355e63d GIT binary patch literal 688 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%0Di3$i&8Io0Myn# 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 literal 0 HcmV?d00001 diff --git a/frontend/website/ghpcfe/static/img/white-servers.png b/frontend/website/ghpcfe/static/img/white-servers.png new file mode 100644 index 0000000000000000000000000000000000000000..13003d6c809c37d4683d1312b9c953debf53b066 GIT binary patch literal 17346 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≫ki3a!h`3U}S>nr?^}g~}(6AMu{t{KD=_ zK2!I3qa&uNk#g+|t`mH?;Ys&trKaGvE;WlJi|@zO*EOmp5*kO84~|`DU^`1gbKt~0 zc&>^W>P*qe#hBDG=rBt(y)?C*!dQC&19Tf3D?)6Noquk$579yx8usRarJYONsnWC# zbG;dD!3R(WnrK~%c}**1(Fz$XIk~ptdJ89Uv=2~Ri4&sBr-X*7vy_;6Wq)`0;52if zm#}~tS z#0=tnR_)tD!uyg-dMwF)lL4ITOPw#MX}8Z4A|Fzj%LIE`7D5F3g9EiP5lJz^68z;x zYG9~qbK;URl8B{eaF}4UrO9JHuHcM&80C#}hSQ7qwB((;=7uRsDX8wr-YcTfR~h=O zL0gKrk#?^BMhz)6R5mFsooR{n!uB*ix7y5pQJohHSLfJfOB3*Q&-DjO?f|+na*s?N zmEic{2}SxL#mfsktG&zC@kh$DG{LWc?Bj3ONLp(g0rXPJw!aS^5d0#X77-;kc&y+} z)FG&R6+UkQK{DI#KEC#XLOw!;)-@c*)t5E{Z!PJ3r~z!sk&VJe^`|p5VaHq{m7xy^ zt!jn0YnEu2>wRb^K1E6#R&xlccAPFJ77tzU4Zxl$Uy0NR#nLR6Qi z(r7tymjFYmXw?Nz@OI5>+&0Kf$#7&fLCm?x$SNb24rU*6m9{P#2hF1nAK$*o*dFRI z!FIAzvE-Xg6Uq5iFFrbcfouk@O-}%AAY)~ZYs~|XQfm_Qek%HHELsMoDIrkX;s8tN zBZMK^XQmt;YmEmU4{3iuVfjG41uViXUK`Rj0DuB{_`d-1(h<3b1QF^+tW26nmGxFg3b6vvmIm98WG`sa80nJl#j zPMbPf@W95JmEjk1+E(XhEzF-{EK&~JJL*ePLfL=n`xzgyIE*u4fh2wD*O&PFlGK#x1<+4y? z48JzNbFAYbdww6ZYvmhMv$bI;EyyKVW$AKT`Jdd*kY~8!6UX*Un{vz9V z3@^uQ`yymN2m|pWy=wcj_EaXJP0a13Raj!A;8_ z)OqvNLza~WJxv)MT zo9pC>I-Rux)Oy32_mSZ;gF@QR7S3BP?Vp4sNclFM`@H2OVX0-dj>1bj?>Zv)30YV&H$< O0OX{Upk)$q)QP9U3yV^Cm_8jNRwWq_f7~B5NQD$1;eBh-%=!a%b4D(wT^eK}1(W z)il)Zpn$v?^vV)?iMR5o$oaG!r{(IJlUOc+B2TTTkP({|OBH)Edg8PZjdo$qCzvJ2hxKFo>s7KrD@(baKSk7k@tYmoPr>V2P>OAT4A8Qt z4T%eg#sdr{#>6W|E_h%hFc40zOq97OwzcnBQM*U=*jD1&R_qip)0WaObHuR~;lNh( zLx6!iab+CT_T-wP>u}oEmo({4Sq*Tq-5}`*zr7rmza9Z1J-P2>osIw1l~Z9!e|%-wbJ?0@#B;1KMUir2+a56wD{O@QYL^(HTP#)-9>()~Rj zbsp8~4)HsH#XfGcIRScBn=fgBkQW)wVu+*R0w;*QX7sBRBnB`=RSFE&vjQAze(z>k7n=+K%0q{oK&CU?nwc0@X7t z@hWP>NFVi{dOC+ogj5bT7n+0~tO4hE92S>~XQX0t;TUk;3oGJt#{nbBI%RB{_%q(R zEy6pkuWs8eaC->XscrFSSMj60X7B<$dytu(yuzF{S^o5;hlYT+iU@|o0V|6(!e+8KvsG~(xY2`A36s6C=zcvpY1+=lI$c0RLA}4B{;+?w1YF!r z09!u)jgE{E3By;3qtTv6yO&*RmAVx)Sujw2uTXWvTaPnzuvH!dq9!f3_O0nx{e`#a z`J?wvQe+@P3=hzzL(E<

    ', + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + selector: false, + placement: 'top', + offset: 0, + container: false, + fallbackPlacement: 'flip', + boundary: 'scrollParent', + sanitize: true, + sanitizeFn: null, + allowList: DefaultAllowlist, + popperConfig: null + }; + var Event$1 = { + HIDE: "hide" + EVENT_KEY$6, + HIDDEN: "hidden" + EVENT_KEY$6, + SHOW: "show" + EVENT_KEY$6, + SHOWN: "shown" + EVENT_KEY$6, + INSERTED: "inserted" + EVENT_KEY$6, + CLICK: "click" + EVENT_KEY$6, + FOCUSIN: "focusin" + EVENT_KEY$6, + FOCUSOUT: "focusout" + EVENT_KEY$6, + MOUSEENTER: "mouseenter" + EVENT_KEY$6, + MOUSELEAVE: "mouseleave" + EVENT_KEY$6 + }; + var CLASS_NAME_FADE$1 = 'fade'; + var CLASS_NAME_MODAL = 'modal'; + var CLASS_NAME_SHOW$3 = 'show'; + var HOVER_STATE_SHOW = 'show'; + var HOVER_STATE_OUT = 'out'; + var SELECTOR_TOOLTIP_INNER = '.tooltip-inner'; + var TRIGGER_HOVER = 'hover'; + var TRIGGER_FOCUS = 'focus'; + var TRIGGER_CLICK = 'click'; + var TRIGGER_MANUAL = 'manual'; + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Tooltip = /*#__PURE__*/function () { + function Tooltip(element, config) { + if (typeof Popper === 'undefined') { + throw new TypeError('Bootstrap\'s tooltips require Popper.js (https://popper.js.org)'); + } // private + + + this._isEnabled = true; + this._timeout = 0; + this._hoverState = ''; + this._activeTrigger = {}; + this._popper = null; // Protected + + this.element = element; + this.config = this._getConfig(config); + this.tip = null; + + this._setListeners(); + + Data.setData(element, this.constructor.DATA_KEY, this); + } // Getters + + + var _proto = Tooltip.prototype; + + // Public + _proto.enable = function enable() { + this._isEnabled = true; + }; + + _proto.disable = function disable() { + this._isEnabled = false; + }; + + _proto.toggleEnabled = function toggleEnabled() { + this._isEnabled = !this._isEnabled; + }; + + _proto.toggle = function toggle(event) { + if (!this._isEnabled) { + return; + } + + if (event) { + var dataKey = this.constructor.DATA_KEY; + var context = Data.getData(event.delegateTarget, dataKey); + + if (!context) { + context = new this.constructor(event.delegateTarget, this._getDelegateConfig()); + Data.setData(event.delegateTarget, dataKey, context); + } + + context._activeTrigger.click = !context._activeTrigger.click; + + if (context._isWithActiveTrigger()) { + context._enter(null, context); + } else { + context._leave(null, context); + } + } else { + if (this.getTipElement().classList.contains(CLASS_NAME_SHOW$3)) { + this._leave(null, this); + + return; + } + + this._enter(null, this); + } + }; + + _proto.dispose = function dispose() { + clearTimeout(this._timeout); + Data.removeData(this.element, this.constructor.DATA_KEY); + EventHandler.off(this.element, this.constructor.EVENT_KEY); + EventHandler.off(this.element.closest("." + CLASS_NAME_MODAL), 'hide.bs.modal', this._hideModalHandler); + + if (this.tip) { + this.tip.parentNode.removeChild(this.tip); + } + + this._isEnabled = null; + this._timeout = null; + this._hoverState = null; + this._activeTrigger = null; + + if (this._popper) { + this._popper.destroy(); + } + + this._popper = null; + this.element = null; + this.config = null; + this.tip = null; + }; + + _proto.show = function show() { + var _this = this; + + if (this.element.style.display === 'none') { + throw new Error('Please use show on visible elements'); + } + + if (this.isWithContent() && this._isEnabled) { + var showEvent = EventHandler.trigger(this.element, this.constructor.Event.SHOW); + var shadowRoot = findShadowRoot(this.element); + var isInTheDom = shadowRoot === null ? this.element.ownerDocument.documentElement.contains(this.element) : shadowRoot.contains(this.element); + + if (showEvent.defaultPrevented || !isInTheDom) { + return; + } + + var tip = this.getTipElement(); + var tipId = getUID(this.constructor.NAME); + tip.setAttribute('id', tipId); + this.element.setAttribute('aria-describedby', tipId); + this.setContent(); + + if (this.config.animation) { + tip.classList.add(CLASS_NAME_FADE$1); + } + + var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement; + + var attachment = this._getAttachment(placement); + + this._addAttachmentClass(attachment); + + var container = this._getContainer(); + + Data.setData(tip, this.constructor.DATA_KEY, this); + + if (!this.element.ownerDocument.documentElement.contains(this.tip)) { + container.appendChild(tip); + } + + EventHandler.trigger(this.element, this.constructor.Event.INSERTED); + this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment)); + tip.classList.add(CLASS_NAME_SHOW$3); // If this is a touch-enabled device we add extra + // empty mouseover listeners to the body's immediate children; + // only needed because of broken event delegation on iOS + // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html + + if ('ontouchstart' in document.documentElement) { + var _ref; + + (_ref = []).concat.apply(_ref, document.body.children).forEach(function (element) { + EventHandler.on(element, 'mouseover', noop()); + }); + } + + var complete = function complete() { + if (_this.config.animation) { + _this._fixTransition(); + } + + var prevHoverState = _this._hoverState; + _this._hoverState = null; + EventHandler.trigger(_this.element, _this.constructor.Event.SHOWN); + + if (prevHoverState === HOVER_STATE_OUT) { + _this._leave(null, _this); + } + }; + + if (this.tip.classList.contains(CLASS_NAME_FADE$1)) { + var transitionDuration = getTransitionDurationFromElement(this.tip); + EventHandler.one(this.tip, TRANSITION_END, complete); + emulateTransitionEnd(this.tip, transitionDuration); + } else { + complete(); + } + } + }; + + _proto.hide = function hide() { + var _this2 = this; + + if (!this._popper) { + return; + } + + var tip = this.getTipElement(); + + var complete = function complete() { + if (_this2._hoverState !== HOVER_STATE_SHOW && tip.parentNode) { + tip.parentNode.removeChild(tip); + } + + _this2._cleanTipClass(); + + _this2.element.removeAttribute('aria-describedby'); + + EventHandler.trigger(_this2.element, _this2.constructor.Event.HIDDEN); + + _this2._popper.destroy(); + }; + + var hideEvent = EventHandler.trigger(this.element, this.constructor.Event.HIDE); + + if (hideEvent.defaultPrevented) { + return; + } + + tip.classList.remove(CLASS_NAME_SHOW$3); // If this is a touch-enabled device we remove the extra + // empty mouseover listeners we added for iOS support + + if ('ontouchstart' in document.documentElement) { + var _ref2; + + (_ref2 = []).concat.apply(_ref2, document.body.children).forEach(function (element) { + return EventHandler.off(element, 'mouseover', noop); + }); + } + + this._activeTrigger[TRIGGER_CLICK] = false; + this._activeTrigger[TRIGGER_FOCUS] = false; + this._activeTrigger[TRIGGER_HOVER] = false; + + if (this.tip.classList.contains(CLASS_NAME_FADE$1)) { + var transitionDuration = getTransitionDurationFromElement(tip); + EventHandler.one(tip, TRANSITION_END, complete); + emulateTransitionEnd(tip, transitionDuration); + } else { + complete(); + } + + this._hoverState = ''; + }; + + _proto.update = function update() { + if (this._popper !== null) { + this._popper.scheduleUpdate(); + } + } // Protected + ; + + _proto.isWithContent = function isWithContent() { + return Boolean(this.getTitle()); + }; + + _proto.getTipElement = function getTipElement() { + if (this.tip) { + return this.tip; + } + + var element = document.createElement('div'); + element.innerHTML = this.config.template; + this.tip = element.children[0]; + return this.tip; + }; + + _proto.setContent = function setContent() { + var tip = this.getTipElement(); + this.setElementContent(SelectorEngine.findOne(SELECTOR_TOOLTIP_INNER, tip), this.getTitle()); + tip.classList.remove(CLASS_NAME_FADE$1, CLASS_NAME_SHOW$3); + }; + + _proto.setElementContent = function setElementContent(element, content) { + if (element === null) { + return; + } + + if (typeof content === 'object' && isElement(content)) { + if (content.jquery) { + content = content[0]; + } // content is a DOM node or a jQuery + + + if (this.config.html) { + if (content.parentNode !== element) { + element.innerHTML = ''; + element.appendChild(content); + } + } else { + element.textContent = content.textContent; + } + + return; + } + + if (this.config.html) { + if (this.config.sanitize) { + content = sanitizeHtml(content, this.config.allowList, this.config.sanitizeFn); + } + + element.innerHTML = content; + } else { + element.textContent = content; + } + }; + + _proto.getTitle = function getTitle() { + var title = this.element.getAttribute('data-original-title'); + + if (!title) { + title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title; + } + + return title; + } // Private + ; + + _proto._getPopperConfig = function _getPopperConfig(attachment) { + var _this3 = this; + + var defaultBsConfig = { + placement: attachment, + modifiers: { + offset: this._getOffset(), + flip: { + behavior: this.config.fallbackPlacement + }, + arrow: { + element: "." + this.constructor.NAME + "-arrow" + }, + preventOverflow: { + boundariesElement: this.config.boundary + } + }, + onCreate: function onCreate(data) { + if (data.originalPlacement !== data.placement) { + _this3._handlePopperPlacementChange(data); + } + }, + onUpdate: function onUpdate(data) { + return _this3._handlePopperPlacementChange(data); + } + }; + return _extends({}, defaultBsConfig, this.config.popperConfig); + }; + + _proto._addAttachmentClass = function _addAttachmentClass(attachment) { + this.getTipElement().classList.add(CLASS_PREFIX + "-" + attachment); + }; + + _proto._getOffset = function _getOffset() { + var _this4 = this; + + var offset = {}; + + if (typeof this.config.offset === 'function') { + offset.fn = function (data) { + data.offsets = _extends({}, data.offsets, _this4.config.offset(data.offsets, _this4.element) || {}); + return data; + }; + } else { + offset.offset = this.config.offset; + } + + return offset; + }; + + _proto._getContainer = function _getContainer() { + if (this.config.container === false) { + return document.body; + } + + if (isElement(this.config.container)) { + return this.config.container; + } + + return SelectorEngine.findOne(this.config.container); + }; + + _proto._getAttachment = function _getAttachment(placement) { + return AttachmentMap[placement.toUpperCase()]; + }; + + _proto._setListeners = function _setListeners() { + var _this5 = this; + + var triggers = this.config.trigger.split(' '); + triggers.forEach(function (trigger) { + if (trigger === 'click') { + EventHandler.on(_this5.element, _this5.constructor.Event.CLICK, _this5.config.selector, function (event) { + return _this5.toggle(event); + }); + } else if (trigger !== TRIGGER_MANUAL) { + var eventIn = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN; + var eventOut = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT; + EventHandler.on(_this5.element, eventIn, _this5.config.selector, function (event) { + return _this5._enter(event); + }); + EventHandler.on(_this5.element, eventOut, _this5.config.selector, function (event) { + return _this5._leave(event); + }); + } + }); + + this._hideModalHandler = function () { + if (_this5.element) { + _this5.hide(); + } + }; + + EventHandler.on(this.element.closest("." + CLASS_NAME_MODAL), 'hide.bs.modal', this._hideModalHandler); + + if (this.config.selector) { + this.config = _extends({}, this.config, { + trigger: 'manual', + selector: '' + }); + } else { + this._fixTitle(); + } + }; + + _proto._fixTitle = function _fixTitle() { + var titleType = typeof this.element.getAttribute('data-original-title'); + + if (this.element.getAttribute('title') || titleType !== 'string') { + this.element.setAttribute('data-original-title', this.element.getAttribute('title') || ''); + this.element.setAttribute('title', ''); + } + }; + + _proto._enter = function _enter(event, context) { + var dataKey = this.constructor.DATA_KEY; + context = context || Data.getData(event.delegateTarget, dataKey); + + if (!context) { + context = new this.constructor(event.delegateTarget, this._getDelegateConfig()); + Data.setData(event.delegateTarget, dataKey, context); + } + + if (event) { + context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true; + } + + if (context.getTipElement().classList.contains(CLASS_NAME_SHOW$3) || context._hoverState === HOVER_STATE_SHOW) { + context._hoverState = HOVER_STATE_SHOW; + return; + } + + clearTimeout(context._timeout); + context._hoverState = HOVER_STATE_SHOW; + + if (!context.config.delay || !context.config.delay.show) { + context.show(); + return; + } + + context._timeout = setTimeout(function () { + if (context._hoverState === HOVER_STATE_SHOW) { + context.show(); + } + }, context.config.delay.show); + }; + + _proto._leave = function _leave(event, context) { + var dataKey = this.constructor.DATA_KEY; + context = context || Data.getData(event.delegateTarget, dataKey); + + if (!context) { + context = new this.constructor(event.delegateTarget, this._getDelegateConfig()); + Data.setData(event.delegateTarget, dataKey, context); + } + + if (event) { + context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = false; + } + + if (context._isWithActiveTrigger()) { + return; + } + + clearTimeout(context._timeout); + context._hoverState = HOVER_STATE_OUT; + + if (!context.config.delay || !context.config.delay.hide) { + context.hide(); + return; + } + + context._timeout = setTimeout(function () { + if (context._hoverState === HOVER_STATE_OUT) { + context.hide(); + } + }, context.config.delay.hide); + }; + + _proto._isWithActiveTrigger = function _isWithActiveTrigger() { + for (var trigger in this._activeTrigger) { + if (this._activeTrigger[trigger]) { + return true; + } + } + + return false; + }; + + _proto._getConfig = function _getConfig(config) { + var dataAttributes = Manipulator.getDataAttributes(this.element); + Object.keys(dataAttributes).forEach(function (dataAttr) { + if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) { + delete dataAttributes[dataAttr]; + } + }); + + if (config && typeof config.container === 'object' && config.container.jquery) { + config.container = config.container[0]; + } + + config = _extends({}, this.constructor.Default, dataAttributes, typeof config === 'object' && config ? config : {}); + + if (typeof config.delay === 'number') { + config.delay = { + show: config.delay, + hide: config.delay + }; + } + + if (typeof config.title === 'number') { + config.title = config.title.toString(); + } + + if (typeof config.content === 'number') { + config.content = config.content.toString(); + } + + typeCheckConfig(NAME$6, config, this.constructor.DefaultType); + + if (config.sanitize) { + config.template = sanitizeHtml(config.template, config.allowList, config.sanitizeFn); + } + + return config; + }; + + _proto._getDelegateConfig = function _getDelegateConfig() { + var config = {}; + + if (this.config) { + for (var key in this.config) { + if (this.constructor.Default[key] !== this.config[key]) { + config[key] = this.config[key]; + } + } + } + + return config; + }; + + _proto._cleanTipClass = function _cleanTipClass() { + var tip = this.getTipElement(); + var tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX); + + if (tabClass !== null && tabClass.length > 0) { + tabClass.map(function (token) { + return token.trim(); + }).forEach(function (tClass) { + return tip.classList.remove(tClass); + }); + } + }; + + _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) { + this.tip = popperData.instance.popper; + + this._cleanTipClass(); + + this._addAttachmentClass(this._getAttachment(popperData.placement)); + }; + + _proto._fixTransition = function _fixTransition() { + var tip = this.getTipElement(); + var initConfigAnimation = this.config.animation; + + if (tip.getAttribute('x-placement') !== null) { + return; + } + + tip.classList.remove(CLASS_NAME_FADE$1); + this.config.animation = false; + this.hide(); + this.show(); + this.config.animation = initConfigAnimation; + } // Static + ; + + Tooltip.jQueryInterface = function jQueryInterface(config) { + return this.each(function () { + var data = Data.getData(this, DATA_KEY$6); + + var _config = typeof config === 'object' && config; + + if (!data && /dispose|hide/.test(config)) { + return; + } + + if (!data) { + data = new Tooltip(this, _config); + } + + if (typeof config === 'string') { + if (typeof data[config] === 'undefined') { + throw new TypeError("No method named \"" + config + "\""); + } + + data[config](); + } + }); + }; + + Tooltip.getInstance = function getInstance(element) { + return Data.getData(element, DATA_KEY$6); + }; + + _createClass(Tooltip, null, [{ + key: "VERSION", + get: function get() { + return VERSION$6; + } + }, { + key: "Default", + get: function get() { + return Default$4; + } + }, { + key: "NAME", + get: function get() { + return NAME$6; + } + }, { + key: "DATA_KEY", + get: function get() { + return DATA_KEY$6; + } + }, { + key: "Event", + get: function get() { + return Event$1; + } + }, { + key: "EVENT_KEY", + get: function get() { + return EVENT_KEY$6; + } + }, { + key: "DefaultType", + get: function get() { + return DefaultType$4; + } + }]); + + return Tooltip; + }(); + + var $$7 = getjQuery(); + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + * add .tooltip to jQuery only if jQuery is present + */ + + /* istanbul ignore if */ + + if ($$7) { + var JQUERY_NO_CONFLICT$6 = $$7.fn[NAME$6]; + $$7.fn[NAME$6] = Tooltip.jQueryInterface; + $$7.fn[NAME$6].Constructor = Tooltip; + + $$7.fn[NAME$6].noConflict = function () { + $$7.fn[NAME$6] = JQUERY_NO_CONFLICT$6; + return Tooltip.jQueryInterface; + }; + } + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME$7 = 'popover'; + var VERSION$7 = '5.0.0-alpha2'; + var DATA_KEY$7 = 'bs.popover'; + var EVENT_KEY$7 = "." + DATA_KEY$7; + var CLASS_PREFIX$1 = 'bs-popover'; + var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g'); + + var Default$5 = _extends({}, Tooltip.Default, { + placement: 'right', + trigger: 'click', + content: '', + template: '' + }); + + var DefaultType$5 = _extends({}, Tooltip.DefaultType, { + content: '(string|element|function)' + }); + + var Event$2 = { + HIDE: "hide" + EVENT_KEY$7, + HIDDEN: "hidden" + EVENT_KEY$7, + SHOW: "show" + EVENT_KEY$7, + SHOWN: "shown" + EVENT_KEY$7, + INSERTED: "inserted" + EVENT_KEY$7, + CLICK: "click" + EVENT_KEY$7, + FOCUSIN: "focusin" + EVENT_KEY$7, + FOCUSOUT: "focusout" + EVENT_KEY$7, + MOUSEENTER: "mouseenter" + EVENT_KEY$7, + MOUSELEAVE: "mouseleave" + EVENT_KEY$7 + }; + var CLASS_NAME_FADE$2 = 'fade'; + var CLASS_NAME_SHOW$4 = 'show'; + var SELECTOR_TITLE = '.popover-header'; + var SELECTOR_CONTENT = '.popover-body'; + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Popover = /*#__PURE__*/function (_Tooltip) { + _inheritsLoose(Popover, _Tooltip); + + function Popover() { + return _Tooltip.apply(this, arguments) || this; + } + + var _proto = Popover.prototype; + + // Overrides + _proto.isWithContent = function isWithContent() { + return this.getTitle() || this._getContent(); + }; + + _proto.setContent = function setContent() { + var tip = this.getTipElement(); // we use append for html objects to maintain js events + + this.setElementContent(SelectorEngine.findOne(SELECTOR_TITLE, tip), this.getTitle()); + + var content = this._getContent(); + + if (typeof content === 'function') { + content = content.call(this.element); + } + + this.setElementContent(SelectorEngine.findOne(SELECTOR_CONTENT, tip), content); + tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$4); + } // Private + ; + + _proto._addAttachmentClass = function _addAttachmentClass(attachment) { + this.getTipElement().classList.add(CLASS_PREFIX$1 + "-" + attachment); + }; + + _proto._getContent = function _getContent() { + return this.element.getAttribute('data-content') || this.config.content; + }; + + _proto._cleanTipClass = function _cleanTipClass() { + var tip = this.getTipElement(); + var tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX$1); + + if (tabClass !== null && tabClass.length > 0) { + tabClass.map(function (token) { + return token.trim(); + }).forEach(function (tClass) { + return tip.classList.remove(tClass); + }); + } + } // Static + ; + + Popover.jQueryInterface = function jQueryInterface(config) { + return this.each(function () { + var data = Data.getData(this, DATA_KEY$7); + + var _config = typeof config === 'object' ? config : null; + + if (!data && /dispose|hide/.test(config)) { + return; + } + + if (!data) { + data = new Popover(this, _config); + Data.setData(this, DATA_KEY$7, data); + } + + if (typeof config === 'string') { + if (typeof data[config] === 'undefined') { + throw new TypeError("No method named \"" + config + "\""); + } + + data[config](); + } + }); + }; + + Popover.getInstance = function getInstance(element) { + return Data.getData(element, DATA_KEY$7); + }; + + _createClass(Popover, null, [{ + key: "VERSION", + // Getters + get: function get() { + return VERSION$7; + } + }, { + key: "Default", + get: function get() { + return Default$5; + } + }, { + key: "NAME", + get: function get() { + return NAME$7; + } + }, { + key: "DATA_KEY", + get: function get() { + return DATA_KEY$7; + } + }, { + key: "Event", + get: function get() { + return Event$2; + } + }, { + key: "EVENT_KEY", + get: function get() { + return EVENT_KEY$7; + } + }, { + key: "DefaultType", + get: function get() { + return DefaultType$5; + } + }]); + + return Popover; + }(Tooltip); + + var $$8 = getjQuery(); + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + + /* istanbul ignore if */ + + if ($$8) { + var JQUERY_NO_CONFLICT$7 = $$8.fn[NAME$7]; + $$8.fn[NAME$7] = Popover.jQueryInterface; + $$8.fn[NAME$7].Constructor = Popover; + + $$8.fn[NAME$7].noConflict = function () { + $$8.fn[NAME$7] = JQUERY_NO_CONFLICT$7; + return Popover.jQueryInterface; + }; + } + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME$8 = 'scrollspy'; + var VERSION$8 = '5.0.0-alpha2'; + var DATA_KEY$8 = 'bs.scrollspy'; + var EVENT_KEY$8 = "." + DATA_KEY$8; + var DATA_API_KEY$6 = '.data-api'; + var Default$6 = { + offset: 10, + method: 'auto', + target: '' + }; + var DefaultType$6 = { + offset: 'number', + method: 'string', + target: '(string|element)' + }; + var EVENT_ACTIVATE = "activate" + EVENT_KEY$8; + var EVENT_SCROLL = "scroll" + EVENT_KEY$8; + var EVENT_LOAD_DATA_API$1 = "load" + EVENT_KEY$8 + DATA_API_KEY$6; + var CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'; + var CLASS_NAME_ACTIVE$2 = 'active'; + var SELECTOR_DATA_SPY = '[data-spy="scroll"]'; + var SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'; + var SELECTOR_NAV_LINKS = '.nav-link'; + var SELECTOR_NAV_ITEMS = '.nav-item'; + var SELECTOR_LIST_ITEMS = '.list-group-item'; + var SELECTOR_DROPDOWN = '.dropdown'; + var SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'; + var METHOD_OFFSET = 'offset'; + var METHOD_POSITION = 'position'; + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var ScrollSpy = /*#__PURE__*/function () { + function ScrollSpy(element, config) { + var _this = this; + + this._element = element; + this._scrollElement = element.tagName === 'BODY' ? window : element; + this._config = this._getConfig(config); + this._selector = this._config.target + " " + SELECTOR_NAV_LINKS + ", " + this._config.target + " " + SELECTOR_LIST_ITEMS + ", " + this._config.target + " ." + CLASS_NAME_DROPDOWN_ITEM; + this._offsets = []; + this._targets = []; + this._activeTarget = null; + this._scrollHeight = 0; + EventHandler.on(this._scrollElement, EVENT_SCROLL, function (event) { + return _this._process(event); + }); + this.refresh(); + + this._process(); + + Data.setData(element, DATA_KEY$8, this); + } // Getters + + + var _proto = ScrollSpy.prototype; + + // Public + _proto.refresh = function refresh() { + var _this2 = this; + + var autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION; + var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method; + var offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0; + this._offsets = []; + this._targets = []; + this._scrollHeight = this._getScrollHeight(); + var targets = SelectorEngine.find(this._selector); + targets.map(function (element) { + var targetSelector = getSelectorFromElement(element); + var target = targetSelector ? SelectorEngine.findOne(targetSelector) : null; + + if (target) { + var targetBCR = target.getBoundingClientRect(); + + if (targetBCR.width || targetBCR.height) { + return [Manipulator[offsetMethod](target).top + offsetBase, targetSelector]; + } + } + + return null; + }).filter(function (item) { + return item; + }).sort(function (a, b) { + return a[0] - b[0]; + }).forEach(function (item) { + _this2._offsets.push(item[0]); + + _this2._targets.push(item[1]); + }); + }; + + _proto.dispose = function dispose() { + Data.removeData(this._element, DATA_KEY$8); + EventHandler.off(this._scrollElement, EVENT_KEY$8); + this._element = null; + this._scrollElement = null; + this._config = null; + this._selector = null; + this._offsets = null; + this._targets = null; + this._activeTarget = null; + this._scrollHeight = null; + } // Private + ; + + _proto._getConfig = function _getConfig(config) { + config = _extends({}, Default$6, typeof config === 'object' && config ? config : {}); + + if (typeof config.target !== 'string' && isElement(config.target)) { + var id = config.target.id; + + if (!id) { + id = getUID(NAME$8); + config.target.id = id; + } + + config.target = "#" + id; + } + + typeCheckConfig(NAME$8, config, DefaultType$6); + return config; + }; + + _proto._getScrollTop = function _getScrollTop() { + return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop; + }; + + _proto._getScrollHeight = function _getScrollHeight() { + return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); + }; + + _proto._getOffsetHeight = function _getOffsetHeight() { + return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height; + }; + + _proto._process = function _process() { + var scrollTop = this._getScrollTop() + this._config.offset; + + var scrollHeight = this._getScrollHeight(); + + var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight(); + + if (this._scrollHeight !== scrollHeight) { + this.refresh(); + } + + if (scrollTop >= maxScroll) { + var target = this._targets[this._targets.length - 1]; + + if (this._activeTarget !== target) { + this._activate(target); + } + + return; + } + + if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) { + this._activeTarget = null; + + this._clear(); + + return; + } + + for (var i = this._offsets.length; i--;) { + var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]); + + if (isActiveTarget) { + this._activate(this._targets[i]); + } + } + }; + + _proto._activate = function _activate(target) { + this._activeTarget = target; + + this._clear(); + + var queries = this._selector.split(',').map(function (selector) { + return selector + "[data-target=\"" + target + "\"]," + selector + "[href=\"" + target + "\"]"; + }); + + var link = SelectorEngine.findOne(queries.join(',')); + + if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) { + SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE, link.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$2); + link.classList.add(CLASS_NAME_ACTIVE$2); + } else { + // Set triggered link as active + link.classList.add(CLASS_NAME_ACTIVE$2); + SelectorEngine.parents(link, SELECTOR_NAV_LIST_GROUP).forEach(function (listGroup) { + // Set triggered links parents as active + // With both
      and

    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 K8c4O*(f 'click') + + var typeEvent = originalTypeEvent.replace(stripNameRegex, ''); + var custom = customEvents[typeEvent]; + + if (custom) { + typeEvent = custom; + } + + var isNative = nativeEvents.indexOf(typeEvent) > -1; + + if (!isNative) { + typeEvent = originalTypeEvent; + } + + return [delegation, originalHandler, typeEvent]; + } + + function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) { + if (typeof originalTypeEvent !== 'string' || !element) { + return; + } + + if (!handler) { + handler = delegationFn; + delegationFn = null; + } + + var _normalizeParams = normalizeParams(originalTypeEvent, handler, delegationFn), + delegation = _normalizeParams[0], + originalHandler = _normalizeParams[1], + typeEvent = _normalizeParams[2]; + + var events = getEvent(element); + var handlers = events[typeEvent] || (events[typeEvent] = {}); + var previousFn = findHandler(handlers, originalHandler, delegation ? handler : null); + + if (previousFn) { + previousFn.oneOff = previousFn.oneOff && oneOff; + return; + } + + var uid = getUidEvent(originalHandler, originalTypeEvent.replace(namespaceRegex, '')); + var fn = delegation ? bootstrapDelegationHandler(element, handler, delegationFn) : bootstrapHandler(element, handler); + fn.delegationSelector = delegation ? handler : null; + fn.originalHandler = originalHandler; + fn.oneOff = oneOff; + fn.uidEvent = uid; + handlers[uid] = fn; + element.addEventListener(typeEvent, fn, delegation); + } + + function removeHandler(element, events, typeEvent, handler, delegationSelector) { + var fn = findHandler(events[typeEvent], handler, delegationSelector); + + if (!fn) { + return; + } + + element.removeEventListener(typeEvent, fn, Boolean(delegationSelector)); + delete events[typeEvent][fn.uidEvent]; + } + + function removeNamespacedHandlers(element, events, typeEvent, namespace) { + var storeElementEvent = events[typeEvent] || {}; + Object.keys(storeElementEvent).forEach(function (handlerKey) { + if (handlerKey.indexOf(namespace) > -1) { + var event = storeElementEvent[handlerKey]; + removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector); + } + }); + } + + var EventHandler = { + on: function on(element, event, handler, delegationFn) { + addHandler(element, event, handler, delegationFn, false); + }, + one: function one(element, event, handler, delegationFn) { + addHandler(element, event, handler, delegationFn, true); + }, + off: function off(element, originalTypeEvent, handler, delegationFn) { + if (typeof originalTypeEvent !== 'string' || !element) { + return; + } + + var _normalizeParams2 = normalizeParams(originalTypeEvent, handler, delegationFn), + delegation = _normalizeParams2[0], + originalHandler = _normalizeParams2[1], + typeEvent = _normalizeParams2[2]; + + var inNamespace = typeEvent !== originalTypeEvent; + var events = getEvent(element); + var isNamespace = originalTypeEvent.charAt(0) === '.'; + + if (typeof originalHandler !== 'undefined') { + // Simplest case: handler is passed, remove that listener ONLY. + if (!events || !events[typeEvent]) { + return; + } + + removeHandler(element, events, typeEvent, originalHandler, delegation ? handler : null); + return; + } + + if (isNamespace) { + Object.keys(events).forEach(function (elementEvent) { + removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1)); + }); + } + + var storeElementEvent = events[typeEvent] || {}; + Object.keys(storeElementEvent).forEach(function (keyHandlers) { + var handlerKey = keyHandlers.replace(stripUidRegex, ''); + + if (!inNamespace || originalTypeEvent.indexOf(handlerKey) > -1) { + var event = storeElementEvent[keyHandlers]; + removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector); + } + }); + }, + trigger: function trigger(element, event, args) { + if (typeof event !== 'string' || !element) { + return null; + } + + var typeEvent = event.replace(stripNameRegex, ''); + var inNamespace = event !== typeEvent; + var isNative = nativeEvents.indexOf(typeEvent) > -1; + var jQueryEvent; + var bubbles = true; + var nativeDispatch = true; + var defaultPrevented = false; + var evt = null; + + if (inNamespace && $) { + jQueryEvent = $.Event(event, args); + $(element).trigger(jQueryEvent); + bubbles = !jQueryEvent.isPropagationStopped(); + nativeDispatch = !jQueryEvent.isImmediatePropagationStopped(); + defaultPrevented = jQueryEvent.isDefaultPrevented(); + } + + if (isNative) { + evt = document.createEvent('HTMLEvents'); + evt.initEvent(typeEvent, bubbles, true); + } else { + evt = new CustomEvent(event, { + bubbles: bubbles, + cancelable: true + }); + } // merge custom information in our event + + + if (typeof args !== 'undefined') { + Object.keys(args).forEach(function (key) { + Object.defineProperty(evt, key, { + get: function get() { + return args[key]; + } + }); + }); + } + + if (defaultPrevented) { + evt.preventDefault(); + + if (!defaultPreventedPreservedOnDispatch) { + Object.defineProperty(evt, 'defaultPrevented', { + get: function get() { + return true; + } + }); + } + } + + if (nativeDispatch) { + element.dispatchEvent(evt); + } + + if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') { + jQueryEvent.preventDefault(); + } + + return evt; + } + }; + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME = 'alert'; + var VERSION = '5.0.0-alpha2'; + var DATA_KEY = 'bs.alert'; + var EVENT_KEY = "." + DATA_KEY; + var DATA_API_KEY = '.data-api'; + var SELECTOR_DISMISS = '[data-dismiss="alert"]'; + var EVENT_CLOSE = "close" + EVENT_KEY; + var EVENT_CLOSED = "closed" + EVENT_KEY; + var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY; + var CLASSNAME_ALERT = 'alert'; + var CLASSNAME_FADE = 'fade'; + var CLASSNAME_SHOW = 'show'; + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Alert = /*#__PURE__*/function () { + function Alert(element) { + this._element = element; + + if (this._element) { + Data.setData(element, DATA_KEY, this); + } + } // Getters + + + var _proto = Alert.prototype; + + // Public + _proto.close = function close(element) { + var rootElement = element ? this._getRootElement(element) : this._element; + + var customEvent = this._triggerCloseEvent(rootElement); + + if (customEvent === null || customEvent.defaultPrevented) { + return; + } + + this._removeElement(rootElement); + }; + + _proto.dispose = function dispose() { + Data.removeData(this._element, DATA_KEY); + this._element = null; + } // Private + ; + + _proto._getRootElement = function _getRootElement(element) { + return getElementFromSelector(element) || element.closest("." + CLASSNAME_ALERT); + }; + + _proto._triggerCloseEvent = function _triggerCloseEvent(element) { + return EventHandler.trigger(element, EVENT_CLOSE); + }; + + _proto._removeElement = function _removeElement(element) { + var _this = this; + + element.classList.remove(CLASSNAME_SHOW); + + if (!element.classList.contains(CLASSNAME_FADE)) { + this._destroyElement(element); + + return; + } + + var transitionDuration = getTransitionDurationFromElement(element); + EventHandler.one(element, TRANSITION_END, function () { + return _this._destroyElement(element); + }); + emulateTransitionEnd(element, transitionDuration); + }; + + _proto._destroyElement = function _destroyElement(element) { + if (element.parentNode) { + element.parentNode.removeChild(element); + } + + EventHandler.trigger(element, EVENT_CLOSED); + } // Static + ; + + Alert.jQueryInterface = function jQueryInterface(config) { + return this.each(function () { + var data = Data.getData(this, DATA_KEY); + + if (!data) { + data = new Alert(this); + } + + if (config === 'close') { + data[config](this); + } + }); + }; + + Alert.handleDismiss = function handleDismiss(alertInstance) { + return function (event) { + if (event) { + event.preventDefault(); + } + + alertInstance.close(this); + }; + }; + + Alert.getInstance = function getInstance(element) { + return Data.getData(element, DATA_KEY); + }; + + _createClass(Alert, null, [{ + key: "VERSION", + get: function get() { + return VERSION; + } + }]); + + return Alert; + }(); + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + + EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DISMISS, Alert.handleDismiss(new Alert())); + var $$1 = getjQuery(); + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + * add .alert to jQuery only if jQuery is present + */ + + /* istanbul ignore if */ + + if ($$1) { + var JQUERY_NO_CONFLICT = $$1.fn[NAME]; + $$1.fn[NAME] = Alert.jQueryInterface; + $$1.fn[NAME].Constructor = Alert; + + $$1.fn[NAME].noConflict = function () { + $$1.fn[NAME] = JQUERY_NO_CONFLICT; + return Alert.jQueryInterface; + }; + } + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME$1 = 'button'; + var VERSION$1 = '5.0.0-alpha2'; + var DATA_KEY$1 = 'bs.button'; + var EVENT_KEY$1 = "." + DATA_KEY$1; + var DATA_API_KEY$1 = '.data-api'; + var CLASS_NAME_ACTIVE = 'active'; + var SELECTOR_DATA_TOGGLE = '[data-toggle="button"]'; + var EVENT_CLICK_DATA_API$1 = "click" + EVENT_KEY$1 + DATA_API_KEY$1; + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Button = /*#__PURE__*/function () { + function Button(element) { + this._element = element; + Data.setData(element, DATA_KEY$1, this); + } // Getters + + + var _proto = Button.prototype; + + // Public + _proto.toggle = function toggle() { + // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method + this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE)); + }; + + _proto.dispose = function dispose() { + Data.removeData(this._element, DATA_KEY$1); + this._element = null; + } // Static + ; + + Button.jQueryInterface = function jQueryInterface(config) { + return this.each(function () { + var data = Data.getData(this, DATA_KEY$1); + + if (!data) { + data = new Button(this); + } + + if (config === 'toggle') { + data[config](); + } + }); + }; + + Button.getInstance = function getInstance(element) { + return Data.getData(element, DATA_KEY$1); + }; + + _createClass(Button, null, [{ + key: "VERSION", + get: function get() { + return VERSION$1; + } + }]); + + return Button; + }(); + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + + EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE, function (event) { + event.preventDefault(); + var button = event.target.closest(SELECTOR_DATA_TOGGLE); + var data = Data.getData(button, DATA_KEY$1); + + if (!data) { + data = new Button(button); + } + + data.toggle(); + }); + var $$2 = getjQuery(); + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + * add .button to jQuery only if jQuery is present + */ + + /* istanbul ignore if */ + + if ($$2) { + var JQUERY_NO_CONFLICT$1 = $$2.fn[NAME$1]; + $$2.fn[NAME$1] = Button.jQueryInterface; + $$2.fn[NAME$1].Constructor = Button; + + $$2.fn[NAME$1].noConflict = function () { + $$2.fn[NAME$1] = JQUERY_NO_CONFLICT$1; + return Button.jQueryInterface; + }; + } + + /** + * -------------------------------------------------------------------------- + * Bootstrap (v5.0.0-alpha2): dom/manipulator.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + * -------------------------------------------------------------------------- + */ + function normalizeData(val) { + if (val === 'true') { + return true; + } + + if (val === 'false') { + return false; + } + + if (val === Number(val).toString()) { + return Number(val); + } + + if (val === '' || val === 'null') { + return null; + } + + return val; + } + + function normalizeDataKey(key) { + return key.replace(/[A-Z]/g, function (chr) { + return "-" + chr.toLowerCase(); + }); + } + + var Manipulator = { + setDataAttribute: function setDataAttribute(element, key, value) { + element.setAttribute("data-" + normalizeDataKey(key), value); + }, + removeDataAttribute: function removeDataAttribute(element, key) { + element.removeAttribute("data-" + normalizeDataKey(key)); + }, + getDataAttributes: function getDataAttributes(element) { + if (!element) { + return {}; + } + + var attributes = _extends({}, element.dataset); + + Object.keys(attributes).forEach(function (key) { + attributes[key] = normalizeData(attributes[key]); + }); + return attributes; + }, + getDataAttribute: function getDataAttribute(element, key) { + return normalizeData(element.getAttribute("data-" + normalizeDataKey(key))); + }, + offset: function offset(element) { + var rect = element.getBoundingClientRect(); + return { + top: rect.top + document.body.scrollTop, + left: rect.left + document.body.scrollLeft + }; + }, + position: function position(element) { + return { + top: element.offsetTop, + left: element.offsetLeft + }; + }, + toggleClass: function toggleClass(element, className) { + if (!element) { + return; + } + + if (element.classList.contains(className)) { + element.classList.remove(className); + } else { + element.classList.add(className); + } + } + }; + + /** + * -------------------------------------------------------------------------- + * Bootstrap (v5.0.0-alpha2): dom/selector-engine.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + * -------------------------------------------------------------------------- + */ + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NODE_TEXT = 3; + var SelectorEngine = { + matches: function matches(element, selector) { + return element.matches(selector); + }, + find: function find$1(selector, element) { + var _ref; + + if (element === void 0) { + element = document.documentElement; + } + + return (_ref = []).concat.apply(_ref, find.call(element, selector)); + }, + findOne: function findOne$1(selector, element) { + if (element === void 0) { + element = document.documentElement; + } + + return findOne.call(element, selector); + }, + children: function children(element, selector) { + var _ref2; + + var children = (_ref2 = []).concat.apply(_ref2, element.children); + + return children.filter(function (child) { + return child.matches(selector); + }); + }, + parents: function parents(element, selector) { + var parents = []; + var ancestor = element.parentNode; + + while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) { + if (this.matches(ancestor, selector)) { + parents.push(ancestor); + } + + ancestor = ancestor.parentNode; + } + + return parents; + }, + prev: function prev(element, selector) { + var previous = element.previousElementSibling; + + while (previous) { + if (previous.matches(selector)) { + return [previous]; + } + + previous = previous.previousElementSibling; + } + + return []; + }, + next: function next(element, selector) { + var next = element.nextElementSibling; + + while (next) { + if (this.matches(next, selector)) { + return [next]; + } + + next = next.nextElementSibling; + } + + return []; + } + }; + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME$2 = 'carousel'; + var VERSION$2 = '5.0.0-alpha2'; + var DATA_KEY$2 = 'bs.carousel'; + var EVENT_KEY$2 = "." + DATA_KEY$2; + var DATA_API_KEY$2 = '.data-api'; + var ARROW_LEFT_KEY = 'ArrowLeft'; + var ARROW_RIGHT_KEY = 'ArrowRight'; + var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch + + var SWIPE_THRESHOLD = 40; + var Default = { + interval: 5000, + keyboard: true, + slide: false, + pause: 'hover', + wrap: true, + touch: true + }; + var DefaultType = { + interval: '(number|boolean)', + keyboard: 'boolean', + slide: '(boolean|string)', + pause: '(string|boolean)', + wrap: 'boolean', + touch: 'boolean' + }; + var DIRECTION_NEXT = 'next'; + var DIRECTION_PREV = 'prev'; + var DIRECTION_LEFT = 'left'; + var DIRECTION_RIGHT = 'right'; + var EVENT_SLIDE = "slide" + EVENT_KEY$2; + var EVENT_SLID = "slid" + EVENT_KEY$2; + var EVENT_KEYDOWN = "keydown" + EVENT_KEY$2; + var EVENT_MOUSEENTER = "mouseenter" + EVENT_KEY$2; + var EVENT_MOUSELEAVE = "mouseleave" + EVENT_KEY$2; + var EVENT_TOUCHSTART = "touchstart" + EVENT_KEY$2; + var EVENT_TOUCHMOVE = "touchmove" + EVENT_KEY$2; + var EVENT_TOUCHEND = "touchend" + EVENT_KEY$2; + var EVENT_POINTERDOWN = "pointerdown" + EVENT_KEY$2; + var EVENT_POINTERUP = "pointerup" + EVENT_KEY$2; + var EVENT_DRAG_START = "dragstart" + EVENT_KEY$2; + var EVENT_LOAD_DATA_API = "load" + EVENT_KEY$2 + DATA_API_KEY$2; + var EVENT_CLICK_DATA_API$2 = "click" + EVENT_KEY$2 + DATA_API_KEY$2; + var CLASS_NAME_CAROUSEL = 'carousel'; + var CLASS_NAME_ACTIVE$1 = 'active'; + var CLASS_NAME_SLIDE = 'slide'; + var CLASS_NAME_RIGHT = 'carousel-item-right'; + var CLASS_NAME_LEFT = 'carousel-item-left'; + var CLASS_NAME_NEXT = 'carousel-item-next'; + var CLASS_NAME_PREV = 'carousel-item-prev'; + var CLASS_NAME_POINTER_EVENT = 'pointer-event'; + var SELECTOR_ACTIVE = '.active'; + var SELECTOR_ACTIVE_ITEM = '.active.carousel-item'; + var SELECTOR_ITEM = '.carousel-item'; + var SELECTOR_ITEM_IMG = '.carousel-item img'; + var SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'; + var SELECTOR_INDICATORS = '.carousel-indicators'; + var SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'; + var SELECTOR_DATA_RIDE = '[data-ride="carousel"]'; + var PointerType = { + TOUCH: 'touch', + PEN: 'pen' + }; + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Carousel = /*#__PURE__*/function () { + function Carousel(element, config) { + this._items = null; + this._interval = null; + this._activeElement = null; + this._isPaused = false; + this._isSliding = false; + this.touchTimeout = null; + this.touchStartX = 0; + this.touchDeltaX = 0; + this._config = this._getConfig(config); + this._element = element; + this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element); + this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0; + this._pointerEvent = Boolean(window.PointerEvent); + + this._addEventListeners(); + + Data.setData(element, DATA_KEY$2, this); + } // Getters + + + var _proto = Carousel.prototype; + + // Public + _proto.next = function next() { + if (!this._isSliding) { + this._slide(DIRECTION_NEXT); + } + }; + + _proto.nextWhenVisible = function nextWhenVisible() { + // Don't call next when the page isn't visible + // or the carousel or its parent isn't visible + if (!document.hidden && isVisible(this._element)) { + this.next(); + } + }; + + _proto.prev = function prev() { + if (!this._isSliding) { + this._slide(DIRECTION_PREV); + } + }; + + _proto.pause = function pause(event) { + if (!event) { + this._isPaused = true; + } + + if (SelectorEngine.findOne(SELECTOR_NEXT_PREV, this._element)) { + triggerTransitionEnd(this._element); + this.cycle(true); + } + + clearInterval(this._interval); + this._interval = null; + }; + + _proto.cycle = function cycle(event) { + if (!event) { + this._isPaused = false; + } + + if (this._interval) { + clearInterval(this._interval); + this._interval = null; + } + + if (this._config && this._config.interval && !this._isPaused) { + this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval); + } + }; + + _proto.to = function to(index) { + var _this = this; + + this._activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element); + + var activeIndex = this._getItemIndex(this._activeElement); + + if (index > this._items.length - 1 || index < 0) { + return; + } + + if (this._isSliding) { + EventHandler.one(this._element, EVENT_SLID, function () { + return _this.to(index); + }); + return; + } + + if (activeIndex === index) { + this.pause(); + this.cycle(); + return; + } + + var direction = index > activeIndex ? DIRECTION_NEXT : DIRECTION_PREV; + + this._slide(direction, this._items[index]); + }; + + _proto.dispose = function dispose() { + EventHandler.off(this._element, EVENT_KEY$2); + Data.removeData(this._element, DATA_KEY$2); + this._items = null; + this._config = null; + this._element = null; + this._interval = null; + this._isPaused = null; + this._isSliding = null; + this._activeElement = null; + this._indicatorsElement = null; + } // Private + ; + + _proto._getConfig = function _getConfig(config) { + config = _extends({}, Default, config); + typeCheckConfig(NAME$2, config, DefaultType); + return config; + }; + + _proto._handleSwipe = function _handleSwipe() { + var absDeltax = Math.abs(this.touchDeltaX); + + if (absDeltax <= SWIPE_THRESHOLD) { + return; + } + + var direction = absDeltax / this.touchDeltaX; + this.touchDeltaX = 0; // swipe left + + if (direction > 0) { + this.prev(); + } // swipe right + + + if (direction < 0) { + this.next(); + } + }; + + _proto._addEventListeners = function _addEventListeners() { + var _this2 = this; + + if (this._config.keyboard) { + EventHandler.on(this._element, EVENT_KEYDOWN, function (event) { + return _this2._keydown(event); + }); + } + + if (this._config.pause === 'hover') { + EventHandler.on(this._element, EVENT_MOUSEENTER, function (event) { + return _this2.pause(event); + }); + EventHandler.on(this._element, EVENT_MOUSELEAVE, function (event) { + return _this2.cycle(event); + }); + } + + if (this._config.touch && this._touchSupported) { + this._addTouchEventListeners(); + } + }; + + _proto._addTouchEventListeners = function _addTouchEventListeners() { + var _this3 = this; + + var start = function start(event) { + if (_this3._pointerEvent && PointerType[event.pointerType.toUpperCase()]) { + _this3.touchStartX = event.clientX; + } else if (!_this3._pointerEvent) { + _this3.touchStartX = event.touches[0].clientX; + } + }; + + var move = function move(event) { + // ensure swiping with one touch and not pinching + if (event.touches && event.touches.length > 1) { + _this3.touchDeltaX = 0; + } else { + _this3.touchDeltaX = event.touches[0].clientX - _this3.touchStartX; + } + }; + + var end = function end(event) { + if (_this3._pointerEvent && PointerType[event.pointerType.toUpperCase()]) { + _this3.touchDeltaX = event.clientX - _this3.touchStartX; + } + + _this3._handleSwipe(); + + if (_this3._config.pause === 'hover') { + // If it's a touch-enabled device, mouseenter/leave are fired as + // part of the mouse compatibility events on first tap - the carousel + // would stop cycling until user tapped out of it; + // here, we listen for touchend, explicitly pause the carousel + // (as if it's the second time we tap on it, mouseenter compat event + // is NOT fired) and after a timeout (to allow for mouse compatibility + // events to fire) we explicitly restart cycling + _this3.pause(); + + if (_this3.touchTimeout) { + clearTimeout(_this3.touchTimeout); + } + + _this3.touchTimeout = setTimeout(function (event) { + return _this3.cycle(event); + }, TOUCHEVENT_COMPAT_WAIT + _this3._config.interval); + } + }; + + SelectorEngine.find(SELECTOR_ITEM_IMG, this._element).forEach(function (itemImg) { + EventHandler.on(itemImg, EVENT_DRAG_START, function (e) { + return e.preventDefault(); + }); + }); + + if (this._pointerEvent) { + EventHandler.on(this._element, EVENT_POINTERDOWN, function (event) { + return start(event); + }); + EventHandler.on(this._element, EVENT_POINTERUP, function (event) { + return end(event); + }); + + this._element.classList.add(CLASS_NAME_POINTER_EVENT); + } else { + EventHandler.on(this._element, EVENT_TOUCHSTART, function (event) { + return start(event); + }); + EventHandler.on(this._element, EVENT_TOUCHMOVE, function (event) { + return move(event); + }); + EventHandler.on(this._element, EVENT_TOUCHEND, function (event) { + return end(event); + }); + } + }; + + _proto._keydown = function _keydown(event) { + if (/input|textarea/i.test(event.target.tagName)) { + return; + } + + switch (event.key) { + case ARROW_LEFT_KEY: + event.preventDefault(); + this.prev(); + break; + + case ARROW_RIGHT_KEY: + event.preventDefault(); + this.next(); + break; + } + }; + + _proto._getItemIndex = function _getItemIndex(element) { + this._items = element && element.parentNode ? SelectorEngine.find(SELECTOR_ITEM, element.parentNode) : []; + return this._items.indexOf(element); + }; + + _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) { + var isNextDirection = direction === DIRECTION_NEXT; + var isPrevDirection = direction === DIRECTION_PREV; + + var activeIndex = this._getItemIndex(activeElement); + + var lastItemIndex = this._items.length - 1; + var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex; + + if (isGoingToWrap && !this._config.wrap) { + return activeElement; + } + + var delta = direction === DIRECTION_PREV ? -1 : 1; + var itemIndex = (activeIndex + delta) % this._items.length; + return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex]; + }; + + _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) { + var targetIndex = this._getItemIndex(relatedTarget); + + var fromIndex = this._getItemIndex(SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)); + + return EventHandler.trigger(this._element, EVENT_SLIDE, { + relatedTarget: relatedTarget, + direction: eventDirectionName, + from: fromIndex, + to: targetIndex + }); + }; + + _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) { + if (this._indicatorsElement) { + var indicators = SelectorEngine.find(SELECTOR_ACTIVE, this._indicatorsElement); + + for (var i = 0; i < indicators.length; i++) { + indicators[i].classList.remove(CLASS_NAME_ACTIVE$1); + } + + var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)]; + + if (nextIndicator) { + nextIndicator.classList.add(CLASS_NAME_ACTIVE$1); + } + } + }; + + _proto._slide = function _slide(direction, element) { + var _this4 = this; + + var activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element); + + var activeElementIndex = this._getItemIndex(activeElement); + + var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement); + + var nextElementIndex = this._getItemIndex(nextElement); + + var isCycling = Boolean(this._interval); + var directionalClassName; + var orderClassName; + var eventDirectionName; + + if (direction === DIRECTION_NEXT) { + directionalClassName = CLASS_NAME_LEFT; + orderClassName = CLASS_NAME_NEXT; + eventDirectionName = DIRECTION_LEFT; + } else { + directionalClassName = CLASS_NAME_RIGHT; + orderClassName = CLASS_NAME_PREV; + eventDirectionName = DIRECTION_RIGHT; + } + + if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE$1)) { + this._isSliding = false; + return; + } + + var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName); + + if (slideEvent.defaultPrevented) { + return; + } + + if (!activeElement || !nextElement) { + // Some weirdness is happening, so we bail + return; + } + + this._isSliding = true; + + if (isCycling) { + this.pause(); + } + + this._setActiveIndicatorElement(nextElement); + + if (this._element.classList.contains(CLASS_NAME_SLIDE)) { + nextElement.classList.add(orderClassName); + reflow(nextElement); + activeElement.classList.add(directionalClassName); + nextElement.classList.add(directionalClassName); + var nextElementInterval = parseInt(nextElement.getAttribute('data-interval'), 10); + + if (nextElementInterval) { + this._config.defaultInterval = this._config.defaultInterval || this._config.interval; + this._config.interval = nextElementInterval; + } else { + this._config.interval = this._config.defaultInterval || this._config.interval; + } + + var transitionDuration = getTransitionDurationFromElement(activeElement); + EventHandler.one(activeElement, TRANSITION_END, function () { + nextElement.classList.remove(directionalClassName, orderClassName); + nextElement.classList.add(CLASS_NAME_ACTIVE$1); + activeElement.classList.remove(CLASS_NAME_ACTIVE$1, orderClassName, directionalClassName); + _this4._isSliding = false; + setTimeout(function () { + EventHandler.trigger(_this4._element, EVENT_SLID, { + relatedTarget: nextElement, + direction: eventDirectionName, + from: activeElementIndex, + to: nextElementIndex + }); + }, 0); + }); + emulateTransitionEnd(activeElement, transitionDuration); + } else { + activeElement.classList.remove(CLASS_NAME_ACTIVE$1); + nextElement.classList.add(CLASS_NAME_ACTIVE$1); + this._isSliding = false; + EventHandler.trigger(this._element, EVENT_SLID, { + relatedTarget: nextElement, + direction: eventDirectionName, + from: activeElementIndex, + to: nextElementIndex + }); + } + + if (isCycling) { + this.cycle(); + } + } // Static + ; + + Carousel.carouselInterface = function carouselInterface(element, config) { + var data = Data.getData(element, DATA_KEY$2); + + var _config = _extends({}, Default, Manipulator.getDataAttributes(element)); + + if (typeof config === 'object') { + _config = _extends({}, _config, config); + } + + var action = typeof config === 'string' ? config : _config.slide; + + if (!data) { + data = new Carousel(element, _config); + } + + if (typeof config === 'number') { + data.to(config); + } else if (typeof action === 'string') { + if (typeof data[action] === 'undefined') { + throw new TypeError("No method named \"" + action + "\""); + } + + data[action](); + } else if (_config.interval && _config.ride) { + data.pause(); + data.cycle(); + } + }; + + Carousel.jQueryInterface = function jQueryInterface(config) { + return this.each(function () { + Carousel.carouselInterface(this, config); + }); + }; + + Carousel.dataApiClickHandler = function dataApiClickHandler(event) { + var target = getElementFromSelector(this); + + if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) { + return; + } + + var config = _extends({}, Manipulator.getDataAttributes(target), Manipulator.getDataAttributes(this)); + + var slideIndex = this.getAttribute('data-slide-to'); + + if (slideIndex) { + config.interval = false; + } + + Carousel.carouselInterface(target, config); + + if (slideIndex) { + Data.getData(target, DATA_KEY$2).to(slideIndex); + } + + event.preventDefault(); + }; + + Carousel.getInstance = function getInstance(element) { + return Data.getData(element, DATA_KEY$2); + }; + + _createClass(Carousel, null, [{ + key: "VERSION", + get: function get() { + return VERSION$2; + } + }, { + key: "Default", + get: function get() { + return Default; + } + }]); + + return Carousel; + }(); + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + + EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_SLIDE, Carousel.dataApiClickHandler); + EventHandler.on(window, EVENT_LOAD_DATA_API, function () { + var carousels = SelectorEngine.find(SELECTOR_DATA_RIDE); + + for (var i = 0, len = carousels.length; i < len; i++) { + Carousel.carouselInterface(carousels[i], Data.getData(carousels[i], DATA_KEY$2)); + } + }); + var $$3 = getjQuery(); + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + * add .carousel to jQuery only if jQuery is present + */ + + /* istanbul ignore if */ + + if ($$3) { + var JQUERY_NO_CONFLICT$2 = $$3.fn[NAME$2]; + $$3.fn[NAME$2] = Carousel.jQueryInterface; + $$3.fn[NAME$2].Constructor = Carousel; + + $$3.fn[NAME$2].noConflict = function () { + $$3.fn[NAME$2] = JQUERY_NO_CONFLICT$2; + return Carousel.jQueryInterface; + }; + } + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME$3 = 'collapse'; + var VERSION$3 = '5.0.0-alpha2'; + var DATA_KEY$3 = 'bs.collapse'; + var EVENT_KEY$3 = "." + DATA_KEY$3; + var DATA_API_KEY$3 = '.data-api'; + var Default$1 = { + toggle: true, + parent: '' + }; + var DefaultType$1 = { + toggle: 'boolean', + parent: '(string|element)' + }; + var EVENT_SHOW = "show" + EVENT_KEY$3; + var EVENT_SHOWN = "shown" + EVENT_KEY$3; + var EVENT_HIDE = "hide" + EVENT_KEY$3; + var EVENT_HIDDEN = "hidden" + EVENT_KEY$3; + var EVENT_CLICK_DATA_API$3 = "click" + EVENT_KEY$3 + DATA_API_KEY$3; + var CLASS_NAME_SHOW = 'show'; + var CLASS_NAME_COLLAPSE = 'collapse'; + var CLASS_NAME_COLLAPSING = 'collapsing'; + var CLASS_NAME_COLLAPSED = 'collapsed'; + var WIDTH = 'width'; + var HEIGHT = 'height'; + var SELECTOR_ACTIVES = '.show, .collapsing'; + var SELECTOR_DATA_TOGGLE$1 = '[data-toggle="collapse"]'; + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Collapse = /*#__PURE__*/function () { + function Collapse(element, config) { + this._isTransitioning = false; + this._element = element; + this._config = this._getConfig(config); + this._triggerArray = SelectorEngine.find(SELECTOR_DATA_TOGGLE$1 + "[href=\"#" + element.id + "\"]," + (SELECTOR_DATA_TOGGLE$1 + "[data-target=\"#" + element.id + "\"]")); + var toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$1); + + for (var i = 0, len = toggleList.length; i < len; i++) { + var elem = toggleList[i]; + var selector = getSelectorFromElement(elem); + var filterElement = SelectorEngine.find(selector).filter(function (foundElem) { + return foundElem === element; + }); + + if (selector !== null && filterElement.length) { + this._selector = selector; + + this._triggerArray.push(elem); + } + } + + this._parent = this._config.parent ? this._getParent() : null; + + if (!this._config.parent) { + this._addAriaAndCollapsedClass(this._element, this._triggerArray); + } + + if (this._config.toggle) { + this.toggle(); + } + + Data.setData(element, DATA_KEY$3, this); + } // Getters + + + var _proto = Collapse.prototype; + + // Public + _proto.toggle = function toggle() { + if (this._element.classList.contains(CLASS_NAME_SHOW)) { + this.hide(); + } else { + this.show(); + } + }; + + _proto.show = function show() { + var _this = this; + + if (this._isTransitioning || this._element.classList.contains(CLASS_NAME_SHOW)) { + return; + } + + var actives; + var activesData; + + if (this._parent) { + actives = SelectorEngine.find(SELECTOR_ACTIVES, this._parent).filter(function (elem) { + if (typeof _this._config.parent === 'string') { + return elem.getAttribute('data-parent') === _this._config.parent; + } + + return elem.classList.contains(CLASS_NAME_COLLAPSE); + }); + + if (actives.length === 0) { + actives = null; + } + } + + var container = SelectorEngine.findOne(this._selector); + + if (actives) { + var tempActiveData = actives.filter(function (elem) { + return container !== elem; + }); + activesData = tempActiveData[0] ? Data.getData(tempActiveData[0], DATA_KEY$3) : null; + + if (activesData && activesData._isTransitioning) { + return; + } + } + + var startEvent = EventHandler.trigger(this._element, EVENT_SHOW); + + if (startEvent.defaultPrevented) { + return; + } + + if (actives) { + actives.forEach(function (elemActive) { + if (container !== elemActive) { + Collapse.collapseInterface(elemActive, 'hide'); + } + + if (!activesData) { + Data.setData(elemActive, DATA_KEY$3, null); + } + }); + } + + var dimension = this._getDimension(); + + this._element.classList.remove(CLASS_NAME_COLLAPSE); + + this._element.classList.add(CLASS_NAME_COLLAPSING); + + this._element.style[dimension] = 0; + + if (this._triggerArray.length) { + this._triggerArray.forEach(function (element) { + element.classList.remove(CLASS_NAME_COLLAPSED); + element.setAttribute('aria-expanded', true); + }); + } + + this.setTransitioning(true); + + var complete = function complete() { + _this._element.classList.remove(CLASS_NAME_COLLAPSING); + + _this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW); + + _this._element.style[dimension] = ''; + + _this.setTransitioning(false); + + EventHandler.trigger(_this._element, EVENT_SHOWN); + }; + + var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); + var scrollSize = "scroll" + capitalizedDimension; + var transitionDuration = getTransitionDurationFromElement(this._element); + EventHandler.one(this._element, TRANSITION_END, complete); + emulateTransitionEnd(this._element, transitionDuration); + this._element.style[dimension] = this._element[scrollSize] + "px"; + }; + + _proto.hide = function hide() { + var _this2 = this; + + if (this._isTransitioning || !this._element.classList.contains(CLASS_NAME_SHOW)) { + return; + } + + var startEvent = EventHandler.trigger(this._element, EVENT_HIDE); + + if (startEvent.defaultPrevented) { + return; + } + + var dimension = this._getDimension(); + + this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px"; + reflow(this._element); + + this._element.classList.add(CLASS_NAME_COLLAPSING); + + this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW); + + var triggerArrayLength = this._triggerArray.length; + + if (triggerArrayLength > 0) { + for (var i = 0; i < triggerArrayLength; i++) { + var trigger = this._triggerArray[i]; + var elem = getElementFromSelector(trigger); + + if (elem && !elem.classList.contains(CLASS_NAME_SHOW)) { + trigger.classList.add(CLASS_NAME_COLLAPSED); + trigger.setAttribute('aria-expanded', false); + } + } + } + + this.setTransitioning(true); + + var complete = function complete() { + _this2.setTransitioning(false); + + _this2._element.classList.remove(CLASS_NAME_COLLAPSING); + + _this2._element.classList.add(CLASS_NAME_COLLAPSE); + + EventHandler.trigger(_this2._element, EVENT_HIDDEN); + }; + + this._element.style[dimension] = ''; + var transitionDuration = getTransitionDurationFromElement(this._element); + EventHandler.one(this._element, TRANSITION_END, complete); + emulateTransitionEnd(this._element, transitionDuration); + }; + + _proto.setTransitioning = function setTransitioning(isTransitioning) { + this._isTransitioning = isTransitioning; + }; + + _proto.dispose = function dispose() { + Data.removeData(this._element, DATA_KEY$3); + this._config = null; + this._parent = null; + this._element = null; + this._triggerArray = null; + this._isTransitioning = null; + } // Private + ; + + _proto._getConfig = function _getConfig(config) { + config = _extends({}, Default$1, config); + config.toggle = Boolean(config.toggle); // Coerce string values + + typeCheckConfig(NAME$3, config, DefaultType$1); + return config; + }; + + _proto._getDimension = function _getDimension() { + return this._element.classList.contains(WIDTH) ? WIDTH : HEIGHT; + }; + + _proto._getParent = function _getParent() { + var _this3 = this; + + var parent = this._config.parent; + + if (isElement(parent)) { + // it's a jQuery object + if (typeof parent.jquery !== 'undefined' || typeof parent[0] !== 'undefined') { + parent = parent[0]; + } + } else { + parent = SelectorEngine.findOne(parent); + } + + var selector = SELECTOR_DATA_TOGGLE$1 + "[data-parent=\"" + parent + "\"]"; + SelectorEngine.find(selector, parent).forEach(function (element) { + var selected = getElementFromSelector(element); + + _this3._addAriaAndCollapsedClass(selected, [element]); + }); + return parent; + }; + + _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) { + if (!element || !triggerArray.length) { + return; + } + + var isOpen = element.classList.contains(CLASS_NAME_SHOW); + triggerArray.forEach(function (elem) { + if (isOpen) { + elem.classList.remove(CLASS_NAME_COLLAPSED); + } else { + elem.classList.add(CLASS_NAME_COLLAPSED); + } + + elem.setAttribute('aria-expanded', isOpen); + }); + } // Static + ; + + Collapse.collapseInterface = function collapseInterface(element, config) { + var data = Data.getData(element, DATA_KEY$3); + + var _config = _extends({}, Default$1, Manipulator.getDataAttributes(element), typeof config === 'object' && config ? config : {}); + + if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) { + _config.toggle = false; + } + + if (!data) { + data = new Collapse(element, _config); + } + + if (typeof config === 'string') { + if (typeof data[config] === 'undefined') { + throw new TypeError("No method named \"" + config + "\""); + } + + data[config](); + } + }; + + Collapse.jQueryInterface = function jQueryInterface(config) { + return this.each(function () { + Collapse.collapseInterface(this, config); + }); + }; + + Collapse.getInstance = function getInstance(element) { + return Data.getData(element, DATA_KEY$3); + }; + + _createClass(Collapse, null, [{ + key: "VERSION", + get: function get() { + return VERSION$3; + } + }, { + key: "Default", + get: function get() { + return Default$1; + } + }]); + + return Collapse; + }(); + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + + EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$1, function (event) { + // preventDefault only for elements (which change the URL) not inside the collapsible element + if (event.target.tagName === 'A') { + event.preventDefault(); + } + + var triggerData = Manipulator.getDataAttributes(this); + var selector = getSelectorFromElement(this); + var selectorElements = SelectorEngine.find(selector); + selectorElements.forEach(function (element) { + var data = Data.getData(element, DATA_KEY$3); + var config; + + if (data) { + // update parent attribute + if (data._parent === null && typeof triggerData.parent === 'string') { + data._config.parent = triggerData.parent; + data._parent = data._getParent(); + } + + config = 'toggle'; + } else { + config = triggerData; + } + + Collapse.collapseInterface(element, config); + }); + }); + var $$4 = getjQuery(); + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + * add .collapse to jQuery only if jQuery is present + */ + + /* istanbul ignore if */ + + if ($$4) { + var JQUERY_NO_CONFLICT$3 = $$4.fn[NAME$3]; + $$4.fn[NAME$3] = Collapse.jQueryInterface; + $$4.fn[NAME$3].Constructor = Collapse; + + $$4.fn[NAME$3].noConflict = function () { + $$4.fn[NAME$3] = JQUERY_NO_CONFLICT$3; + return Collapse.jQueryInterface; + }; + } + + /**! + * @fileOverview Kickass library to create and place poppers near their reference elements. + * @version 1.16.1 + * @license + * Copyright (c) 2016 Federico Zivolo and 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. + */ + var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined'; + + var timeoutDuration = function () { + var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; + for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) { + if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) { + return 1; + } + } + return 0; + }(); + + function microtaskDebounce(fn) { + var called = false; + return function () { + if (called) { + return; + } + called = true; + window.Promise.resolve().then(function () { + called = false; + fn(); + }); + }; + } + + function taskDebounce(fn) { + var scheduled = false; + return function () { + if (!scheduled) { + scheduled = true; + setTimeout(function () { + scheduled = false; + fn(); + }, timeoutDuration); + } + }; + } + + var supportsMicroTasks = isBrowser && window.Promise; + + /** + * Create a debounced version of a method, that's asynchronously deferred + * but called in the minimum time possible. + * + * @method + * @memberof Popper.Utils + * @argument {Function} fn + * @returns {Function} + */ + var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce; + + /** + * Check if the given variable is a function + * @method + * @memberof Popper.Utils + * @argument {Any} functionToCheck - variable to check + * @returns {Boolean} answer to: is a function? + */ + function isFunction(functionToCheck) { + var getType = {}; + return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; + } + + /** + * Get CSS computed property of the given element + * @method + * @memberof Popper.Utils + * @argument {Eement} element + * @argument {String} property + */ + function getStyleComputedProperty(element, property) { + if (element.nodeType !== 1) { + return []; + } + // NOTE: 1 DOM access here + var window = element.ownerDocument.defaultView; + var css = window.getComputedStyle(element, null); + return property ? css[property] : css; + } + + /** + * Returns the parentNode or the host of the element + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Element} parent + */ + function getParentNode(element) { + if (element.nodeName === 'HTML') { + return element; + } + return element.parentNode || element.host; + } + + /** + * Returns the scrolling parent of the given element + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Element} scroll parent + */ + function getScrollParent(element) { + // Return body, `getScroll` will take care to get the correct `scrollTop` from it + if (!element) { + return document.body; + } + + switch (element.nodeName) { + case 'HTML': + case 'BODY': + return element.ownerDocument.body; + case '#document': + return element.body; + } + + // Firefox want us to check `-x` and `-y` variations as well + + var _getStyleComputedProp = getStyleComputedProperty(element), + overflow = _getStyleComputedProp.overflow, + overflowX = _getStyleComputedProp.overflowX, + overflowY = _getStyleComputedProp.overflowY; + + if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { + return element; + } + + return getScrollParent(getParentNode(element)); + } + + /** + * Returns the reference node of the reference object, or the reference object itself. + * @method + * @memberof Popper.Utils + * @param {Element|Object} reference - the reference element (the popper will be relative to this) + * @returns {Element} parent + */ + function getReferenceNode(reference) { + return reference && reference.referenceNode ? reference.referenceNode : reference; + } + + var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode); + var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent); + + /** + * Determines if the browser is Internet Explorer + * @method + * @memberof Popper.Utils + * @param {Number} version to check + * @returns {Boolean} isIE + */ + function isIE(version) { + if (version === 11) { + return isIE11; + } + if (version === 10) { + return isIE10; + } + return isIE11 || isIE10; + } + + /** + * Returns the offset parent of the given element + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Element} offset parent + */ + function getOffsetParent(element) { + if (!element) { + return document.documentElement; + } + + var noOffsetParent = isIE(10) ? document.body : null; + + // NOTE: 1 DOM access here + var offsetParent = element.offsetParent || null; + // Skip hidden elements which don't have an offsetParent + while (offsetParent === noOffsetParent && element.nextElementSibling) { + offsetParent = (element = element.nextElementSibling).offsetParent; + } + + var nodeName = offsetParent && offsetParent.nodeName; + + if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') { + return element ? element.ownerDocument.documentElement : document.documentElement; + } + + // .offsetParent will return the closest TH, TD or TABLE in case + // no offsetParent is present, I hate this job... + if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') { + return getOffsetParent(offsetParent); + } + + return offsetParent; + } + + function isOffsetContainer(element) { + var nodeName = element.nodeName; + + if (nodeName === 'BODY') { + return false; + } + return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element; + } + + /** + * Finds the root node (document, shadowDOM root) of the given element + * @method + * @memberof Popper.Utils + * @argument {Element} node + * @returns {Element} root node + */ + function getRoot(node) { + if (node.parentNode !== null) { + return getRoot(node.parentNode); + } + + return node; + } + + /** + * Finds the offset parent common to the two provided nodes + * @method + * @memberof Popper.Utils + * @argument {Element} element1 + * @argument {Element} element2 + * @returns {Element} common offset parent + */ + function findCommonOffsetParent(element1, element2) { + // This check is needed to avoid errors in case one of the elements isn't defined for any reason + if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { + return document.documentElement; + } + + // Here we make sure to give as "start" the element that comes first in the DOM + var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING; + var start = order ? element1 : element2; + var end = order ? element2 : element1; + + // Get common ancestor container + var range = document.createRange(); + range.setStart(start, 0); + range.setEnd(end, 0); + var commonAncestorContainer = range.commonAncestorContainer; + + // Both nodes are inside #document + + if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) { + if (isOffsetContainer(commonAncestorContainer)) { + return commonAncestorContainer; + } + + return getOffsetParent(commonAncestorContainer); + } + + // one of the nodes is inside shadowDOM, find which one + var element1root = getRoot(element1); + if (element1root.host) { + return findCommonOffsetParent(element1root.host, element2); + } else { + return findCommonOffsetParent(element1, getRoot(element2).host); + } + } + + /** + * Gets the scroll value of the given element in the given side (top and left) + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @argument {String} side `top` or `left` + * @returns {number} amount of scrolled pixels + */ + function getScroll(element) { + var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top'; + + var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft'; + var nodeName = element.nodeName; + + if (nodeName === 'BODY' || nodeName === 'HTML') { + var html = element.ownerDocument.documentElement; + var scrollingElement = element.ownerDocument.scrollingElement || html; + return scrollingElement[upperSide]; + } + + return element[upperSide]; + } + + /* + * Sum or subtract the element scroll values (left and top) from a given rect object + * @method + * @memberof Popper.Utils + * @param {Object} rect - Rect object you want to change + * @param {HTMLElement} element - The element from the function reads the scroll values + * @param {Boolean} subtract - set to true if you want to subtract the scroll values + * @return {Object} rect - The modifier rect object + */ + function includeScroll(rect, element) { + var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var scrollTop = getScroll(element, 'top'); + var scrollLeft = getScroll(element, 'left'); + var modifier = subtract ? -1 : 1; + rect.top += scrollTop * modifier; + rect.bottom += scrollTop * modifier; + rect.left += scrollLeft * modifier; + rect.right += scrollLeft * modifier; + return rect; + } + + /* + * Helper to detect borders of a given element + * @method + * @memberof Popper.Utils + * @param {CSSStyleDeclaration} styles + * Result of `getStyleComputedProperty` on the given element + * @param {String} axis - `x` or `y` + * @return {number} borders - The borders size of the given axis + */ + + function getBordersSize(styles, axis) { + var sideA = axis === 'x' ? 'Left' : 'Top'; + var sideB = sideA === 'Left' ? 'Right' : 'Bottom'; + + return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']); + } + + function getSize(axis, body, html, computedStyle) { + return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0); + } + + function getWindowSizes(document) { + var body = document.body; + var html = document.documentElement; + var computedStyle = isIE(10) && getComputedStyle(html); + + return { + height: getSize('Height', body, html, computedStyle), + width: getSize('Width', body, html, computedStyle) + }; + } + + var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + }; + + var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + + + + + var defineProperty = function (obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + }; + + var _extends$1 = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + /** + * Given element offsets, generate an output similar to getBoundingClientRect + * @method + * @memberof Popper.Utils + * @argument {Object} offsets + * @returns {Object} ClientRect like output + */ + function getClientRect(offsets) { + return _extends$1({}, offsets, { + right: offsets.left + offsets.width, + bottom: offsets.top + offsets.height + }); + } + + /** + * Get bounding client rect of given element + * @method + * @memberof Popper.Utils + * @param {HTMLElement} element + * @return {Object} client rect + */ + function getBoundingClientRect(element) { + var rect = {}; + + // IE10 10 FIX: Please, don't ask, the element isn't + // considered in DOM in some circumstances... + // This isn't reproducible in IE10 compatibility mode of IE11 + try { + if (isIE(10)) { + rect = element.getBoundingClientRect(); + var scrollTop = getScroll(element, 'top'); + var scrollLeft = getScroll(element, 'left'); + rect.top += scrollTop; + rect.left += scrollLeft; + rect.bottom += scrollTop; + rect.right += scrollLeft; + } else { + rect = element.getBoundingClientRect(); + } + } catch (e) {} + + var result = { + left: rect.left, + top: rect.top, + width: rect.right - rect.left, + height: rect.bottom - rect.top + }; + + // subtract scrollbar size from sizes + var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {}; + var width = sizes.width || element.clientWidth || result.width; + var height = sizes.height || element.clientHeight || result.height; + + var horizScrollbar = element.offsetWidth - width; + var vertScrollbar = element.offsetHeight - height; + + // if an hypothetical scrollbar is detected, we must be sure it's not a `border` + // we make this check conditional for performance reasons + if (horizScrollbar || vertScrollbar) { + var styles = getStyleComputedProperty(element); + horizScrollbar -= getBordersSize(styles, 'x'); + vertScrollbar -= getBordersSize(styles, 'y'); + + result.width -= horizScrollbar; + result.height -= vertScrollbar; + } + + return getClientRect(result); + } + + function getOffsetRectRelativeToArbitraryNode(children, parent) { + var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var isIE10 = isIE(10); + var isHTML = parent.nodeName === 'HTML'; + var childrenRect = getBoundingClientRect(children); + var parentRect = getBoundingClientRect(parent); + var scrollParent = getScrollParent(children); + + var styles = getStyleComputedProperty(parent); + var borderTopWidth = parseFloat(styles.borderTopWidth); + var borderLeftWidth = parseFloat(styles.borderLeftWidth); + + // In cases where the parent is fixed, we must ignore negative scroll in offset calc + if (fixedPosition && isHTML) { + parentRect.top = Math.max(parentRect.top, 0); + parentRect.left = Math.max(parentRect.left, 0); + } + var offsets = getClientRect({ + top: childrenRect.top - parentRect.top - borderTopWidth, + left: childrenRect.left - parentRect.left - borderLeftWidth, + width: childrenRect.width, + height: childrenRect.height + }); + offsets.marginTop = 0; + offsets.marginLeft = 0; + + // Subtract margins of documentElement in case it's being used as parent + // we do this only on HTML because it's the only element that behaves + // differently when margins are applied to it. The margins are included in + // the box of the documentElement, in the other cases not. + if (!isIE10 && isHTML) { + var marginTop = parseFloat(styles.marginTop); + var marginLeft = parseFloat(styles.marginLeft); + + offsets.top -= borderTopWidth - marginTop; + offsets.bottom -= borderTopWidth - marginTop; + offsets.left -= borderLeftWidth - marginLeft; + offsets.right -= borderLeftWidth - marginLeft; + + // Attach marginTop and marginLeft because in some circumstances we may need them + offsets.marginTop = marginTop; + offsets.marginLeft = marginLeft; + } + + if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') { + offsets = includeScroll(offsets, parent); + } + + return offsets; + } + + function getViewportOffsetRectRelativeToArtbitraryNode(element) { + var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var html = element.ownerDocument.documentElement; + var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); + var width = Math.max(html.clientWidth, window.innerWidth || 0); + var height = Math.max(html.clientHeight, window.innerHeight || 0); + + var scrollTop = !excludeScroll ? getScroll(html) : 0; + var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; + + var offset = { + top: scrollTop - relativeOffset.top + relativeOffset.marginTop, + left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, + width: width, + height: height + }; + + return getClientRect(offset); + } + + /** + * Check if the given element is fixed or is inside a fixed parent + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @argument {Element} customContainer + * @returns {Boolean} answer to "isFixed?" + */ + function isFixed(element) { + var nodeName = element.nodeName; + if (nodeName === 'BODY' || nodeName === 'HTML') { + return false; + } + if (getStyleComputedProperty(element, 'position') === 'fixed') { + return true; + } + var parentNode = getParentNode(element); + if (!parentNode) { + return false; + } + return isFixed(parentNode); + } + + /** + * Finds the first parent of an element that has a transformed property defined + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Element} first transformed parent or documentElement + */ + + function getFixedPositionOffsetParent(element) { + // This check is needed to avoid errors in case one of the elements isn't defined for any reason + if (!element || !element.parentElement || isIE()) { + return document.documentElement; + } + var el = element.parentElement; + while (el && getStyleComputedProperty(el, 'transform') === 'none') { + el = el.parentElement; + } + return el || document.documentElement; + } + + /** + * Computed the boundaries limits and return them + * @method + * @memberof Popper.Utils + * @param {HTMLElement} popper + * @param {HTMLElement} reference + * @param {number} padding + * @param {HTMLElement} boundariesElement - Element used to define the boundaries + * @param {Boolean} fixedPosition - Is in fixed position mode + * @returns {Object} Coordinates of the boundaries + */ + function getBoundaries(popper, reference, padding, boundariesElement) { + var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + + // NOTE: 1 DOM access here + + var boundaries = { top: 0, left: 0 }; + var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); + + // Handle viewport case + if (boundariesElement === 'viewport') { + boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); + } else { + // Handle other cases based on DOM element used as boundaries + var boundariesNode = void 0; + if (boundariesElement === 'scrollParent') { + boundariesNode = getScrollParent(getParentNode(reference)); + if (boundariesNode.nodeName === 'BODY') { + boundariesNode = popper.ownerDocument.documentElement; + } + } else if (boundariesElement === 'window') { + boundariesNode = popper.ownerDocument.documentElement; + } else { + boundariesNode = boundariesElement; + } + + var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition); + + // In case of HTML, we need a different computation + if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { + var _getWindowSizes = getWindowSizes(popper.ownerDocument), + height = _getWindowSizes.height, + width = _getWindowSizes.width; + + boundaries.top += offsets.top - offsets.marginTop; + boundaries.bottom = height + offsets.top; + boundaries.left += offsets.left - offsets.marginLeft; + boundaries.right = width + offsets.left; + } else { + // for all the other DOM elements, this one is good + boundaries = offsets; + } + } + + // Add paddings + padding = padding || 0; + var isPaddingNumber = typeof padding === 'number'; + boundaries.left += isPaddingNumber ? padding : padding.left || 0; + boundaries.top += isPaddingNumber ? padding : padding.top || 0; + boundaries.right -= isPaddingNumber ? padding : padding.right || 0; + boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0; + + return boundaries; + } + + function getArea(_ref) { + var width = _ref.width, + height = _ref.height; + + return width * height; + } + + /** + * Utility used to transform the `auto` placement to the placement with more + * available space. + * @method + * @memberof Popper.Utils + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) { + var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; + + if (placement.indexOf('auto') === -1) { + return placement; + } + + var boundaries = getBoundaries(popper, reference, padding, boundariesElement); + + var rects = { + top: { + width: boundaries.width, + height: refRect.top - boundaries.top + }, + right: { + width: boundaries.right - refRect.right, + height: boundaries.height + }, + bottom: { + width: boundaries.width, + height: boundaries.bottom - refRect.bottom + }, + left: { + width: refRect.left - boundaries.left, + height: boundaries.height + } + }; + + var sortedAreas = Object.keys(rects).map(function (key) { + return _extends$1({ + key: key + }, rects[key], { + area: getArea(rects[key]) + }); + }).sort(function (a, b) { + return b.area - a.area; + }); + + var filteredAreas = sortedAreas.filter(function (_ref2) { + var width = _ref2.width, + height = _ref2.height; + return width >= popper.clientWidth && height >= popper.clientHeight; + }); + + var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key; + + var variation = placement.split('-')[1]; + + return computedPlacement + (variation ? '-' + variation : ''); + } + + /** + * Get offsets to the reference element + * @method + * @memberof Popper.Utils + * @param {Object} state + * @param {Element} popper - the popper element + * @param {Element} reference - the reference element (the popper will be relative to this) + * @param {Element} fixedPosition - is in fixed position mode + * @returns {Object} An object containing the offsets which will be applied to the popper + */ + function getReferenceOffsets(state, popper, reference) { + var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; + + var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); + return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); + } + + /** + * Get the outer sizes of the given element (offset size + margins) + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Object} object containing width and height properties + */ + function getOuterSizes(element) { + var window = element.ownerDocument.defaultView; + var styles = window.getComputedStyle(element); + var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0); + var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0); + var result = { + width: element.offsetWidth + y, + height: element.offsetHeight + x + }; + return result; + } + + /** + * Get the opposite placement of the given one + * @method + * @memberof Popper.Utils + * @argument {String} placement + * @returns {String} flipped placement + */ + function getOppositePlacement(placement) { + var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; + return placement.replace(/left|right|bottom|top/g, function (matched) { + return hash[matched]; + }); + } + + /** + * Get offsets to the popper + * @method + * @memberof Popper.Utils + * @param {Object} position - CSS position the Popper will get applied + * @param {HTMLElement} popper - the popper element + * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) + * @param {String} placement - one of the valid placement options + * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper + */ + function getPopperOffsets(popper, referenceOffsets, placement) { + placement = placement.split('-')[0]; + + // Get popper node sizes + var popperRect = getOuterSizes(popper); + + // Add position, width and height to our offsets object + var popperOffsets = { + width: popperRect.width, + height: popperRect.height + }; + + // depending by the popper placement we have to compute its offsets slightly differently + var isHoriz = ['right', 'left'].indexOf(placement) !== -1; + var mainSide = isHoriz ? 'top' : 'left'; + var secondarySide = isHoriz ? 'left' : 'top'; + var measurement = isHoriz ? 'height' : 'width'; + var secondaryMeasurement = !isHoriz ? 'height' : 'width'; + + popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2; + if (placement === secondarySide) { + popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; + } else { + popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)]; + } + + return popperOffsets; + } + + /** + * Mimics the `find` method of Array + * @method + * @memberof Popper.Utils + * @argument {Array} arr + * @argument prop + * @argument value + * @returns index or -1 + */ + function find$1(arr, check) { + // use native find if supported + if (Array.prototype.find) { + return arr.find(check); + } + + // use `filter` to obtain the same behavior of `find` + return arr.filter(check)[0]; + } + + /** + * Return the index of the matching object + * @method + * @memberof Popper.Utils + * @argument {Array} arr + * @argument prop + * @argument value + * @returns index or -1 + */ + function findIndex(arr, prop, value) { + // use native findIndex if supported + if (Array.prototype.findIndex) { + return arr.findIndex(function (cur) { + return cur[prop] === value; + }); + } + + // use `find` + `indexOf` if `findIndex` isn't supported + var match = find$1(arr, function (obj) { + return obj[prop] === value; + }); + return arr.indexOf(match); + } + + /** + * Loop trough the list of modifiers and run them in order, + * each of them will then edit the data object. + * @method + * @memberof Popper.Utils + * @param {dataObject} data + * @param {Array} modifiers + * @param {String} ends - Optional modifier name used as stopper + * @returns {dataObject} + */ + function runModifiers(modifiers, data, ends) { + var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends)); + + modifiersToRun.forEach(function (modifier) { + if (modifier['function']) { + // eslint-disable-line dot-notation + console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); + } + var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation + if (modifier.enabled && isFunction(fn)) { + // Add properties to offsets to make them a complete clientRect object + // we do this before each modifier to make sure the previous one doesn't + // mess with these values + data.offsets.popper = getClientRect(data.offsets.popper); + data.offsets.reference = getClientRect(data.offsets.reference); + + data = fn(data, modifier); + } + }); + + return data; + } + + /** + * Updates the position of the popper, computing the new offsets and applying + * the new style.
    + * Prefer `scheduleUpdate` over `update` because of performance reasons. + * @method + * @memberof Popper + */ + function update() { + // if popper is destroyed, don't perform any further update + if (this.state.isDestroyed) { + return; + } + + var data = { + instance: this, + styles: {}, + arrowStyles: {}, + attributes: {}, + flipped: false, + offsets: {} + }; + + // compute reference element offsets + data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed); + + // compute auto placement, store placement inside the data object, + // modifiers will be able to edit `placement` if needed + // and refer to originalPlacement to know the original value + data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding); + + // store the computed placement inside `originalPlacement` + data.originalPlacement = data.placement; + + data.positionFixed = this.options.positionFixed; + + // compute the popper offsets + data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement); + + data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'; + + // run the modifiers + data = runModifiers(this.modifiers, data); + + // the first `update` will call `onCreate` callback + // the other ones will call `onUpdate` callback + if (!this.state.isCreated) { + this.state.isCreated = true; + this.options.onCreate(data); + } else { + this.options.onUpdate(data); + } + } + + /** + * Helper used to know if the given modifier is enabled. + * @method + * @memberof Popper.Utils + * @returns {Boolean} + */ + function isModifierEnabled(modifiers, modifierName) { + return modifiers.some(function (_ref) { + var name = _ref.name, + enabled = _ref.enabled; + return enabled && name === modifierName; + }); + } + + /** + * Get the prefixed supported property name + * @method + * @memberof Popper.Utils + * @argument {String} property (camelCase) + * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) + */ + function getSupportedPropertyName(property) { + var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; + var upperProp = property.charAt(0).toUpperCase() + property.slice(1); + + for (var i = 0; i < prefixes.length; i++) { + var prefix = prefixes[i]; + var toCheck = prefix ? '' + prefix + upperProp : property; + if (typeof document.body.style[toCheck] !== 'undefined') { + return toCheck; + } + } + return null; + } + + /** + * Destroys the popper. + * @method + * @memberof Popper + */ + function destroy() { + this.state.isDestroyed = true; + + // touch DOM only if `applyStyle` modifier is enabled + if (isModifierEnabled(this.modifiers, 'applyStyle')) { + this.popper.removeAttribute('x-placement'); + this.popper.style.position = ''; + this.popper.style.top = ''; + this.popper.style.left = ''; + this.popper.style.right = ''; + this.popper.style.bottom = ''; + this.popper.style.willChange = ''; + this.popper.style[getSupportedPropertyName('transform')] = ''; + } + + this.disableEventListeners(); + + // remove the popper if user explicitly asked for the deletion on destroy + // do not use `remove` because IE11 doesn't support it + if (this.options.removeOnDestroy) { + this.popper.parentNode.removeChild(this.popper); + } + return this; + } + + /** + * Get the window associated with the element + * @argument {Element} element + * @returns {Window} + */ + function getWindow(element) { + var ownerDocument = element.ownerDocument; + return ownerDocument ? ownerDocument.defaultView : window; + } + + function attachToScrollParents(scrollParent, event, callback, scrollParents) { + var isBody = scrollParent.nodeName === 'BODY'; + var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; + target.addEventListener(event, callback, { passive: true }); + + if (!isBody) { + attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents); + } + scrollParents.push(target); + } + + /** + * Setup needed event listeners used to update the popper position + * @method + * @memberof Popper.Utils + * @private + */ + function setupEventListeners(reference, options, state, updateBound) { + // Resize event listener on window + state.updateBound = updateBound; + getWindow(reference).addEventListener('resize', state.updateBound, { passive: true }); + + // Scroll event listener on scroll parents + var scrollElement = getScrollParent(reference); + attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents); + state.scrollElement = scrollElement; + state.eventsEnabled = true; + + return state; + } + + /** + * It will add resize/scroll events and start recalculating + * position of the popper element when they are triggered. + * @method + * @memberof Popper + */ + function enableEventListeners() { + if (!this.state.eventsEnabled) { + this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate); + } + } + + /** + * Remove event listeners used to update the popper position + * @method + * @memberof Popper.Utils + * @private + */ + function removeEventListeners(reference, state) { + // Remove resize event listener on window + getWindow(reference).removeEventListener('resize', state.updateBound); + + // Remove scroll event listener on scroll parents + state.scrollParents.forEach(function (target) { + target.removeEventListener('scroll', state.updateBound); + }); + + // Reset state + state.updateBound = null; + state.scrollParents = []; + state.scrollElement = null; + state.eventsEnabled = false; + return state; + } + + /** + * It will remove resize/scroll events and won't recalculate popper position + * when they are triggered. It also won't trigger `onUpdate` callback anymore, + * unless you call `update` method manually. + * @method + * @memberof Popper + */ + function disableEventListeners() { + if (this.state.eventsEnabled) { + cancelAnimationFrame(this.scheduleUpdate); + this.state = removeEventListeners(this.reference, this.state); + } + } + + /** + * Tells if a given input is a number + * @method + * @memberof Popper.Utils + * @param {*} input to check + * @return {Boolean} + */ + function isNumeric(n) { + return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); + } + + /** + * Set the style to the given popper + * @method + * @memberof Popper.Utils + * @argument {Element} element - Element to apply the style to + * @argument {Object} styles + * Object with a list of properties and values which will be applied to the element + */ + function setStyles(element, styles) { + Object.keys(styles).forEach(function (prop) { + var unit = ''; + // add unit if the value is numeric and is one of the following + if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) { + unit = 'px'; + } + element.style[prop] = styles[prop] + unit; + }); + } + + /** + * Set the attributes to the given popper + * @method + * @memberof Popper.Utils + * @argument {Element} element - Element to apply the attributes to + * @argument {Object} styles + * Object with a list of properties and values which will be applied to the element + */ + function setAttributes(element, attributes) { + Object.keys(attributes).forEach(function (prop) { + var value = attributes[prop]; + if (value !== false) { + element.setAttribute(prop, attributes[prop]); + } else { + element.removeAttribute(prop); + } + }); + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} data.styles - List of style properties - values to apply to popper element + * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The same data object + */ + function applyStyle(data) { + // any property present in `data.styles` will be applied to the popper, + // in this way we can make the 3rd party modifiers add custom styles to it + // Be aware, modifiers could override the properties defined in the previous + // lines of this modifier! + setStyles(data.instance.popper, data.styles); + + // any property present in `data.attributes` will be applied to the popper, + // they will be set as HTML attributes of the element + setAttributes(data.instance.popper, data.attributes); + + // if arrowElement is defined and arrowStyles has some properties + if (data.arrowElement && Object.keys(data.arrowStyles).length) { + setStyles(data.arrowElement, data.arrowStyles); + } + + return data; + } + + /** + * Set the x-placement attribute before everything else because it could be used + * to add margins to the popper margins needs to be calculated to get the + * correct popper offsets. + * @method + * @memberof Popper.modifiers + * @param {HTMLElement} reference - The reference element used to position the popper + * @param {HTMLElement} popper - The HTML element used as popper + * @param {Object} options - Popper.js options + */ + function applyStyleOnLoad(reference, popper, options, modifierOptions, state) { + // compute reference element offsets + var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); + + // compute auto placement, store placement inside the data object, + // modifiers will be able to edit `placement` if needed + // and refer to originalPlacement to know the original value + var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding); + + popper.setAttribute('x-placement', placement); + + // Apply `position` to popper before anything else because + // without the position applied we can't guarantee correct computations + setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' }); + + return options; + } + + /** + * @function + * @memberof Popper.Utils + * @argument {Object} data - The data object generated by `update` method + * @argument {Boolean} shouldRound - If the offsets should be rounded at all + * @returns {Object} The popper's position offsets rounded + * + * The tale of pixel-perfect positioning. It's still not 100% perfect, but as + * good as it can be within reason. + * Discussion here: https://github.com/FezVrasta/popper.js/pull/715 + * + * Low DPI screens cause a popper to be blurry if not using full pixels (Safari + * as well on High DPI screens). + * + * Firefox prefers no rounding for positioning and does not have blurriness on + * high DPI screens. + * + * Only horizontal placement and left/right values need to be considered. + */ + function getRoundedOffsets(data, shouldRound) { + var _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + var round = Math.round, + floor = Math.floor; + + var noRound = function noRound(v) { + return v; + }; + + var referenceWidth = round(reference.width); + var popperWidth = round(popper.width); + + var isVertical = ['left', 'right'].indexOf(data.placement) !== -1; + var isVariation = data.placement.indexOf('-') !== -1; + var sameWidthParity = referenceWidth % 2 === popperWidth % 2; + var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1; + + var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor; + var verticalToInteger = !shouldRound ? noRound : round; + + return { + left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left), + top: verticalToInteger(popper.top), + bottom: verticalToInteger(popper.bottom), + right: horizontalToInteger(popper.right) + }; + } + + var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent); + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function computeStyle(data, options) { + var x = options.x, + y = options.y; + var popper = data.offsets.popper; + + // Remove this legacy support in Popper.js v2 + + var legacyGpuAccelerationOption = find$1(data.instance.modifiers, function (modifier) { + return modifier.name === 'applyStyle'; + }).gpuAcceleration; + if (legacyGpuAccelerationOption !== undefined) { + console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); + } + var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; + + var offsetParent = getOffsetParent(data.instance.popper); + var offsetParentRect = getBoundingClientRect(offsetParent); + + // Styles + var styles = { + position: popper.position + }; + + var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox); + + var sideA = x === 'bottom' ? 'top' : 'bottom'; + var sideB = y === 'right' ? 'left' : 'right'; + + // if gpuAcceleration is set to `true` and transform is supported, + // we use `translate3d` to apply the position to the popper we + // automatically use the supported prefixed version if needed + var prefixedProperty = getSupportedPropertyName('transform'); + + // now, let's make a step back and look at this code closely (wtf?) + // If the content of the popper grows once it's been positioned, it + // may happen that the popper gets misplaced because of the new content + // overflowing its reference element + // To avoid this problem, we provide two options (x and y), which allow + // the consumer to define the offset origin. + // If we position a popper on top of a reference element, we can set + // `x` to `top` to make the popper grow towards its top instead of + // its bottom. + var left = void 0, + top = void 0; + if (sideA === 'bottom') { + // when offsetParent is the positioning is relative to the bottom of the screen (excluding the scrollbar) + // and not the bottom of the html element + if (offsetParent.nodeName === 'HTML') { + top = -offsetParent.clientHeight + offsets.bottom; + } else { + top = -offsetParentRect.height + offsets.bottom; + } + } else { + top = offsets.top; + } + if (sideB === 'right') { + if (offsetParent.nodeName === 'HTML') { + left = -offsetParent.clientWidth + offsets.right; + } else { + left = -offsetParentRect.width + offsets.right; + } + } else { + left = offsets.left; + } + if (gpuAcceleration && prefixedProperty) { + styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; + styles[sideA] = 0; + styles[sideB] = 0; + styles.willChange = 'transform'; + } else { + // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties + var invertTop = sideA === 'bottom' ? -1 : 1; + var invertLeft = sideB === 'right' ? -1 : 1; + styles[sideA] = top * invertTop; + styles[sideB] = left * invertLeft; + styles.willChange = sideA + ', ' + sideB; + } + + // Attributes + var attributes = { + 'x-placement': data.placement + }; + + // Update `data` attributes, styles and arrowStyles + data.attributes = _extends$1({}, attributes, data.attributes); + data.styles = _extends$1({}, styles, data.styles); + data.arrowStyles = _extends$1({}, data.offsets.arrow, data.arrowStyles); + + return data; + } + + /** + * Helper used to know if the given modifier depends from another one.
    + * It checks if the needed modifier is listed and enabled. + * @method + * @memberof Popper.Utils + * @param {Array} modifiers - list of modifiers + * @param {String} requestingName - name of requesting modifier + * @param {String} requestedName - name of requested modifier + * @returns {Boolean} + */ + function isModifierRequired(modifiers, requestingName, requestedName) { + var requesting = find$1(modifiers, function (_ref) { + var name = _ref.name; + return name === requestingName; + }); + + var isRequired = !!requesting && modifiers.some(function (modifier) { + return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; + }); + + if (!isRequired) { + var _requesting = '`' + requestingName + '`'; + var requested = '`' + requestedName + '`'; + console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); + } + return isRequired; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function arrow(data, options) { + var _data$offsets$arrow; + + // arrow depends on keepTogether in order to work + if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { + return data; + } + + var arrowElement = options.element; + + // if arrowElement is a string, suppose it's a CSS selector + if (typeof arrowElement === 'string') { + arrowElement = data.instance.popper.querySelector(arrowElement); + + // if arrowElement is not found, don't run the modifier + if (!arrowElement) { + return data; + } + } else { + // if the arrowElement isn't a query selector we must check that the + // provided DOM node is child of its popper node + if (!data.instance.popper.contains(arrowElement)) { + console.warn('WARNING: `arrow.element` must be child of its popper element!'); + return data; + } + } + + var placement = data.placement.split('-')[0]; + var _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + + var isVertical = ['left', 'right'].indexOf(placement) !== -1; + + var len = isVertical ? 'height' : 'width'; + var sideCapitalized = isVertical ? 'Top' : 'Left'; + var side = sideCapitalized.toLowerCase(); + var altSide = isVertical ? 'left' : 'top'; + var opSide = isVertical ? 'bottom' : 'right'; + var arrowElementSize = getOuterSizes(arrowElement)[len]; + + // + // extends keepTogether behavior making sure the popper and its + // reference have enough pixels in conjunction + // + + // top/left side + if (reference[opSide] - arrowElementSize < popper[side]) { + data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); + } + // bottom/right side + if (reference[side] + arrowElementSize > popper[opSide]) { + data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; + } + data.offsets.popper = getClientRect(data.offsets.popper); + + // compute center of the popper + var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; + + // Compute the sideValue using the updated popper offsets + // take popper margin in account because we don't have this info available + var css = getStyleComputedProperty(data.instance.popper); + var popperMarginSide = parseFloat(css['margin' + sideCapitalized]); + var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']); + var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; + + // prevent arrowElement from being placed not contiguously to its popper + sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); + + data.arrowElement = arrowElement; + data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); + + return data; + } + + /** + * Get the opposite placement variation of the given one + * @method + * @memberof Popper.Utils + * @argument {String} placement variation + * @returns {String} flipped placement variation + */ + function getOppositeVariation(variation) { + if (variation === 'end') { + return 'start'; + } else if (variation === 'start') { + return 'end'; + } + return variation; + } + + /** + * List of accepted placements to use as values of the `placement` option.
    + * Valid placements are: + * - `auto` + * - `top` + * - `right` + * - `bottom` + * - `left` + * + * Each placement can have a variation from this list: + * - `-start` + * - `-end` + * + * Variations are interpreted easily if you think of them as the left to right + * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` + * is right.
    + * Vertically (`left` and `right`), `start` is top and `end` is bottom. + * + * Some valid examples are: + * - `top-end` (on top of reference, right aligned) + * - `right-start` (on right of reference, top aligned) + * - `bottom` (on bottom, centered) + * - `auto-end` (on the side with more space available, alignment depends by placement) + * + * @static + * @type {Array} + * @enum {String} + * @readonly + * @method placements + * @memberof Popper + */ + var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']; + + // Get rid of `auto` `auto-start` and `auto-end` + var validPlacements = placements.slice(3); + + /** + * Given an initial placement, returns all the subsequent placements + * clockwise (or counter-clockwise). + * + * @method + * @memberof Popper.Utils + * @argument {String} placement - A valid placement (it accepts variations) + * @argument {Boolean} counter - Set to true to walk the placements counterclockwise + * @returns {Array} placements including their variations + */ + function clockwise(placement) { + var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var index = validPlacements.indexOf(placement); + var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); + return counter ? arr.reverse() : arr; + } + + var BEHAVIORS = { + FLIP: 'flip', + CLOCKWISE: 'clockwise', + COUNTERCLOCKWISE: 'counterclockwise' + }; + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function flip(data, options) { + // if `inner` modifier is enabled, we can't use the `flip` modifier + if (isModifierEnabled(data.instance.modifiers, 'inner')) { + return data; + } + + if (data.flipped && data.placement === data.originalPlacement) { + // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides + return data; + } + + var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed); + + var placement = data.placement.split('-')[0]; + var placementOpposite = getOppositePlacement(placement); + var variation = data.placement.split('-')[1] || ''; + + var flipOrder = []; + + switch (options.behavior) { + case BEHAVIORS.FLIP: + flipOrder = [placement, placementOpposite]; + break; + case BEHAVIORS.CLOCKWISE: + flipOrder = clockwise(placement); + break; + case BEHAVIORS.COUNTERCLOCKWISE: + flipOrder = clockwise(placement, true); + break; + default: + flipOrder = options.behavior; + } + + flipOrder.forEach(function (step, index) { + if (placement !== step || flipOrder.length === index + 1) { + return data; + } + + placement = data.placement.split('-')[0]; + placementOpposite = getOppositePlacement(placement); + + var popperOffsets = data.offsets.popper; + var refOffsets = data.offsets.reference; + + // using floor because the reference offsets may contain decimals we are not going to consider here + var floor = Math.floor; + var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom); + + var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); + var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); + var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); + var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); + + var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; + + // flip the variation if required + var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; + + // flips variation if reference element overflows boundaries + var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom); + + // flips variation if popper content overflows boundaries + var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop); + + var flippedVariation = flippedVariationByRef || flippedVariationByContent; + + if (overlapsRef || overflowsBoundaries || flippedVariation) { + // this boolean to detect any flip loop + data.flipped = true; + + if (overlapsRef || overflowsBoundaries) { + placement = flipOrder[index + 1]; + } + + if (flippedVariation) { + variation = getOppositeVariation(variation); + } + + data.placement = placement + (variation ? '-' + variation : ''); + + // this object contains `position`, we want to preserve it along with + // any additional property we may add in the future + data.offsets.popper = _extends$1({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); + + data = runModifiers(data.instance.modifiers, data, 'flip'); + } + }); + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function keepTogether(data) { + var _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + + var placement = data.placement.split('-')[0]; + var floor = Math.floor; + var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; + var side = isVertical ? 'right' : 'bottom'; + var opSide = isVertical ? 'left' : 'top'; + var measurement = isVertical ? 'width' : 'height'; + + if (popper[side] < floor(reference[opSide])) { + data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; + } + if (popper[opSide] > floor(reference[side])) { + data.offsets.popper[opSide] = floor(reference[side]); + } + + return data; + } + + /** + * Converts a string containing value + unit into a px value number + * @function + * @memberof {modifiers~offset} + * @private + * @argument {String} str - Value + unit string + * @argument {String} measurement - `height` or `width` + * @argument {Object} popperOffsets + * @argument {Object} referenceOffsets + * @returns {Number|String} + * Value in pixels, or original string if no values were extracted + */ + function toValue(str, measurement, popperOffsets, referenceOffsets) { + // separate value from unit + var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); + var value = +split[1]; + var unit = split[2]; + + // If it's not a number it's an operator, I guess + if (!value) { + return str; + } + + if (unit.indexOf('%') === 0) { + var element = void 0; + switch (unit) { + case '%p': + element = popperOffsets; + break; + case '%': + case '%r': + default: + element = referenceOffsets; + } + + var rect = getClientRect(element); + return rect[measurement] / 100 * value; + } else if (unit === 'vh' || unit === 'vw') { + // if is a vh or vw, we calculate the size based on the viewport + var size = void 0; + if (unit === 'vh') { + size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); + } else { + size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); + } + return size / 100 * value; + } else { + // if is an explicit pixel unit, we get rid of the unit and keep the value + // if is an implicit unit, it's px, and we return just the value + return value; + } + } + + /** + * Parse an `offset` string to extrapolate `x` and `y` numeric offsets. + * @function + * @memberof {modifiers~offset} + * @private + * @argument {String} offset + * @argument {Object} popperOffsets + * @argument {Object} referenceOffsets + * @argument {String} basePlacement + * @returns {Array} a two cells array with x and y offsets in numbers + */ + function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { + var offsets = [0, 0]; + + // Use height if placement is left or right and index is 0 otherwise use width + // in this way the first offset will use an axis and the second one + // will use the other one + var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; + + // Split the offset string to obtain a list of values and operands + // The regex addresses values with the plus or minus sign in front (+10, -20, etc) + var fragments = offset.split(/(\+|\-)/).map(function (frag) { + return frag.trim(); + }); + + // Detect if the offset string contains a pair of values or a single one + // they could be separated by comma or space + var divider = fragments.indexOf(find$1(fragments, function (frag) { + return frag.search(/,|\s/) !== -1; + })); + + if (fragments[divider] && fragments[divider].indexOf(',') === -1) { + console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); + } + + // If divider is found, we divide the list of values and operands to divide + // them by ofset X and Y. + var splitRegex = /\s*,\s*|\s+/; + var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments]; + + // Convert the values with units to absolute pixels to allow our computations + ops = ops.map(function (op, index) { + // Most of the units rely on the orientation of the popper + var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; + var mergeWithPrevious = false; + return op + // This aggregates any `+` or `-` sign that aren't considered operators + // e.g.: 10 + +5 => [10, +, +5] + .reduce(function (a, b) { + if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { + a[a.length - 1] = b; + mergeWithPrevious = true; + return a; + } else if (mergeWithPrevious) { + a[a.length - 1] += b; + mergeWithPrevious = false; + return a; + } else { + return a.concat(b); + } + }, []) + // Here we convert the string values into number values (in px) + .map(function (str) { + return toValue(str, measurement, popperOffsets, referenceOffsets); + }); + }); + + // Loop trough the offsets arrays and execute the operations + ops.forEach(function (op, index) { + op.forEach(function (frag, index2) { + if (isNumeric(frag)) { + offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); + } + }); + }); + return offsets; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @argument {Number|String} options.offset=0 + * The offset value as described in the modifier description + * @returns {Object} The data object, properly modified + */ + function offset(data, _ref) { + var offset = _ref.offset; + var placement = data.placement, + _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + + var basePlacement = placement.split('-')[0]; + + var offsets = void 0; + if (isNumeric(+offset)) { + offsets = [+offset, 0]; + } else { + offsets = parseOffset(offset, popper, reference, basePlacement); + } + + if (basePlacement === 'left') { + popper.top += offsets[0]; + popper.left -= offsets[1]; + } else if (basePlacement === 'right') { + popper.top += offsets[0]; + popper.left += offsets[1]; + } else if (basePlacement === 'top') { + popper.left += offsets[0]; + popper.top -= offsets[1]; + } else if (basePlacement === 'bottom') { + popper.left += offsets[0]; + popper.top += offsets[1]; + } + + data.popper = popper; + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function preventOverflow(data, options) { + var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); + + // If offsetParent is the reference element, we really want to + // go one step up and use the next offsetParent as reference to + // avoid to make this modifier completely useless and look like broken + if (data.instance.reference === boundariesElement) { + boundariesElement = getOffsetParent(boundariesElement); + } + + // NOTE: DOM access here + // resets the popper's position so that the document size can be calculated excluding + // the size of the popper element itself + var transformProp = getSupportedPropertyName('transform'); + var popperStyles = data.instance.popper.style; // assignment to help minification + var top = popperStyles.top, + left = popperStyles.left, + transform = popperStyles[transformProp]; + + popperStyles.top = ''; + popperStyles.left = ''; + popperStyles[transformProp] = ''; + + var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); + + // NOTE: DOM access here + // restores the original style properties after the offsets have been computed + popperStyles.top = top; + popperStyles.left = left; + popperStyles[transformProp] = transform; + + options.boundaries = boundaries; + + var order = options.priority; + var popper = data.offsets.popper; + + var check = { + primary: function primary(placement) { + var value = popper[placement]; + if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { + value = Math.max(popper[placement], boundaries[placement]); + } + return defineProperty({}, placement, value); + }, + secondary: function secondary(placement) { + var mainSide = placement === 'right' ? 'left' : 'top'; + var value = popper[mainSide]; + if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { + value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); + } + return defineProperty({}, mainSide, value); + } + }; + + order.forEach(function (placement) { + var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; + popper = _extends$1({}, popper, check[side](placement)); + }); + + data.offsets.popper = popper; + + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function shift(data) { + var placement = data.placement; + var basePlacement = placement.split('-')[0]; + var shiftvariation = placement.split('-')[1]; + + // if shift shiftvariation is specified, run the modifier + if (shiftvariation) { + var _data$offsets = data.offsets, + reference = _data$offsets.reference, + popper = _data$offsets.popper; + + var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; + var side = isVertical ? 'left' : 'top'; + var measurement = isVertical ? 'width' : 'height'; + + var shiftOffsets = { + start: defineProperty({}, side, reference[side]), + end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement]) + }; + + data.offsets.popper = _extends$1({}, popper, shiftOffsets[shiftvariation]); + } + + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function hide(data) { + if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { + return data; + } + + var refRect = data.offsets.reference; + var bound = find$1(data.instance.modifiers, function (modifier) { + return modifier.name === 'preventOverflow'; + }).boundaries; + + if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { + // Avoid unnecessary DOM access if visibility hasn't changed + if (data.hide === true) { + return data; + } + + data.hide = true; + data.attributes['x-out-of-boundaries'] = ''; + } else { + // Avoid unnecessary DOM access if visibility hasn't changed + if (data.hide === false) { + return data; + } + + data.hide = false; + data.attributes['x-out-of-boundaries'] = false; + } + + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function inner(data) { + var placement = data.placement; + var basePlacement = placement.split('-')[0]; + var _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + + var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; + + var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; + + popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); + + data.placement = getOppositePlacement(placement); + data.offsets.popper = getClientRect(popper); + + return data; + } + + /** + * Modifier function, each modifier can have a function of this type assigned + * to its `fn` property.
    + * These functions will be called on each update, this means that you must + * make sure they are performant enough to avoid performance bottlenecks. + * + * @function ModifierFn + * @argument {dataObject} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {dataObject} The data object, properly modified + */ + + /** + * Modifiers are plugins used to alter the behavior of your poppers.
    + * Popper.js uses a set of 9 modifiers to provide all the basic functionalities + * needed by the library. + * + * Usually you don't want to override the `order`, `fn` and `onLoad` props. + * All the other properties are configurations that could be tweaked. + * @namespace modifiers + */ + var modifiers = { + /** + * Modifier used to shift the popper on the start or end of its reference + * element.
    + * It will read the variation of the `placement` property.
    + * It can be one either `-end` or `-start`. + * @memberof modifiers + * @inner + */ + shift: { + /** @prop {number} order=100 - Index used to define the order of execution */ + order: 100, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: shift + }, + + /** + * The `offset` modifier can shift your popper on both its axis. + * + * It accepts the following units: + * - `px` or unit-less, interpreted as pixels + * - `%` or `%r`, percentage relative to the length of the reference element + * - `%p`, percentage relative to the length of the popper element + * - `vw`, CSS viewport width unit + * - `vh`, CSS viewport height unit + * + * For length is intended the main axis relative to the placement of the popper.
    + * This means that if the placement is `top` or `bottom`, the length will be the + * `width`. In case of `left` or `right`, it will be the `height`. + * + * You can provide a single value (as `Number` or `String`), or a pair of values + * as `String` divided by a comma or one (or more) white spaces.
    + * The latter is a deprecated method because it leads to confusion and will be + * removed in v2.
    + * Additionally, it accepts additions and subtractions between different units. + * Note that multiplications and divisions aren't supported. + * + * Valid examples are: + * ``` + * 10 + * '10%' + * '10, 10' + * '10%, 10' + * '10 + 10%' + * '10 - 5vh + 3%' + * '-10px + 5vh, 5px - 6%' + * ``` + * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap + * > with their reference element, unfortunately, you will have to disable the `flip` modifier. + * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373). + * + * @memberof modifiers + * @inner + */ + offset: { + /** @prop {number} order=200 - Index used to define the order of execution */ + order: 200, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: offset, + /** @prop {Number|String} offset=0 + * The offset value as described in the modifier description + */ + offset: 0 + }, + + /** + * Modifier used to prevent the popper from being positioned outside the boundary. + * + * A scenario exists where the reference itself is not within the boundaries.
    + * We can say it has "escaped the boundaries" — or just "escaped".
    + * In this case we need to decide whether the popper should either: + * + * - detach from the reference and remain "trapped" in the boundaries, or + * - if it should ignore the boundary and "escape with its reference" + * + * When `escapeWithReference` is set to`true` and reference is completely + * outside its boundaries, the popper will overflow (or completely leave) + * the boundaries in order to remain attached to the edge of the reference. + * + * @memberof modifiers + * @inner + */ + preventOverflow: { + /** @prop {number} order=300 - Index used to define the order of execution */ + order: 300, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: preventOverflow, + /** + * @prop {Array} [priority=['left','right','top','bottom']] + * Popper will try to prevent overflow following these priorities by default, + * then, it could overflow on the left and on top of the `boundariesElement` + */ + priority: ['left', 'right', 'top', 'bottom'], + /** + * @prop {number} padding=5 + * Amount of pixel used to define a minimum distance between the boundaries + * and the popper. This makes sure the popper always has a little padding + * between the edges of its container + */ + padding: 5, + /** + * @prop {String|HTMLElement} boundariesElement='scrollParent' + * Boundaries used by the modifier. Can be `scrollParent`, `window`, + * `viewport` or any DOM element. + */ + boundariesElement: 'scrollParent' + }, + + /** + * Modifier used to make sure the reference and its popper stay near each other + * without leaving any gap between the two. Especially useful when the arrow is + * enabled and you want to ensure that it points to its reference element. + * It cares only about the first axis. You can still have poppers with margin + * between the popper and its reference element. + * @memberof modifiers + * @inner + */ + keepTogether: { + /** @prop {number} order=400 - Index used to define the order of execution */ + order: 400, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: keepTogether + }, + + /** + * This modifier is used to move the `arrowElement` of the popper to make + * sure it is positioned between the reference element and its popper element. + * It will read the outer size of the `arrowElement` node to detect how many + * pixels of conjunction are needed. + * + * It has no effect if no `arrowElement` is provided. + * @memberof modifiers + * @inner + */ + arrow: { + /** @prop {number} order=500 - Index used to define the order of execution */ + order: 500, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: arrow, + /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ + element: '[x-arrow]' + }, + + /** + * Modifier used to flip the popper's placement when it starts to overlap its + * reference element. + * + * Requires the `preventOverflow` modifier before it in order to work. + * + * **NOTE:** this modifier will interrupt the current update cycle and will + * restart it if it detects the need to flip the placement. + * @memberof modifiers + * @inner + */ + flip: { + /** @prop {number} order=600 - Index used to define the order of execution */ + order: 600, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: flip, + /** + * @prop {String|Array} behavior='flip' + * The behavior used to change the popper's placement. It can be one of + * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid + * placements (with optional variations) + */ + behavior: 'flip', + /** + * @prop {number} padding=5 + * The popper will flip if it hits the edges of the `boundariesElement` + */ + padding: 5, + /** + * @prop {String|HTMLElement} boundariesElement='viewport' + * The element which will define the boundaries of the popper position. + * The popper will never be placed outside of the defined boundaries + * (except if `keepTogether` is enabled) + */ + boundariesElement: 'viewport', + /** + * @prop {Boolean} flipVariations=false + * The popper will switch placement variation between `-start` and `-end` when + * the reference element overlaps its boundaries. + * + * The original placement should have a set variation. + */ + flipVariations: false, + /** + * @prop {Boolean} flipVariationsByContent=false + * The popper will switch placement variation between `-start` and `-end` when + * the popper element overlaps its reference boundaries. + * + * The original placement should have a set variation. + */ + flipVariationsByContent: false + }, + + /** + * Modifier used to make the popper flow toward the inner of the reference element. + * By default, when this modifier is disabled, the popper will be placed outside + * the reference element. + * @memberof modifiers + * @inner + */ + inner: { + /** @prop {number} order=700 - Index used to define the order of execution */ + order: 700, + /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ + enabled: false, + /** @prop {ModifierFn} */ + fn: inner + }, + + /** + * Modifier used to hide the popper when its reference element is outside of the + * popper boundaries. It will set a `x-out-of-boundaries` attribute which can + * be used to hide with a CSS selector the popper when its reference is + * out of boundaries. + * + * Requires the `preventOverflow` modifier before it in order to work. + * @memberof modifiers + * @inner + */ + hide: { + /** @prop {number} order=800 - Index used to define the order of execution */ + order: 800, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: hide + }, + + /** + * Computes the style that will be applied to the popper element to gets + * properly positioned. + * + * Note that this modifier will not touch the DOM, it just prepares the styles + * so that `applyStyle` modifier can apply it. This separation is useful + * in case you need to replace `applyStyle` with a custom implementation. + * + * This modifier has `850` as `order` value to maintain backward compatibility + * with previous versions of Popper.js. Expect the modifiers ordering method + * to change in future major versions of the library. + * + * @memberof modifiers + * @inner + */ + computeStyle: { + /** @prop {number} order=850 - Index used to define the order of execution */ + order: 850, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: computeStyle, + /** + * @prop {Boolean} gpuAcceleration=true + * If true, it uses the CSS 3D transformation to position the popper. + * Otherwise, it will use the `top` and `left` properties + */ + gpuAcceleration: true, + /** + * @prop {string} [x='bottom'] + * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. + * Change this if your popper should grow in a direction different from `bottom` + */ + x: 'bottom', + /** + * @prop {string} [x='left'] + * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. + * Change this if your popper should grow in a direction different from `right` + */ + y: 'right' + }, + + /** + * Applies the computed styles to the popper element. + * + * All the DOM manipulations are limited to this modifier. This is useful in case + * you want to integrate Popper.js inside a framework or view library and you + * want to delegate all the DOM manipulations to it. + * + * Note that if you disable this modifier, you must make sure the popper element + * has its position set to `absolute` before Popper.js can do its work! + * + * Just disable this modifier and define your own to achieve the desired effect. + * + * @memberof modifiers + * @inner + */ + applyStyle: { + /** @prop {number} order=900 - Index used to define the order of execution */ + order: 900, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: applyStyle, + /** @prop {Function} */ + onLoad: applyStyleOnLoad, + /** + * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier + * @prop {Boolean} gpuAcceleration=true + * If true, it uses the CSS 3D transformation to position the popper. + * Otherwise, it will use the `top` and `left` properties + */ + gpuAcceleration: undefined + } + }; + + /** + * The `dataObject` is an object containing all the information used by Popper.js. + * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks. + * @name dataObject + * @property {Object} data.instance The Popper.js instance + * @property {String} data.placement Placement applied to popper + * @property {String} data.originalPlacement Placement originally defined on init + * @property {Boolean} data.flipped True if popper has been flipped by flip modifier + * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper + * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier + * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`) + * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`) + * @property {Object} data.boundaries Offsets of the popper boundaries + * @property {Object} data.offsets The measurements of popper, reference and arrow elements + * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values + * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values + * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 + */ + + /** + * Default options provided to Popper.js constructor.
    + * These can be overridden using the `options` argument of Popper.js.
    + * To override an option, simply pass an object with the same + * structure of the `options` object, as the 3rd argument. For example: + * ``` + * new Popper(ref, pop, { + * modifiers: { + * preventOverflow: { enabled: false } + * } + * }) + * ``` + * @type {Object} + * @static + * @memberof Popper + */ + var Defaults = { + /** + * Popper's placement. + * @prop {Popper.placements} placement='bottom' + */ + placement: 'bottom', + + /** + * Set this to true if you want popper to position it self in 'fixed' mode + * @prop {Boolean} positionFixed=false + */ + positionFixed: false, + + /** + * Whether events (resize, scroll) are initially enabled. + * @prop {Boolean} eventsEnabled=true + */ + eventsEnabled: true, + + /** + * Set to true if you want to automatically remove the popper when + * you call the `destroy` method. + * @prop {Boolean} removeOnDestroy=false + */ + removeOnDestroy: false, + + /** + * Callback called when the popper is created.
    + * By default, it is set to no-op.
    + * Access Popper.js instance with `data.instance`. + * @prop {onCreate} + */ + onCreate: function onCreate() {}, + + /** + * Callback called when the popper is updated. This callback is not called + * on the initialization/creation of the popper, but only on subsequent + * updates.
    + * By default, it is set to no-op.
    + * Access Popper.js instance with `data.instance`. + * @prop {onUpdate} + */ + onUpdate: function onUpdate() {}, + + /** + * List of modifiers used to modify the offsets before they are applied to the popper. + * They provide most of the functionalities of Popper.js. + * @prop {modifiers} + */ + modifiers: modifiers + }; + + /** + * @callback onCreate + * @param {dataObject} data + */ + + /** + * @callback onUpdate + * @param {dataObject} data + */ + + // Utils + // Methods + var Popper = function () { + /** + * Creates a new Popper.js instance. + * @class Popper + * @param {Element|referenceObject} reference - The reference element used to position the popper + * @param {Element} popper - The HTML / XML element used as the popper + * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) + * @return {Object} instance - The generated Popper.js instance + */ + function Popper(reference, popper) { + var _this = this; + + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + classCallCheck(this, Popper); + + this.scheduleUpdate = function () { + return requestAnimationFrame(_this.update); + }; + + // make update() debounced, so that it only runs at most once-per-tick + this.update = debounce(this.update.bind(this)); + + // with {} we create a new object with the options inside it + this.options = _extends$1({}, Popper.Defaults, options); + + // init state + this.state = { + isDestroyed: false, + isCreated: false, + scrollParents: [] + }; + + // get reference and popper elements (allow jQuery wrappers) + this.reference = reference && reference.jquery ? reference[0] : reference; + this.popper = popper && popper.jquery ? popper[0] : popper; + + // Deep merge modifiers options + this.options.modifiers = {}; + Object.keys(_extends$1({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { + _this.options.modifiers[name] = _extends$1({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); + }); + + // Refactoring modifiers' list (Object => Array) + this.modifiers = Object.keys(this.options.modifiers).map(function (name) { + return _extends$1({ + name: name + }, _this.options.modifiers[name]); + }) + // sort the modifiers by order + .sort(function (a, b) { + return a.order - b.order; + }); + + // modifiers have the ability to execute arbitrary code when Popper.js get inited + // such code is executed in the same order of its modifier + // they could add new properties to their options configuration + // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! + this.modifiers.forEach(function (modifierOptions) { + if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { + modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); + } + }); + + // fire the first update to position the popper in the right place + this.update(); + + var eventsEnabled = this.options.eventsEnabled; + if (eventsEnabled) { + // setup event listeners, they will take care of update the position in specific situations + this.enableEventListeners(); + } + + this.state.eventsEnabled = eventsEnabled; + } + + // We can't use class properties because they don't get listed in the + // class prototype and break stuff like Sinon stubs + + + createClass(Popper, [{ + key: 'update', + value: function update$$1() { + return update.call(this); + } + }, { + key: 'destroy', + value: function destroy$$1() { + return destroy.call(this); + } + }, { + key: 'enableEventListeners', + value: function enableEventListeners$$1() { + return enableEventListeners.call(this); + } + }, { + key: 'disableEventListeners', + value: function disableEventListeners$$1() { + return disableEventListeners.call(this); + } + + /** + * Schedules an update. It will run on the next UI update available. + * @method scheduleUpdate + * @memberof Popper + */ + + + /** + * Collection of utilities useful when writing custom modifiers. + * Starting from version 1.7, this method is available only if you + * include `popper-utils.js` before `popper.js`. + * + * **DEPRECATION**: This way to access PopperUtils is deprecated + * and will be removed in v2! Use the PopperUtils module directly instead. + * Due to the high instability of the methods contained in Utils, we can't + * guarantee them to follow semver. Use them at your own risk! + * @static + * @private + * @type {Object} + * @deprecated since version 1.8 + * @member Utils + * @memberof Popper + */ + + }]); + return Popper; + }(); + + /** + * The `referenceObject` is an object that provides an interface compatible with Popper.js + * and lets you use it as replacement of a real DOM node.
    + * You can use this method to position a popper relatively to a set of coordinates + * in case you don't have a DOM node to use as reference. + * + * ``` + * new Popper(referenceObject, popperNode); + * ``` + * + * NB: This feature isn't supported in Internet Explorer 10. + * @name referenceObject + * @property {Function} data.getBoundingClientRect + * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. + * @property {number} data.clientWidth + * An ES6 getter that will return the width of the virtual reference element. + * @property {number} data.clientHeight + * An ES6 getter that will return the height of the virtual reference element. + */ + + + Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; + Popper.placements = placements; + Popper.Defaults = Defaults; + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME$4 = 'dropdown'; + var VERSION$4 = '5.0.0-alpha2'; + var DATA_KEY$4 = 'bs.dropdown'; + var EVENT_KEY$4 = "." + DATA_KEY$4; + var DATA_API_KEY$4 = '.data-api'; + var ESCAPE_KEY = 'Escape'; + var SPACE_KEY = 'Space'; + var TAB_KEY = 'Tab'; + var ARROW_UP_KEY = 'ArrowUp'; + var ARROW_DOWN_KEY = 'ArrowDown'; + var RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button + + var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEY + "|" + ARROW_DOWN_KEY + "|" + ESCAPE_KEY); + var EVENT_HIDE$1 = "hide" + EVENT_KEY$4; + var EVENT_HIDDEN$1 = "hidden" + EVENT_KEY$4; + var EVENT_SHOW$1 = "show" + EVENT_KEY$4; + var EVENT_SHOWN$1 = "shown" + EVENT_KEY$4; + var EVENT_CLICK = "click" + EVENT_KEY$4; + var EVENT_CLICK_DATA_API$4 = "click" + EVENT_KEY$4 + DATA_API_KEY$4; + var EVENT_KEYDOWN_DATA_API = "keydown" + EVENT_KEY$4 + DATA_API_KEY$4; + var EVENT_KEYUP_DATA_API = "keyup" + EVENT_KEY$4 + DATA_API_KEY$4; + var CLASS_NAME_DISABLED = 'disabled'; + var CLASS_NAME_SHOW$1 = 'show'; + var CLASS_NAME_DROPUP = 'dropup'; + var CLASS_NAME_DROPRIGHT = 'dropright'; + var CLASS_NAME_DROPLEFT = 'dropleft'; + var CLASS_NAME_MENURIGHT = 'dropdown-menu-right'; + var CLASS_NAME_NAVBAR = 'navbar'; + var CLASS_NAME_POSITION_STATIC = 'position-static'; + var SELECTOR_DATA_TOGGLE$2 = '[data-toggle="dropdown"]'; + var SELECTOR_FORM_CHILD = '.dropdown form'; + var SELECTOR_MENU = '.dropdown-menu'; + var SELECTOR_NAVBAR_NAV = '.navbar-nav'; + var SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'; + var PLACEMENT_TOP = 'top-start'; + var PLACEMENT_TOPEND = 'top-end'; + var PLACEMENT_BOTTOM = 'bottom-start'; + var PLACEMENT_BOTTOMEND = 'bottom-end'; + var PLACEMENT_RIGHT = 'right-start'; + var PLACEMENT_LEFT = 'left-start'; + var Default$2 = { + offset: 0, + flip: true, + boundary: 'scrollParent', + reference: 'toggle', + display: 'dynamic', + popperConfig: null + }; + var DefaultType$2 = { + offset: '(number|string|function)', + flip: 'boolean', + boundary: '(string|element)', + reference: '(string|element)', + display: 'string', + popperConfig: '(null|object)' + }; + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Dropdown = /*#__PURE__*/function () { + function Dropdown(element, config) { + this._element = element; + this._popper = null; + this._config = this._getConfig(config); + this._menu = this._getMenuElement(); + this._inNavbar = this._detectNavbar(); + + this._addEventListeners(); + + Data.setData(element, DATA_KEY$4, this); + } // Getters + + + var _proto = Dropdown.prototype; + + // Public + _proto.toggle = function toggle() { + if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED)) { + return; + } + + var isActive = this._element.classList.contains(CLASS_NAME_SHOW$1); + + Dropdown.clearMenus(); + + if (isActive) { + return; + } + + this.show(); + }; + + _proto.show = function show() { + if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED) || this._menu.classList.contains(CLASS_NAME_SHOW$1)) { + return; + } + + var parent = Dropdown.getParentFromElement(this._element); + var relatedTarget = { + relatedTarget: this._element + }; + var showEvent = EventHandler.trigger(this._element, EVENT_SHOW$1, relatedTarget); + + if (showEvent.defaultPrevented) { + return; + } // Disable totally Popper.js for Dropdown in Navbar + + + if (!this._inNavbar) { + if (typeof Popper === 'undefined') { + throw new TypeError('Bootstrap\'s dropdowns require Popper.js (https://popper.js.org)'); + } + + var referenceElement = this._element; + + if (this._config.reference === 'parent') { + referenceElement = parent; + } else if (isElement(this._config.reference)) { + referenceElement = this._config.reference; // Check if it's jQuery element + + if (typeof this._config.reference.jquery !== 'undefined') { + referenceElement = this._config.reference[0]; + } + } // If boundary is not `scrollParent`, then set position to `static` + // to allow the menu to "escape" the scroll parent's boundaries + // https://github.com/twbs/bootstrap/issues/24251 + + + if (this._config.boundary !== 'scrollParent') { + parent.classList.add(CLASS_NAME_POSITION_STATIC); + } + + this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig()); + } // If this is a touch-enabled device we add extra + // empty mouseover listeners to the body's immediate children; + // only needed because of broken event delegation on iOS + // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html + + + if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) { + var _ref; + + (_ref = []).concat.apply(_ref, document.body.children).forEach(function (elem) { + return EventHandler.on(elem, 'mouseover', null, noop()); + }); + } + + this._element.focus(); + + this._element.setAttribute('aria-expanded', true); + + Manipulator.toggleClass(this._menu, CLASS_NAME_SHOW$1); + Manipulator.toggleClass(this._element, CLASS_NAME_SHOW$1); + EventHandler.trigger(parent, EVENT_SHOWN$1, relatedTarget); + }; + + _proto.hide = function hide() { + if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED) || !this._menu.classList.contains(CLASS_NAME_SHOW$1)) { + return; + } + + var parent = Dropdown.getParentFromElement(this._element); + var relatedTarget = { + relatedTarget: this._element + }; + var hideEvent = EventHandler.trigger(parent, EVENT_HIDE$1, relatedTarget); + + if (hideEvent.defaultPrevented) { + return; + } + + if (this._popper) { + this._popper.destroy(); + } + + Manipulator.toggleClass(this._menu, CLASS_NAME_SHOW$1); + Manipulator.toggleClass(this._element, CLASS_NAME_SHOW$1); + EventHandler.trigger(parent, EVENT_HIDDEN$1, relatedTarget); + }; + + _proto.dispose = function dispose() { + Data.removeData(this._element, DATA_KEY$4); + EventHandler.off(this._element, EVENT_KEY$4); + this._element = null; + this._menu = null; + + if (this._popper) { + this._popper.destroy(); + + this._popper = null; + } + }; + + _proto.update = function update() { + this._inNavbar = this._detectNavbar(); + + if (this._popper) { + this._popper.scheduleUpdate(); + } + } // Private + ; + + _proto._addEventListeners = function _addEventListeners() { + var _this = this; + + EventHandler.on(this._element, EVENT_CLICK, function (event) { + event.preventDefault(); + event.stopPropagation(); + + _this.toggle(); + }); + }; + + _proto._getConfig = function _getConfig(config) { + config = _extends({}, this.constructor.Default, Manipulator.getDataAttributes(this._element), config); + typeCheckConfig(NAME$4, config, this.constructor.DefaultType); + return config; + }; + + _proto._getMenuElement = function _getMenuElement() { + return SelectorEngine.next(this._element, SELECTOR_MENU)[0]; + }; + + _proto._getPlacement = function _getPlacement() { + var parentDropdown = this._element.parentNode; + var placement = PLACEMENT_BOTTOM; // Handle dropup + + if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) { + placement = PLACEMENT_TOP; + + if (this._menu.classList.contains(CLASS_NAME_MENURIGHT)) { + placement = PLACEMENT_TOPEND; + } + } else if (parentDropdown.classList.contains(CLASS_NAME_DROPRIGHT)) { + placement = PLACEMENT_RIGHT; + } else if (parentDropdown.classList.contains(CLASS_NAME_DROPLEFT)) { + placement = PLACEMENT_LEFT; + } else if (this._menu.classList.contains(CLASS_NAME_MENURIGHT)) { + placement = PLACEMENT_BOTTOMEND; + } + + return placement; + }; + + _proto._detectNavbar = function _detectNavbar() { + return Boolean(this._element.closest("." + CLASS_NAME_NAVBAR)); + }; + + _proto._getOffset = function _getOffset() { + var _this2 = this; + + var offset = {}; + + if (typeof this._config.offset === 'function') { + offset.fn = function (data) { + data.offsets = _extends({}, data.offsets, _this2._config.offset(data.offsets, _this2._element) || {}); + return data; + }; + } else { + offset.offset = this._config.offset; + } + + return offset; + }; + + _proto._getPopperConfig = function _getPopperConfig() { + var popperConfig = { + placement: this._getPlacement(), + modifiers: { + offset: this._getOffset(), + flip: { + enabled: this._config.flip + }, + preventOverflow: { + boundariesElement: this._config.boundary + } + } + }; // Disable Popper.js if we have a static display + + if (this._config.display === 'static') { + popperConfig.modifiers.applyStyle = { + enabled: false + }; + } + + return _extends({}, popperConfig, this._config.popperConfig); + } // Static + ; + + Dropdown.dropdownInterface = function dropdownInterface(element, config) { + var data = Data.getData(element, DATA_KEY$4); + + var _config = typeof config === 'object' ? config : null; + + if (!data) { + data = new Dropdown(element, _config); + } + + if (typeof config === 'string') { + if (typeof data[config] === 'undefined') { + throw new TypeError("No method named \"" + config + "\""); + } + + data[config](); + } + }; + + Dropdown.jQueryInterface = function jQueryInterface(config) { + return this.each(function () { + Dropdown.dropdownInterface(this, config); + }); + }; + + Dropdown.clearMenus = function clearMenus(event) { + if (event && (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY)) { + return; + } + + var toggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE$2); + + for (var i = 0, len = toggles.length; i < len; i++) { + var parent = Dropdown.getParentFromElement(toggles[i]); + var context = Data.getData(toggles[i], DATA_KEY$4); + var relatedTarget = { + relatedTarget: toggles[i] + }; + + if (event && event.type === 'click') { + relatedTarget.clickEvent = event; + } + + if (!context) { + continue; + } + + var dropdownMenu = context._menu; + + if (!toggles[i].classList.contains(CLASS_NAME_SHOW$1)) { + continue; + } + + if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.key === TAB_KEY) && dropdownMenu.contains(event.target)) { + continue; + } + + var hideEvent = EventHandler.trigger(parent, EVENT_HIDE$1, relatedTarget); + + if (hideEvent.defaultPrevented) { + continue; + } // If this is a touch-enabled device we remove the extra + // empty mouseover listeners we added for iOS support + + + if ('ontouchstart' in document.documentElement) { + var _ref2; + + (_ref2 = []).concat.apply(_ref2, document.body.children).forEach(function (elem) { + return EventHandler.off(elem, 'mouseover', null, noop()); + }); + } + + toggles[i].setAttribute('aria-expanded', 'false'); + + if (context._popper) { + context._popper.destroy(); + } + + dropdownMenu.classList.remove(CLASS_NAME_SHOW$1); + toggles[i].classList.remove(CLASS_NAME_SHOW$1); + EventHandler.trigger(parent, EVENT_HIDDEN$1, relatedTarget); + } + }; + + Dropdown.getParentFromElement = function getParentFromElement(element) { + return getElementFromSelector(element) || element.parentNode; + }; + + Dropdown.dataApiKeydownHandler = function dataApiKeydownHandler(event) { + // If not input/textarea: + // - And not a key in REGEXP_KEYDOWN => not a dropdown command + // If input/textarea: + // - If space key => not a dropdown command + // - If key is other than escape + // - If key is not up or down => not a dropdown command + // - If trigger inside the menu => not a dropdown command + if (/input|textarea/i.test(event.target.tagName) ? event.key === SPACE_KEY || event.key !== ESCAPE_KEY && (event.key !== ARROW_DOWN_KEY && event.key !== ARROW_UP_KEY || event.target.closest(SELECTOR_MENU)) : !REGEXP_KEYDOWN.test(event.key)) { + return; + } + + event.preventDefault(); + event.stopPropagation(); + + if (this.disabled || this.classList.contains(CLASS_NAME_DISABLED)) { + return; + } + + var parent = Dropdown.getParentFromElement(this); + var isActive = this.classList.contains(CLASS_NAME_SHOW$1); + + if (event.key === ESCAPE_KEY) { + var button = this.matches(SELECTOR_DATA_TOGGLE$2) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$2)[0]; + button.focus(); + Dropdown.clearMenus(); + return; + } + + if (!isActive || event.key === SPACE_KEY) { + Dropdown.clearMenus(); + return; + } + + var items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, parent).filter(isVisible); + + if (!items.length) { + return; + } + + var index = items.indexOf(event.target); + + if (event.key === ARROW_UP_KEY && index > 0) { + // Up + index--; + } + + if (event.key === ARROW_DOWN_KEY && index < items.length - 1) { + // Down + index++; + } // index is -1 if the first keydown is an ArrowUp + + + index = index === -1 ? 0 : index; + items[index].focus(); + }; + + Dropdown.getInstance = function getInstance(element) { + return Data.getData(element, DATA_KEY$4); + }; + + _createClass(Dropdown, null, [{ + key: "VERSION", + get: function get() { + return VERSION$4; + } + }, { + key: "Default", + get: function get() { + return Default$2; + } + }, { + key: "DefaultType", + get: function get() { + return DefaultType$2; + } + }]); + + return Dropdown; + }(); + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + + EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$2, Dropdown.dataApiKeydownHandler); + EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler); + EventHandler.on(document, EVENT_CLICK_DATA_API$4, Dropdown.clearMenus); + EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus); + EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$2, function (event) { + event.preventDefault(); + event.stopPropagation(); + Dropdown.dropdownInterface(this, 'toggle'); + }); + EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_FORM_CHILD, function (e) { + return e.stopPropagation(); + }); + var $$5 = getjQuery(); + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + * add .dropdown to jQuery only if jQuery is present + */ + + /* istanbul ignore if */ + + if ($$5) { + var JQUERY_NO_CONFLICT$4 = $$5.fn[NAME$4]; + $$5.fn[NAME$4] = Dropdown.jQueryInterface; + $$5.fn[NAME$4].Constructor = Dropdown; + + $$5.fn[NAME$4].noConflict = function () { + $$5.fn[NAME$4] = JQUERY_NO_CONFLICT$4; + return Dropdown.jQueryInterface; + }; + } + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME$5 = 'modal'; + var VERSION$5 = '5.0.0-alpha2'; + var DATA_KEY$5 = 'bs.modal'; + var EVENT_KEY$5 = "." + DATA_KEY$5; + var DATA_API_KEY$5 = '.data-api'; + var ESCAPE_KEY$1 = 'Escape'; + var Default$3 = { + backdrop: true, + keyboard: true, + focus: true, + show: true + }; + var DefaultType$3 = { + backdrop: '(boolean|string)', + keyboard: 'boolean', + focus: 'boolean', + show: 'boolean' + }; + var EVENT_HIDE$2 = "hide" + EVENT_KEY$5; + var EVENT_HIDE_PREVENTED = "hidePrevented" + EVENT_KEY$5; + var EVENT_HIDDEN$2 = "hidden" + EVENT_KEY$5; + var EVENT_SHOW$2 = "show" + EVENT_KEY$5; + var EVENT_SHOWN$2 = "shown" + EVENT_KEY$5; + var EVENT_FOCUSIN = "focusin" + EVENT_KEY$5; + var EVENT_RESIZE = "resize" + EVENT_KEY$5; + var EVENT_CLICK_DISMISS = "click.dismiss" + EVENT_KEY$5; + var EVENT_KEYDOWN_DISMISS = "keydown.dismiss" + EVENT_KEY$5; + var EVENT_MOUSEUP_DISMISS = "mouseup.dismiss" + EVENT_KEY$5; + var EVENT_MOUSEDOWN_DISMISS = "mousedown.dismiss" + EVENT_KEY$5; + var EVENT_CLICK_DATA_API$5 = "click" + EVENT_KEY$5 + DATA_API_KEY$5; + var CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'; + var CLASS_NAME_BACKDROP = 'modal-backdrop'; + var CLASS_NAME_OPEN = 'modal-open'; + var CLASS_NAME_FADE = 'fade'; + var CLASS_NAME_SHOW$2 = 'show'; + var CLASS_NAME_STATIC = 'modal-static'; + var SELECTOR_DIALOG = '.modal-dialog'; + var SELECTOR_MODAL_BODY = '.modal-body'; + var SELECTOR_DATA_TOGGLE$3 = '[data-toggle="modal"]'; + var SELECTOR_DATA_DISMISS = '[data-dismiss="modal"]'; + var SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'; + var SELECTOR_STICKY_CONTENT = '.sticky-top'; + /** + * ------------------------------------------------------------------------ + * Class Definition + * ------------------------------------------------------------------------ + */ + + var Modal = /*#__PURE__*/function () { + function Modal(element, config) { + this._config = this._getConfig(config); + this._element = element; + this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, element); + this._backdrop = null; + this._isShown = false; + this._isBodyOverflowing = false; + this._ignoreBackdropClick = false; + this._isTransitioning = false; + this._scrollbarWidth = 0; + Data.setData(element, DATA_KEY$5, this); + } // Getters + + + var _proto = Modal.prototype; + + // Public + _proto.toggle = function toggle(relatedTarget) { + return this._isShown ? this.hide() : this.show(relatedTarget); + }; + + _proto.show = function show(relatedTarget) { + var _this = this; + + if (this._isShown || this._isTransitioning) { + return; + } + + if (this._element.classList.contains(CLASS_NAME_FADE)) { + this._isTransitioning = true; + } + + var showEvent = EventHandler.trigger(this._element, EVENT_SHOW$2, { + relatedTarget: relatedTarget + }); + + if (this._isShown || showEvent.defaultPrevented) { + return; + } + + this._isShown = true; + + this._checkScrollbar(); + + this._setScrollbar(); + + this._adjustDialog(); + + this._setEscapeEvent(); + + this._setResizeEvent(); + + EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, function (event) { + return _this.hide(event); + }); + EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, function () { + EventHandler.one(_this._element, EVENT_MOUSEUP_DISMISS, function (event) { + if (event.target === _this._element) { + _this._ignoreBackdropClick = true; + } + }); + }); + + this._showBackdrop(function () { + return _this._showElement(relatedTarget); + }); + }; + + _proto.hide = function hide(event) { + var _this2 = this; + + if (event) { + event.preventDefault(); + } + + if (!this._isShown || this._isTransitioning) { + return; + } + + var hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$2); + + if (hideEvent.defaultPrevented) { + return; + } + + this._isShown = false; + + var transition = this._element.classList.contains(CLASS_NAME_FADE); + + if (transition) { + this._isTransitioning = true; + } + + this._setEscapeEvent(); + + this._setResizeEvent(); + + EventHandler.off(document, EVENT_FOCUSIN); + + this._element.classList.remove(CLASS_NAME_SHOW$2); + + EventHandler.off(this._element, EVENT_CLICK_DISMISS); + EventHandler.off(this._dialog, EVENT_MOUSEDOWN_DISMISS); + + if (transition) { + var transitionDuration = getTransitionDurationFromElement(this._element); + EventHandler.one(this._element, TRANSITION_END, function (event) { + return _this2._hideModal(event); + }); + emulateTransitionEnd(this._element, transitionDuration); + } else { + this._hideModal(); + } + }; + + _proto.dispose = function dispose() { + [window, this._element, this._dialog].forEach(function (htmlElement) { + return EventHandler.off(htmlElement, EVENT_KEY$5); + }); + /** + * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API` + * Do not move `document` in `htmlElements` array + * It will remove `EVENT_CLICK_DATA_API` event that should remain + */ + + EventHandler.off(document, EVENT_FOCUSIN); + Data.removeData(this._element, DATA_KEY$5); + this._config = null; + this._element = null; + this._dialog = null; + this._backdrop = null; + this._isShown = null; + this._isBodyOverflowing = null; + this._ignoreBackdropClick = null; + this._isTransitioning = null; + this._scrollbarWidth = null; + }; + + _proto.handleUpdate = function handleUpdate() { + this._adjustDialog(); + } // Private + ; + + _proto._getConfig = function _getConfig(config) { + config = _extends({}, Default$3, config); + typeCheckConfig(NAME$5, config, DefaultType$3); + return config; + }; + + _proto._showElement = function _showElement(relatedTarget) { + var _this3 = this; + + var transition = this._element.classList.contains(CLASS_NAME_FADE); + + var modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog); + + if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) { + // Don't move modal's DOM position + document.body.appendChild(this._element); + } + + this._element.style.display = 'block'; + + this._element.removeAttribute('aria-hidden'); + + this._element.setAttribute('aria-modal', true); + + this._element.setAttribute('role', 'dialog'); + + this._element.scrollTop = 0; + + if (modalBody) { + modalBody.scrollTop = 0; + } + + if (transition) { + reflow(this._element); + } + + this._element.classList.add(CLASS_NAME_SHOW$2); + + if (this._config.focus) { + this._enforceFocus(); + } + + var transitionComplete = function transitionComplete() { + if (_this3._config.focus) { + _this3._element.focus(); + } + + _this3._isTransitioning = false; + EventHandler.trigger(_this3._element, EVENT_SHOWN$2, { + relatedTarget: relatedTarget + }); + }; + + if (transition) { + var transitionDuration = getTransitionDurationFromElement(this._dialog); + EventHandler.one(this._dialog, TRANSITION_END, transitionComplete); + emulateTransitionEnd(this._dialog, transitionDuration); + } else { + transitionComplete(); + } + }; + + _proto._enforceFocus = function _enforceFocus() { + var _this4 = this; + + EventHandler.off(document, EVENT_FOCUSIN); // guard against infinite focus loop + + EventHandler.on(document, EVENT_FOCUSIN, function (event) { + if (document !== event.target && _this4._element !== event.target && !_this4._element.contains(event.target)) { + _this4._element.focus(); + } + }); + }; + + _proto._setEscapeEvent = function _setEscapeEvent() { + var _this5 = this; + + if (this._isShown) { + EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, function (event) { + if (_this5._config.keyboard && event.key === ESCAPE_KEY$1) { + event.preventDefault(); + + _this5.hide(); + } else if (!_this5._config.keyboard && event.key === ESCAPE_KEY$1) { + _this5._triggerBackdropTransition(); + } + }); + } else { + EventHandler.off(this._element, EVENT_KEYDOWN_DISMISS); + } + }; + + _proto._setResizeEvent = function _setResizeEvent() { + var _this6 = this; + + if (this._isShown) { + EventHandler.on(window, EVENT_RESIZE, function () { + return _this6._adjustDialog(); + }); + } else { + EventHandler.off(window, EVENT_RESIZE); + } + }; + + _proto._hideModal = function _hideModal() { + var _this7 = this; + + this._element.style.display = 'none'; + + this._element.setAttribute('aria-hidden', true); + + this._element.removeAttribute('aria-modal'); + + this._element.removeAttribute('role'); + + this._isTransitioning = false; + + this._showBackdrop(function () { + document.body.classList.remove(CLASS_NAME_OPEN); + + _this7._resetAdjustments(); + + _this7._resetScrollbar(); + + EventHandler.trigger(_this7._element, EVENT_HIDDEN$2); + }); + }; + + _proto._removeBackdrop = function _removeBackdrop() { + this._backdrop.parentNode.removeChild(this._backdrop); + + this._backdrop = null; + }; + + _proto._showBackdrop = function _showBackdrop(callback) { + var _this8 = this; + + var animate = this._element.classList.contains(CLASS_NAME_FADE) ? CLASS_NAME_FADE : ''; + + if (this._isShown && this._config.backdrop) { + this._backdrop = document.createElement('div'); + this._backdrop.className = CLASS_NAME_BACKDROP; + + if (animate) { + this._backdrop.classList.add(animate); + } + + document.body.appendChild(this._backdrop); + EventHandler.on(this._element, EVENT_CLICK_DISMISS, function (event) { + if (_this8._ignoreBackdropClick) { + _this8._ignoreBackdropClick = false; + return; + } + + if (event.target !== event.currentTarget) { + return; + } + + _this8._triggerBackdropTransition(); + }); + + if (animate) { + reflow(this._backdrop); + } + + this._backdrop.classList.add(CLASS_NAME_SHOW$2); + + if (!animate) { + callback(); + return; + } + + var backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop); + EventHandler.one(this._backdrop, TRANSITION_END, callback); + emulateTransitionEnd(this._backdrop, backdropTransitionDuration); + } else if (!this._isShown && this._backdrop) { + this._backdrop.classList.remove(CLASS_NAME_SHOW$2); + + var callbackRemove = function callbackRemove() { + _this8._removeBackdrop(); + + callback(); + }; + + if (this._element.classList.contains(CLASS_NAME_FADE)) { + var _backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop); + + EventHandler.one(this._backdrop, TRANSITION_END, callbackRemove); + emulateTransitionEnd(this._backdrop, _backdropTransitionDuration); + } else { + callbackRemove(); + } + } else { + callback(); + } + }; + + _proto._triggerBackdropTransition = function _triggerBackdropTransition() { + var _this9 = this; + + if (this._config.backdrop === 'static') { + var hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); + + if (hideEvent.defaultPrevented) { + return; + } + + var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; + + if (!isModalOverflowing) { + this._element.style.overflowY = 'hidden'; + } + + this._element.classList.add(CLASS_NAME_STATIC); + + var modalTransitionDuration = getTransitionDurationFromElement(this._dialog); + EventHandler.off(this._element, TRANSITION_END); + EventHandler.one(this._element, TRANSITION_END, function () { + _this9._element.classList.remove(CLASS_NAME_STATIC); + + if (!isModalOverflowing) { + EventHandler.one(_this9._element, TRANSITION_END, function () { + _this9._element.style.overflowY = ''; + }); + emulateTransitionEnd(_this9._element, modalTransitionDuration); + } + }); + emulateTransitionEnd(this._element, modalTransitionDuration); + + this._element.focus(); + } else { + this.hide(); + } + } // ---------------------------------------------------------------------- + // the following methods are used to handle overflowing modals + // ---------------------------------------------------------------------- + ; + + _proto._adjustDialog = function _adjustDialog() { + var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; + + if (!this._isBodyOverflowing && isModalOverflowing) { + this._element.style.paddingLeft = this._scrollbarWidth + "px"; + } + + if (this._isBodyOverflowing && !isModalOverflowing) { + this._element.style.paddingRight = this._scrollbarWidth + "px"; + } + }; + + _proto._resetAdjustments = function _resetAdjustments() { + this._element.style.paddingLeft = ''; + this._element.style.paddingRight = ''; + }; + + _proto._checkScrollbar = function _checkScrollbar() { + var rect = document.body.getBoundingClientRect(); + this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth; + this._scrollbarWidth = this._getScrollbarWidth(); + }; + + _proto._setScrollbar = function _setScrollbar() { + var _this10 = this; + + if (this._isBodyOverflowing) { + // Note: DOMNode.style.paddingRight returns the actual value or '' if not set + // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set + // Adjust fixed content padding + SelectorEngine.find(SELECTOR_FIXED_CONTENT).forEach(function (element) { + var actualPadding = element.style.paddingRight; + var calculatedPadding = window.getComputedStyle(element)['padding-right']; + Manipulator.setDataAttribute(element, 'padding-right', actualPadding); + element.style.paddingRight = parseFloat(calculatedPadding) + _this10._scrollbarWidth + "px"; + }); // Adjust sticky content margin + + SelectorEngine.find(SELECTOR_STICKY_CONTENT).forEach(function (element) { + var actualMargin = element.style.marginRight; + var calculatedMargin = window.getComputedStyle(element)['margin-right']; + Manipulator.setDataAttribute(element, 'margin-right', actualMargin); + element.style.marginRight = parseFloat(calculatedMargin) - _this10._scrollbarWidth + "px"; + }); // Adjust body padding + + var actualPadding = document.body.style.paddingRight; + var calculatedPadding = window.getComputedStyle(document.body)['padding-right']; + Manipulator.setDataAttribute(document.body, 'padding-right', actualPadding); + document.body.style.paddingRight = parseFloat(calculatedPadding) + this._scrollbarWidth + "px"; + } + + document.body.classList.add(CLASS_NAME_OPEN); + }; + + _proto._resetScrollbar = function _resetScrollbar() { + // Restore fixed content padding + SelectorEngine.find(SELECTOR_FIXED_CONTENT).forEach(function (element) { + var padding = Manipulator.getDataAttribute(element, 'padding-right'); + + if (typeof padding !== 'undefined') { + Manipulator.removeDataAttribute(element, 'padding-right'); + element.style.paddingRight = padding; + } + }); // Restore sticky content and navbar-toggler margin + + SelectorEngine.find("" + SELECTOR_STICKY_CONTENT).forEach(function (element) { + var margin = Manipulator.getDataAttribute(element, 'margin-right'); + + if (typeof margin !== 'undefined') { + Manipulator.removeDataAttribute(element, 'margin-right'); + element.style.marginRight = margin; + } + }); // Restore body padding + + var padding = Manipulator.getDataAttribute(document.body, 'padding-right'); + + if (typeof padding === 'undefined') { + document.body.style.paddingRight = ''; + } else { + Manipulator.removeDataAttribute(document.body, 'padding-right'); + document.body.style.paddingRight = padding; + } + }; + + _proto._getScrollbarWidth = function _getScrollbarWidth() { + // thx d.walsh + var scrollDiv = document.createElement('div'); + scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER; + document.body.appendChild(scrollDiv); + var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth; + document.body.removeChild(scrollDiv); + return scrollbarWidth; + } // Static + ; + + Modal.jQueryInterface = function jQueryInterface(config, relatedTarget) { + return this.each(function () { + var data = Data.getData(this, DATA_KEY$5); + + var _config = _extends({}, Default$3, Manipulator.getDataAttributes(this), typeof config === 'object' && config ? config : {}); + + if (!data) { + data = new Modal(this, _config); + } + + if (typeof config === 'string') { + if (typeof data[config] === 'undefined') { + throw new TypeError("No method named \"" + config + "\""); + } + + data[config](relatedTarget); + } else if (_config.show) { + data.show(relatedTarget); + } + }); + }; + + Modal.getInstance = function getInstance(element) { + return Data.getData(element, DATA_KEY$5); + }; + + _createClass(Modal, null, [{ + key: "VERSION", + get: function get() { + return VERSION$5; + } + }, { + key: "Default", + get: function get() { + return Default$3; + } + }]); + + return Modal; + }(); + /** + * ------------------------------------------------------------------------ + * Data Api implementation + * ------------------------------------------------------------------------ + */ + + + EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_TOGGLE$3, function (event) { + var _this11 = this; + + var target = getElementFromSelector(this); + + if (this.tagName === 'A' || this.tagName === 'AREA') { + event.preventDefault(); + } + + EventHandler.one(target, EVENT_SHOW$2, function (showEvent) { + if (showEvent.defaultPrevented) { + // only register focus restorer if modal will actually get shown + return; + } + + EventHandler.one(target, EVENT_HIDDEN$2, function () { + if (isVisible(_this11)) { + _this11.focus(); + } + }); + }); + var data = Data.getData(target, DATA_KEY$5); + + if (!data) { + var config = _extends({}, Manipulator.getDataAttributes(target), Manipulator.getDataAttributes(this)); + + data = new Modal(target, config); + } + + data.show(this); + }); + var $$6 = getjQuery(); + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + * add .modal to jQuery only if jQuery is present + */ + + /* istanbul ignore if */ + + if ($$6) { + var JQUERY_NO_CONFLICT$5 = $$6.fn[NAME$5]; + $$6.fn[NAME$5] = Modal.jQueryInterface; + $$6.fn[NAME$5].Constructor = Modal; + + $$6.fn[NAME$5].noConflict = function () { + $$6.fn[NAME$5] = JQUERY_NO_CONFLICT$5; + return Modal.jQueryInterface; + }; + } + + /** + * -------------------------------------------------------------------------- + * Bootstrap (v5.0.0-alpha2): util/sanitizer.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + * -------------------------------------------------------------------------- + */ + var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']; + var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; + /** + * A pattern that recognizes a commonly useful subset of URLs that are safe. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + + var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi; + /** + * A pattern that matches safe data URLs. Only matches image, video and audio types. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + + var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i; + + var allowedAttribute = function allowedAttribute(attr, allowedAttributeList) { + var attrName = attr.nodeName.toLowerCase(); + + if (allowedAttributeList.indexOf(attrName) !== -1) { + if (uriAttrs.indexOf(attrName) !== -1) { + return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)); + } + + return true; + } + + var regExp = allowedAttributeList.filter(function (attrRegex) { + return attrRegex instanceof RegExp; + }); // Check if a regular expression validates the attribute. + + for (var i = 0, len = regExp.length; i < len; i++) { + if (attrName.match(regExp[i])) { + return true; + } + } + + return false; + }; + + var DefaultAllowlist = { + // Global attributes allowed on any supplied element below. + '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], + a: ['target', 'href', 'title', 'rel'], + area: [], + b: [], + br: [], + col: [], + code: [], + div: [], + em: [], + hr: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + i: [], + img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], + li: [], + ol: [], + p: [], + pre: [], + s: [], + small: [], + span: [], + sub: [], + sup: [], + strong: [], + u: [], + ul: [] + }; + function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) { + var _ref; + + if (!unsafeHtml.length) { + return unsafeHtml; + } + + if (sanitizeFn && typeof sanitizeFn === 'function') { + return sanitizeFn(unsafeHtml); + } + + var domParser = new window.DOMParser(); + var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); + var allowlistKeys = Object.keys(allowList); + + var elements = (_ref = []).concat.apply(_ref, createdDocument.body.querySelectorAll('*')); + + var _loop = function _loop(i, len) { + var _ref2; + + var el = elements[i]; + var elName = el.nodeName.toLowerCase(); + + if (allowlistKeys.indexOf(elName) === -1) { + el.parentNode.removeChild(el); + return "continue"; + } + + var attributeList = (_ref2 = []).concat.apply(_ref2, el.attributes); + + var allowedAttributes = [].concat(allowList['*'] || [], allowList[elName] || []); + attributeList.forEach(function (attr) { + if (!allowedAttribute(attr, allowedAttributes)) { + el.removeAttribute(attr.nodeName); + } + }); + }; + + for (var i = 0, len = elements.length; i < len; i++) { + var _ret = _loop(i); + + if (_ret === "continue") continue; + } + + return createdDocument.body.innerHTML; + } + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var NAME$6 = 'tooltip'; + var VERSION$6 = '5.0.0-alpha2'; + var DATA_KEY$6 = 'bs.tooltip'; + var EVENT_KEY$6 = "." + DATA_KEY$6; + var CLASS_PREFIX = 'bs-tooltip'; + var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); + var DISALLOWED_ATTRIBUTES = ['sanitize', 'allowList', 'sanitizeFn']; + var DefaultType$4 = { + animation: 'boolean', + template: 'string', + title: '(string|element|function)', + trigger: 'string', + delay: '(number|object)', + html: 'boolean', + selector: '(string|boolean)', + placement: '(string|function)', + offset: '(number|string|function)', + container: '(string|element|boolean)', + fallbackPlacement: '(string|array)', + boundary: '(string|element)', + sanitize: 'boolean', + sanitizeFn: '(null|function)', + allowList: 'object', + popperConfig: '(null|object)' + }; + var AttachmentMap = { + AUTO: 'auto', + TOP: 'top', + RIGHT: 'right', + BOTTOM: 'bottom', + LEFT: 'left' + }; + var Default$4 = { + animation: true, + template: '