diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 00000000..2df3689b --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 509d127c5ef4496493be718a2d00a444 +tags: d77d1c0d9ca2f4c8421862c7c5a0d620 diff --git a/.doctrees/404.doctree b/.doctrees/404.doctree new file mode 100644 index 00000000..488846bc Binary files /dev/null and b/.doctrees/404.doctree differ diff --git a/.doctrees/clinicians/home.doctree b/.doctrees/clinicians/home.doctree new file mode 100644 index 00000000..fcc4c34f Binary files /dev/null and b/.doctrees/clinicians/home.doctree differ diff --git a/.doctrees/clinicians/reports.doctree b/.doctrees/clinicians/reports.doctree new file mode 100644 index 00000000..3cc524d8 Binary files /dev/null and b/.doctrees/clinicians/reports.doctree differ diff --git a/.doctrees/clinicians/setup.doctree b/.doctrees/clinicians/setup.doctree new file mode 100644 index 00000000..b5e8bc56 Binary files /dev/null and b/.doctrees/clinicians/setup.doctree differ diff --git a/.doctrees/environment.pickle b/.doctrees/environment.pickle new file mode 100644 index 00000000..ab203e3c Binary files /dev/null and b/.doctrees/environment.pickle differ diff --git a/.doctrees/index.doctree b/.doctrees/index.doctree new file mode 100644 index 00000000..2d030215 Binary files /dev/null and b/.doctrees/index.doctree differ diff --git a/.doctrees/nightscout/admin_tools.doctree b/.doctrees/nightscout/admin_tools.doctree new file mode 100644 index 00000000..0b1995e8 Binary files /dev/null and b/.doctrees/nightscout/admin_tools.doctree differ diff --git a/.doctrees/nightscout/advanced.doctree b/.doctrees/nightscout/advanced.doctree new file mode 100644 index 00000000..ca2646ba Binary files /dev/null and b/.doctrees/nightscout/advanced.doctree differ diff --git a/.doctrees/nightscout/close_loop.doctree b/.doctrees/nightscout/close_loop.doctree new file mode 100644 index 00000000..94aa265b Binary files /dev/null and b/.doctrees/nightscout/close_loop.doctree differ diff --git a/.doctrees/nightscout/database.doctree b/.doctrees/nightscout/database.doctree new file mode 100644 index 00000000..2dd21a4f Binary files /dev/null and b/.doctrees/nightscout/database.doctree differ diff --git a/.doctrees/nightscout/discover.doctree b/.doctrees/nightscout/discover.doctree new file mode 100644 index 00000000..cea48319 Binary files /dev/null and b/.doctrees/nightscout/discover.doctree differ diff --git a/.doctrees/nightscout/dns.doctree b/.doctrees/nightscout/dns.doctree new file mode 100644 index 00000000..d0cea823 Binary files /dev/null and b/.doctrees/nightscout/dns.doctree differ diff --git a/.doctrees/nightscout/docker.doctree b/.doctrees/nightscout/docker.doctree new file mode 100644 index 00000000..0acca535 Binary files /dev/null and b/.doctrees/nightscout/docker.doctree differ diff --git a/.doctrees/nightscout/downloaders.doctree b/.doctrees/nightscout/downloaders.doctree new file mode 100644 index 00000000..eba954ca Binary files /dev/null and b/.doctrees/nightscout/downloaders.doctree differ diff --git a/.doctrees/nightscout/first_setup.doctree b/.doctrees/nightscout/first_setup.doctree new file mode 100644 index 00000000..b9e13128 Binary files /dev/null and b/.doctrees/nightscout/first_setup.doctree differ diff --git a/.doctrees/nightscout/github.doctree b/.doctrees/nightscout/github.doctree new file mode 100644 index 00000000..4af5bca1 Binary files /dev/null and b/.doctrees/nightscout/github.doctree differ diff --git a/.doctrees/nightscout/ifttt.doctree b/.doctrees/nightscout/ifttt.doctree new file mode 100644 index 00000000..2e6bb8ae Binary files /dev/null and b/.doctrees/nightscout/ifttt.doctree differ diff --git a/.doctrees/nightscout/multiadmin.doctree b/.doctrees/nightscout/multiadmin.doctree new file mode 100644 index 00000000..31d71eb5 Binary files /dev/null and b/.doctrees/nightscout/multiadmin.doctree differ diff --git a/.doctrees/nightscout/new_user.doctree b/.doctrees/nightscout/new_user.doctree new file mode 100644 index 00000000..9e5bf647 Binary files /dev/null and b/.doctrees/nightscout/new_user.doctree differ diff --git a/.doctrees/nightscout/platform.doctree b/.doctrees/nightscout/platform.doctree new file mode 100644 index 00000000..fb92f6b5 Binary files /dev/null and b/.doctrees/nightscout/platform.doctree differ diff --git a/.doctrees/nightscout/plugins-old.doctree b/.doctrees/nightscout/plugins-old.doctree new file mode 100644 index 00000000..ce11047c Binary files /dev/null and b/.doctrees/nightscout/plugins-old.doctree differ diff --git a/.doctrees/nightscout/plugins-v15.doctree b/.doctrees/nightscout/plugins-v15.doctree new file mode 100644 index 00000000..402f80c1 Binary files /dev/null and b/.doctrees/nightscout/plugins-v15.doctree differ diff --git a/.doctrees/nightscout/profile_editor.doctree b/.doctrees/nightscout/profile_editor.doctree new file mode 100644 index 00000000..ac6c49d9 Binary files /dev/null and b/.doctrees/nightscout/profile_editor.doctree differ diff --git a/.doctrees/nightscout/pushover.doctree b/.doctrees/nightscout/pushover.doctree new file mode 100644 index 00000000..69bf0503 Binary files /dev/null and b/.doctrees/nightscout/pushover.doctree differ diff --git a/.doctrees/nightscout/reports.doctree b/.doctrees/nightscout/reports.doctree new file mode 100644 index 00000000..82073495 Binary files /dev/null and b/.doctrees/nightscout/reports.doctree differ diff --git a/.doctrees/nightscout/security.doctree b/.doctrees/nightscout/security.doctree new file mode 100644 index 00000000..09e2c905 Binary files /dev/null and b/.doctrees/nightscout/security.doctree differ diff --git a/.doctrees/nightscout/setup_variables.doctree b/.doctrees/nightscout/setup_variables.doctree new file mode 100644 index 00000000..f3dc90e5 Binary files /dev/null and b/.doctrees/nightscout/setup_variables.doctree differ diff --git a/.doctrees/nightscout/stringhelp.doctree b/.doctrees/nightscout/stringhelp.doctree new file mode 100644 index 00000000..6065c9d8 Binary files /dev/null and b/.doctrees/nightscout/stringhelp.doctree differ diff --git a/.doctrees/nightscout/tokens.doctree b/.doctrees/nightscout/tokens.doctree new file mode 100644 index 00000000..a81d09af Binary files /dev/null and b/.doctrees/nightscout/tokens.doctree differ diff --git a/.doctrees/nightscout/ubuntu.doctree b/.doctrees/nightscout/ubuntu.doctree new file mode 100644 index 00000000..440b0846 Binary files /dev/null and b/.doctrees/nightscout/ubuntu.doctree differ diff --git a/.doctrees/nightscout/wearable.doctree b/.doctrees/nightscout/wearable.doctree new file mode 100644 index 00000000..c9b0853d Binary files /dev/null and b/.doctrees/nightscout/wearable.doctree differ diff --git a/.doctrees/nightscout/wizard.doctree b/.doctrees/nightscout/wizard.doctree new file mode 100644 index 00000000..002dccd0 Binary files /dev/null and b/.doctrees/nightscout/wizard.doctree differ diff --git a/.doctrees/nightscout/xdripteam.doctree b/.doctrees/nightscout/xdripteam.doctree new file mode 100644 index 00000000..597dcb85 Binary files /dev/null and b/.doctrees/nightscout/xdripteam.doctree differ diff --git a/.doctrees/pages/configure/index.doctree b/.doctrees/pages/configure/index.doctree new file mode 100644 index 00000000..a793c6a8 Binary files /dev/null and b/.doctrees/pages/configure/index.doctree differ diff --git a/.doctrees/pages/mongostring/index.doctree b/.doctrees/pages/mongostring/index.doctree new file mode 100644 index 00000000..3a645675 Binary files /dev/null and b/.doctrees/pages/mongostring/index.doctree differ diff --git a/.doctrees/pages/update-fork/index.doctree b/.doctrees/pages/update-fork/index.doctree new file mode 100644 index 00000000..4feef3c3 Binary files /dev/null and b/.doctrees/pages/update-fork/index.doctree differ diff --git a/.doctrees/translate.doctree b/.doctrees/translate.doctree new file mode 100644 index 00000000..7081a53a Binary files /dev/null and b/.doctrees/translate.doctree differ diff --git a/.doctrees/troubleshoot/atlas.doctree b/.doctrees/troubleshoot/atlas.doctree new file mode 100644 index 00000000..eaeea24c Binary files /dev/null and b/.doctrees/troubleshoot/atlas.doctree differ diff --git a/.doctrees/troubleshoot/azure.doctree b/.doctrees/troubleshoot/azure.doctree new file mode 100644 index 00000000..04da931a Binary files /dev/null and b/.doctrees/troubleshoot/azure.doctree differ diff --git a/.doctrees/troubleshoot/cleanup.doctree b/.doctrees/troubleshoot/cleanup.doctree new file mode 100644 index 00000000..735d4799 Binary files /dev/null and b/.doctrees/troubleshoot/cleanup.doctree differ diff --git a/.doctrees/troubleshoot/connection_string.doctree b/.doctrees/troubleshoot/connection_string.doctree new file mode 100644 index 00000000..c0d995eb Binary files /dev/null and b/.doctrees/troubleshoot/connection_string.doctree differ diff --git a/.doctrees/troubleshoot/dexcom_bridge.doctree b/.doctrees/troubleshoot/dexcom_bridge.doctree new file mode 100644 index 00000000..d1426695 Binary files /dev/null and b/.doctrees/troubleshoot/dexcom_bridge.doctree differ diff --git a/.doctrees/troubleshoot/fly.io.doctree b/.doctrees/troubleshoot/fly.io.doctree new file mode 100644 index 00000000..ea9dc719 Binary files /dev/null and b/.doctrees/troubleshoot/fly.io.doctree differ diff --git a/.doctrees/troubleshoot/github.doctree b/.doctrees/troubleshoot/github.doctree new file mode 100644 index 00000000..824c5643 Binary files /dev/null and b/.doctrees/troubleshoot/github.doctree differ diff --git a/.doctrees/troubleshoot/heroku.doctree b/.doctrees/troubleshoot/heroku.doctree new file mode 100644 index 00000000..6bfebcbd Binary files /dev/null and b/.doctrees/troubleshoot/heroku.doctree differ diff --git a/.doctrees/troubleshoot/northflank.doctree b/.doctrees/troubleshoot/northflank.doctree new file mode 100644 index 00000000..cccb7db9 Binary files /dev/null and b/.doctrees/troubleshoot/northflank.doctree differ diff --git a/.doctrees/troubleshoot/railway.doctree b/.doctrees/troubleshoot/railway.doctree new file mode 100644 index 00000000..dd36ae6b Binary files /dev/null and b/.doctrees/troubleshoot/railway.doctree differ diff --git a/.doctrees/troubleshoot/render.doctree b/.doctrees/troubleshoot/render.doctree new file mode 100644 index 00000000..34a183b0 Binary files /dev/null and b/.doctrees/troubleshoot/render.doctree differ diff --git a/.doctrees/troubleshoot/troublehoot.doctree b/.doctrees/troubleshoot/troublehoot.doctree new file mode 100644 index 00000000..b7592318 Binary files /dev/null and b/.doctrees/troubleshoot/troublehoot.doctree differ diff --git a/.doctrees/troubleshoot/troubleshoot.doctree b/.doctrees/troubleshoot/troubleshoot.doctree new file mode 100644 index 00000000..37bf8879 Binary files /dev/null and b/.doctrees/troubleshoot/troubleshoot.doctree differ diff --git a/.doctrees/update/dev_branch.doctree b/.doctrees/update/dev_branch.doctree new file mode 100644 index 00000000..750154a9 Binary files /dev/null and b/.doctrees/update/dev_branch.doctree differ diff --git a/.doctrees/update/downgrade.doctree b/.doctrees/update/downgrade.doctree new file mode 100644 index 00000000..af60800f Binary files /dev/null and b/.doctrees/update/downgrade.doctree differ diff --git a/.doctrees/update/redeploy.doctree b/.doctrees/update/redeploy.doctree new file mode 100644 index 00000000..417578b5 Binary files /dev/null and b/.doctrees/update/redeploy.doctree differ diff --git a/.doctrees/update/upd_stack.doctree b/.doctrees/update/upd_stack.doctree new file mode 100644 index 00000000..b1f079cd Binary files /dev/null and b/.doctrees/update/upd_stack.doctree differ diff --git a/.doctrees/update/update.doctree b/.doctrees/update/update.doctree new file mode 100644 index 00000000..4e3b8c65 Binary files /dev/null and b/.doctrees/update/update.doctree differ diff --git a/.doctrees/uploader/setup.doctree b/.doctrees/uploader/setup.doctree new file mode 100644 index 00000000..464054e6 Binary files /dev/null and b/.doctrees/uploader/setup.doctree differ diff --git a/.doctrees/uploader/uploaders.doctree b/.doctrees/uploader/uploaders.doctree new file mode 100644 index 00000000..a4089604 Binary files /dev/null and b/.doctrees/uploader/uploaders.doctree differ diff --git a/.doctrees/uploader/xdripcarelink.doctree b/.doctrees/uploader/xdripcarelink.doctree new file mode 100644 index 00000000..6c256428 Binary files /dev/null and b/.doctrees/uploader/xdripcarelink.doctree differ diff --git a/.doctrees/vendors/10BE.doctree b/.doctrees/vendors/10BE.doctree new file mode 100644 index 00000000..71ef1447 Binary files /dev/null and b/.doctrees/vendors/10BE.doctree differ diff --git a/.doctrees/vendors/NAS/synology.doctree b/.doctrees/vendors/NAS/synology.doctree new file mode 100644 index 00000000..3adb6852 Binary files /dev/null and b/.doctrees/vendors/NAS/synology.doctree differ diff --git a/.doctrees/vendors/T1Pal/new_user.doctree b/.doctrees/vendors/T1Pal/new_user.doctree new file mode 100644 index 00000000..6b755ebe Binary files /dev/null and b/.doctrees/vendors/T1Pal/new_user.doctree differ diff --git a/.doctrees/vendors/VPS/docker.doctree b/.doctrees/vendors/VPS/docker.doctree new file mode 100644 index 00000000..dfba5e73 Binary files /dev/null and b/.doctrees/vendors/VPS/docker.doctree differ diff --git a/.doctrees/vendors/VPS/ubuntu.doctree b/.doctrees/vendors/VPS/ubuntu.doctree new file mode 100644 index 00000000..7e477893 Binary files /dev/null and b/.doctrees/vendors/VPS/ubuntu.doctree differ diff --git a/.doctrees/vendors/azure/migrate.doctree b/.doctrees/vendors/azure/migrate.doctree new file mode 100644 index 00000000..44a27526 Binary files /dev/null and b/.doctrees/vendors/azure/migrate.doctree differ diff --git a/.doctrees/vendors/azure/new_user.doctree b/.doctrees/vendors/azure/new_user.doctree new file mode 100644 index 00000000..fa78df84 Binary files /dev/null and b/.doctrees/vendors/azure/new_user.doctree differ diff --git a/.doctrees/vendors/azure/new_user_a.doctree b/.doctrees/vendors/azure/new_user_a.doctree new file mode 100644 index 00000000..73977aad Binary files /dev/null and b/.doctrees/vendors/azure/new_user_a.doctree differ diff --git a/.doctrees/vendors/azure/new_user_b.doctree b/.doctrees/vendors/azure/new_user_b.doctree new file mode 100644 index 00000000..6fb06d15 Binary files /dev/null and b/.doctrees/vendors/azure/new_user_b.doctree differ diff --git a/.doctrees/vendors/digitalocean/new_user.doctree b/.doctrees/vendors/digitalocean/new_user.doctree new file mode 100644 index 00000000..6fe8b4d6 Binary files /dev/null and b/.doctrees/vendors/digitalocean/new_user.doctree differ diff --git a/.doctrees/vendors/fly.io/new_user.doctree b/.doctrees/vendors/fly.io/new_user.doctree new file mode 100644 index 00000000..ba0eddab Binary files /dev/null and b/.doctrees/vendors/fly.io/new_user.doctree differ diff --git a/.doctrees/vendors/github/create.doctree b/.doctrees/vendors/github/create.doctree new file mode 100644 index 00000000..8188fb73 Binary files /dev/null and b/.doctrees/vendors/github/create.doctree differ diff --git a/.doctrees/vendors/github/delete.doctree b/.doctrees/vendors/github/delete.doctree new file mode 100644 index 00000000..c4ee1f6a Binary files /dev/null and b/.doctrees/vendors/github/delete.doctree differ diff --git a/.doctrees/vendors/github/update.doctree b/.doctrees/vendors/github/update.doctree new file mode 100644 index 00000000..62d7fce3 Binary files /dev/null and b/.doctrees/vendors/github/update.doctree differ diff --git a/.doctrees/vendors/github/update_b.doctree b/.doctrees/vendors/github/update_b.doctree new file mode 100644 index 00000000..6e03ffb6 Binary files /dev/null and b/.doctrees/vendors/github/update_b.doctree differ diff --git a/.doctrees/vendors/google/new_user.doctree b/.doctrees/vendors/google/new_user.doctree new file mode 100644 index 00000000..a2c51d70 Binary files /dev/null and b/.doctrees/vendors/google/new_user.doctree differ diff --git a/.doctrees/vendors/heroku.doctree b/.doctrees/vendors/heroku.doctree new file mode 100644 index 00000000..6043694b Binary files /dev/null and b/.doctrees/vendors/heroku.doctree differ diff --git a/.doctrees/vendors/heroku/ecoplan.doctree b/.doctrees/vendors/heroku/ecoplan.doctree new file mode 100644 index 00000000..5a466ecd Binary files /dev/null and b/.doctrees/vendors/heroku/ecoplan.doctree differ diff --git a/.doctrees/vendors/heroku/hobbyplan.doctree b/.doctrees/vendors/heroku/hobbyplan.doctree new file mode 100644 index 00000000..475f625a Binary files /dev/null and b/.doctrees/vendors/heroku/hobbyplan.doctree differ diff --git a/.doctrees/vendors/heroku/mfa.doctree b/.doctrees/vendors/heroku/mfa.doctree new file mode 100644 index 00000000..61c1b8d6 Binary files /dev/null and b/.doctrees/vendors/heroku/mfa.doctree differ diff --git a/.doctrees/vendors/heroku/migrate.doctree b/.doctrees/vendors/heroku/migrate.doctree new file mode 100644 index 00000000..fff54cb4 Binary files /dev/null and b/.doctrees/vendors/heroku/migrate.doctree differ diff --git a/.doctrees/vendors/heroku/new_user.doctree b/.doctrees/vendors/heroku/new_user.doctree new file mode 100644 index 00000000..bae3fe4a Binary files /dev/null and b/.doctrees/vendors/heroku/new_user.doctree differ diff --git a/.doctrees/vendors/mongodb/atlas.doctree b/.doctrees/vendors/mongodb/atlas.doctree new file mode 100644 index 00000000..5c304942 Binary files /dev/null and b/.doctrees/vendors/mongodb/atlas.doctree differ diff --git a/.doctrees/vendors/nightscout4u/new_user.doctree b/.doctrees/vendors/nightscout4u/new_user.doctree new file mode 100644 index 00000000..a075fe70 Binary files /dev/null and b/.doctrees/vendors/nightscout4u/new_user.doctree differ diff --git a/.doctrees/vendors/northflank/database.doctree b/.doctrees/vendors/northflank/database.doctree new file mode 100644 index 00000000..4aac4749 Binary files /dev/null and b/.doctrees/vendors/northflank/database.doctree differ diff --git a/.doctrees/vendors/northflank/migrate.doctree b/.doctrees/vendors/northflank/migrate.doctree new file mode 100644 index 00000000..14f2b2e4 Binary files /dev/null and b/.doctrees/vendors/northflank/migrate.doctree differ diff --git a/.doctrees/vendors/northflank/migrate_a.doctree b/.doctrees/vendors/northflank/migrate_a.doctree new file mode 100644 index 00000000..2a3b33c7 Binary files /dev/null and b/.doctrees/vendors/northflank/migrate_a.doctree differ diff --git a/.doctrees/vendors/northflank/new_user.doctree b/.doctrees/vendors/northflank/new_user.doctree new file mode 100644 index 00000000..6c549fdc Binary files /dev/null and b/.doctrees/vendors/northflank/new_user.doctree differ diff --git a/.doctrees/vendors/northflank/new_user_a.doctree b/.doctrees/vendors/northflank/new_user_a.doctree new file mode 100644 index 00000000..7d39957f Binary files /dev/null and b/.doctrees/vendors/northflank/new_user_a.doctree differ diff --git a/.doctrees/vendors/northflank/new_user_d.doctree b/.doctrees/vendors/northflank/new_user_d.doctree new file mode 100644 index 00000000..53ecfaa0 Binary files /dev/null and b/.doctrees/vendors/northflank/new_user_d.doctree differ diff --git a/.doctrees/vendors/oracle/new_user.doctree b/.doctrees/vendors/oracle/new_user.doctree new file mode 100644 index 00000000..22e021f4 Binary files /dev/null and b/.doctrees/vendors/oracle/new_user.doctree differ diff --git a/.doctrees/vendors/railway/NightscoutVariablesRailway.doctree b/.doctrees/vendors/railway/NightscoutVariablesRailway.doctree new file mode 100644 index 00000000..c2e1229d Binary files /dev/null and b/.doctrees/vendors/railway/NightscoutVariablesRailway.doctree differ diff --git a/.doctrees/vendors/railway/database.doctree b/.doctrees/vendors/railway/database.doctree new file mode 100644 index 00000000..b89ac3ed Binary files /dev/null and b/.doctrees/vendors/railway/database.doctree differ diff --git a/.doctrees/vendors/railway/migrate.doctree b/.doctrees/vendors/railway/migrate.doctree new file mode 100644 index 00000000..d4f011e2 Binary files /dev/null and b/.doctrees/vendors/railway/migrate.doctree differ diff --git a/.doctrees/vendors/railway/migration.doctree b/.doctrees/vendors/railway/migration.doctree new file mode 100644 index 00000000..3e0a3a09 Binary files /dev/null and b/.doctrees/vendors/railway/migration.doctree differ diff --git a/.doctrees/vendors/railway/new_user.doctree b/.doctrees/vendors/railway/new_user.doctree new file mode 100644 index 00000000..b49b1201 Binary files /dev/null and b/.doctrees/vendors/railway/new_user.doctree differ diff --git a/.doctrees/vendors/railway/new_user2.doctree b/.doctrees/vendors/railway/new_user2.doctree new file mode 100644 index 00000000..c44c1fdf Binary files /dev/null and b/.doctrees/vendors/railway/new_user2.doctree differ diff --git a/.doctrees/vendors/railway/new_user_a.doctree b/.doctrees/vendors/railway/new_user_a.doctree new file mode 100644 index 00000000..8975ef57 Binary files /dev/null and b/.doctrees/vendors/railway/new_user_a.doctree differ diff --git a/.doctrees/vendors/railway/new_user_b.doctree b/.doctrees/vendors/railway/new_user_b.doctree new file mode 100644 index 00000000..ec4b8313 Binary files /dev/null and b/.doctrees/vendors/railway/new_user_b.doctree differ diff --git a/.doctrees/vendors/railway/new_user_d.doctree b/.doctrees/vendors/railway/new_user_d.doctree new file mode 100644 index 00000000..6a3640bf Binary files /dev/null and b/.doctrees/vendors/railway/new_user_d.doctree differ diff --git a/.doctrees/vendors/raspberry-pi/new_user.doctree b/.doctrees/vendors/raspberry-pi/new_user.doctree new file mode 100644 index 00000000..6e815e33 Binary files /dev/null and b/.doctrees/vendors/raspberry-pi/new_user.doctree differ diff --git a/.doctrees/vendors/render/new_user.doctree b/.doctrees/vendors/render/new_user.doctree new file mode 100644 index 00000000..32a4ccb4 Binary files /dev/null and b/.doctrees/vendors/render/new_user.doctree differ diff --git a/.doctrees/vendors/render/new_user_a.doctree b/.doctrees/vendors/render/new_user_a.doctree new file mode 100644 index 00000000..e5bfe7c0 Binary files /dev/null and b/.doctrees/vendors/render/new_user_a.doctree differ diff --git a/.doctrees/vendors/render/new_user_d.doctree b/.doctrees/vendors/render/new_user_d.doctree new file mode 100644 index 00000000..28177ade Binary files /dev/null and b/.doctrees/vendors/render/new_user_d.doctree differ diff --git a/.doctrees/vendors/serendipity/index.doctree b/.doctrees/vendors/serendipity/index.doctree new file mode 100644 index 00000000..37320b7a Binary files /dev/null and b/.doctrees/vendors/serendipity/index.doctree differ diff --git a/.doctrees/vendors/synology/new_user.doctree b/.doctrees/vendors/synology/new_user.doctree new file mode 100644 index 00000000..76a91ed7 Binary files /dev/null and b/.doctrees/vendors/synology/new_user.doctree differ diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/404/index.html b/404/index.html new file mode 100644 index 00000000..926c444e --- /dev/null +++ b/404/index.html @@ -0,0 +1,195 @@ + + + + + + + 404 - Page not found — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

404 - Page not found

+

Copy the URL and report it here.

+
+https://raw.githubusercontent.com/nightscout/cgm-remote-monitor/master/static/images/errorcat.jpg +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/_downloads/8ff7fa269d11fd145d3ac558602ade94/NightscoutVariablesUbuntu.html b/_downloads/8ff7fa269d11fd145d3ac558602ade94/NightscoutVariablesUbuntu.html new file mode 100644 index 00000000..afb772e8 --- /dev/null +++ b/_downloads/8ff7fa269d11fd145d3ac558602ade94/NightscoutVariablesUbuntu.html @@ -0,0 +1,385 @@ + + + + + +

Configure your Nightscout variables

+With this form you can easily decide which features to enable and customize your Nightscout. +

+

Mandatory variables

+

These three variables below must have a value.



+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BASE_URL
The BASE_URL consists of your Ubuntu computer/VPS IP and the Port 1337 on which the Nightscout app runs (replace 123.456.789.123 with your IP and leave :1337).

MONGO_CONNECTION
The MongoDB Connection String to connect to your MongoDB cluster. It will look like this: mongodb://MONGO_NS_USER:MONGO_NS_PASSWORD@127.0.0.1:27017/MONGO_NS_DB but you need to replace MONGO_NS_USER, MONGO_NS_PASSWORD and MONGO_NS_DB by your own database user and name.

API_SECRET
A passphrase that must be at least 12 characters long. Avoid 'special' characters, which can cause problems in some cases.

DISPLAY_UNITS +
Preferred BG units for the site: 'mg/dl' or 'mmol/l' (or just 'mmol').

+ +

Customizations

+

Leave default values if you don't want to change them.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CUSTOM_TITLE
The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer.

THEME +
Default setting for new browser views for the color theme of the CGM graph. ('default' 'colors' or 'colorblindfriendly')

ENABLE
Plugins to enable for your site. Must be a space-delimited lower-case list. Include the word 'bridge' here if you are receiving data from the Dexcom Share service.

SHOW_PLUGINS
Default setting for whether or not these plugins are checked (active) by default not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case.

TIME_FORMAT +
Default setting for new browser views for the time mode. ('12' or '24')

NIGHT_MODE
Default setting for new browser views for whether Night Mode should be enabled. ('on' or 'off')

BOLUS_RENDER_OVER
U value over which the bolus values are rendered on the chart if the 'x U and Over' option is selected.

+ +

Dexcom Share

+

If you want Nightscout to import direcly from Dexcom Share

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
BRIDGE_USER_NAME
Your Dexcom account username to receive CGM data from the Dexcom Share service. Also make sure to include 'bridge' in your ENABLE line.

BRIDGE_PASSWORD
Your Dexcom account password to receive CGM data from the Dexcom Share service. Also make sure to include 'bridge' in your ENABLE line.

BRIDGE_SERVER +
If you are bridging from the Dexcom Share service and are anywhere *outside* the US change this to EU. ('US' or 'EU')

+ +

Alarms

+

You can customize alarms or leave them to default values

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ALARM_TYPES +
simple' and/or 'predict'. Simple alarms trigger when BG crosses the various thresholds set below. Predict alarms use a formula that forecasts where the BG is going based on its trend. You will *not* get warnings when crossing the BG thresholds set below when using the predict type.

ALARM_URGENT_HIGH
Default setting for new browser views for the Urgent High alarm (triggered when BG crosses BG_HIGH). ('on' or 'off')

BG_HIGH
Urgent High BG threshold triggers the ALARM_URGENT_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable.

ALARM_URGENT_LOW
Default setting for new browser views for the Urgent Low alarm (triggered when BG crosses BG_LOW). ('on' or 'off')

BG_LOW
Urgent Low BG threshold triggers the ALARM_URGENT_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable.

ALARM_HIGH
Default setting for new browser views for the High alarm (triggered when BG crosses BG_TARGET_TOP). ('on' or 'off')

BG_TARGET_TOP
High BG threshold triggers the ALARM_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable.

ALARM_LOW
Default setting for new browser views for the Low alarm (triggered when BG crosses BG_TARGET_BOTTOM). ('on' or 'off')

BG_TARGET_BOTTOM
Low BG threshold triggers the ALARM_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable.

ALARM_TIMEAGO_URGENT
Default setting for new browser views for an urgent alarm when CGM data hasn't been received in the number of minutes set in ALARM_TIMEAGO_URGENT_MINS. ('on' or 'off')

ALARM_TIMEAGO_URGENT_MINS
Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_URGENT alarm.

ALARM_TIMEAGO_WARN
Default setting for new browser views for a warning alarm when CGM data hasn't been received in the number of minutes set in ALARM_TIMEAGO_WARN_MINS. ('on' or 'off')

ALARM_TIMEAGO_WARN_MINS
Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_WARN alarm.

+ + +

+

Now click on the Validate button below

+ +

If errors show up, please correct them and click Validate again.

+

Click the button above.

+

+

+ +

+ +

+ + + + diff --git a/_downloads/9dcf00d43de2dd4067ba56ae19a896e2/stringhelp.html b/_downloads/9dcf00d43de2dd4067ba56ae19a896e2/stringhelp.html new file mode 100644 index 00000000..0ed2c12d --- /dev/null +++ b/_downloads/9dcf00d43de2dd4067ba56ae19a896e2/stringhelp.html @@ -0,0 +1,54 @@ + + + +

Atlas new site creation connection string utility

+
+Step 1: Copy your new Atlas connection string below:
+It should look like mongodb+srv://yourdbuser:<password>@cluster.zzzzz.mongodb.net/?retryWrites=true&w=majority +
+ +

+Step 2: Enter your database password below:
+Note:
+ - The password is the one used when creating the Atlas database.
+ +
+

Step 3: Click Generate

+ +

+Step 4: Copy the resulting connection string in your MONGODB_URI variable + + + + diff --git a/_downloads/e4cb5a358b76b05bbc69edc42c0a7577/docker-compose.yml b/_downloads/e4cb5a358b76b05bbc69edc42c0a7577/docker-compose.yml new file mode 100644 index 00000000..341f6712 --- /dev/null +++ b/_downloads/e4cb5a358b76b05bbc69edc42c0a7577/docker-compose.yml @@ -0,0 +1,127 @@ +version: '3.9' + +x-logging: + &default-logging + options: + max-size: '10m' + max-file: '5' + driver: json-file + +services: + nightscout: + image: nightscout/cgm-remote-monitor:latest + environment: +# ----------------------------------------------------------------------------------------------- +# Here are your Nightscout variables: +# Respect the format VARIABLE: value (with a space after :) +# +# Mandatory information + TZ: YOUR_TIMEZONE + API_SECRET: YOUR_API_SECRET + ENABLE: careportal sage iage cage iob cob basal upbat devicestatus dbsize cors + SHOW_PLUGINS: careportal sage iob cob dbsize cors ar2 + DISPLAY_UNITS: mg/dl + + #BRIDGE_USER_NAME: username + #BRIDGE_PASSWORD: password + #BRIDGE_SERVER: EU + + AUTH_DEFAULT_ROLES: readable + NIGHT_MODE: off + THEME: colors + TIME_FORMAT: 24 + SCALE_Y: linear + AR2_CONE_FACTOR: 0 + SHOW_RAWBG: always + DBSIZE_MAX: DISK_SIZE + #BASAL_RENDER: default + BOLUS_RENDER_FORMAT_SMALL: minimal + BOLUS_RENDER_OVER: 1 + + BG_LOW: 60 + BG_TARGET_BOTTOM: 70 + BG_TARGET_TOP: 180 + BG_HIGH: 200 + ALARM_TYPES: simple + ALARM_HIGH: on + ALARM_LOW: on + ALARM_URGENT_HIGH: on + ALARM_URGENT_LOW: on + ALARM_TIMEAGO_URGENT: on + ALARM_TIMEAGO_URGENT_MINS: 30 + ALARM_TIMEAGO_WARN: on + ALARM_TIMEAGO_WARN_MINS: 15 + + DEVICESTATUS_ADVANCED: true + SAGE_INFO: 336 + SAGE_URGENT: 348 + SAGE_WARN: 342 + #SHOW_FORECAST: + #PUMP_FIELDS: reservoir battery clock status + #PUMP_RETRO_FIELDS: battery reservoir clock status + #PUMP_URGENT_BATT: 26 + #PUMP_WARN_BATT: 51 + #IAGE_INFO: 68 + #IAGE_URGENT: 79 + #IAGE_WARN: 72 + #PUMP_ENABLE_ALERTS: true + #PUMP_URGENT_BATT_U: 30 + #PUMP_URGENT_BATT_V: 1.25 + #PUMP_URGENT_RES: 10 + #PUMP_URGENT_CLOCK: 30 + #LOOP_ENABLE_ALERTS: true + #LOOP_WARN: 20 + #LOOP_URGENT: 60 +# ----------------------------------------------------------------------------------------------- +# Do not change anything below unless you know what you are doing +# ----------------------------------------------------------------------------------------------- + INSECURE_USE_HTTP: 'true' + MONGO_CONNECTION: mongodb://mongo:27017/Nightscout + ports: + - "1337:1337" + depends_on: + - mongo + labels: + - 'traefik.enable=true' + # Change the below Host from `localhost` to be the web address where Nightscout is running. + # Also change the email address in the `traefik` service below. + - 'traefik.http.routers.nightscout.rule=Host(`YOUR_PUBLIC_HOST_URL`)' + - 'traefik.http.routers.nightscout.entrypoints=websecure' + - 'traefik.http.routers.nightscout.tls.certresolver=le' + volumes: + - /nightscout/docker:/var/opt/ssl/:ro + restart: unless-stopped + + mongo: +# Note you can also use mongo:5 + image: mongo:4.4 + container_name: mongo + volumes: + - ./data:/data/db +# Enable only of you want external access, but then you should modify mongo login and passord + #ports: + #- "27017:27017" + logging: *default-logging + restart: unless-stopped + + traefik: + image: traefik:latest + container_name: 'traefik' + command: + - '--providers.docker=true' + - '--providers.docker.exposedbydefault=false' + - '--entrypoints.web.address=:80' + - '--entrypoints.web.http.redirections.entrypoint.to=websecure' + - '--entrypoints.websecure.address=:443' + - "--certificatesresolvers.le.acme.httpchallenge=true" + - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web" + - '--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json' + # Change the below to match your email address + - '--certificatesresolvers.le.acme.email=YOUR_EMAIL' + ports: + - '443:443' + - '80:80' + volumes: + - './letsencrypt:/letsencrypt' + - '/var/run/docker.sock:/var/run/docker.sock:ro' + restart: unless-stopped \ No newline at end of file diff --git a/_downloads/e8c47bec80e9e7174f9413e7b2ce64c3/render.txt b/_downloads/e8c47bec80e9e7174f9413e7b2ce64c3/render.txt new file mode 100644 index 00000000..0adb96ea --- /dev/null +++ b/_downloads/e8c47bec80e9e7174f9413e7b2ce64c3/render.txt @@ -0,0 +1,79 @@ +# Easily deploy NightScout CGM Remote Monitor (https://github.com/nightscout/cgm-remote-monitor) +# to Render (https://render.com) +# ------------------------------ +# 1. Fork https://github.com/nightscout/cgm-remote-monitor to your own GitHub account. +# 2. Add a render.yaml file to the root of your forked repo, copy/paste the contents below +# 3. Commit the new file (and push to GitHub) +# 4. In Render, click "New +" > "Blueprint" +# 5. Connect your own, forked cgm-remote-monitor repo +# 6. Fill in required environment variables +# 7. Click "Apply" and wait for the deploy to complete. + +services: + - type: web + name: nightscout + env: node + region: oregon # optional (defaults to oregon. Other regions: ohio, frankfurt, singapore) + plan: free # optional (defaults to free - this a FREE PLAN, maybe... https://render.com/pricing) + buildCommand: npm install + startCommand: npm start + healthCheckPath: / + envVars: + - key: INSECURE_USE_HTTP # TLS is terminated before reaching the app, so only needs to respond to HTTP. + value: true + - key: HOSTNAME # bind app to any internal IP + value: "0.0.0.0" + - key: MONGODB_URI # The MongoDB Connection String to connect to your MongoDB cluster. If you don't have this from MongoDB Atlas, please re-read installation instructions at http://nightscout.github.io/nightscout/new_user/ before continuing + sync: false # will be requested when Blueprint is created + - key: ALARM_HIGH # Default setting for new browser views, for the High alarm (triggered when BG crosses BG_TARGET_TOP). ('on' or 'off') + value: "on" + - key: ALARM_LOW # Default setting for new browser views, for the Low alarm (triggered when BG crosses BG_TARGET_BOTTOM). ('on' or 'off') + value: "on" + - key: ALARM_TIMEAGO_URGENT # Default setting for new browser views, for an urgent alarm when CGM data hasn't been received in the number of minutes set in ALARM_TIMEAGO_URGENT_MINS. ('on' or 'off') + value: "on" + - key: ALARM_TIMEAGO_URGENT_MINS # Default setting for new browser views, for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_URGENT alarm. + value: "30" + - key: ALARM_TIMEAGO_WARN # Default setting for new browser views, for a warning alarm when CGM data hasn't been received in the number of minutes set in ALARM_TIMEAGO_WARN_MINS. ('on' or 'off') + value: "on" + - key: ALARM_TIMEAGO_WARN_MINS # Default setting for new browser views, for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_WARN alarm. + value: "15" + - key: ALARM_TYPES # 'simple' and/or 'predict'. Simple alarms trigger when BG crosses the various thresholds set below. Predict alarms use a formula that forecasts where the BG is going based on its trend. You will *not* get warnings when crossing the BG thresholds set below when using the predict type. + value: "simple" + - key: ALARM_URGENT_HIGH # Default setting for new browser views, for the Urgent High alarm (triggered when BG crosses BG_HIGH). ('on' or 'off') + value: "on" + - key: ALARM_URGENT_LOW # Default setting for new browser views, for the Urgent Low alarm (triggered when BG crosses BG_LOW). ('on' or 'off') + value: "on" + - key: API_SECRET # A passphrase that must be at least 12 characters long. Avoid 'special' characters, which can cause problems in some cases. + sync: false # will be requested when Blueprint is created + - key: BG_HIGH # Urgent High BG threshold, triggers the ALARM_URGENT_HIGH alarm. Set in mg/dL or mmol/L, as set in DISPLAY_UNITS variable. + value: "260" + - key: BG_LOW # Urgent Low BG threshold, triggers the ALARM_URGENT_LOW alarm. Set in mg/dL or mmol/L, as set in DISPLAY_UNITS variable. + value: "55" + - key: BG_TARGET_BOTTOM # Low BG threshold, triggers the ALARM_LOW alarm. Set in mg/dL or mmol/L, as set in DISPLAY_UNITS variable. + value: "80" + - key: BG_TARGET_TOP # High BG threshold, triggers the ALARM_HIGH alarm. Set in mg/dL or mmol/L, as set in DISPLAY_UNITS variable. + value: "180" + - key: BOLUS_RENDER_OVER # U value over which the bolus values are rendered on the chart if the 'x U and Over' option is selected. + value: "1" + - key: BRIDGE_PASSWORD # Your Dexcom account password, to receive CGM data from the Dexcom Share service. Also make sure to include 'bridge' in your ENABLE line. + value: "password" + - key: BRIDGE_SERVER # If you are bridging from the Dexcom Share service, and are anywhere *outside* the US, change this to EU. ('US' or 'EU') + value: "EU" + - key: BRIDGE_USER_NAME # Your Dexcom account username, to receive CGM data from the Dexcom Share service. Also make sure to include 'bridge' in your ENABLE line. + value: "username" + - key: CUSTOM_TITLE # The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer. + value: "" + - key: DISPLAY_UNITS # Preferred BG units for the site: 'mg/dl' or 'mmol/L' (or just 'mmol'). + sync: false # will be requested when Blueprint is created + - key: ENABLE # Plugins to enable for your site. Must be a space-delimited, lower-case list. Include the word 'bridge' here if you are receiving data from the Dexcom Share service. Include 'mmconnect' if you are bridging from the MiniMed CareLink service. + value: "careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors" + - key: NIGHT_MODE # Default setting for new browser views, for whether Night Mode should be enabled. ('on' or 'off') + value: "off" + - key: SHOW_PLUGINS # Default setting for whether or not these plugins are checked (active) by default, not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case. + value: "careportal dbize" + - key: SHOW_RAWBG # Default setting for new browser views, for the display of raw CGM data (if available). ('always', 'never', or 'noise') + value: "never" + - key: THEME # Default setting for new browser views, for the color theme of the CGM graph. ('default', 'colors', or 'colorblindfriendly') + value: "colors" + - key: TIME_FORMAT # Default setting for new browser views, for the time mode. ('12' or '24') + value: "12" \ No newline at end of file diff --git a/_images/10BE.png b/_images/10BE.png new file mode 100644 index 00000000..a50ecadb Binary files /dev/null and b/_images/10BE.png differ diff --git a/_images/APNKeys.png b/_images/APNKeys.png new file mode 100644 index 00000000..ee7d6792 Binary files /dev/null and b/_images/APNKeys.png differ diff --git a/_images/AddFile.png b/_images/AddFile.png new file mode 100644 index 00000000..f3fde6db Binary files /dev/null and b/_images/AddFile.png differ diff --git a/_images/Admin00.png b/_images/Admin00.png new file mode 100644 index 00000000..45a1938e Binary files /dev/null and b/_images/Admin00.png differ diff --git a/_images/Admin01.png b/_images/Admin01.png new file mode 100644 index 00000000..f4869539 Binary files /dev/null and b/_images/Admin01.png differ diff --git a/_images/Admin02.png b/_images/Admin02.png new file mode 100644 index 00000000..ca283cb4 Binary files /dev/null and b/_images/Admin02.png differ diff --git a/_images/Admin03.png b/_images/Admin03.png new file mode 100644 index 00000000..ed9338a3 Binary files /dev/null and b/_images/Admin03.png differ diff --git a/_images/Admin04.png b/_images/Admin04.png new file mode 100644 index 00000000..121d448f Binary files /dev/null and b/_images/Admin04.png differ diff --git a/_images/Admin05.png b/_images/Admin05.png new file mode 100644 index 00000000..aae15293 Binary files /dev/null and b/_images/Admin05.png differ diff --git a/_images/Admin05b.png b/_images/Admin05b.png new file mode 100644 index 00000000..75cedd58 Binary files /dev/null and b/_images/Admin05b.png differ diff --git a/_images/Admin06.png b/_images/Admin06.png new file mode 100644 index 00000000..d595096d Binary files /dev/null and b/_images/Admin06.png differ diff --git a/_images/Admin07.png b/_images/Admin07.png new file mode 100644 index 00000000..cbf7b410 Binary files /dev/null and b/_images/Admin07.png differ diff --git a/_images/Admin08.png b/_images/Admin08.png new file mode 100644 index 00000000..1bd7bbd1 Binary files /dev/null and b/_images/Admin08.png differ diff --git a/_images/Admin09.png b/_images/Admin09.png new file mode 100644 index 00000000..2591050f Binary files /dev/null and b/_images/Admin09.png differ diff --git a/_images/Admin10.png b/_images/Admin10.png new file mode 100644 index 00000000..5439f4aa Binary files /dev/null and b/_images/Admin10.png differ diff --git a/_images/Atlas.png b/_images/Atlas.png new file mode 100644 index 00000000..8ac8cd3d Binary files /dev/null and b/_images/Atlas.png differ diff --git a/_images/AtlasX01.png b/_images/AtlasX01.png new file mode 100644 index 00000000..b2c8ed33 Binary files /dev/null and b/_images/AtlasX01.png differ diff --git a/_images/AtlasX02.png b/_images/AtlasX02.png new file mode 100644 index 00000000..dbe53d56 Binary files /dev/null and b/_images/AtlasX02.png differ diff --git a/_images/AtlasX03.png b/_images/AtlasX03.png new file mode 100644 index 00000000..d471e534 Binary files /dev/null and b/_images/AtlasX03.png differ diff --git a/_images/AtlasX04.png b/_images/AtlasX04.png new file mode 100644 index 00000000..17edecb5 Binary files /dev/null and b/_images/AtlasX04.png differ diff --git a/_images/AtlasX07.png b/_images/AtlasX07.png new file mode 100644 index 00000000..f8ce7c50 Binary files /dev/null and b/_images/AtlasX07.png differ diff --git a/_images/Azure.png b/_images/Azure.png new file mode 100644 index 00000000..a7f93a5e Binary files /dev/null and b/_images/Azure.png differ diff --git a/_images/Azure01.png b/_images/Azure01.png new file mode 100644 index 00000000..48da50dc Binary files /dev/null and b/_images/Azure01.png differ diff --git a/_images/Azure02.png b/_images/Azure02.png new file mode 100644 index 00000000..0c04a9e4 Binary files /dev/null and b/_images/Azure02.png differ diff --git a/_images/Azure03.png b/_images/Azure03.png new file mode 100644 index 00000000..020a64f9 Binary files /dev/null and b/_images/Azure03.png differ diff --git a/_images/Azure05.png b/_images/Azure05.png new file mode 100644 index 00000000..c67619d0 Binary files /dev/null and b/_images/Azure05.png differ diff --git a/_images/Azure12.png b/_images/Azure12.png new file mode 100644 index 00000000..8123940a Binary files /dev/null and b/_images/Azure12.png differ diff --git a/_images/Azure15.png b/_images/Azure15.png new file mode 100644 index 00000000..ac1c99b0 Binary files /dev/null and b/_images/Azure15.png differ diff --git a/_images/Azure16.png b/_images/Azure16.png new file mode 100644 index 00000000..61f3004a Binary files /dev/null and b/_images/Azure16.png differ diff --git a/_images/Azure16r.png b/_images/Azure16r.png new file mode 100644 index 00000000..3a228bca Binary files /dev/null and b/_images/Azure16r.png differ diff --git a/_images/Azure22.png b/_images/Azure22.png new file mode 100644 index 00000000..a00b0c9c Binary files /dev/null and b/_images/Azure22.png differ diff --git a/_images/Azure23.png b/_images/Azure23.png new file mode 100644 index 00000000..4f17c518 Binary files /dev/null and b/_images/Azure23.png differ diff --git a/_images/Azure24.png b/_images/Azure24.png new file mode 100644 index 00000000..f4abbaa6 Binary files /dev/null and b/_images/Azure24.png differ diff --git a/_images/Azure25.png b/_images/Azure25.png new file mode 100644 index 00000000..41a55dba Binary files /dev/null and b/_images/Azure25.png differ diff --git a/_images/Azure26.png b/_images/Azure26.png new file mode 100644 index 00000000..62548342 Binary files /dev/null and b/_images/Azure26.png differ diff --git a/_images/Azure27.png b/_images/Azure27.png new file mode 100644 index 00000000..b88c12e3 Binary files /dev/null and b/_images/Azure27.png differ diff --git a/_images/Azure28.png b/_images/Azure28.png new file mode 100644 index 00000000..1553e31f Binary files /dev/null and b/_images/Azure28.png differ diff --git a/_images/Azure29.png b/_images/Azure29.png new file mode 100644 index 00000000..9c4e0d08 Binary files /dev/null and b/_images/Azure29.png differ diff --git a/_images/Azure30.png b/_images/Azure30.png new file mode 100644 index 00000000..82ab53d0 Binary files /dev/null and b/_images/Azure30.png differ diff --git a/_images/Azure31.png b/_images/Azure31.png new file mode 100644 index 00000000..053bbed5 Binary files /dev/null and b/_images/Azure31.png differ diff --git a/_images/Azure32.png b/_images/Azure32.png new file mode 100644 index 00000000..143ad753 Binary files /dev/null and b/_images/Azure32.png differ diff --git a/_images/Azure33.png b/_images/Azure33.png new file mode 100644 index 00000000..6cca9f2b Binary files /dev/null and b/_images/Azure33.png differ diff --git a/_images/Azure34.png b/_images/Azure34.png new file mode 100644 index 00000000..d6ea812d Binary files /dev/null and b/_images/Azure34.png differ diff --git a/_images/Azure35.png b/_images/Azure35.png new file mode 100644 index 00000000..488ae3d8 Binary files /dev/null and b/_images/Azure35.png differ diff --git a/_images/Azure36.png b/_images/Azure36.png new file mode 100644 index 00000000..38bced4b Binary files /dev/null and b/_images/Azure36.png differ diff --git a/_images/Azure37.png b/_images/Azure37.png new file mode 100644 index 00000000..95ef6dcb Binary files /dev/null and b/_images/Azure37.png differ diff --git a/_images/Azure38.png b/_images/Azure38.png new file mode 100644 index 00000000..cbeddadf Binary files /dev/null and b/_images/Azure38.png differ diff --git a/_images/Azure39.png b/_images/Azure39.png new file mode 100644 index 00000000..1d3cc17b Binary files /dev/null and b/_images/Azure39.png differ diff --git a/_images/Azure40.png b/_images/Azure40.png new file mode 100644 index 00000000..2eaa703f Binary files /dev/null and b/_images/Azure40.png differ diff --git a/_images/Azure42.png b/_images/Azure42.png new file mode 100644 index 00000000..3974bb52 Binary files /dev/null and b/_images/Azure42.png differ diff --git a/_images/Azure43.png b/_images/Azure43.png new file mode 100644 index 00000000..a43f2a13 Binary files /dev/null and b/_images/Azure43.png differ diff --git a/_images/Azure44.png b/_images/Azure44.png new file mode 100644 index 00000000..85f3f037 Binary files /dev/null and b/_images/Azure44.png differ diff --git a/_images/Azure45.png b/_images/Azure45.png new file mode 100644 index 00000000..81369c7b Binary files /dev/null and b/_images/Azure45.png differ diff --git a/_images/Azure46.png b/_images/Azure46.png new file mode 100644 index 00000000..6724b2b9 Binary files /dev/null and b/_images/Azure46.png differ diff --git a/_images/Azure47.png b/_images/Azure47.png new file mode 100644 index 00000000..e141223c Binary files /dev/null and b/_images/Azure47.png differ diff --git a/_images/Azure48.png b/_images/Azure48.png new file mode 100644 index 00000000..86637400 Binary files /dev/null and b/_images/Azure48.png differ diff --git a/_images/Azure49.png b/_images/Azure49.png new file mode 100644 index 00000000..bd0387cf Binary files /dev/null and b/_images/Azure49.png differ diff --git a/_images/Azure50.png b/_images/Azure50.png new file mode 100644 index 00000000..ee3139f2 Binary files /dev/null and b/_images/Azure50.png differ diff --git a/_images/AzureName.png b/_images/AzureName.png new file mode 100644 index 00000000..81864c93 Binary files /dev/null and b/_images/AzureName.png differ diff --git a/_images/AzureT01.png b/_images/AzureT01.png new file mode 100644 index 00000000..36948919 Binary files /dev/null and b/_images/AzureT01.png differ diff --git a/_images/AzureT02.png b/_images/AzureT02.png new file mode 100644 index 00000000..060ef090 Binary files /dev/null and b/_images/AzureT02.png differ diff --git a/_images/AzureT03.png b/_images/AzureT03.png new file mode 100644 index 00000000..1cf8a5f6 Binary files /dev/null and b/_images/AzureT03.png differ diff --git a/_images/AzureU02.png b/_images/AzureU02.png new file mode 100644 index 00000000..dce63bb0 Binary files /dev/null and b/_images/AzureU02.png differ diff --git a/_images/Cleanup00.png b/_images/Cleanup00.png new file mode 100644 index 00000000..a7c43b2c Binary files /dev/null and b/_images/Cleanup00.png differ diff --git a/_images/Cleanup00a.png b/_images/Cleanup00a.png new file mode 100644 index 00000000..ae69bf6f Binary files /dev/null and b/_images/Cleanup00a.png differ diff --git a/_images/Cleanup01.png b/_images/Cleanup01.png new file mode 100644 index 00000000..e6c5d1fd Binary files /dev/null and b/_images/Cleanup01.png differ diff --git a/_images/Cleanup02.png b/_images/Cleanup02.png new file mode 100644 index 00000000..40401cfa Binary files /dev/null and b/_images/Cleanup02.png differ diff --git a/_images/Cleanup03.png b/_images/Cleanup03.png new file mode 100644 index 00000000..1a57c0b0 Binary files /dev/null and b/_images/Cleanup03.png differ diff --git a/_images/Cleanup031.png b/_images/Cleanup031.png new file mode 100644 index 00000000..7ce714e0 Binary files /dev/null and b/_images/Cleanup031.png differ diff --git a/_images/Cleanup04.png b/_images/Cleanup04.png new file mode 100644 index 00000000..842e985f Binary files /dev/null and b/_images/Cleanup04.png differ diff --git a/_images/Cleanup05.png b/_images/Cleanup05.png new file mode 100644 index 00000000..8151ea9d Binary files /dev/null and b/_images/Cleanup05.png differ diff --git a/_images/Cleanup06.png b/_images/Cleanup06.png new file mode 100644 index 00000000..e52372c4 Binary files /dev/null and b/_images/Cleanup06.png differ diff --git a/_images/Cleanup07.png b/_images/Cleanup07.png new file mode 100644 index 00000000..feeec012 Binary files /dev/null and b/_images/Cleanup07.png differ diff --git a/_images/Cleanup08.png b/_images/Cleanup08.png new file mode 100644 index 00000000..886d443b Binary files /dev/null and b/_images/Cleanup08.png differ diff --git a/_images/Cleanup09.png b/_images/Cleanup09.png new file mode 100644 index 00000000..6dc4751c Binary files /dev/null and b/_images/Cleanup09.png differ diff --git a/_images/Cleanup10.png b/_images/Cleanup10.png new file mode 100644 index 00000000..00bdca44 Binary files /dev/null and b/_images/Cleanup10.png differ diff --git a/_images/Cleanup11.png b/_images/Cleanup11.png new file mode 100644 index 00000000..515549cc Binary files /dev/null and b/_images/Cleanup11.png differ diff --git a/_images/Cleanup12.png b/_images/Cleanup12.png new file mode 100644 index 00000000..fd46055c Binary files /dev/null and b/_images/Cleanup12.png differ diff --git a/_images/Cleanup13.png b/_images/Cleanup13.png new file mode 100644 index 00000000..bc5cde30 Binary files /dev/null and b/_images/Cleanup13.png differ diff --git a/_images/Cleanup14.png b/_images/Cleanup14.png new file mode 100644 index 00000000..be1fd476 Binary files /dev/null and b/_images/Cleanup14.png differ diff --git a/_images/Cleanup15.png b/_images/Cleanup15.png new file mode 100644 index 00000000..ffa4cf42 Binary files /dev/null and b/_images/Cleanup15.png differ diff --git a/_images/Cleanup16.png b/_images/Cleanup16.png new file mode 100644 index 00000000..4a95f397 Binary files /dev/null and b/_images/Cleanup16.png differ diff --git a/_images/Clinic01.png b/_images/Clinic01.png new file mode 100644 index 00000000..311e4afb Binary files /dev/null and b/_images/Clinic01.png differ diff --git a/_images/Clinic02.png b/_images/Clinic02.png new file mode 100644 index 00000000..b005a37b Binary files /dev/null and b/_images/Clinic02.png differ diff --git a/_images/Clinic03.png b/_images/Clinic03.png new file mode 100644 index 00000000..65e143fb Binary files /dev/null and b/_images/Clinic03.png differ diff --git a/_images/Clinic04.png b/_images/Clinic04.png new file mode 100644 index 00000000..f59d0f78 Binary files /dev/null and b/_images/Clinic04.png differ diff --git a/_images/Clinic05.png b/_images/Clinic05.png new file mode 100644 index 00000000..941e8244 Binary files /dev/null and b/_images/Clinic05.png differ diff --git a/_images/Clinic06.png b/_images/Clinic06.png new file mode 100644 index 00000000..a79d3f80 Binary files /dev/null and b/_images/Clinic06.png differ diff --git a/_images/Clinic07.png b/_images/Clinic07.png new file mode 100644 index 00000000..5d2590cf Binary files /dev/null and b/_images/Clinic07.png differ diff --git a/_images/Clinic08.png b/_images/Clinic08.png new file mode 100644 index 00000000..91cd89f1 Binary files /dev/null and b/_images/Clinic08.png differ diff --git a/_images/Clinic09.png b/_images/Clinic09.png new file mode 100644 index 00000000..1663b51f Binary files /dev/null and b/_images/Clinic09.png differ diff --git a/_images/Clinic10.png b/_images/Clinic10.png new file mode 100644 index 00000000..4d914fef Binary files /dev/null and b/_images/Clinic10.png differ diff --git a/_images/Clinic11.png b/_images/Clinic11.png new file mode 100644 index 00000000..1c9ee7dc Binary files /dev/null and b/_images/Clinic11.png differ diff --git a/_images/Clinic12.png b/_images/Clinic12.png new file mode 100644 index 00000000..033efce5 Binary files /dev/null and b/_images/Clinic12.png differ diff --git a/_images/Clinic13.png b/_images/Clinic13.png new file mode 100644 index 00000000..90daeac5 Binary files /dev/null and b/_images/Clinic13.png differ diff --git a/_images/Clinic14.png b/_images/Clinic14.png new file mode 100644 index 00000000..dfde1a39 Binary files /dev/null and b/_images/Clinic14.png differ diff --git a/_images/Clinic15.png b/_images/Clinic15.png new file mode 100644 index 00000000..fc6ad422 Binary files /dev/null and b/_images/Clinic15.png differ diff --git a/_images/Clinic16.png b/_images/Clinic16.png new file mode 100644 index 00000000..76a2faa3 Binary files /dev/null and b/_images/Clinic16.png differ diff --git a/_images/Clinic17.png b/_images/Clinic17.png new file mode 100644 index 00000000..062cbdc5 Binary files /dev/null and b/_images/Clinic17.png differ diff --git a/_images/Clinic18.png b/_images/Clinic18.png new file mode 100644 index 00000000..abc33e8f Binary files /dev/null and b/_images/Clinic18.png differ diff --git a/_images/Clinic19.png b/_images/Clinic19.png new file mode 100644 index 00000000..006fdbb0 Binary files /dev/null and b/_images/Clinic19.png differ diff --git a/_images/Clinic20.png b/_images/Clinic20.png new file mode 100644 index 00000000..b8f4bb8d Binary files /dev/null and b/_images/Clinic20.png differ diff --git a/_images/Clinic21.png b/_images/Clinic21.png new file mode 100644 index 00000000..dc341b10 Binary files /dev/null and b/_images/Clinic21.png differ diff --git a/_images/Clinic22.png b/_images/Clinic22.png new file mode 100644 index 00000000..0c56b36e Binary files /dev/null and b/_images/Clinic22.png differ diff --git a/_images/Clinic23.png b/_images/Clinic23.png new file mode 100644 index 00000000..8fa81e6e Binary files /dev/null and b/_images/Clinic23.png differ diff --git a/_images/Clinic24.png b/_images/Clinic24.png new file mode 100644 index 00000000..5b2d87d1 Binary files /dev/null and b/_images/Clinic24.png differ diff --git a/_images/Clinic25.png b/_images/Clinic25.png new file mode 100644 index 00000000..087eb779 Binary files /dev/null and b/_images/Clinic25.png differ diff --git a/_images/Clinic26.png b/_images/Clinic26.png new file mode 100644 index 00000000..aafe8c65 Binary files /dev/null and b/_images/Clinic26.png differ diff --git a/_images/Comparison.png b/_images/Comparison.png new file mode 100644 index 00000000..15bfd21d Binary files /dev/null and b/_images/Comparison.png differ diff --git a/_images/Comparison2.png b/_images/Comparison2.png new file mode 100644 index 00000000..8e410707 Binary files /dev/null and b/_images/Comparison2.png differ diff --git a/_images/Comparison3.png b/_images/Comparison3.png new file mode 100644 index 00000000..e81513e1 Binary files /dev/null and b/_images/Comparison3.png differ diff --git a/_images/DNS01.png b/_images/DNS01.png new file mode 100644 index 00000000..83a8896a Binary files /dev/null and b/_images/DNS01.png differ diff --git a/_images/DNS02.png b/_images/DNS02.png new file mode 100644 index 00000000..c260d3c3 Binary files /dev/null and b/_images/DNS02.png differ diff --git a/_images/DNS03.png b/_images/DNS03.png new file mode 100644 index 00000000..fcb1d936 Binary files /dev/null and b/_images/DNS03.png differ diff --git a/_images/DNS04.png b/_images/DNS04.png new file mode 100644 index 00000000..3b25db1e Binary files /dev/null and b/_images/DNS04.png differ diff --git a/_images/DNS05.png b/_images/DNS05.png new file mode 100644 index 00000000..cbeb30c0 Binary files /dev/null and b/_images/DNS05.png differ diff --git a/_images/DNS06.png b/_images/DNS06.png new file mode 100644 index 00000000..fa9b5243 Binary files /dev/null and b/_images/DNS06.png differ diff --git a/_images/DNS07.png b/_images/DNS07.png new file mode 100644 index 00000000..f75d2f93 Binary files /dev/null and b/_images/DNS07.png differ diff --git a/_images/DNS08.png b/_images/DNS08.png new file mode 100644 index 00000000..779551fd Binary files /dev/null and b/_images/DNS08.png differ diff --git a/_images/DNS09.png b/_images/DNS09.png new file mode 100644 index 00000000..1982b766 Binary files /dev/null and b/_images/DNS09.png differ diff --git a/_images/DNS10.png b/_images/DNS10.png new file mode 100644 index 00000000..d99baed6 Binary files /dev/null and b/_images/DNS10.png differ diff --git a/_images/DNS11.png b/_images/DNS11.png new file mode 100644 index 00000000..8ce21bbd Binary files /dev/null and b/_images/DNS11.png differ diff --git a/_images/DNS12.png b/_images/DNS12.png new file mode 100644 index 00000000..005e7bd4 Binary files /dev/null and b/_images/DNS12.png differ diff --git a/_images/DNS13.png b/_images/DNS13.png new file mode 100644 index 00000000..3eaf7418 Binary files /dev/null and b/_images/DNS13.png differ diff --git a/_images/Dev00.png b/_images/Dev00.png new file mode 100644 index 00000000..be7e32a4 Binary files /dev/null and b/_images/Dev00.png differ diff --git a/_images/Dev01.png b/_images/Dev01.png new file mode 100644 index 00000000..17d40fa5 Binary files /dev/null and b/_images/Dev01.png differ diff --git a/_images/Dev03.png b/_images/Dev03.png new file mode 100644 index 00000000..1fb8f2e6 Binary files /dev/null and b/_images/Dev03.png differ diff --git a/_images/Dev04.png b/_images/Dev04.png new file mode 100644 index 00000000..ce8e0f51 Binary files /dev/null and b/_images/Dev04.png differ diff --git a/_images/Dev05.png b/_images/Dev05.png new file mode 100644 index 00000000..f05b401c Binary files /dev/null and b/_images/Dev05.png differ diff --git a/_images/Dev06.png b/_images/Dev06.png new file mode 100644 index 00000000..0d8ea2c8 Binary files /dev/null and b/_images/Dev06.png differ diff --git a/_images/Dev07.png b/_images/Dev07.png new file mode 100644 index 00000000..f62cc6c8 Binary files /dev/null and b/_images/Dev07.png differ diff --git a/_images/Dev12.png b/_images/Dev12.png new file mode 100644 index 00000000..522236c2 Binary files /dev/null and b/_images/Dev12.png differ diff --git a/_images/Dev13.png b/_images/Dev13.png new file mode 100644 index 00000000..ddd99440 Binary files /dev/null and b/_images/Dev13.png differ diff --git a/_images/Dev14.png b/_images/Dev14.png new file mode 100644 index 00000000..26eb8037 Binary files /dev/null and b/_images/Dev14.png differ diff --git a/_images/Dev15.png b/_images/Dev15.png new file mode 100644 index 00000000..65d8285f Binary files /dev/null and b/_images/Dev15.png differ diff --git a/_images/Dev16.png b/_images/Dev16.png new file mode 100644 index 00000000..98677b1e Binary files /dev/null and b/_images/Dev16.png differ diff --git a/_images/Dev17.png b/_images/Dev17.png new file mode 100644 index 00000000..3d8d30a3 Binary files /dev/null and b/_images/Dev17.png differ diff --git a/_images/Dev18.png b/_images/Dev18.png new file mode 100644 index 00000000..4b242485 Binary files /dev/null and b/_images/Dev18.png differ diff --git a/_images/Dev19.png b/_images/Dev19.png new file mode 100644 index 00000000..26f295bd Binary files /dev/null and b/_images/Dev19.png differ diff --git a/_images/DexShare00.png b/_images/DexShare00.png new file mode 100644 index 00000000..806befb2 Binary files /dev/null and b/_images/DexShare00.png differ diff --git a/_images/DexShare01.png b/_images/DexShare01.png new file mode 100644 index 00000000..38140c37 Binary files /dev/null and b/_images/DexShare01.png differ diff --git a/_images/DexShare01b.png b/_images/DexShare01b.png new file mode 100644 index 00000000..23501144 Binary files /dev/null and b/_images/DexShare01b.png differ diff --git a/_images/DexShare02.png b/_images/DexShare02.png new file mode 100644 index 00000000..123dc737 Binary files /dev/null and b/_images/DexShare02.png differ diff --git a/_images/DexShare05.png b/_images/DexShare05.png new file mode 100644 index 00000000..3ac463e0 Binary files /dev/null and b/_images/DexShare05.png differ diff --git a/_images/Downgrade00.png b/_images/Downgrade00.png new file mode 100644 index 00000000..24fe185d Binary files /dev/null and b/_images/Downgrade00.png differ diff --git a/_images/Downgrade01.png b/_images/Downgrade01.png new file mode 100644 index 00000000..be715a91 Binary files /dev/null and b/_images/Downgrade01.png differ diff --git a/_images/Downgrade02.png b/_images/Downgrade02.png new file mode 100644 index 00000000..9b83cf1e Binary files /dev/null and b/_images/Downgrade02.png differ diff --git a/_images/Downgrade03.png b/_images/Downgrade03.png new file mode 100644 index 00000000..c89ea765 Binary files /dev/null and b/_images/Downgrade03.png differ diff --git a/_images/Downgrade04.png b/_images/Downgrade04.png new file mode 100644 index 00000000..fdfaf4ea Binary files /dev/null and b/_images/Downgrade04.png differ diff --git a/_images/Fly.io.png b/_images/Fly.io.png new file mode 100644 index 00000000..0197c121 Binary files /dev/null and b/_images/Fly.io.png differ diff --git a/_images/FlyIO00.png b/_images/FlyIO00.png new file mode 100644 index 00000000..4174ea90 Binary files /dev/null and b/_images/FlyIO00.png differ diff --git a/_images/FlyIO05.png b/_images/FlyIO05.png new file mode 100644 index 00000000..544944d4 Binary files /dev/null and b/_images/FlyIO05.png differ diff --git a/_images/FlyIO06.png b/_images/FlyIO06.png new file mode 100644 index 00000000..a4a9237e Binary files /dev/null and b/_images/FlyIO06.png differ diff --git a/_images/FlyIO07.png b/_images/FlyIO07.png new file mode 100644 index 00000000..9164afbb Binary files /dev/null and b/_images/FlyIO07.png differ diff --git a/_images/FlyIO08.png b/_images/FlyIO08.png new file mode 100644 index 00000000..5fac1b98 Binary files /dev/null and b/_images/FlyIO08.png differ diff --git a/_images/FlyIO09.png b/_images/FlyIO09.png new file mode 100644 index 00000000..c3096047 Binary files /dev/null and b/_images/FlyIO09.png differ diff --git a/_images/FlyIO10.png b/_images/FlyIO10.png new file mode 100644 index 00000000..da5bfdde Binary files /dev/null and b/_images/FlyIO10.png differ diff --git a/_images/FlyIO11.png b/_images/FlyIO11.png new file mode 100644 index 00000000..30b2492a Binary files /dev/null and b/_images/FlyIO11.png differ diff --git a/_images/FlyIO12.png b/_images/FlyIO12.png new file mode 100644 index 00000000..6b6869a6 Binary files /dev/null and b/_images/FlyIO12.png differ diff --git a/_images/FlyIO13.png b/_images/FlyIO13.png new file mode 100644 index 00000000..0e92d7cf Binary files /dev/null and b/_images/FlyIO13.png differ diff --git a/_images/FlyIO14.png b/_images/FlyIO14.png new file mode 100644 index 00000000..fcfe655a Binary files /dev/null and b/_images/FlyIO14.png differ diff --git a/_images/FlyIO15.png b/_images/FlyIO15.png new file mode 100644 index 00000000..1b4ab584 Binary files /dev/null and b/_images/FlyIO15.png differ diff --git a/_images/FlyIO17.png b/_images/FlyIO17.png new file mode 100644 index 00000000..9026b1a8 Binary files /dev/null and b/_images/FlyIO17.png differ diff --git a/_images/FlyIO18.png b/_images/FlyIO18.png new file mode 100644 index 00000000..a08a4ccc Binary files /dev/null and b/_images/FlyIO18.png differ diff --git a/_images/FlyIO21.png b/_images/FlyIO21.png new file mode 100644 index 00000000..38ef849b Binary files /dev/null and b/_images/FlyIO21.png differ diff --git a/_images/FlyIO22.png b/_images/FlyIO22.png new file mode 100644 index 00000000..fd83399d Binary files /dev/null and b/_images/FlyIO22.png differ diff --git a/_images/FlyIOA1.png b/_images/FlyIOA1.png new file mode 100644 index 00000000..62f244b7 Binary files /dev/null and b/_images/FlyIOA1.png differ diff --git a/_images/FlyIOA2.png b/_images/FlyIOA2.png new file mode 100644 index 00000000..730ebb66 Binary files /dev/null and b/_images/FlyIOA2.png differ diff --git a/_images/FlyM10.png b/_images/FlyM10.png new file mode 100644 index 00000000..01f42770 Binary files /dev/null and b/_images/FlyM10.png differ diff --git a/_images/FlyT01.png b/_images/FlyT01.png new file mode 100644 index 00000000..1165dff0 Binary files /dev/null and b/_images/FlyT01.png differ diff --git a/_images/FlyT03.png b/_images/FlyT03.png new file mode 100644 index 00000000..d8f89e64 Binary files /dev/null and b/_images/FlyT03.png differ diff --git a/_images/FlyT04.png b/_images/FlyT04.png new file mode 100644 index 00000000..70448c04 Binary files /dev/null and b/_images/FlyT04.png differ diff --git a/_images/FlyT08.png b/_images/FlyT08.png new file mode 100644 index 00000000..18f30ded Binary files /dev/null and b/_images/FlyT08.png differ diff --git a/_images/FlyT09.png b/_images/FlyT09.png new file mode 100644 index 00000000..15f007fb Binary files /dev/null and b/_images/FlyT09.png differ diff --git a/_images/Follower00.png b/_images/Follower00.png new file mode 100644 index 00000000..4fdc43bc Binary files /dev/null and b/_images/Follower00.png differ diff --git a/_images/Follower01.png b/_images/Follower01.png new file mode 100644 index 00000000..02e45840 Binary files /dev/null and b/_images/Follower01.png differ diff --git a/_images/Follower02.png b/_images/Follower02.png new file mode 100644 index 00000000..9b7321fd Binary files /dev/null and b/_images/Follower02.png differ diff --git a/_images/Follower04.png b/_images/Follower04.png new file mode 100644 index 00000000..60d24b5a Binary files /dev/null and b/_images/Follower04.png differ diff --git a/_images/Follower05.png b/_images/Follower05.png new file mode 100644 index 00000000..b30d45ae Binary files /dev/null and b/_images/Follower05.png differ diff --git a/_images/Follower06.png b/_images/Follower06.png new file mode 100644 index 00000000..9d091f48 Binary files /dev/null and b/_images/Follower06.png differ diff --git a/_images/Follower07.png b/_images/Follower07.png new file mode 100644 index 00000000..17504348 Binary files /dev/null and b/_images/Follower07.png differ diff --git a/_images/Follower08.png b/_images/Follower08.png new file mode 100644 index 00000000..dbda3f37 Binary files /dev/null and b/_images/Follower08.png differ diff --git a/_images/Follower09.png b/_images/Follower09.png new file mode 100644 index 00000000..9451464d Binary files /dev/null and b/_images/Follower09.png differ diff --git a/_images/Follower10.png b/_images/Follower10.png new file mode 100644 index 00000000..098a7917 Binary files /dev/null and b/_images/Follower10.png differ diff --git a/_images/Follower11.png b/_images/Follower11.png new file mode 100644 index 00000000..2a19232d Binary files /dev/null and b/_images/Follower11.png differ diff --git a/_images/GCNS.png b/_images/GCNS.png new file mode 100644 index 00000000..f0b6c35b Binary files /dev/null and b/_images/GCNS.png differ diff --git a/_images/GoogleCloud.png b/_images/GoogleCloud.png new file mode 100644 index 00000000..30425501 Binary files /dev/null and b/_images/GoogleCloud.png differ diff --git a/_images/Heroku.png b/_images/Heroku.png new file mode 100644 index 00000000..02a92ce2 Binary files /dev/null and b/_images/Heroku.png differ diff --git a/_images/HerokuE02.png b/_images/HerokuE02.png new file mode 100644 index 00000000..0cf261c7 Binary files /dev/null and b/_images/HerokuE02.png differ diff --git a/_images/HerokuE03.png b/_images/HerokuE03.png new file mode 100644 index 00000000..a5948abf Binary files /dev/null and b/_images/HerokuE03.png differ diff --git a/_images/HerokuH01.png b/_images/HerokuH01.png new file mode 100644 index 00000000..ce2e0875 Binary files /dev/null and b/_images/HerokuH01.png differ diff --git a/_images/HerokuH02.png b/_images/HerokuH02.png new file mode 100644 index 00000000..d7721338 Binary files /dev/null and b/_images/HerokuH02.png differ diff --git a/_images/HerokuH03.png b/_images/HerokuH03.png new file mode 100644 index 00000000..00227212 Binary files /dev/null and b/_images/HerokuH03.png differ diff --git a/_images/HerokuH04.png b/_images/HerokuH04.png new file mode 100644 index 00000000..e74aa6bf Binary files /dev/null and b/_images/HerokuH04.png differ diff --git a/_images/HerokuM01.png b/_images/HerokuM01.png new file mode 100644 index 00000000..d1970e54 Binary files /dev/null and b/_images/HerokuM01.png differ diff --git a/_images/HerokuM02.png b/_images/HerokuM02.png new file mode 100644 index 00000000..efeb6151 Binary files /dev/null and b/_images/HerokuM02.png differ diff --git a/_images/HerokuM03.png b/_images/HerokuM03.png new file mode 100644 index 00000000..b5c65fd8 Binary files /dev/null and b/_images/HerokuM03.png differ diff --git a/_images/HerokuM04.png b/_images/HerokuM04.png new file mode 100644 index 00000000..1fabfa71 Binary files /dev/null and b/_images/HerokuM04.png differ diff --git a/_images/IFTTT_NSkey.png b/_images/IFTTT_NSkey.png new file mode 100644 index 00000000..8322a2cf Binary files /dev/null and b/_images/IFTTT_NSkey.png differ diff --git a/_images/IFTTT_button.png b/_images/IFTTT_button.png new file mode 100644 index 00000000..10720e54 Binary files /dev/null and b/_images/IFTTT_button.png differ diff --git a/_images/IFTTT_buttonpress.png b/_images/IFTTT_buttonpress.png new file mode 100644 index 00000000..10165523 Binary files /dev/null and b/_images/IFTTT_buttonpress.png differ diff --git a/_images/IFTTT_connect1.png b/_images/IFTTT_connect1.png new file mode 100644 index 00000000..b1dcedd4 Binary files /dev/null and b/_images/IFTTT_connect1.png differ diff --git a/_images/IFTTT_enable.png b/_images/IFTTT_enable.png new file mode 100644 index 00000000..a3963c40 Binary files /dev/null and b/_images/IFTTT_enable.png differ diff --git a/_images/IFTTT_newapplet.png b/_images/IFTTT_newapplet.png new file mode 100644 index 00000000..0ce3057c Binary files /dev/null and b/_images/IFTTT_newapplet.png differ diff --git a/_images/IFTTT_reorder.png b/_images/IFTTT_reorder.png new file mode 100644 index 00000000..740888a9 Binary files /dev/null and b/_images/IFTTT_reorder.png differ diff --git a/_images/IFTTT_signup.png b/_images/IFTTT_signup.png new file mode 100644 index 00000000..fbac6891 Binary files /dev/null and b/_images/IFTTT_signup.png differ diff --git a/_images/IFTTT_that.png b/_images/IFTTT_that.png new file mode 100644 index 00000000..de782d8f Binary files /dev/null and b/_images/IFTTT_that.png differ diff --git a/_images/IFTTT_that2.png b/_images/IFTTT_that2.png new file mode 100644 index 00000000..30ab60a0 Binary files /dev/null and b/_images/IFTTT_that2.png differ diff --git a/_images/IFTTT_this.png b/_images/IFTTT_this.png new file mode 100644 index 00000000..d51c4499 Binary files /dev/null and b/_images/IFTTT_this.png differ diff --git a/_images/IFTTT_today.PNG b/_images/IFTTT_today.PNG new file mode 100644 index 00000000..a418381b Binary files /dev/null and b/_images/IFTTT_today.PNG differ diff --git a/_images/IconPhone.png b/_images/IconPhone.png new file mode 100644 index 00000000..7be53716 Binary files /dev/null and b/_images/IconPhone.png differ diff --git a/_images/IconSW.png b/_images/IconSW.png new file mode 100644 index 00000000..c355501f Binary files /dev/null and b/_images/IconSW.png differ diff --git a/_images/IconTablet.png b/_images/IconTablet.png new file mode 100644 index 00000000..dcb07c1c Binary files /dev/null and b/_images/IconTablet.png differ diff --git a/_images/LockNO.png b/_images/LockNO.png new file mode 100644 index 00000000..9e74198a Binary files /dev/null and b/_images/LockNO.png differ diff --git a/_images/LockOK.png b/_images/LockOK.png new file mode 100644 index 00000000..ad871759 Binary files /dev/null and b/_images/LockOK.png differ diff --git a/_images/MFA00.png b/_images/MFA00.png new file mode 100644 index 00000000..88be4a88 Binary files /dev/null and b/_images/MFA00.png differ diff --git a/_images/MFA00a.png b/_images/MFA00a.png new file mode 100644 index 00000000..9d4484fa Binary files /dev/null and b/_images/MFA00a.png differ diff --git a/_images/MFA01.png b/_images/MFA01.png new file mode 100644 index 00000000..11c5efad Binary files /dev/null and b/_images/MFA01.png differ diff --git a/_images/MFA02.png b/_images/MFA02.png new file mode 100644 index 00000000..3a8421c1 Binary files /dev/null and b/_images/MFA02.png differ diff --git a/_images/MFA03.png b/_images/MFA03.png new file mode 100644 index 00000000..52075e3b Binary files /dev/null and b/_images/MFA03.png differ diff --git a/_images/MFA03b.png b/_images/MFA03b.png new file mode 100644 index 00000000..d38f78d7 Binary files /dev/null and b/_images/MFA03b.png differ diff --git a/_images/MFA03c.png b/_images/MFA03c.png new file mode 100644 index 00000000..a2f781fd Binary files /dev/null and b/_images/MFA03c.png differ diff --git a/_images/MFA03d.png b/_images/MFA03d.png new file mode 100644 index 00000000..7ce86d1e Binary files /dev/null and b/_images/MFA03d.png differ diff --git a/_images/MFA03e.png b/_images/MFA03e.png new file mode 100644 index 00000000..60ec7538 Binary files /dev/null and b/_images/MFA03e.png differ diff --git a/_images/MFA03f.png b/_images/MFA03f.png new file mode 100644 index 00000000..3dc7ba03 Binary files /dev/null and b/_images/MFA03f.png differ diff --git a/_images/MFA03g.png b/_images/MFA03g.png new file mode 100644 index 00000000..25ef54ab Binary files /dev/null and b/_images/MFA03g.png differ diff --git a/_images/MFA04.png b/_images/MFA04.png new file mode 100644 index 00000000..61e1d369 Binary files /dev/null and b/_images/MFA04.png differ diff --git a/_images/MFA04a.png b/_images/MFA04a.png new file mode 100644 index 00000000..8f6b4fd4 Binary files /dev/null and b/_images/MFA04a.png differ diff --git a/_images/MFA05.png b/_images/MFA05.png new file mode 100644 index 00000000..b5aaaf34 Binary files /dev/null and b/_images/MFA05.png differ diff --git a/_images/MFA06.png b/_images/MFA06.png new file mode 100644 index 00000000..576daa29 Binary files /dev/null and b/_images/MFA06.png differ diff --git a/_images/MFA07.png b/_images/MFA07.png new file mode 100644 index 00000000..7862111c Binary files /dev/null and b/_images/MFA07.png differ diff --git a/_images/MFA08.png b/_images/MFA08.png new file mode 100644 index 00000000..8eaeced2 Binary files /dev/null and b/_images/MFA08.png differ diff --git a/_images/MigrateNS57.png b/_images/MigrateNS57.png new file mode 100644 index 00000000..0ac0c03b Binary files /dev/null and b/_images/MigrateNS57.png differ diff --git a/_images/MongoDB.png b/_images/MongoDB.png new file mode 100644 index 00000000..d533ecbd Binary files /dev/null and b/_images/MongoDB.png differ diff --git a/_images/MultiNS00.png b/_images/MultiNS00.png new file mode 100644 index 00000000..dd74dacf Binary files /dev/null and b/_images/MultiNS00.png differ diff --git a/_images/MultiNS01.png b/_images/MultiNS01.png new file mode 100644 index 00000000..c92ffe58 Binary files /dev/null and b/_images/MultiNS01.png differ diff --git a/_images/MultiNS02.png b/_images/MultiNS02.png new file mode 100644 index 00000000..8fd7762f Binary files /dev/null and b/_images/MultiNS02.png differ diff --git a/_images/MultiNS03.png b/_images/MultiNS03.png new file mode 100644 index 00000000..47e77e3a Binary files /dev/null and b/_images/MultiNS03.png differ diff --git a/_images/MultiNS04.png b/_images/MultiNS04.png new file mode 100644 index 00000000..2a407614 Binary files /dev/null and b/_images/MultiNS04.png differ diff --git a/_images/MultiNS05.png b/_images/MultiNS05.png new file mode 100644 index 00000000..20516ee2 Binary files /dev/null and b/_images/MultiNS05.png differ diff --git a/_images/MultiNS06.png b/_images/MultiNS06.png new file mode 100644 index 00000000..b42156c5 Binary files /dev/null and b/_images/MultiNS06.png differ diff --git a/_images/MultiNS07.png b/_images/MultiNS07.png new file mode 100644 index 00000000..d45f4e8a Binary files /dev/null and b/_images/MultiNS07.png differ diff --git a/_images/MultiNS08.png b/_images/MultiNS08.png new file mode 100644 index 00000000..5805b2b6 Binary files /dev/null and b/_images/MultiNS08.png differ diff --git a/_images/MultiNS09.png b/_images/MultiNS09.png new file mode 100644 index 00000000..eb356bb9 Binary files /dev/null and b/_images/MultiNS09.png differ diff --git a/_images/MultiNS10.png b/_images/MultiNS10.png new file mode 100644 index 00000000..4bd9c7e5 Binary files /dev/null and b/_images/MultiNS10.png differ diff --git a/_images/MultiNS11.png b/_images/MultiNS11.png new file mode 100644 index 00000000..ff1b101b Binary files /dev/null and b/_images/MultiNS11.png differ diff --git a/_images/MultiNS12.png b/_images/MultiNS12.png new file mode 100644 index 00000000..b31c3b33 Binary files /dev/null and b/_images/MultiNS12.png differ diff --git a/_images/MultiNS13.png b/_images/MultiNS13.png new file mode 100644 index 00000000..807dc26d Binary files /dev/null and b/_images/MultiNS13.png differ diff --git a/_images/MultiNS14.png b/_images/MultiNS14.png new file mode 100644 index 00000000..e43c4953 Binary files /dev/null and b/_images/MultiNS14.png differ diff --git a/_images/MultiNS15.png b/_images/MultiNS15.png new file mode 100644 index 00000000..672cf92c Binary files /dev/null and b/_images/MultiNS15.png differ diff --git a/_images/NewBranch.png b/_images/NewBranch.png new file mode 100644 index 00000000..40e57ea4 Binary files /dev/null and b/_images/NewBranch.png differ diff --git a/_images/NewNS00.png b/_images/NewNS00.png new file mode 100644 index 00000000..201bc856 Binary files /dev/null and b/_images/NewNS00.png differ diff --git a/_images/NewNS00a.png b/_images/NewNS00a.png new file mode 100644 index 00000000..9fcc7fae Binary files /dev/null and b/_images/NewNS00a.png differ diff --git a/_images/NewNS01.png b/_images/NewNS01.png new file mode 100644 index 00000000..4d0d0fb3 Binary files /dev/null and b/_images/NewNS01.png differ diff --git a/_images/NewNS02.png b/_images/NewNS02.png new file mode 100644 index 00000000..768b8d65 Binary files /dev/null and b/_images/NewNS02.png differ diff --git a/_images/NewNS03.png b/_images/NewNS03.png new file mode 100644 index 00000000..7c9c6334 Binary files /dev/null and b/_images/NewNS03.png differ diff --git a/_images/NewNS04.png b/_images/NewNS04.png new file mode 100644 index 00000000..42ee3404 Binary files /dev/null and b/_images/NewNS04.png differ diff --git a/_images/NewNS07.png b/_images/NewNS07.png new file mode 100644 index 00000000..658cb63f Binary files /dev/null and b/_images/NewNS07.png differ diff --git a/_images/NewNS09.png b/_images/NewNS09.png new file mode 100644 index 00000000..101d7944 Binary files /dev/null and b/_images/NewNS09.png differ diff --git a/_images/NewNS10.png b/_images/NewNS10.png new file mode 100644 index 00000000..09fd22b2 Binary files /dev/null and b/_images/NewNS10.png differ diff --git a/_images/NewNS11.png b/_images/NewNS11.png new file mode 100644 index 00000000..9ecb3abc Binary files /dev/null and b/_images/NewNS11.png differ diff --git a/_images/NewNS12.png b/_images/NewNS12.png new file mode 100644 index 00000000..92250fdc Binary files /dev/null and b/_images/NewNS12.png differ diff --git a/_images/NewNS12a.png b/_images/NewNS12a.png new file mode 100644 index 00000000..9c0b987e Binary files /dev/null and b/_images/NewNS12a.png differ diff --git a/_images/NewNS13.png b/_images/NewNS13.png new file mode 100644 index 00000000..2796f37f Binary files /dev/null and b/_images/NewNS13.png differ diff --git a/_images/NewNS14.png b/_images/NewNS14.png new file mode 100644 index 00000000..3c285652 Binary files /dev/null and b/_images/NewNS14.png differ diff --git a/_images/NewNS15.png b/_images/NewNS15.png new file mode 100644 index 00000000..12fb2180 Binary files /dev/null and b/_images/NewNS15.png differ diff --git a/_images/NewNS16.png b/_images/NewNS16.png new file mode 100644 index 00000000..f89b7a26 Binary files /dev/null and b/_images/NewNS16.png differ diff --git a/_images/NewNS18.png b/_images/NewNS18.png new file mode 100644 index 00000000..09e00b76 Binary files /dev/null and b/_images/NewNS18.png differ diff --git a/_images/NewNS18b.png b/_images/NewNS18b.png new file mode 100644 index 00000000..723a172a Binary files /dev/null and b/_images/NewNS18b.png differ diff --git a/_images/NewNS18c.png b/_images/NewNS18c.png new file mode 100644 index 00000000..bbde4a3d Binary files /dev/null and b/_images/NewNS18c.png differ diff --git a/_images/NewNS18d.png b/_images/NewNS18d.png new file mode 100644 index 00000000..1a3c9435 Binary files /dev/null and b/_images/NewNS18d.png differ diff --git a/_images/NewNS18e.png b/_images/NewNS18e.png new file mode 100644 index 00000000..23a7c835 Binary files /dev/null and b/_images/NewNS18e.png differ diff --git a/_images/NewNS19.png b/_images/NewNS19.png new file mode 100644 index 00000000..0e0a3f5f Binary files /dev/null and b/_images/NewNS19.png differ diff --git a/_images/NewNS19b.png b/_images/NewNS19b.png new file mode 100644 index 00000000..fe64c45d Binary files /dev/null and b/_images/NewNS19b.png differ diff --git a/_images/NewNS20.png b/_images/NewNS20.png new file mode 100644 index 00000000..2822af2e Binary files /dev/null and b/_images/NewNS20.png differ diff --git a/_images/NewNS21.png b/_images/NewNS21.png new file mode 100644 index 00000000..5adffbcd Binary files /dev/null and b/_images/NewNS21.png differ diff --git a/_images/NewNS22.png b/_images/NewNS22.png new file mode 100644 index 00000000..747e2753 Binary files /dev/null and b/_images/NewNS22.png differ diff --git a/_images/NewNS23.png b/_images/NewNS23.png new file mode 100644 index 00000000..5130a75f Binary files /dev/null and b/_images/NewNS23.png differ diff --git a/_images/NewNS24.png b/_images/NewNS24.png new file mode 100644 index 00000000..f07e0c24 Binary files /dev/null and b/_images/NewNS24.png differ diff --git a/_images/NewNS24b.png b/_images/NewNS24b.png new file mode 100644 index 00000000..d0915a8a Binary files /dev/null and b/_images/NewNS24b.png differ diff --git a/_images/NewNS25.png b/_images/NewNS25.png new file mode 100644 index 00000000..229a0531 Binary files /dev/null and b/_images/NewNS25.png differ diff --git a/_images/NewNS26.png b/_images/NewNS26.png new file mode 100644 index 00000000..aba72891 Binary files /dev/null and b/_images/NewNS26.png differ diff --git a/_images/NewNS27.png b/_images/NewNS27.png new file mode 100644 index 00000000..62be24da Binary files /dev/null and b/_images/NewNS27.png differ diff --git a/_images/NewNS28.png b/_images/NewNS28.png new file mode 100644 index 00000000..d99bc2c3 Binary files /dev/null and b/_images/NewNS28.png differ diff --git a/_images/NewNS29.png b/_images/NewNS29.png new file mode 100644 index 00000000..b42412cf Binary files /dev/null and b/_images/NewNS29.png differ diff --git a/_images/NewNS30.png b/_images/NewNS30.png new file mode 100644 index 00000000..86c752c3 Binary files /dev/null and b/_images/NewNS30.png differ diff --git a/_images/NewNS33.png b/_images/NewNS33.png new file mode 100644 index 00000000..bb3e523f Binary files /dev/null and b/_images/NewNS33.png differ diff --git a/_images/NewNS34.png b/_images/NewNS34.png new file mode 100644 index 00000000..c8113c01 Binary files /dev/null and b/_images/NewNS34.png differ diff --git a/_images/NewNS35.png b/_images/NewNS35.png new file mode 100644 index 00000000..72075dea Binary files /dev/null and b/_images/NewNS35.png differ diff --git a/_images/NewNS36.png b/_images/NewNS36.png new file mode 100644 index 00000000..6afed074 Binary files /dev/null and b/_images/NewNS36.png differ diff --git a/_images/NewNS37.png b/_images/NewNS37.png new file mode 100644 index 00000000..9376facc Binary files /dev/null and b/_images/NewNS37.png differ diff --git a/_images/NewNS38.png b/_images/NewNS38.png new file mode 100644 index 00000000..9edbb8a8 Binary files /dev/null and b/_images/NewNS38.png differ diff --git a/_images/NewNS39.png b/_images/NewNS39.png new file mode 100644 index 00000000..4d6fe59c Binary files /dev/null and b/_images/NewNS39.png differ diff --git a/_images/NewNS40.png b/_images/NewNS40.png new file mode 100644 index 00000000..b3ce6670 Binary files /dev/null and b/_images/NewNS40.png differ diff --git a/_images/NewNS41.png b/_images/NewNS41.png new file mode 100644 index 00000000..3b868303 Binary files /dev/null and b/_images/NewNS41.png differ diff --git a/_images/NewNS42.png b/_images/NewNS42.png new file mode 100644 index 00000000..fe9c79f6 Binary files /dev/null and b/_images/NewNS42.png differ diff --git a/_images/NewNS43.png b/_images/NewNS43.png new file mode 100644 index 00000000..82057cc3 Binary files /dev/null and b/_images/NewNS43.png differ diff --git a/_images/NewNS44.png b/_images/NewNS44.png new file mode 100644 index 00000000..e6aeff3e Binary files /dev/null and b/_images/NewNS44.png differ diff --git a/_images/NewNS45.png b/_images/NewNS45.png new file mode 100644 index 00000000..18fb3b63 Binary files /dev/null and b/_images/NewNS45.png differ diff --git a/_images/NewNS46.png b/_images/NewNS46.png new file mode 100644 index 00000000..068fd9c5 Binary files /dev/null and b/_images/NewNS46.png differ diff --git a/_images/NewNS47.png b/_images/NewNS47.png new file mode 100644 index 00000000..4c3349fc Binary files /dev/null and b/_images/NewNS47.png differ diff --git a/_images/NewNS48.png b/_images/NewNS48.png new file mode 100644 index 00000000..67337f09 Binary files /dev/null and b/_images/NewNS48.png differ diff --git a/_images/NewNS49.png b/_images/NewNS49.png new file mode 100644 index 00000000..e4f27699 Binary files /dev/null and b/_images/NewNS49.png differ diff --git a/_images/NewNS50.png b/_images/NewNS50.png new file mode 100644 index 00000000..42a5194a Binary files /dev/null and b/_images/NewNS50.png differ diff --git a/_images/NewNS51.png b/_images/NewNS51.png new file mode 100644 index 00000000..4c8409a1 Binary files /dev/null and b/_images/NewNS51.png differ diff --git a/_images/Nightscout4u.png b/_images/Nightscout4u.png new file mode 100644 index 00000000..1be12ae9 Binary files /dev/null and b/_images/Nightscout4u.png differ diff --git a/_images/Northflank.png b/_images/Northflank.png new file mode 100644 index 00000000..584d4aa3 Binary files /dev/null and b/_images/Northflank.png differ diff --git a/_images/Northflank00.png b/_images/Northflank00.png new file mode 100644 index 00000000..a3b39580 Binary files /dev/null and b/_images/Northflank00.png differ diff --git a/_images/Northflank00a.png b/_images/Northflank00a.png new file mode 100644 index 00000000..0109d221 Binary files /dev/null and b/_images/Northflank00a.png differ diff --git a/_images/Northflank00b.png b/_images/Northflank00b.png new file mode 100644 index 00000000..200a2caf Binary files /dev/null and b/_images/Northflank00b.png differ diff --git a/_images/Northflank00c.png b/_images/Northflank00c.png new file mode 100644 index 00000000..fa76f1ec Binary files /dev/null and b/_images/Northflank00c.png differ diff --git a/_images/Northflank01.png b/_images/Northflank01.png new file mode 100644 index 00000000..06f14989 Binary files /dev/null and b/_images/Northflank01.png differ diff --git a/_images/Northflank02.png b/_images/Northflank02.png new file mode 100644 index 00000000..7d19d412 Binary files /dev/null and b/_images/Northflank02.png differ diff --git a/_images/Northflank03.png b/_images/Northflank03.png new file mode 100644 index 00000000..b88d9285 Binary files /dev/null and b/_images/Northflank03.png differ diff --git a/_images/Northflank04.png b/_images/Northflank04.png new file mode 100644 index 00000000..841f8c10 Binary files /dev/null and b/_images/Northflank04.png differ diff --git a/_images/Northflank05.png b/_images/Northflank05.png new file mode 100644 index 00000000..e19a942e Binary files /dev/null and b/_images/Northflank05.png differ diff --git a/_images/Northflank06.png b/_images/Northflank06.png new file mode 100644 index 00000000..5451dc63 Binary files /dev/null and b/_images/Northflank06.png differ diff --git a/_images/Northflank07.png b/_images/Northflank07.png new file mode 100644 index 00000000..47af362d Binary files /dev/null and b/_images/Northflank07.png differ diff --git a/_images/Northflank08.png b/_images/Northflank08.png new file mode 100644 index 00000000..95103c1f Binary files /dev/null and b/_images/Northflank08.png differ diff --git a/_images/Northflank09.png b/_images/Northflank09.png new file mode 100644 index 00000000..75d160c6 Binary files /dev/null and b/_images/Northflank09.png differ diff --git a/_images/Northflank10.png b/_images/Northflank10.png new file mode 100644 index 00000000..7fa90132 Binary files /dev/null and b/_images/Northflank10.png differ diff --git a/_images/Northflank11.png b/_images/Northflank11.png new file mode 100644 index 00000000..cee472c2 Binary files /dev/null and b/_images/Northflank11.png differ diff --git a/_images/Northflank11b.png b/_images/Northflank11b.png new file mode 100644 index 00000000..a78223dc Binary files /dev/null and b/_images/Northflank11b.png differ diff --git a/_images/Northflank12.png b/_images/Northflank12.png new file mode 100644 index 00000000..9c479c22 Binary files /dev/null and b/_images/Northflank12.png differ diff --git a/_images/Northflank13.png b/_images/Northflank13.png new file mode 100644 index 00000000..f9e564a9 Binary files /dev/null and b/_images/Northflank13.png differ diff --git a/_images/Northflank14.png b/_images/Northflank14.png new file mode 100644 index 00000000..3c6b46b7 Binary files /dev/null and b/_images/Northflank14.png differ diff --git a/_images/Northflank15.png b/_images/Northflank15.png new file mode 100644 index 00000000..58b19d9f Binary files /dev/null and b/_images/Northflank15.png differ diff --git a/_images/Northflank16.png b/_images/Northflank16.png new file mode 100644 index 00000000..066b8745 Binary files /dev/null and b/_images/Northflank16.png differ diff --git a/_images/Northflank17.png b/_images/Northflank17.png new file mode 100644 index 00000000..f7a847a6 Binary files /dev/null and b/_images/Northflank17.png differ diff --git a/_images/Northflank18.png b/_images/Northflank18.png new file mode 100644 index 00000000..d1d03c22 Binary files /dev/null and b/_images/Northflank18.png differ diff --git a/_images/Northflank19.png b/_images/Northflank19.png new file mode 100644 index 00000000..3a305c27 Binary files /dev/null and b/_images/Northflank19.png differ diff --git a/_images/Northflank20.png b/_images/Northflank20.png new file mode 100644 index 00000000..f9329050 Binary files /dev/null and b/_images/Northflank20.png differ diff --git a/_images/Northflank21.png b/_images/Northflank21.png new file mode 100644 index 00000000..4b61be3d Binary files /dev/null and b/_images/Northflank21.png differ diff --git a/_images/Northflank22.png b/_images/Northflank22.png new file mode 100644 index 00000000..777dabd1 Binary files /dev/null and b/_images/Northflank22.png differ diff --git a/_images/Northflank22a.png b/_images/Northflank22a.png new file mode 100644 index 00000000..278017ff Binary files /dev/null and b/_images/Northflank22a.png differ diff --git a/_images/Northflank23.png b/_images/Northflank23.png new file mode 100644 index 00000000..5d0b12af Binary files /dev/null and b/_images/Northflank23.png differ diff --git a/_images/Northflank24.png b/_images/Northflank24.png new file mode 100644 index 00000000..375f3b02 Binary files /dev/null and b/_images/Northflank24.png differ diff --git a/_images/Northflank25.png b/_images/Northflank25.png new file mode 100644 index 00000000..fbd647e8 Binary files /dev/null and b/_images/Northflank25.png differ diff --git a/_images/Northflank26.png b/_images/Northflank26.png new file mode 100644 index 00000000..551f32ac Binary files /dev/null and b/_images/Northflank26.png differ diff --git a/_images/Northflank27.png b/_images/Northflank27.png new file mode 100644 index 00000000..a2be8126 Binary files /dev/null and b/_images/Northflank27.png differ diff --git a/_images/Northflank28.png b/_images/Northflank28.png new file mode 100644 index 00000000..2ae75698 Binary files /dev/null and b/_images/Northflank28.png differ diff --git a/_images/Northflank29.png b/_images/Northflank29.png new file mode 100644 index 00000000..90928085 Binary files /dev/null and b/_images/Northflank29.png differ diff --git a/_images/Northflank30.png b/_images/Northflank30.png new file mode 100644 index 00000000..1a9c1d95 Binary files /dev/null and b/_images/Northflank30.png differ diff --git a/_images/Northflank31.png b/_images/Northflank31.png new file mode 100644 index 00000000..0d62112a Binary files /dev/null and b/_images/Northflank31.png differ diff --git a/_images/Northflank32.png b/_images/Northflank32.png new file mode 100644 index 00000000..75de8d91 Binary files /dev/null and b/_images/Northflank32.png differ diff --git a/_images/Northflank33.png b/_images/Northflank33.png new file mode 100644 index 00000000..179cd025 Binary files /dev/null and b/_images/Northflank33.png differ diff --git a/_images/Northflank34.png b/_images/Northflank34.png new file mode 100644 index 00000000..bcf36b5c Binary files /dev/null and b/_images/Northflank34.png differ diff --git a/_images/Northflank36.png b/_images/Northflank36.png new file mode 100644 index 00000000..594e01c0 Binary files /dev/null and b/_images/Northflank36.png differ diff --git a/_images/Northflank37.png b/_images/Northflank37.png new file mode 100644 index 00000000..381eb32d Binary files /dev/null and b/_images/Northflank37.png differ diff --git a/_images/Northflank38.png b/_images/Northflank38.png new file mode 100644 index 00000000..54d2f561 Binary files /dev/null and b/_images/Northflank38.png differ diff --git a/_images/Northflank39.png b/_images/Northflank39.png new file mode 100644 index 00000000..6ee05fff Binary files /dev/null and b/_images/Northflank39.png differ diff --git a/_images/Northflank40.png b/_images/Northflank40.png new file mode 100644 index 00000000..17fcafd4 Binary files /dev/null and b/_images/Northflank40.png differ diff --git a/_images/NorthflankDB01.png b/_images/NorthflankDB01.png new file mode 100644 index 00000000..a817022d Binary files /dev/null and b/_images/NorthflankDB01.png differ diff --git a/_images/NorthflankDB02.png b/_images/NorthflankDB02.png new file mode 100644 index 00000000..2ad6cbc1 Binary files /dev/null and b/_images/NorthflankDB02.png differ diff --git a/_images/NorthflankDB02a.png b/_images/NorthflankDB02a.png new file mode 100644 index 00000000..a9d29d81 Binary files /dev/null and b/_images/NorthflankDB02a.png differ diff --git a/_images/NorthflankDB03.png b/_images/NorthflankDB03.png new file mode 100644 index 00000000..cf6830d2 Binary files /dev/null and b/_images/NorthflankDB03.png differ diff --git a/_images/NorthflankDB04.png b/_images/NorthflankDB04.png new file mode 100644 index 00000000..5f8bcec3 Binary files /dev/null and b/_images/NorthflankDB04.png differ diff --git a/_images/NorthflankDB05.png b/_images/NorthflankDB05.png new file mode 100644 index 00000000..ba69cc16 Binary files /dev/null and b/_images/NorthflankDB05.png differ diff --git a/_images/NorthflankDB06.png b/_images/NorthflankDB06.png new file mode 100644 index 00000000..ab38154d Binary files /dev/null and b/_images/NorthflankDB06.png differ diff --git a/_images/NorthflankDB07.png b/_images/NorthflankDB07.png new file mode 100644 index 00000000..5c333670 Binary files /dev/null and b/_images/NorthflankDB07.png differ diff --git a/_images/NorthflankDB08.png b/_images/NorthflankDB08.png new file mode 100644 index 00000000..b60aef9c Binary files /dev/null and b/_images/NorthflankDB08.png differ diff --git a/_images/NorthflankDB09.png b/_images/NorthflankDB09.png new file mode 100644 index 00000000..a9e95935 Binary files /dev/null and b/_images/NorthflankDB09.png differ diff --git a/_images/NorthflankDB10.png b/_images/NorthflankDB10.png new file mode 100644 index 00000000..cfd202c2 Binary files /dev/null and b/_images/NorthflankDB10.png differ diff --git a/_images/NorthflankM01.png b/_images/NorthflankM01.png new file mode 100644 index 00000000..dc45b35e Binary files /dev/null and b/_images/NorthflankM01.png differ diff --git a/_images/NorthflankM02.png b/_images/NorthflankM02.png new file mode 100644 index 00000000..622e3a53 Binary files /dev/null and b/_images/NorthflankM02.png differ diff --git a/_images/NorthflankM03.png b/_images/NorthflankM03.png new file mode 100644 index 00000000..9ce7ad8a Binary files /dev/null and b/_images/NorthflankM03.png differ diff --git a/_images/NorthflankM04.png b/_images/NorthflankM04.png new file mode 100644 index 00000000..92025ef5 Binary files /dev/null and b/_images/NorthflankM04.png differ diff --git a/_images/NorthflankM05.png b/_images/NorthflankM05.png new file mode 100644 index 00000000..32b6ba39 Binary files /dev/null and b/_images/NorthflankM05.png differ diff --git a/_images/NorthflankM06.png b/_images/NorthflankM06.png new file mode 100644 index 00000000..cb95a932 Binary files /dev/null and b/_images/NorthflankM06.png differ diff --git a/_images/NorthflankM07.png b/_images/NorthflankM07.png new file mode 100644 index 00000000..ae988b20 Binary files /dev/null and b/_images/NorthflankM07.png differ diff --git a/_images/NorthflankM08.png b/_images/NorthflankM08.png new file mode 100644 index 00000000..810b4781 Binary files /dev/null and b/_images/NorthflankM08.png differ diff --git a/_images/NorthflankM09.png b/_images/NorthflankM09.png new file mode 100644 index 00000000..3bc1fc21 Binary files /dev/null and b/_images/NorthflankM09.png differ diff --git a/_images/NorthflankM10.png b/_images/NorthflankM10.png new file mode 100644 index 00000000..abf18d33 Binary files /dev/null and b/_images/NorthflankM10.png differ diff --git a/_images/NorthflankS1.png b/_images/NorthflankS1.png new file mode 100644 index 00000000..6b3c2f5e Binary files /dev/null and b/_images/NorthflankS1.png differ diff --git a/_images/NorthflankS2.png b/_images/NorthflankS2.png new file mode 100644 index 00000000..07a5a580 Binary files /dev/null and b/_images/NorthflankS2.png differ diff --git a/_images/NorthflankSP.png b/_images/NorthflankSP.png new file mode 100644 index 00000000..1aab5290 Binary files /dev/null and b/_images/NorthflankSP.png differ diff --git a/_images/NorthflankT01.png b/_images/NorthflankT01.png new file mode 100644 index 00000000..c4a225e1 Binary files /dev/null and b/_images/NorthflankT01.png differ diff --git a/_images/NorthflankT02.png b/_images/NorthflankT02.png new file mode 100644 index 00000000..308816d1 Binary files /dev/null and b/_images/NorthflankT02.png differ diff --git a/_images/PebbleNSFoundation.jpeg b/_images/PebbleNSFoundation.jpeg new file mode 100644 index 00000000..8768a775 Binary files /dev/null and b/_images/PebbleNSFoundation.jpeg differ diff --git a/_images/Profile00.png b/_images/Profile00.png new file mode 100644 index 00000000..846e8ad4 Binary files /dev/null and b/_images/Profile00.png differ diff --git a/_images/Profile01.png b/_images/Profile01.png new file mode 100644 index 00000000..30a66453 Binary files /dev/null and b/_images/Profile01.png differ diff --git a/_images/Profile02.png b/_images/Profile02.png new file mode 100644 index 00000000..341211e3 Binary files /dev/null and b/_images/Profile02.png differ diff --git a/_images/Profile03.png b/_images/Profile03.png new file mode 100644 index 00000000..ac4867ae Binary files /dev/null and b/_images/Profile03.png differ diff --git a/_images/Profile04.png b/_images/Profile04.png new file mode 100644 index 00000000..0debdaae Binary files /dev/null and b/_images/Profile04.png differ diff --git a/_images/Profile05.png b/_images/Profile05.png new file mode 100644 index 00000000..8ce1865a Binary files /dev/null and b/_images/Profile05.png differ diff --git a/_images/Profile06.png b/_images/Profile06.png new file mode 100644 index 00000000..ecb5d253 Binary files /dev/null and b/_images/Profile06.png differ diff --git a/_images/Profile07.png b/_images/Profile07.png new file mode 100644 index 00000000..556bc363 Binary files /dev/null and b/_images/Profile07.png differ diff --git a/_images/Railway.png b/_images/Railway.png new file mode 100644 index 00000000..18332c11 Binary files /dev/null and b/_images/Railway.png differ diff --git a/_images/Railway00.png b/_images/Railway00.png new file mode 100644 index 00000000..53714052 Binary files /dev/null and b/_images/Railway00.png differ diff --git a/_images/Railway01.png b/_images/Railway01.png new file mode 100644 index 00000000..fbbde892 Binary files /dev/null and b/_images/Railway01.png differ diff --git a/_images/Railway01a.png b/_images/Railway01a.png new file mode 100644 index 00000000..0c6c3eed Binary files /dev/null and b/_images/Railway01a.png differ diff --git a/_images/Railway01b.png b/_images/Railway01b.png new file mode 100644 index 00000000..cfd8ecee Binary files /dev/null and b/_images/Railway01b.png differ diff --git a/_images/Railway01c.png b/_images/Railway01c.png new file mode 100644 index 00000000..97b944fe Binary files /dev/null and b/_images/Railway01c.png differ diff --git a/_images/Railway01d.png b/_images/Railway01d.png new file mode 100644 index 00000000..6a6e8067 Binary files /dev/null and b/_images/Railway01d.png differ diff --git a/_images/Railway01e.png b/_images/Railway01e.png new file mode 100644 index 00000000..1dcded51 Binary files /dev/null and b/_images/Railway01e.png differ diff --git a/_images/Railway02.png b/_images/Railway02.png new file mode 100644 index 00000000..9b912727 Binary files /dev/null and b/_images/Railway02.png differ diff --git a/_images/Railway03.png b/_images/Railway03.png new file mode 100644 index 00000000..b509a527 Binary files /dev/null and b/_images/Railway03.png differ diff --git a/_images/Railway04.png b/_images/Railway04.png new file mode 100644 index 00000000..ba7c55d5 Binary files /dev/null and b/_images/Railway04.png differ diff --git a/_images/Railway05.png b/_images/Railway05.png new file mode 100644 index 00000000..b7e0d9fa Binary files /dev/null and b/_images/Railway05.png differ diff --git a/_images/Railway06.png b/_images/Railway06.png new file mode 100644 index 00000000..1f7dafb9 Binary files /dev/null and b/_images/Railway06.png differ diff --git a/_images/Railway06a.png b/_images/Railway06a.png new file mode 100644 index 00000000..1b7292c6 Binary files /dev/null and b/_images/Railway06a.png differ diff --git a/_images/Railway06a2.png b/_images/Railway06a2.png new file mode 100644 index 00000000..812a1f23 Binary files /dev/null and b/_images/Railway06a2.png differ diff --git a/_images/Railway06b.png b/_images/Railway06b.png new file mode 100644 index 00000000..a715e8c8 Binary files /dev/null and b/_images/Railway06b.png differ diff --git a/_images/Railway06b2.png b/_images/Railway06b2.png new file mode 100644 index 00000000..77582b01 Binary files /dev/null and b/_images/Railway06b2.png differ diff --git a/_images/Railway06c.png b/_images/Railway06c.png new file mode 100644 index 00000000..08e4727e Binary files /dev/null and b/_images/Railway06c.png differ diff --git a/_images/Railway07.png b/_images/Railway07.png new file mode 100644 index 00000000..d6a38d22 Binary files /dev/null and b/_images/Railway07.png differ diff --git a/_images/Railway07a.png b/_images/Railway07a.png new file mode 100644 index 00000000..8b72041c Binary files /dev/null and b/_images/Railway07a.png differ diff --git a/_images/Railway08.png b/_images/Railway08.png new file mode 100644 index 00000000..260e29ab Binary files /dev/null and b/_images/Railway08.png differ diff --git a/_images/Railway08a.png b/_images/Railway08a.png new file mode 100644 index 00000000..6e3b6e54 Binary files /dev/null and b/_images/Railway08a.png differ diff --git a/_images/Railway09.png b/_images/Railway09.png new file mode 100644 index 00000000..2d10429e Binary files /dev/null and b/_images/Railway09.png differ diff --git a/_images/Railway10.png b/_images/Railway10.png new file mode 100644 index 00000000..2fe06347 Binary files /dev/null and b/_images/Railway10.png differ diff --git a/_images/Railway11.png b/_images/Railway11.png new file mode 100644 index 00000000..16dfc57f Binary files /dev/null and b/_images/Railway11.png differ diff --git a/_images/Railway13.png b/_images/Railway13.png new file mode 100644 index 00000000..f2bc9216 Binary files /dev/null and b/_images/Railway13.png differ diff --git a/_images/Railway14.png b/_images/Railway14.png new file mode 100644 index 00000000..18df1df4 Binary files /dev/null and b/_images/Railway14.png differ diff --git a/_images/Railway15.png b/_images/Railway15.png new file mode 100644 index 00000000..4e99a787 Binary files /dev/null and b/_images/Railway15.png differ diff --git a/_images/Railway16.png b/_images/Railway16.png new file mode 100644 index 00000000..1fc9b43a Binary files /dev/null and b/_images/Railway16.png differ diff --git a/_images/Railway17.png b/_images/Railway17.png new file mode 100644 index 00000000..ec57e2a6 Binary files /dev/null and b/_images/Railway17.png differ diff --git a/_images/Railway21.png b/_images/Railway21.png new file mode 100644 index 00000000..4ac76c0c Binary files /dev/null and b/_images/Railway21.png differ diff --git a/_images/Railway33.png b/_images/Railway33.png new file mode 100644 index 00000000..93c6515c Binary files /dev/null and b/_images/Railway33.png differ diff --git a/_images/Railway34.png b/_images/Railway34.png new file mode 100644 index 00000000..3231dbd7 Binary files /dev/null and b/_images/Railway34.png differ diff --git a/_images/Railway36.png b/_images/Railway36.png new file mode 100644 index 00000000..48302532 Binary files /dev/null and b/_images/Railway36.png differ diff --git a/_images/Railway37.png b/_images/Railway37.png new file mode 100644 index 00000000..a507cbee Binary files /dev/null and b/_images/Railway37.png differ diff --git a/_images/Railway38.png b/_images/Railway38.png new file mode 100644 index 00000000..6ddf536c Binary files /dev/null and b/_images/Railway38.png differ diff --git a/_images/Railway39.png b/_images/Railway39.png new file mode 100644 index 00000000..86ed3965 Binary files /dev/null and b/_images/Railway39.png differ diff --git a/_images/Railway40.png b/_images/Railway40.png new file mode 100644 index 00000000..de9b645b Binary files /dev/null and b/_images/Railway40.png differ diff --git a/_images/Railway41.png b/_images/Railway41.png new file mode 100644 index 00000000..7d0ecb4d Binary files /dev/null and b/_images/Railway41.png differ diff --git a/_images/Railway42.png b/_images/Railway42.png new file mode 100644 index 00000000..0cf67680 Binary files /dev/null and b/_images/Railway42.png differ diff --git a/_images/Railway43.png b/_images/Railway43.png new file mode 100644 index 00000000..ad6b5e90 Binary files /dev/null and b/_images/Railway43.png differ diff --git a/_images/RailwayD01.png b/_images/RailwayD01.png new file mode 100644 index 00000000..52597ebc Binary files /dev/null and b/_images/RailwayD01.png differ diff --git a/_images/RailwayD02.png b/_images/RailwayD02.png new file mode 100644 index 00000000..c8fc839f Binary files /dev/null and b/_images/RailwayD02.png differ diff --git a/_images/RailwayD03.png b/_images/RailwayD03.png new file mode 100644 index 00000000..a79be881 Binary files /dev/null and b/_images/RailwayD03.png differ diff --git a/_images/RailwayD04.png b/_images/RailwayD04.png new file mode 100644 index 00000000..22e20d3e Binary files /dev/null and b/_images/RailwayD04.png differ diff --git a/_images/RailwayD05.png b/_images/RailwayD05.png new file mode 100644 index 00000000..6b9c209d Binary files /dev/null and b/_images/RailwayD05.png differ diff --git a/_images/RailwayD06.png b/_images/RailwayD06.png new file mode 100644 index 00000000..7d4e2f72 Binary files /dev/null and b/_images/RailwayD06.png differ diff --git a/_images/RailwayD07.png b/_images/RailwayD07.png new file mode 100644 index 00000000..6066f0d3 Binary files /dev/null and b/_images/RailwayD07.png differ diff --git a/_images/RailwayD08.png b/_images/RailwayD08.png new file mode 100644 index 00000000..216607b1 Binary files /dev/null and b/_images/RailwayD08.png differ diff --git a/_images/RailwayD09.png b/_images/RailwayD09.png new file mode 100644 index 00000000..97eaeb88 Binary files /dev/null and b/_images/RailwayD09.png differ diff --git a/_images/RailwayD10.png b/_images/RailwayD10.png new file mode 100644 index 00000000..9b7c647f Binary files /dev/null and b/_images/RailwayD10.png differ diff --git a/_images/RailwayD11.png b/_images/RailwayD11.png new file mode 100644 index 00000000..0f191376 Binary files /dev/null and b/_images/RailwayD11.png differ diff --git a/_images/RailwayDB01.png b/_images/RailwayDB01.png new file mode 100644 index 00000000..99adfcc8 Binary files /dev/null and b/_images/RailwayDB01.png differ diff --git a/_images/RailwayDB02.png b/_images/RailwayDB02.png new file mode 100644 index 00000000..62d9220c Binary files /dev/null and b/_images/RailwayDB02.png differ diff --git a/_images/RailwayDB03.png b/_images/RailwayDB03.png new file mode 100644 index 00000000..d3d20e25 Binary files /dev/null and b/_images/RailwayDB03.png differ diff --git a/_images/RailwayDB04.png b/_images/RailwayDB04.png new file mode 100644 index 00000000..8161a0f8 Binary files /dev/null and b/_images/RailwayDB04.png differ diff --git a/_images/RailwayDB05.png b/_images/RailwayDB05.png new file mode 100644 index 00000000..976ca947 Binary files /dev/null and b/_images/RailwayDB05.png differ diff --git a/_images/RailwayGitHub.png b/_images/RailwayGitHub.png new file mode 100644 index 00000000..12fe3415 Binary files /dev/null and b/_images/RailwayGitHub.png differ diff --git a/_images/RailwayM02.png b/_images/RailwayM02.png new file mode 100644 index 00000000..d952c695 Binary files /dev/null and b/_images/RailwayM02.png differ diff --git a/_images/RailwayM03.png b/_images/RailwayM03.png new file mode 100644 index 00000000..e4211e29 Binary files /dev/null and b/_images/RailwayM03.png differ diff --git a/_images/RailwayM14.png b/_images/RailwayM14.png new file mode 100644 index 00000000..f1ccf4b6 Binary files /dev/null and b/_images/RailwayM14.png differ diff --git a/_images/RailwayM15.png b/_images/RailwayM15.png new file mode 100644 index 00000000..96fefba1 Binary files /dev/null and b/_images/RailwayM15.png differ diff --git a/_images/RailwayM16.png b/_images/RailwayM16.png new file mode 100644 index 00000000..84535638 Binary files /dev/null and b/_images/RailwayM16.png differ diff --git a/_images/RailwayM17.png b/_images/RailwayM17.png new file mode 100644 index 00000000..eabda072 Binary files /dev/null and b/_images/RailwayM17.png differ diff --git a/_images/RailwayM18.png b/_images/RailwayM18.png new file mode 100644 index 00000000..f24ce711 Binary files /dev/null and b/_images/RailwayM18.png differ diff --git a/_images/RailwayM19.png b/_images/RailwayM19.png new file mode 100644 index 00000000..e685b28f Binary files /dev/null and b/_images/RailwayM19.png differ diff --git a/_images/RailwayM20.png b/_images/RailwayM20.png new file mode 100644 index 00000000..0d68b9a5 Binary files /dev/null and b/_images/RailwayM20.png differ diff --git a/_images/RailwayM21.png b/_images/RailwayM21.png new file mode 100644 index 00000000..4536cb83 Binary files /dev/null and b/_images/RailwayM21.png differ diff --git a/_images/RailwayM21b.png b/_images/RailwayM21b.png new file mode 100644 index 00000000..db2afd76 Binary files /dev/null and b/_images/RailwayM21b.png differ diff --git a/_images/RailwayM21c.png b/_images/RailwayM21c.png new file mode 100644 index 00000000..15021d4c Binary files /dev/null and b/_images/RailwayM21c.png differ diff --git a/_images/RailwayM22.png b/_images/RailwayM22.png new file mode 100644 index 00000000..41338d29 Binary files /dev/null and b/_images/RailwayM22.png differ diff --git a/_images/RailwayM23.png b/_images/RailwayM23.png new file mode 100644 index 00000000..fbdd3d7c Binary files /dev/null and b/_images/RailwayM23.png differ diff --git a/_images/RailwayM24.png b/_images/RailwayM24.png new file mode 100644 index 00000000..7fbe2eea Binary files /dev/null and b/_images/RailwayM24.png differ diff --git a/_images/RailwayM25.png b/_images/RailwayM25.png new file mode 100644 index 00000000..cccea027 Binary files /dev/null and b/_images/RailwayM25.png differ diff --git a/_images/RailwayS1.png b/_images/RailwayS1.png new file mode 100644 index 00000000..991993a9 Binary files /dev/null and b/_images/RailwayS1.png differ diff --git a/_images/RailwayS2.png b/_images/RailwayS2.png new file mode 100644 index 00000000..fe258c02 Binary files /dev/null and b/_images/RailwayS2.png differ diff --git a/_images/RailwayT01.png b/_images/RailwayT01.png new file mode 100644 index 00000000..21433cfd Binary files /dev/null and b/_images/RailwayT01.png differ diff --git a/_images/RailwayT02.png b/_images/RailwayT02.png new file mode 100644 index 00000000..187d32aa Binary files /dev/null and b/_images/RailwayT02.png differ diff --git a/_images/RailwayT03.png b/_images/RailwayT03.png new file mode 100644 index 00000000..f3bb33b4 Binary files /dev/null and b/_images/RailwayT03.png differ diff --git a/_images/RailwayT04.png b/_images/RailwayT04.png new file mode 100644 index 00000000..da10cc40 Binary files /dev/null and b/_images/RailwayT04.png differ diff --git a/_images/RailwayT05.png b/_images/RailwayT05.png new file mode 100644 index 00000000..e7f9dfb5 Binary files /dev/null and b/_images/RailwayT05.png differ diff --git a/_images/RailwayT06.png b/_images/RailwayT06.png new file mode 100644 index 00000000..04854dbf Binary files /dev/null and b/_images/RailwayT06.png differ diff --git a/_images/RailwayT07.png b/_images/RailwayT07.png new file mode 100644 index 00000000..86f39afb Binary files /dev/null and b/_images/RailwayT07.png differ diff --git a/_images/RailwayT08.png b/_images/RailwayT08.png new file mode 100644 index 00000000..048826f2 Binary files /dev/null and b/_images/RailwayT08.png differ diff --git a/_images/RailwayT09.png b/_images/RailwayT09.png new file mode 100644 index 00000000..aafd4dab Binary files /dev/null and b/_images/RailwayT09.png differ diff --git a/_images/RailwayT10.png b/_images/RailwayT10.png new file mode 100644 index 00000000..cc92376f Binary files /dev/null and b/_images/RailwayT10.png differ diff --git a/_images/RailwayT11.png b/_images/RailwayT11.png new file mode 100644 index 00000000..02cdb7f9 Binary files /dev/null and b/_images/RailwayT11.png differ diff --git a/_images/RailwayT12.png b/_images/RailwayT12.png new file mode 100644 index 00000000..57c75004 Binary files /dev/null and b/_images/RailwayT12.png differ diff --git a/_images/RailwayT13.png b/_images/RailwayT13.png new file mode 100644 index 00000000..cffb5ab2 Binary files /dev/null and b/_images/RailwayT13.png differ diff --git a/_images/RailwayT14.png b/_images/RailwayT14.png new file mode 100644 index 00000000..d8ec969f Binary files /dev/null and b/_images/RailwayT14.png differ diff --git a/_images/RailwayT15.png b/_images/RailwayT15.png new file mode 100644 index 00000000..2cc86e6d Binary files /dev/null and b/_images/RailwayT15.png differ diff --git a/_images/Render.png b/_images/Render.png new file mode 100644 index 00000000..f8068835 Binary files /dev/null and b/_images/Render.png differ diff --git a/_images/Render01.png b/_images/Render01.png new file mode 100644 index 00000000..f682df70 Binary files /dev/null and b/_images/Render01.png differ diff --git a/_images/Render02.png b/_images/Render02.png new file mode 100644 index 00000000..803846c1 Binary files /dev/null and b/_images/Render02.png differ diff --git a/_images/Render03.png b/_images/Render03.png new file mode 100644 index 00000000..f6e50d4b Binary files /dev/null and b/_images/Render03.png differ diff --git a/_images/Render04.png b/_images/Render04.png new file mode 100644 index 00000000..9e537ace Binary files /dev/null and b/_images/Render04.png differ diff --git a/_images/Render05.png b/_images/Render05.png new file mode 100644 index 00000000..9dd3e0f2 Binary files /dev/null and b/_images/Render05.png differ diff --git a/_images/Render06.png b/_images/Render06.png new file mode 100644 index 00000000..5ad42226 Binary files /dev/null and b/_images/Render06.png differ diff --git a/_images/Render07.png b/_images/Render07.png new file mode 100644 index 00000000..8aede996 Binary files /dev/null and b/_images/Render07.png differ diff --git a/_images/Render08.png b/_images/Render08.png new file mode 100644 index 00000000..22159053 Binary files /dev/null and b/_images/Render08.png differ diff --git a/_images/Render09.png b/_images/Render09.png new file mode 100644 index 00000000..42e40c32 Binary files /dev/null and b/_images/Render09.png differ diff --git a/_images/Render10.png b/_images/Render10.png new file mode 100644 index 00000000..3c9453ce Binary files /dev/null and b/_images/Render10.png differ diff --git a/_images/Render11.png b/_images/Render11.png new file mode 100644 index 00000000..f1d9dded Binary files /dev/null and b/_images/Render11.png differ diff --git a/_images/Render12.png b/_images/Render12.png new file mode 100644 index 00000000..418f8e16 Binary files /dev/null and b/_images/Render12.png differ diff --git a/_images/Render13.png b/_images/Render13.png new file mode 100644 index 00000000..2b266764 Binary files /dev/null and b/_images/Render13.png differ diff --git a/_images/Render14.png b/_images/Render14.png new file mode 100644 index 00000000..568d649e Binary files /dev/null and b/_images/Render14.png differ diff --git a/_images/Render15.png b/_images/Render15.png new file mode 100644 index 00000000..abf5a79b Binary files /dev/null and b/_images/Render15.png differ diff --git a/_images/Render16.png b/_images/Render16.png new file mode 100644 index 00000000..d28682e7 Binary files /dev/null and b/_images/Render16.png differ diff --git a/_images/Render17.png b/_images/Render17.png new file mode 100644 index 00000000..7e4f8ba1 Binary files /dev/null and b/_images/Render17.png differ diff --git a/_images/Render18.png b/_images/Render18.png new file mode 100644 index 00000000..504dcb99 Binary files /dev/null and b/_images/Render18.png differ diff --git a/_images/Render19.png b/_images/Render19.png new file mode 100644 index 00000000..742db840 Binary files /dev/null and b/_images/Render19.png differ diff --git a/_images/Render20.png b/_images/Render20.png new file mode 100644 index 00000000..c09f092c Binary files /dev/null and b/_images/Render20.png differ diff --git a/_images/Render21.png b/_images/Render21.png new file mode 100644 index 00000000..9ed80d03 Binary files /dev/null and b/_images/Render21.png differ diff --git a/_images/Render23.png b/_images/Render23.png new file mode 100644 index 00000000..f997d76a Binary files /dev/null and b/_images/Render23.png differ diff --git a/_images/Render24.png b/_images/Render24.png new file mode 100644 index 00000000..6755791a Binary files /dev/null and b/_images/Render24.png differ diff --git a/_images/RenderD01.png b/_images/RenderD01.png new file mode 100644 index 00000000..8976c45e Binary files /dev/null and b/_images/RenderD01.png differ diff --git a/_images/RenderD02.png b/_images/RenderD02.png new file mode 100644 index 00000000..1231d1ec Binary files /dev/null and b/_images/RenderD02.png differ diff --git a/_images/RenderD03.png b/_images/RenderD03.png new file mode 100644 index 00000000..5e8fd19f Binary files /dev/null and b/_images/RenderD03.png differ diff --git a/_images/RenderD04.png b/_images/RenderD04.png new file mode 100644 index 00000000..06d3f4a8 Binary files /dev/null and b/_images/RenderD04.png differ diff --git a/_images/RenderD05.png b/_images/RenderD05.png new file mode 100644 index 00000000..4116a179 Binary files /dev/null and b/_images/RenderD05.png differ diff --git a/_images/RenderD06.png b/_images/RenderD06.png new file mode 100644 index 00000000..5481f470 Binary files /dev/null and b/_images/RenderD06.png differ diff --git a/_images/RenderD07.png b/_images/RenderD07.png new file mode 100644 index 00000000..3928e176 Binary files /dev/null and b/_images/RenderD07.png differ diff --git a/_images/RenderD08.png b/_images/RenderD08.png new file mode 100644 index 00000000..6c763716 Binary files /dev/null and b/_images/RenderD08.png differ diff --git a/_images/RenderD10.png b/_images/RenderD10.png new file mode 100644 index 00000000..eca7a482 Binary files /dev/null and b/_images/RenderD10.png differ diff --git a/_images/RenderD11.png b/_images/RenderD11.png new file mode 100644 index 00000000..60c46185 Binary files /dev/null and b/_images/RenderD11.png differ diff --git a/_images/RenderD12.png b/_images/RenderD12.png new file mode 100644 index 00000000..1f06dc17 Binary files /dev/null and b/_images/RenderD12.png differ diff --git a/_images/RenderT01.png b/_images/RenderT01.png new file mode 100644 index 00000000..a0521766 Binary files /dev/null and b/_images/RenderT01.png differ diff --git a/_images/Reports00.png b/_images/Reports00.png new file mode 100644 index 00000000..577affd6 Binary files /dev/null and b/_images/Reports00.png differ diff --git a/_images/Reports01.png b/_images/Reports01.png new file mode 100644 index 00000000..96cb8822 Binary files /dev/null and b/_images/Reports01.png differ diff --git a/_images/Reports02.png b/_images/Reports02.png new file mode 100644 index 00000000..69b5d23e Binary files /dev/null and b/_images/Reports02.png differ diff --git a/_images/Reports03.png b/_images/Reports03.png new file mode 100644 index 00000000..968d39c9 Binary files /dev/null and b/_images/Reports03.png differ diff --git a/_images/Reports04.png b/_images/Reports04.png new file mode 100644 index 00000000..6f63f0f3 Binary files /dev/null and b/_images/Reports04.png differ diff --git a/_images/Reports05.png b/_images/Reports05.png new file mode 100644 index 00000000..cfbe27b3 Binary files /dev/null and b/_images/Reports05.png differ diff --git a/_images/Reports06.png b/_images/Reports06.png new file mode 100644 index 00000000..a90bcaba Binary files /dev/null and b/_images/Reports06.png differ diff --git a/_images/Reports07.png b/_images/Reports07.png new file mode 100644 index 00000000..8563b8fb Binary files /dev/null and b/_images/Reports07.png differ diff --git a/_images/Reports08.png b/_images/Reports08.png new file mode 100644 index 00000000..284879d3 Binary files /dev/null and b/_images/Reports08.png differ diff --git a/_images/Reports09.png b/_images/Reports09.png new file mode 100644 index 00000000..d96ace43 Binary files /dev/null and b/_images/Reports09.png differ diff --git a/_images/Reports10.png b/_images/Reports10.png new file mode 100644 index 00000000..25cf2edd Binary files /dev/null and b/_images/Reports10.png differ diff --git a/_images/Reports11.png b/_images/Reports11.png new file mode 100644 index 00000000..341933b0 Binary files /dev/null and b/_images/Reports11.png differ diff --git a/_images/Reports12.png b/_images/Reports12.png new file mode 100644 index 00000000..37a8c64b Binary files /dev/null and b/_images/Reports12.png differ diff --git a/_images/Reports13.png b/_images/Reports13.png new file mode 100644 index 00000000..37f54313 Binary files /dev/null and b/_images/Reports13.png differ diff --git a/_images/Reports14.png b/_images/Reports14.png new file mode 100644 index 00000000..4dd46963 Binary files /dev/null and b/_images/Reports14.png differ diff --git a/_images/Reports15.png b/_images/Reports15.png new file mode 100644 index 00000000..f6c4fb63 Binary files /dev/null and b/_images/Reports15.png differ diff --git a/_images/Reports16.png b/_images/Reports16.png new file mode 100644 index 00000000..49ae70fa Binary files /dev/null and b/_images/Reports16.png differ diff --git a/_images/Reports17.png b/_images/Reports17.png new file mode 100644 index 00000000..842b2db0 Binary files /dev/null and b/_images/Reports17.png differ diff --git a/_images/Reports18.png b/_images/Reports18.png new file mode 100644 index 00000000..8934f8fb Binary files /dev/null and b/_images/Reports18.png differ diff --git a/_images/Reports19.png b/_images/Reports19.png new file mode 100644 index 00000000..898010e3 Binary files /dev/null and b/_images/Reports19.png differ diff --git a/_images/Reports20.png b/_images/Reports20.png new file mode 100644 index 00000000..a4bac0f9 Binary files /dev/null and b/_images/Reports20.png differ diff --git a/_images/Reports21.png b/_images/Reports21.png new file mode 100644 index 00000000..5708266b Binary files /dev/null and b/_images/Reports21.png differ diff --git a/_images/Reports22.png b/_images/Reports22.png new file mode 100644 index 00000000..00c5a1c6 Binary files /dev/null and b/_images/Reports22.png differ diff --git a/_images/Security01.png b/_images/Security01.png new file mode 100644 index 00000000..d9551b96 Binary files /dev/null and b/_images/Security01.png differ diff --git a/_images/Security02.png b/_images/Security02.png new file mode 100644 index 00000000..ab7501fe Binary files /dev/null and b/_images/Security02.png differ diff --git a/_images/Security03.png b/_images/Security03.png new file mode 100644 index 00000000..5b6c5906 Binary files /dev/null and b/_images/Security03.png differ diff --git a/_images/Security04.png b/_images/Security04.png new file mode 100644 index 00000000..cf7c339e Binary files /dev/null and b/_images/Security04.png differ diff --git a/_images/Security05.png b/_images/Security05.png new file mode 100644 index 00000000..ab35d2d7 Binary files /dev/null and b/_images/Security05.png differ diff --git a/_images/Security06.png b/_images/Security06.png new file mode 100644 index 00000000..36518db0 Binary files /dev/null and b/_images/Security06.png differ diff --git a/_images/SetupNS00.png b/_images/SetupNS00.png new file mode 100644 index 00000000..8ffdfe3d Binary files /dev/null and b/_images/SetupNS00.png differ diff --git a/_images/SetupNS01.png b/_images/SetupNS01.png new file mode 100644 index 00000000..7a7310c7 Binary files /dev/null and b/_images/SetupNS01.png differ diff --git a/_images/SetupNS02.png b/_images/SetupNS02.png new file mode 100644 index 00000000..c03d4093 Binary files /dev/null and b/_images/SetupNS02.png differ diff --git a/_images/SetupNS03.png b/_images/SetupNS03.png new file mode 100644 index 00000000..23fcea98 Binary files /dev/null and b/_images/SetupNS03.png differ diff --git a/_images/SetupNS04.png b/_images/SetupNS04.png new file mode 100644 index 00000000..6c297955 Binary files /dev/null and b/_images/SetupNS04.png differ diff --git a/_images/SetupNS05.png b/_images/SetupNS05.png new file mode 100644 index 00000000..9c23cc06 Binary files /dev/null and b/_images/SetupNS05.png differ diff --git a/_images/SetupNS06.png b/_images/SetupNS06.png new file mode 100644 index 00000000..b629adc9 Binary files /dev/null and b/_images/SetupNS06.png differ diff --git a/_images/SetupNS07.png b/_images/SetupNS07.png new file mode 100644 index 00000000..ba5ae942 Binary files /dev/null and b/_images/SetupNS07.png differ diff --git a/_images/SetupNS08.png b/_images/SetupNS08.png new file mode 100644 index 00000000..8b24f6e0 Binary files /dev/null and b/_images/SetupNS08.png differ diff --git a/_images/SetupNS09.png b/_images/SetupNS09.png new file mode 100644 index 00000000..c1f86620 Binary files /dev/null and b/_images/SetupNS09.png differ diff --git a/_images/SetupNS10.png b/_images/SetupNS10.png new file mode 100644 index 00000000..91d48588 Binary files /dev/null and b/_images/SetupNS10.png differ diff --git a/_images/SetupNS11.png b/_images/SetupNS11.png new file mode 100644 index 00000000..cbbd3823 Binary files /dev/null and b/_images/SetupNS11.png differ diff --git a/_images/SetupNS12.png b/_images/SetupNS12.png new file mode 100644 index 00000000..9a451b16 Binary files /dev/null and b/_images/SetupNS12.png differ diff --git a/_images/SetupNS13.png b/_images/SetupNS13.png new file mode 100644 index 00000000..0f63a23c Binary files /dev/null and b/_images/SetupNS13.png differ diff --git a/_images/SetupNS13a.png b/_images/SetupNS13a.png new file mode 100644 index 00000000..b3b37e21 Binary files /dev/null and b/_images/SetupNS13a.png differ diff --git a/_images/SetupNS14.png b/_images/SetupNS14.png new file mode 100644 index 00000000..39aec0f8 Binary files /dev/null and b/_images/SetupNS14.png differ diff --git a/_images/SetupNS15.png b/_images/SetupNS15.png new file mode 100644 index 00000000..4cbd9d63 Binary files /dev/null and b/_images/SetupNS15.png differ diff --git a/_images/SetupNS16.png b/_images/SetupNS16.png new file mode 100644 index 00000000..a702445b Binary files /dev/null and b/_images/SetupNS16.png differ diff --git a/_images/SetupNS17.png b/_images/SetupNS17.png new file mode 100644 index 00000000..7f568abd Binary files /dev/null and b/_images/SetupNS17.png differ diff --git a/_images/SetupNS18.png b/_images/SetupNS18.png new file mode 100644 index 00000000..4dc0e234 Binary files /dev/null and b/_images/SetupNS18.png differ diff --git a/_images/SetupNS19.png b/_images/SetupNS19.png new file mode 100644 index 00000000..bf17ca09 Binary files /dev/null and b/_images/SetupNS19.png differ diff --git a/_images/SetupNS20.png b/_images/SetupNS20.png new file mode 100644 index 00000000..0aa9ae6a Binary files /dev/null and b/_images/SetupNS20.png differ diff --git a/_images/SetupNS21.png b/_images/SetupNS21.png new file mode 100644 index 00000000..eef801be Binary files /dev/null and b/_images/SetupNS21.png differ diff --git a/_images/SetupNS23.png b/_images/SetupNS23.png new file mode 100644 index 00000000..63f49cec Binary files /dev/null and b/_images/SetupNS23.png differ diff --git a/_images/SetupNS24.png b/_images/SetupNS24.png new file mode 100644 index 00000000..e29904ed Binary files /dev/null and b/_images/SetupNS24.png differ diff --git a/_images/SetupNS25.png b/_images/SetupNS25.png new file mode 100644 index 00000000..fccd5612 Binary files /dev/null and b/_images/SetupNS25.png differ diff --git a/_images/SetupNS26.png b/_images/SetupNS26.png new file mode 100644 index 00000000..6233adf0 Binary files /dev/null and b/_images/SetupNS26.png differ diff --git a/_images/SetupNS28.png b/_images/SetupNS28.png new file mode 100644 index 00000000..9b3c79b3 Binary files /dev/null and b/_images/SetupNS28.png differ diff --git a/_images/SetupNS29.png b/_images/SetupNS29.png new file mode 100644 index 00000000..d9207b95 Binary files /dev/null and b/_images/SetupNS29.png differ diff --git a/_images/SetupNS30.png b/_images/SetupNS30.png new file mode 100644 index 00000000..2ba181a2 Binary files /dev/null and b/_images/SetupNS30.png differ diff --git a/_images/SetupNS32.png b/_images/SetupNS32.png new file mode 100644 index 00000000..76ebfc42 Binary files /dev/null and b/_images/SetupNS32.png differ diff --git a/_images/SetupNS33.png b/_images/SetupNS33.png new file mode 100644 index 00000000..8de52638 Binary files /dev/null and b/_images/SetupNS33.png differ diff --git a/_images/SetupNS34.png b/_images/SetupNS34.png new file mode 100644 index 00000000..dadcc39d Binary files /dev/null and b/_images/SetupNS34.png differ diff --git a/_images/SetupNS35.png b/_images/SetupNS35.png new file mode 100644 index 00000000..3cb0b63e Binary files /dev/null and b/_images/SetupNS35.png differ diff --git a/_images/SetupNS36.png b/_images/SetupNS36.png new file mode 100644 index 00000000..f076619d Binary files /dev/null and b/_images/SetupNS36.png differ diff --git a/_images/SetupNS39.png b/_images/SetupNS39.png new file mode 100644 index 00000000..06e03144 Binary files /dev/null and b/_images/SetupNS39.png differ diff --git a/_images/SetupNS40.png b/_images/SetupNS40.png new file mode 100644 index 00000000..2071585f Binary files /dev/null and b/_images/SetupNS40.png differ diff --git a/_images/SetupNS41.png b/_images/SetupNS41.png new file mode 100644 index 00000000..106b954d Binary files /dev/null and b/_images/SetupNS41.png differ diff --git a/_images/SetupNS42.png b/_images/SetupNS42.png new file mode 100644 index 00000000..55f374ae Binary files /dev/null and b/_images/SetupNS42.png differ diff --git a/_images/SetupNS43.png b/_images/SetupNS43.png new file mode 100644 index 00000000..61ba4a4d Binary files /dev/null and b/_images/SetupNS43.png differ diff --git a/_images/SetupNS44.png b/_images/SetupNS44.png new file mode 100644 index 00000000..c10da8fa Binary files /dev/null and b/_images/SetupNS44.png differ diff --git a/_images/T1Pal.png b/_images/T1Pal.png new file mode 100644 index 00000000..6acd52ca Binary files /dev/null and b/_images/T1Pal.png differ diff --git a/_images/TShoot00.png b/_images/TShoot00.png new file mode 100644 index 00000000..a57f6714 Binary files /dev/null and b/_images/TShoot00.png differ diff --git a/_images/TShoot01.png b/_images/TShoot01.png new file mode 100644 index 00000000..5ca461f5 Binary files /dev/null and b/_images/TShoot01.png differ diff --git a/_images/TShoot02.png b/_images/TShoot02.png new file mode 100644 index 00000000..edbd862e Binary files /dev/null and b/_images/TShoot02.png differ diff --git a/_images/TShoot03.png b/_images/TShoot03.png new file mode 100644 index 00000000..d4540497 Binary files /dev/null and b/_images/TShoot03.png differ diff --git a/_images/TShoot04.png b/_images/TShoot04.png new file mode 100644 index 00000000..4da581e1 Binary files /dev/null and b/_images/TShoot04.png differ diff --git a/_images/TShoot05.png b/_images/TShoot05.png new file mode 100644 index 00000000..12947df7 Binary files /dev/null and b/_images/TShoot05.png differ diff --git a/_images/TShoot06.png b/_images/TShoot06.png new file mode 100644 index 00000000..fe2ca137 Binary files /dev/null and b/_images/TShoot06.png differ diff --git a/_images/TShoot07.png b/_images/TShoot07.png new file mode 100644 index 00000000..d21af39a Binary files /dev/null and b/_images/TShoot07.png differ diff --git a/_images/TShoot08.png b/_images/TShoot08.png new file mode 100644 index 00000000..a25d3fd9 Binary files /dev/null and b/_images/TShoot08.png differ diff --git a/_images/TShoot09.png b/_images/TShoot09.png new file mode 100644 index 00000000..007e0ca1 Binary files /dev/null and b/_images/TShoot09.png differ diff --git a/_images/TShoot10.png b/_images/TShoot10.png new file mode 100644 index 00000000..a892d445 Binary files /dev/null and b/_images/TShoot10.png differ diff --git a/_images/TShoot11.png b/_images/TShoot11.png new file mode 100644 index 00000000..d8ba899a Binary files /dev/null and b/_images/TShoot11.png differ diff --git a/_images/TShoot12.png b/_images/TShoot12.png new file mode 100644 index 00000000..31684060 Binary files /dev/null and b/_images/TShoot12.png differ diff --git a/_images/TShoot13.png b/_images/TShoot13.png new file mode 100644 index 00000000..16994650 Binary files /dev/null and b/_images/TShoot13.png differ diff --git a/_images/TShoot14.png b/_images/TShoot14.png new file mode 100644 index 00000000..e782ea5e Binary files /dev/null and b/_images/TShoot14.png differ diff --git a/_images/TShoot15.png b/_images/TShoot15.png new file mode 100644 index 00000000..0e1d639a Binary files /dev/null and b/_images/TShoot15.png differ diff --git a/_images/TShoot16.png b/_images/TShoot16.png new file mode 100644 index 00000000..db73a511 Binary files /dev/null and b/_images/TShoot16.png differ diff --git a/_images/TShoot17.png b/_images/TShoot17.png new file mode 100644 index 00000000..3bfdbec7 Binary files /dev/null and b/_images/TShoot17.png differ diff --git a/_images/TShoot18.png b/_images/TShoot18.png new file mode 100644 index 00000000..ad1a8cc0 Binary files /dev/null and b/_images/TShoot18.png differ diff --git a/_images/TShoot19.png b/_images/TShoot19.png new file mode 100644 index 00000000..3f2ce21b Binary files /dev/null and b/_images/TShoot19.png differ diff --git a/_images/TShoot20.png b/_images/TShoot20.png new file mode 100644 index 00000000..6829b34a Binary files /dev/null and b/_images/TShoot20.png differ diff --git a/_images/TShoot21.png b/_images/TShoot21.png new file mode 100644 index 00000000..abd0808a Binary files /dev/null and b/_images/TShoot21.png differ diff --git a/_images/TShoot22.png b/_images/TShoot22.png new file mode 100644 index 00000000..ff5ccc37 Binary files /dev/null and b/_images/TShoot22.png differ diff --git a/_images/TShoot23.png b/_images/TShoot23.png new file mode 100644 index 00000000..eb0bdc53 Binary files /dev/null and b/_images/TShoot23.png differ diff --git a/_images/TShoot24.png b/_images/TShoot24.png new file mode 100644 index 00000000..a5e6206d Binary files /dev/null and b/_images/TShoot24.png differ diff --git a/_images/TShoot25.png b/_images/TShoot25.png new file mode 100644 index 00000000..22a8c744 Binary files /dev/null and b/_images/TShoot25.png differ diff --git a/_images/TShoot30.png b/_images/TShoot30.png new file mode 100644 index 00000000..ed11592e Binary files /dev/null and b/_images/TShoot30.png differ diff --git a/_images/TShoot31.png b/_images/TShoot31.png new file mode 100644 index 00000000..d67ee8c9 Binary files /dev/null and b/_images/TShoot31.png differ diff --git a/_images/TShoot32.png b/_images/TShoot32.png new file mode 100644 index 00000000..0625b6b4 Binary files /dev/null and b/_images/TShoot32.png differ diff --git a/_images/TShoot33.png b/_images/TShoot33.png new file mode 100644 index 00000000..1c2ba56f Binary files /dev/null and b/_images/TShoot33.png differ diff --git a/_images/TShoot34.png b/_images/TShoot34.png new file mode 100644 index 00000000..0b1ae819 Binary files /dev/null and b/_images/TShoot34.png differ diff --git a/_images/TShoot35.png b/_images/TShoot35.png new file mode 100644 index 00000000..270f1678 Binary files /dev/null and b/_images/TShoot35.png differ diff --git a/_images/TShoot36.png b/_images/TShoot36.png new file mode 100644 index 00000000..e9b24494 Binary files /dev/null and b/_images/TShoot36.png differ diff --git a/_images/TShoot37.png b/_images/TShoot37.png new file mode 100644 index 00000000..dabb12f9 Binary files /dev/null and b/_images/TShoot37.png differ diff --git a/_images/TShoot38.png b/_images/TShoot38.png new file mode 100644 index 00000000..1e32dc97 Binary files /dev/null and b/_images/TShoot38.png differ diff --git a/_images/TShoot39.png b/_images/TShoot39.png new file mode 100644 index 00000000..98cfdc32 Binary files /dev/null and b/_images/TShoot39.png differ diff --git a/_images/TShoot41.png b/_images/TShoot41.png new file mode 100644 index 00000000..e5b662d9 Binary files /dev/null and b/_images/TShoot41.png differ diff --git a/_images/TShoot44.png b/_images/TShoot44.png new file mode 100644 index 00000000..0dacc8b3 Binary files /dev/null and b/_images/TShoot44.png differ diff --git a/_images/TShoot45.png b/_images/TShoot45.png new file mode 100644 index 00000000..26c9ade2 Binary files /dev/null and b/_images/TShoot45.png differ diff --git a/_images/TShoot46.png b/_images/TShoot46.png new file mode 100644 index 00000000..ee17da81 Binary files /dev/null and b/_images/TShoot46.png differ diff --git a/_images/TShoot47.png b/_images/TShoot47.png new file mode 100644 index 00000000..4c6d1bac Binary files /dev/null and b/_images/TShoot47.png differ diff --git a/_images/TShoot48.png b/_images/TShoot48.png new file mode 100644 index 00000000..3150d94b Binary files /dev/null and b/_images/TShoot48.png differ diff --git a/_images/TShoot49.png b/_images/TShoot49.png new file mode 100644 index 00000000..34e69d23 Binary files /dev/null and b/_images/TShoot49.png differ diff --git a/_images/TShoot50.png b/_images/TShoot50.png new file mode 100644 index 00000000..8d2b047f Binary files /dev/null and b/_images/TShoot50.png differ diff --git a/_images/TShoot51.png b/_images/TShoot51.png new file mode 100644 index 00000000..0f53dfc9 Binary files /dev/null and b/_images/TShoot51.png differ diff --git a/_images/TShoot52.png b/_images/TShoot52.png new file mode 100644 index 00000000..b1665f22 Binary files /dev/null and b/_images/TShoot52.png differ diff --git a/_images/TShoot53.png b/_images/TShoot53.png new file mode 100644 index 00000000..4fa17b66 Binary files /dev/null and b/_images/TShoot53.png differ diff --git a/_images/TShoot54.png b/_images/TShoot54.png new file mode 100644 index 00000000..fa0e2a45 Binary files /dev/null and b/_images/TShoot54.png differ diff --git a/_images/TShoot55.png b/_images/TShoot55.png new file mode 100644 index 00000000..89f876f7 Binary files /dev/null and b/_images/TShoot55.png differ diff --git a/_images/TShoot56.png b/_images/TShoot56.png new file mode 100644 index 00000000..ac17dbd0 Binary files /dev/null and b/_images/TShoot56.png differ diff --git a/_images/TShoot57.png b/_images/TShoot57.png new file mode 100644 index 00000000..d45d1555 Binary files /dev/null and b/_images/TShoot57.png differ diff --git a/_images/TShoot58.png b/_images/TShoot58.png new file mode 100644 index 00000000..48f71354 Binary files /dev/null and b/_images/TShoot58.png differ diff --git a/_images/TShoot59.png b/_images/TShoot59.png new file mode 100644 index 00000000..f1feadb8 Binary files /dev/null and b/_images/TShoot59.png differ diff --git a/_images/TinyURL.png b/_images/TinyURL.png new file mode 100644 index 00000000..b0737b55 Binary files /dev/null and b/_images/TinyURL.png differ diff --git a/_images/UpdateHK01.png b/_images/UpdateHK01.png new file mode 100644 index 00000000..3ef37709 Binary files /dev/null and b/_images/UpdateHK01.png differ diff --git a/_images/UpdateHK02.png b/_images/UpdateHK02.png new file mode 100644 index 00000000..f590d2bf Binary files /dev/null and b/_images/UpdateHK02.png differ diff --git a/_images/UpdateHK03.png b/_images/UpdateHK03.png new file mode 100644 index 00000000..9a0cda7d Binary files /dev/null and b/_images/UpdateHK03.png differ diff --git a/_images/UpdateNS00.png b/_images/UpdateNS00.png new file mode 100644 index 00000000..26c023b2 Binary files /dev/null and b/_images/UpdateNS00.png differ diff --git a/_images/UpdateNS01.png b/_images/UpdateNS01.png new file mode 100644 index 00000000..2eeac6b5 Binary files /dev/null and b/_images/UpdateNS01.png differ diff --git a/_images/UpdateNS01a.png b/_images/UpdateNS01a.png new file mode 100644 index 00000000..587c031b Binary files /dev/null and b/_images/UpdateNS01a.png differ diff --git a/_images/UpdateNS01b.png b/_images/UpdateNS01b.png new file mode 100644 index 00000000..d0f05136 Binary files /dev/null and b/_images/UpdateNS01b.png differ diff --git a/_images/UpdateNS01c.png b/_images/UpdateNS01c.png new file mode 100644 index 00000000..81422c2b Binary files /dev/null and b/_images/UpdateNS01c.png differ diff --git a/_images/UpdateNS15.png b/_images/UpdateNS15.png new file mode 100644 index 00000000..7554ced3 Binary files /dev/null and b/_images/UpdateNS15.png differ diff --git a/_images/UpdateNS16.png b/_images/UpdateNS16.png new file mode 100644 index 00000000..94d657d7 Binary files /dev/null and b/_images/UpdateNS16.png differ diff --git a/_images/UpdateNS17.png b/_images/UpdateNS17.png new file mode 100644 index 00000000..487e0f80 Binary files /dev/null and b/_images/UpdateNS17.png differ diff --git a/_images/UpdateNS18.png b/_images/UpdateNS18.png new file mode 100644 index 00000000..ae2d8158 Binary files /dev/null and b/_images/UpdateNS18.png differ diff --git a/_images/UpdateNS19.png b/_images/UpdateNS19.png new file mode 100644 index 00000000..2762d6a3 Binary files /dev/null and b/_images/UpdateNS19.png differ diff --git a/_images/UpdateNS20.png b/_images/UpdateNS20.png new file mode 100644 index 00000000..a7d47fcd Binary files /dev/null and b/_images/UpdateNS20.png differ diff --git a/_images/UpdateNS21.png b/_images/UpdateNS21.png new file mode 100644 index 00000000..652732bc Binary files /dev/null and b/_images/UpdateNS21.png differ diff --git a/_images/UpdateNS22.png b/_images/UpdateNS22.png new file mode 100644 index 00000000..91b1305c Binary files /dev/null and b/_images/UpdateNS22.png differ diff --git a/_images/UpdateNS23.png b/_images/UpdateNS23.png new file mode 100644 index 00000000..58fc285a Binary files /dev/null and b/_images/UpdateNS23.png differ diff --git a/_images/UpdateNS24.png b/_images/UpdateNS24.png new file mode 100644 index 00000000..aaa6b02b Binary files /dev/null and b/_images/UpdateNS24.png differ diff --git a/_images/UpdateNS25.png b/_images/UpdateNS25.png new file mode 100644 index 00000000..b3b348f1 Binary files /dev/null and b/_images/UpdateNS25.png differ diff --git a/_images/UpdateNS26.png b/_images/UpdateNS26.png new file mode 100644 index 00000000..444a7a40 Binary files /dev/null and b/_images/UpdateNS26.png differ diff --git a/_images/UpdateNS27.png b/_images/UpdateNS27.png new file mode 100644 index 00000000..bc87a8bc Binary files /dev/null and b/_images/UpdateNS27.png differ diff --git a/_images/UpdateNS28.png b/_images/UpdateNS28.png new file mode 100644 index 00000000..f09f8d66 Binary files /dev/null and b/_images/UpdateNS28.png differ diff --git a/_images/UpdateNS30.png b/_images/UpdateNS30.png new file mode 100644 index 00000000..479ee68e Binary files /dev/null and b/_images/UpdateNS30.png differ diff --git a/_images/Upload02.png b/_images/Upload02.png new file mode 100644 index 00000000..e738a094 Binary files /dev/null and b/_images/Upload02.png differ diff --git a/_images/Upload03.png b/_images/Upload03.png new file mode 100644 index 00000000..bc14543a Binary files /dev/null and b/_images/Upload03.png differ diff --git a/_images/Upload04.png b/_images/Upload04.png new file mode 100644 index 00000000..791f96a7 Binary files /dev/null and b/_images/Upload04.png differ diff --git a/_images/Upload05.png b/_images/Upload05.png new file mode 100644 index 00000000..d043c548 Binary files /dev/null and b/_images/Upload05.png differ diff --git a/_images/Upload06.png b/_images/Upload06.png new file mode 100644 index 00000000..7b962389 Binary files /dev/null and b/_images/Upload06.png differ diff --git a/_images/UploadCFG00.png b/_images/UploadCFG00.png new file mode 100644 index 00000000..29a91c7c Binary files /dev/null and b/_images/UploadCFG00.png differ diff --git a/_images/UploadCFG02.png b/_images/UploadCFG02.png new file mode 100644 index 00000000..55bbf292 Binary files /dev/null and b/_images/UploadCFG02.png differ diff --git a/_images/UploadCFG03.png b/_images/UploadCFG03.png new file mode 100644 index 00000000..025e806c Binary files /dev/null and b/_images/UploadCFG03.png differ diff --git a/_images/UploadCFG04.png b/_images/UploadCFG04.png new file mode 100644 index 00000000..773e6be2 Binary files /dev/null and b/_images/UploadCFG04.png differ diff --git a/_images/UploadCFG05.png b/_images/UploadCFG05.png new file mode 100644 index 00000000..100ff167 Binary files /dev/null and b/_images/UploadCFG05.png differ diff --git a/_images/UploadCFG06.png b/_images/UploadCFG06.png new file mode 100644 index 00000000..80318ead Binary files /dev/null and b/_images/UploadCFG06.png differ diff --git a/_images/UploadCFG08.png b/_images/UploadCFG08.png new file mode 100644 index 00000000..836b89a8 Binary files /dev/null and b/_images/UploadCFG08.png differ diff --git a/_images/UploadCFG09.png b/_images/UploadCFG09.png new file mode 100644 index 00000000..b7f2239b Binary files /dev/null and b/_images/UploadCFG09.png differ diff --git a/_images/UploadCFG10.png b/_images/UploadCFG10.png new file mode 100644 index 00000000..a16ed84e Binary files /dev/null and b/_images/UploadCFG10.png differ diff --git a/_images/UploadCFG11.png b/_images/UploadCFG11.png new file mode 100644 index 00000000..bdabbe45 Binary files /dev/null and b/_images/UploadCFG11.png differ diff --git a/_images/UseNS00.png b/_images/UseNS00.png new file mode 100644 index 00000000..aa702305 Binary files /dev/null and b/_images/UseNS00.png differ diff --git a/_images/UseNS01.png b/_images/UseNS01.png new file mode 100644 index 00000000..7a18181b Binary files /dev/null and b/_images/UseNS01.png differ diff --git a/_images/UseNS03.png b/_images/UseNS03.png new file mode 100644 index 00000000..b9f2a57c Binary files /dev/null and b/_images/UseNS03.png differ diff --git a/_images/UseNS04.png b/_images/UseNS04.png new file mode 100644 index 00000000..ff3c0d54 Binary files /dev/null and b/_images/UseNS04.png differ diff --git a/_images/UseNS05.png b/_images/UseNS05.png new file mode 100644 index 00000000..66937676 Binary files /dev/null and b/_images/UseNS05.png differ diff --git a/_images/UseNS06.png b/_images/UseNS06.png new file mode 100644 index 00000000..4657de8f Binary files /dev/null and b/_images/UseNS06.png differ diff --git a/_images/UseNS07.png b/_images/UseNS07.png new file mode 100644 index 00000000..1a082701 Binary files /dev/null and b/_images/UseNS07.png differ diff --git a/_images/UseNS08.png b/_images/UseNS08.png new file mode 100644 index 00000000..086c6c8f Binary files /dev/null and b/_images/UseNS08.png differ diff --git a/_images/UseNS09.png b/_images/UseNS09.png new file mode 100644 index 00000000..261f815d Binary files /dev/null and b/_images/UseNS09.png differ diff --git a/_images/UseNS10.png b/_images/UseNS10.png new file mode 100644 index 00000000..2f077f92 Binary files /dev/null and b/_images/UseNS10.png differ diff --git a/_images/UseNS11.png b/_images/UseNS11.png new file mode 100644 index 00000000..ceb12216 Binary files /dev/null and b/_images/UseNS11.png differ diff --git a/_images/UseNS12.png b/_images/UseNS12.png new file mode 100644 index 00000000..3e3e4911 Binary files /dev/null and b/_images/UseNS12.png differ diff --git a/_images/UseNS13.png b/_images/UseNS13.png new file mode 100644 index 00000000..f983d319 Binary files /dev/null and b/_images/UseNS13.png differ diff --git a/_images/UseNS14.png b/_images/UseNS14.png new file mode 100644 index 00000000..d1f7e6fc Binary files /dev/null and b/_images/UseNS14.png differ diff --git a/_images/UseNS15.png b/_images/UseNS15.png new file mode 100644 index 00000000..6e0c4822 Binary files /dev/null and b/_images/UseNS15.png differ diff --git a/_images/UseNS16.png b/_images/UseNS16.png new file mode 100644 index 00000000..d501ddd6 Binary files /dev/null and b/_images/UseNS16.png differ diff --git a/_images/UseNS17.png b/_images/UseNS17.png new file mode 100644 index 00000000..07f9e5f9 Binary files /dev/null and b/_images/UseNS17.png differ diff --git a/_images/UseNS18.png b/_images/UseNS18.png new file mode 100644 index 00000000..55b6719b Binary files /dev/null and b/_images/UseNS18.png differ diff --git a/_images/UseNS19.png b/_images/UseNS19.png new file mode 100644 index 00000000..77d93015 Binary files /dev/null and b/_images/UseNS19.png differ diff --git a/_images/UseNS20.png b/_images/UseNS20.png new file mode 100644 index 00000000..5e6ed6ea Binary files /dev/null and b/_images/UseNS20.png differ diff --git a/_images/UseNS21.png b/_images/UseNS21.png new file mode 100644 index 00000000..5355aaf4 Binary files /dev/null and b/_images/UseNS21.png differ diff --git a/_images/UseNS22.png b/_images/UseNS22.png new file mode 100644 index 00000000..b3dffae3 Binary files /dev/null and b/_images/UseNS22.png differ diff --git a/_images/UseNS23.png b/_images/UseNS23.png new file mode 100644 index 00000000..ac3395da Binary files /dev/null and b/_images/UseNS23.png differ diff --git a/_images/UseNS24.png b/_images/UseNS24.png new file mode 100644 index 00000000..2c4454e3 Binary files /dev/null and b/_images/UseNS24.png differ diff --git a/_images/UseNS25.png b/_images/UseNS25.png new file mode 100644 index 00000000..62a0816a Binary files /dev/null and b/_images/UseNS25.png differ diff --git a/_images/Watch00.png b/_images/Watch00.png new file mode 100644 index 00000000..a444ec6f Binary files /dev/null and b/_images/Watch00.png differ diff --git a/_images/Watch01.png b/_images/Watch01.png new file mode 100644 index 00000000..529e49b5 Binary files /dev/null and b/_images/Watch01.png differ diff --git a/_images/Watch02.png b/_images/Watch02.png new file mode 100644 index 00000000..d5c9905c Binary files /dev/null and b/_images/Watch02.png differ diff --git a/_images/Watch03.png b/_images/Watch03.png new file mode 100644 index 00000000..1f4244ba Binary files /dev/null and b/_images/Watch03.png differ diff --git a/_images/Watch04.png b/_images/Watch04.png new file mode 100644 index 00000000..955cf541 Binary files /dev/null and b/_images/Watch04.png differ diff --git a/_images/Yaml00.png b/_images/Yaml00.png new file mode 100644 index 00000000..7f6d1bb2 Binary files /dev/null and b/_images/Yaml00.png differ diff --git a/_images/Yaml01.png b/_images/Yaml01.png new file mode 100644 index 00000000..ddea7027 Binary files /dev/null and b/_images/Yaml01.png differ diff --git a/_images/Yaml02.png b/_images/Yaml02.png new file mode 100644 index 00000000..d7561325 Binary files /dev/null and b/_images/Yaml02.png differ diff --git a/_images/Yaml03.png b/_images/Yaml03.png new file mode 100644 index 00000000..9ac65b5e Binary files /dev/null and b/_images/Yaml03.png differ diff --git a/_images/alexa_maker.png b/_images/alexa_maker.png new file mode 100644 index 00000000..93d34e64 Binary files /dev/null and b/_images/alexa_maker.png differ diff --git a/_images/google1.png b/_images/google1.png new file mode 100644 index 00000000..5ae90115 Binary files /dev/null and b/_images/google1.png differ diff --git a/_images/google2.png b/_images/google2.png new file mode 100644 index 00000000..49355588 Binary files /dev/null and b/_images/google2.png differ diff --git a/_images/google3.png b/_images/google3.png new file mode 100644 index 00000000..e25df23e Binary files /dev/null and b/_images/google3.png differ diff --git a/_images/google4.png b/_images/google4.png new file mode 100644 index 00000000..b7a28442 Binary files /dev/null and b/_images/google4.png differ diff --git a/_images/hashed_API.png b/_images/hashed_API.png new file mode 100644 index 00000000..3ea1d2b1 Binary files /dev/null and b/_images/hashed_API.png differ diff --git a/_images/hashed_API2.png b/_images/hashed_API2.png new file mode 100644 index 00000000..6fb7b23d Binary files /dev/null and b/_images/hashed_API2.png differ diff --git a/_images/heroku-logs.png b/_images/heroku-logs.png new file mode 100644 index 00000000..f01a1763 Binary files /dev/null and b/_images/heroku-logs.png differ diff --git a/_images/nightscout_screenshot_600.png b/_images/nightscout_screenshot_600.png new file mode 100644 index 00000000..799261e1 Binary files /dev/null and b/_images/nightscout_screenshot_600.png differ diff --git a/_images/ns-core-events.png b/_images/ns-core-events.png new file mode 100644 index 00000000..6132d123 Binary files /dev/null and b/_images/ns-core-events.png differ diff --git a/_images/nscloud.png b/_images/nscloud.png new file mode 100644 index 00000000..14c0c18c Binary files /dev/null and b/_images/nscloud.png differ diff --git a/_images/nselements.png b/_images/nselements.png new file mode 100644 index 00000000..cf855329 Binary files /dev/null and b/_images/nselements.png differ diff --git a/_images/railway-logs.png b/_images/railway-logs.png new file mode 100644 index 00000000..dadf79a6 Binary files /dev/null and b/_images/railway-logs.png differ diff --git a/_images/sharing.jpg b/_images/sharing.jpg new file mode 100644 index 00000000..658ad4bb Binary files /dev/null and b/_images/sharing.jpg differ diff --git a/_images/webhooks1.png b/_images/webhooks1.png new file mode 100644 index 00000000..a86bafe2 Binary files /dev/null and b/_images/webhooks1.png differ diff --git a/_images/webhooks10.png b/_images/webhooks10.png new file mode 100644 index 00000000..95131334 Binary files /dev/null and b/_images/webhooks10.png differ diff --git a/_images/webhooks11.png b/_images/webhooks11.png new file mode 100644 index 00000000..972c3694 Binary files /dev/null and b/_images/webhooks11.png differ diff --git a/_images/webhooks12.png b/_images/webhooks12.png new file mode 100644 index 00000000..fc9bc638 Binary files /dev/null and b/_images/webhooks12.png differ diff --git a/_images/webhooks13.png b/_images/webhooks13.png new file mode 100644 index 00000000..00d2d69e Binary files /dev/null and b/_images/webhooks13.png differ diff --git a/_images/webhooks14.png b/_images/webhooks14.png new file mode 100644 index 00000000..4e240096 Binary files /dev/null and b/_images/webhooks14.png differ diff --git a/_images/webhooks15.png b/_images/webhooks15.png new file mode 100644 index 00000000..012ae093 Binary files /dev/null and b/_images/webhooks15.png differ diff --git a/_images/webhooks16.png b/_images/webhooks16.png new file mode 100644 index 00000000..0b3046bf Binary files /dev/null and b/_images/webhooks16.png differ diff --git a/_images/webhooks17.png b/_images/webhooks17.png new file mode 100644 index 00000000..e555121d Binary files /dev/null and b/_images/webhooks17.png differ diff --git a/_images/webhooks18.png b/_images/webhooks18.png new file mode 100644 index 00000000..bf60ca1e Binary files /dev/null and b/_images/webhooks18.png differ diff --git a/_images/webhooks19.png b/_images/webhooks19.png new file mode 100644 index 00000000..9b1f1197 Binary files /dev/null and b/_images/webhooks19.png differ diff --git a/_images/webhooks2.png b/_images/webhooks2.png new file mode 100644 index 00000000..db96463f Binary files /dev/null and b/_images/webhooks2.png differ diff --git a/_images/webhooks20.png b/_images/webhooks20.png new file mode 100644 index 00000000..a58cdd7f Binary files /dev/null and b/_images/webhooks20.png differ diff --git a/_images/webhooks21.png b/_images/webhooks21.png new file mode 100644 index 00000000..9c774240 Binary files /dev/null and b/_images/webhooks21.png differ diff --git a/_images/webhooks22.png b/_images/webhooks22.png new file mode 100644 index 00000000..5759eee7 Binary files /dev/null and b/_images/webhooks22.png differ diff --git a/_images/webhooks23.png b/_images/webhooks23.png new file mode 100644 index 00000000..e9395fa2 Binary files /dev/null and b/_images/webhooks23.png differ diff --git a/_images/webhooks24.png b/_images/webhooks24.png new file mode 100644 index 00000000..9c2a33bb Binary files /dev/null and b/_images/webhooks24.png differ diff --git a/_images/webhooks25.png b/_images/webhooks25.png new file mode 100644 index 00000000..276eb269 Binary files /dev/null and b/_images/webhooks25.png differ diff --git a/_images/webhooks26.png b/_images/webhooks26.png new file mode 100644 index 00000000..67aad602 Binary files /dev/null and b/_images/webhooks26.png differ diff --git a/_images/webhooks27.png b/_images/webhooks27.png new file mode 100644 index 00000000..c1b97b55 Binary files /dev/null and b/_images/webhooks27.png differ diff --git a/_images/webhooks3.png b/_images/webhooks3.png new file mode 100644 index 00000000..8268221e Binary files /dev/null and b/_images/webhooks3.png differ diff --git a/_images/webhooks4.png b/_images/webhooks4.png new file mode 100644 index 00000000..96c6cf32 Binary files /dev/null and b/_images/webhooks4.png differ diff --git a/_images/webhooks5.png b/_images/webhooks5.png new file mode 100644 index 00000000..5f67f2c5 Binary files /dev/null and b/_images/webhooks5.png differ diff --git a/_images/webhooks6.png b/_images/webhooks6.png new file mode 100644 index 00000000..5d69c6ac Binary files /dev/null and b/_images/webhooks6.png differ diff --git a/_images/webhooks7.png b/_images/webhooks7.png new file mode 100644 index 00000000..107a22e4 Binary files /dev/null and b/_images/webhooks7.png differ diff --git a/_images/webhooks8.png b/_images/webhooks8.png new file mode 100644 index 00000000..a9541010 Binary files /dev/null and b/_images/webhooks8.png differ diff --git a/_images/webhooks9.png b/_images/webhooks9.png new file mode 100644 index 00000000..6d45ccc8 Binary files /dev/null and b/_images/webhooks9.png differ diff --git a/_images/wizard.png b/_images/wizard.png new file mode 100644 index 00000000..aebfeda2 Binary files /dev/null and b/_images/wizard.png differ diff --git a/_sources/404.md.txt b/_sources/404.md.txt new file mode 100644 index 00000000..5bb3318a --- /dev/null +++ b/_sources/404.md.txt @@ -0,0 +1,12 @@ +--- +orphan: true +--- + +# 404 - Page not found + +Copy the URL and report it [here](https://github.com/nightscout/nightscout.github.io/issues/new). + +
+ + + diff --git a/_sources/clinicians/home.md.txt b/_sources/clinicians/home.md.txt new file mode 100644 index 00000000..d539eea1 --- /dev/null +++ b/_sources/clinicians/home.md.txt @@ -0,0 +1,61 @@ +# Nightscout for clinicians + +
+ +```{tip} +Unless specified, links within the text are for advanced explanation of the underlying mechanisms but don't necessarily add value for clinicians use of Nightscout. +``` + +## What is Nightscout? + +Nightscout is an open-source cloud application used to visualize, store and share in real-time: + +- data from continuous glucose monitoring sensors +- manually or automatically logged treatments +- basal rates from pumps (optional) + +
+ +## How can I access patient data? + +Your patient should share a unique web URL with you, it will look like `https://name.domain.ext`. + +Since the URL is open for viewing to anybody having internet access to it, patients or caregivers can decide to make the access [secure](/nightscout/security.md#how-to-turn-off-unauthorized-access) and will share a [tokened](/nightscout/security.md#create-authentication-tokens-for-users) read-only access URL looking like `https://name.domain.ext?token=clinic-48aed625abb0ec86`. +You need to use the full URL provided to access your patient Nightscout site. + +Any device connected to the internet can be used to visualize patient data. + +```{admonition} Cannot access patient URL +:class: tip +Should you experience issues to access the Nightscout site, check with your IT team if the domain used by your patient is not blocked by a local internet safety rule. Many patients or caregivers who build their own Nightscout site rely on platforms as a service or free DNS providers that can get classified as unsafe by cybersecurity systems.
+Ask your IT and cybersecurity teams to perform all necessary verifications to allow access to your patient site: Nightscout itself is safe for infrastructures, it doesn't contain any sort of cyberthread or malware. +``` + +Since Nightscout can be hosted in a large variety of [platforms](/nightscout/new_user.md#building-nightscout-diy-in-a-cloud-platform), you can expect the site domain to be (but not only) in the following list: + +`heroku.com`, `azurewebsites.net`, `railway.app`, `fly.dev`, `onrender.com`, `t1pal.com`, `ns10be.de`, `nightscout.pro`, `mooo.com`, `chickenkiller.com`, `crabdance.com`, `strangled.net`, `code.run`, `nightscout4u.com` ... + +```{admonition} Read only access +Writing data into Nightscout is protected with a password called API_SECRET that should not be shared with you by the patient. +``` + +
+ +## What should I see when I open a Nightscout site? + +What will display should be similar to this: + +![Nightscout](/images/nightscout_screenshot_600.png) + +If you see this, it means your patient forgot to send you the link with a read-only token: + + + +
+ +## Next steps: + +Follow the links below. + +- [Setup the main view](setup) to add or view all available information. +- [Generate reports](reports). diff --git a/_sources/clinicians/reports.md.txt b/_sources/clinicians/reports.md.txt new file mode 100644 index 00000000..446d46ec --- /dev/null +++ b/_sources/clinicians/reports.md.txt @@ -0,0 +1,173 @@ +# Nightscout reports + +Access reports from the drawer menu, + + + +
+ +## View profiles + +Profiles view gives important information on the patient therapy parameters. + +Select profiles then SHOW (no additional setup is necessary). + + + +Patients profile(s) will display. + + + +DIA is the duration of the [insulin action](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4454113/). + +Carbs absorption rate is [complex](https://diyps.org/2014/05/29/determining-your-carbohydrate-absorption-rate-diyps-lessons-learned/) to calculate for patients and can be undefined (or zero) if the DIY system doesn't update the value (when existing). + +Insulin to Carbs ratio (IC) and Insulin Sensitivity Factor (ISF) can be defined by time periods. Only one visible value means whole day. + +Basal rates should match the pump settings. + +
+ +## Select a report + +Select the report type: + + + +- `Day to day` +- `Week to week` +- `Daily Stats` +- `Distribution` +- `Hourly stats` +- `Percentile Chart` +- `Weekly Distribution` + +
+ +## Setup the report + +Select the period used to analyze data. + +Enable the check box and either select `From:` and `To: `dates to define the interval + + + +or: + + + +- `Today` +- `Last 2 days` +- `Last 3 days`, +- `Last week` +- `Last 2 weeks` +- `Last Month` +- `Last 3 months` + + Avoid selecting too long periods of time for daily reports. + +
+ +Unless looking for specific `Notes` or `Event type` leave the checkboxes disabled. + + + +
+ +You can select which week days to use. + + + +
+ +Confirm `Target BT range` `bottom` and `top` for TIR (or TITR) and graph range lines. + +You can sort the report from older to newer or newer first. + + + +
+ +Click `SHOW` and wait for data to load and rendering to complete. This might take some time if the period is long (this will also depend on the Nightscout host engine). + + + +
+ +## Day To day + +This report will show BG, day by day, including selected treatments. + + + + + +Enable insulin, carbs and basal rate to have consistent insulin distribution information. + + + +
+ +When changing selections, click again `SHOW` to update the view. + +
+ +## Week to Week + +This report will give a week by week spaghetti view, with color code for week days selected. + + + +
+ +## Daily stats + +This report will give a daily distribution view. + + + +
+ +## Distribution + +This report will give a complete distribution view. + +You also can filter by hours (scroll to the bottom of the page). + + + + + +You can quickly find %TIR, %TUR, %TAR and the rough estimated HbA1c values. + + + +Range must be modified to see %TITR. + +
+ +## Percentile Chart + +This report will give a percentile distribution view. + + + + + +
+ +## Hourly stats + +This report will give an hourly distribution view with a box plot showing 25% and 75% percentile plus mean and standard deviation, then additional hour by hour statistics in a table. + + + +
+ +## Weekly Distribution + +This report will give a weekly view. + + + +
\ No newline at end of file diff --git a/_sources/clinicians/setup.md.txt b/_sources/clinicians/setup.md.txt new file mode 100644 index 00000000..165ee2e0 --- /dev/null +++ b/_sources/clinicians/setup.md.txt @@ -0,0 +1,87 @@ +# Setup the main view + +Before checking reports, you should verify your patient has setup correctly data upload. +The steps below might not be necessary but will probably give you more insights on the patient system. + +If you're only looking for reports, skip this step and continue to [reports](/clinicians/reports). + +
+ +## Customize your view + +Open the main menu, located at the top right of the window, select the drawer icon: + + + +Select the units for blood glucose values. + + + +Select the language used for Nightscout display. + + + +If the patient uses a pump that can send its basal rates, or has setup programmed basal rates, enable basal default display. + + + +Enable all available plugins and save. +This will only modify the way you visualize Nightscout on the device you're using. It will not interfere with the patient settings. + + + +
+ +## Identify displayed items + +A typical DIY closed loop user display will look like this. + + + +Last 48 hours are visible, you can select the upper graph time scale clicking on the corresponding length (2 to 24 hours). You can slide the lower graph selection to visualize the corresponding time period on the top graph. + +The rounded rectangle indicators are called "pills" and contain immediately visible indications, or more insights if you hover on them with the mouse. + +They can be automatically or manually updated by the patient or its closed loop/uploader device, else they will be empty or meaningless. As setting warning and urgent limit values for these pills is not always adjusted by the user in Nightscout variables, they might appear in yellow or red for values that are within normal usage. + + + +Current blood glucose is displayed top left, the arrow only indicates the difference between the current measurement and the previous one (you'll see the measurement age on the left of the view). + + + +- IOB: Insulin on board, is calculated using the insulin duration parameter in the current profile if no external closed loop system is used, or by this external algorithm if any (OpenAPS/Loop). + +- COB: Carbs on board are calculated by the absorption rate set in the profile. +- CAGE, SAGE, BAGE, IAGE are timers counting the time since last Cannula (infusion site), Sensor, Battery and Insulin cartridge change. +- BASAL displays the current basal rate. + +Uploading device battery level and Nightscout storage used space are not of clinical interest. + + + +Connected pumps will show available insulin units, battery status and last registered activity. + + + +DIY closed loop systems can be identified with the [Loop](https://loopkit.github.io/loopdocs/faqs/algorithm-faqs/) (Loop) or [OpenAPS](https://openaps.readthedocs.io/en/latest/docs/While%20You%20Wait%20For%20Gear/Understand-determine-basal.html#understanding-the-determine-basal-logic) (OpenAPS, AndoidAPS, FreeAPS, iAPS) pill. Only one will be enabled, if the other one appears it will normally show an exclamation mark. If a DIY closed loop system Nightscout doesn't show any active pill, configuration needs to be fixed so that Nightscout receives all necessary data (patient responsibility). + + + +Basal display shows the programmed basal in dotted lines and the actual basal modulation. This is an example for the default basal display. + + + +Loop adds rich details to Nightscout real time display, like food types and visual information. + +Hovering on the DIY closed loop system pill (Loop/OpenAPS) will show insights of the algorithm decisions. + + + +
+ +## Next step: + +Follow the link below. + +- [Generate reports](reports). diff --git a/_sources/index.md.txt b/_sources/index.md.txt new file mode 100644 index 00000000..0a4a2c37 --- /dev/null +++ b/_sources/index.md.txt @@ -0,0 +1,337 @@ +# Welcome to Nightscout + +
+ +![Nightscout](/images/nightscout_screenshot_600.png) + +
+ +Health professional? You might not want to build a Nightscout site and just need to find out how to get data from it, [jump to the dedicated pages here](/clinicians/home/). + +
+ +## Introduction + +Nightscout (also known as CGM in the Cloud) is an open-source cloud application used by people with diabetes and parents of kids with diabetes to visualize, store and share the data from their Continuous Glucose Monitoring sensors in real-time. Once setup, Nightscout acts as a central repository of blood glucose and insulin dosing/treatment data for a single person, allowing you to view the CGM graph and treatment data anywhere using just a web browser connected to the internet. + +There are several parts to this system. You need somewhere online to store, process and visualize this data (a Nightscout Site), something to upload CGM data to your Nightscout (an Uploader), and then optionally you can use other devices to access or view this data (one - or more - Follower). + +### Nightscout Site + +- The Nightscout cloud application can be installed by yourself (Do It Yourself, in short: DIY) using hosting services from various cloud service providers. +- You can also pay to use a fully-managed Nightscout hosting service and avoid having to personally build and maintain your site. + +### Uploader + +The CGM data is usually sent to Nightscout by an uploader device such as a mobile cellphone running an app like xDrip+, Spike, xDrip4iOS, Medtronic Uploader and others. Alternatively, the CGM data can be pulled directly from your online Dexcom account. The application you'll need for uploading the data depends on which CGM device you're using and what type of mobile device you have. + +### Followers + +In addition to viewing the data using a web browser, there are also applications available for mobile devices, smartwatches, electronic devices and other cloud-based services which allow you alternative ways to view and interact with the information stored within your Nightscout site (often known as "Followers"). + +![Nightscout Environment](/images/nscloud.png) + +## Development History + +Nightscout was developed by people with Type 1 Diabetes and parents of kids with T1D and has continued to be developed, maintained, and supported by volunteers, clinical use, and commercial sponsorship. The web portal known as Nightscout is made by the [CGM Remote Monitor Contributors](https://github.com/nightscout/cgm-remote-monitor/graphs/contributors) and the Nightscout community over years. + +When first implemented, Nightscout was a solution specifically for remote monitoring of [Dexcom G4 CGM data](https://github.com/hackingtype1/original-android-cgm). Today, there are Nightscout solutions available for nearly all commercial CGM sensors. The goal of the project is to allow the remote monitoring, sharing and analysis of any T1D's glucose levels using existing monitoring devices. + +## What are the values of Nightscout + +We are compelled in the pursuit of **humane** and **equitable** application of technology to **liberating people from the burden of diabetes**. We are not waiting to deliver the benefits we've found in **sharing _all_ diabetes experiences**. Nightscout is free to contribute, free to access, free to criticize, free to try, free to depend on, free to modify, and free to distribute. The Nightscout community demands **respect** and **dignity** for all community members. The reputation of the Nightscout community is affected by the **quality** of the source code, the quality of our relationships, the quality of our discussions, what we are known for doing: the way we treat each other. +Users of Nightscout are impacted by **reliability**, **security** and **confidentiality** of Nightscout. Therefore, the developers and contributors of Nightscout strive to improve the quality of Nightscout while making these opportunities **accessible** to all. + +Nightscout's **longevity**, the application, the ecosystem, and the culture demand we use all tools at our disposable to achieve the values in a **sustainable** way. We are not waiting to do whatever it takes to meet the needs of people affected by the inhumane demands of diabetes. Our active **collaboration** against the burden of diabetes creates the results we desire. + +## What Do I Need? + +You will need: + +- A CGM sensor + +- A way to [upload](uploader/uploaders) your data, to be stored in Nightscout (this is generally an internet-connected mobile phone with a matching uploader app) + +- Internet access + +- Basic computer skills and the ability to **_carefully_** follow the installation guides shown on this site + + **\*"Carefully"** means that you will thoroughly read, follow and complete each step without skipping any and without giving up thinking that it is too difficult - it isn't, you just need to be patient.\* + +```{admonition} IMPORTANT +:class: danger + +Before using Nightscout, it is important to understand that this project: + +- is an open-source, community-based project and is not supported by any company +- is not officially approved or regulated for diabetes therapy and/or treatment in any way + +**If you will be using DIY: You must understand that you take full responsibility for building and running this system and you agree to do so at your own risk.** +``` + +```{admonition} SAFETY +:class: danger + +- This project requires a working internet connection and availability of third-party cloud services +- Do not rely only on Nightscout as the only way you have of knowing your blood glucose values and trends +- Make sure you're ready to cope with an unexpected failure and always have alternative ways to check your blood glucose levels +``` + +## How Much Does It Cost? + +There's no simple answer to this. You basically have two options: + +1. **DIY**: Use instructions on this website to create your own installation. You will need to maintain this installation yourself. There are cloud providers that offer the needed hosting services for free, so your monthly hosting cost can be free - $0 with this option. Historically vast majority of Nightscout users have opted for this choice. Of note, with this option you are the person responsible for ensuring the service is up when you need it. The community aims to support people who choose this option, but this is entirely driven by a voluteer effort and support might not be available when you need it. +2. **Use a service**: You can use a hosting provider that does all of this work for you in exchange for a monthly fee. There are currently three options available for this ([NS10BE](#ns10be), [T1Pal](#t1pal), [Nightscout.Pro](#nightscout-pro), [Serendipity Bio](#serendipity-bio), and [Nightscout4u](#nightscout4u)), all of which are from active Nightscout community members. If you're a non-technical person, this is a **great choice**. + +The Nightscout development community actively supports both of these choices. + +## Build your own Nightscout DIY site + +```{tip} +
Interested in building a Nightscout DIY site? You'll find instructions ⇒ [**HERE**](/nightscout/new_user/) ⇐.

+``` + +**Note:** DIY users of Nightscout have been historically using platforms like [Digital Ocean](https://github.com/jasoncalabrese/project-glu/blob/master/README.md), [Microsoft Azure](https://docs.google.com/document/d/1RP-0KAX0Z46iGmShBdygY7_vQN1d-xEgtK_dSsjCA20/edit) and then Salesforce Heroku to host their sites. With time, more platforms were added. + +If you have the time to author instructions for this purpose, new documentation [pull requests](https://github.com/nightscout/nightscout.github.io/pulls?q=is%3Apr) are extremely welcome as well as [comments](https://github.com/nightscout/nightscout.github.io/issues). + +## Nightscout as a Service + +If you want to save time and avoid the need to maintain a DIY solution, you have three service providers of choice. + +### T1Pal + +```{card} +![](https://t1pal.com/media/t1pal/t1_pal_bear_bw.png) ++++ +[T1Pal](https://t1pal.com) directly supports the sustainability of the Nightscout Project. The monthly subscription for T1Pal is $11.99 USD/month. + +The T1Pal hosting service has been developed by **Ben West**, a member of the original CGM in the Cloud team and an original lead core developer for the Nightscout Project. Database and server administration is automated and managed automatically as part of the service. Contact T1Pal support to request specific features or versions. + +If you need help with T1Pal, please file a support ticket by emailing ***support*** at ***t1pal.com***, or select "Get Support" from [My Account](https://www.t1pal.com/account/). +``` + +### NS10BE + +```{card} + ++++ +[ns.10BE.de](https://ns.10be.de/) was started in Nov 2017 and offers full managed Nightscout Services. You can create Nightscout with a few clicks and won't have to worry about maintenance, updates, database space and CPU limits. A backup of your database and settings is performed every 6-8 hours. You can import data from your old Nightscout instance or MongoDB database, also upload data (Freestyle, Dexcom, Omnipod, ...) via CSV files. The servers are located in different fail-safe data centers in Germany, Finland or France (can be selected) . They are monitored by [uptimerobot](https://ns.10be.de/en/status.html) and own Slackbot. When a server goes down, it restarts itself and sends a twitter message. + +A Nightscout Instance at NS10BE costs €4.99/month, with discounts when increasing subscription duration. + +To see more about NS10 features and costs, take a look at the [features page](https://10be.de/en/pricing.html). The registration is free. + +***Support:*** ***support*** at ***ns.10be.de*** or [https://10be.de/en/contact.html](https://10be.de/en/contact.html) or [https://twitter.com/10be_de](https://twitter.com/10be_de) or [https://www.facebook.com/10be.de](https://www.facebook.com/10be.de) +``` + +### Nightscout Pro + +```{card} + ++++ +[Nightscout.Pro](https://nightscout.pro/) was founded in 2022 by **Andy Low** - A type 1 diabetic web developer from Scotland, UK. Nightscout.Pro offer a completely 'hands-off' approach to Nightscout hosting, meaning all you need to do is subscribe via the website, and your Nightscout site will be created for you, with little to no configuration needed. Your site will be set up in a 'default' configuration, which can be modified by contacting **support** via [Email](mailto:support@nightscout.pro), [Facebook](https://www.facebook.com/nightscoutpro) or [Discord](https://discord.gg/7hYrkqVavU). + +The site is translated into multiple languages, with more in line to be added over time, and can accept payment in various local currencies. + +**Pricing per month** + +| Currency | Price | +| -------- | ----- | +| GBP | £3 | +| USD | $4 | +| EUR | €4 | +| PLN | 18 zł | + +More information about the companies background and processes can be found on the website at [Welcome to Nightscout.Pro.](https://nightscout.pro/welcome-to-nightscout-pro/) +``` + +### Serendipity Bio + +```{card} +![](https://media.serendipitybio.com/serendipity-logo.jpg) ++++ +Serendipity provides instant deployment of Nightscout, literally. + +[Create](https://serendipitybio.com/pricing) your account and we'll: +- Launch your Nightscout server +- Launch your Mongo database +- Provide you a secure, shareable URL + +Never worry about: +- Database size +- Reliabiity of your server +- Upgrading versions + +Serendipity Bio fully manages your Nightscout server and database. + +Nightscout is configured for you automatically on start. Once launched you can use our UI to change your settings to your liking! + +Find support documents [here](https://support.serendipitybio.com/) or [email](mailto:support@serendipitybio.com) us any time! + +Concerned about reliability or sustainability? Serendipity Bio is built using Amazon Web Services, which also hosts all your favorite websites like Netflix, Apple, AirBnB, and ESPN. + +Available globally, a monthly subscription is priced at $12.99 USD per month, payable online via credit card. +``` +### Nightscout4u + +```{card} + ++++ +[Nightscout4u.com](https://www.nightscout4u.com/) started its service in 2023 and offers a simple one-click hosted Nightscout service solution. It is possible to create and use multiple Nightscout instances with one account. + +The service is suitable for beginners to make their first steps and get used to Nightscout for only one Euro per instance and month. + +Check out the easy way of a [hosted Nightscout solution](https://www.nightscout4u.com/). +``` + +## Who Can Help Me? + +You will find many willing and open-hearted people in the Facebook groups. + +The main group for all Nightscout support is the "[CGM in the Cloud](https://www.facebook.com/groups/cgminthecloud/)" Facebook group. + +There are also many local Nightscout communities and you'll probably be able to find one in your own country and language if this helps. + +```{admonition} Technical Support +:class: warning + +Unless you're paying for a hosted Nightscout including support, this project is "**Do It Yourself**" (DIY) and supported by volunteers. Whilst you will almost certainly always will find someone ready to help you for free, building your own Nightscout site **doesn't entitle you to any form of support** from anybody. + +The open-source diabetes movement is founded on the idea of **paying it forward** and helping others to learn things that others took their time to help teach you about. + +*Ask nicely, and nice people will always do nice things and help you.* + +Nightscout developers are busy people and we'd like them to concentrate on maintaining and improving Nightscout, not only supporting users. (This means **do not** send them private messages or friend requests just to help fix something that is already clearly documented or for help that can be easily requested in the CGM in the Cloud group) +``` + +```{admonition} Facebook Privacy +:class: tip + +You'll find a lot of useful and friendly diabetes-oriented groups on Facebook and it's probably the best place to find online support. Some people express concerns about using Facebook: if you're worried about your privacy just remember Facebook will only share the information that you **allow** it to share. +``` + +## How to Use These Docs + +- Use the navigation menu at the top on the left of the screen to find the section that you are looking for. + +- A Table of Contents for the current page is always displayed on the left side of the screen. + +- You can search the Nightscout Docs site by entering your search string (only English) below the Nightscout main logo top left. + +## How Can I Help? + +You'll find the source repository for this documentation [here](https://github.com/nightscout/nightscout.github.io). Please don't hesitate to improve or correct anything you see and create a pull request! + +You're also welcome to contribute or report any error, unclear explanation, typo, broken link etc. by going to GitHub and opening an [issue](https://github.com/nightscout/nightscout.github.io/issues). + +Finally, to help on the development of Nightscout itself, feel free to join in at our [Discord Channel](https://discord.gg/zg7CvCQ). + + + +```{toctree} +:hidden: +uploader/uploaders/ +``` + +```{toctree} +:hidden: +:caption: CREATE YOUR NIGHTSCOUT +nightscout/new_user/ +nightscout/wizard/ +``` + +```{toctree} +:hidden: +:caption: CREATE YOUR DATABASE +nightscout/database/ +vendors/mongodb/atlas/ +vendors/railway/database/ +vendors/northflank/database/ +``` + +```{toctree} +:hidden: +:caption: CREATE YOUR WEB APP +nightscout/platform/ +vendors/azure/new_user/ +vendors/northflank/new_user/ +vendors/render/new_user/ +vendors/railway/new_user/ +vendors/heroku/new_user/ +vendors/fly.io/new_user/ +vendors/google/new_user/ +``` + +```{toctree} +:hidden: +:caption: SETUP NIGHTSCOUT +nightscout/profile_editor/ +uploader/setup/ +nightscout/downloaders/ +nightscout/wearable/ +nightscout/setup_variables/ +uploader/xdripcarelink/ +troubleshoot/dexcom_bridge/ +``` + +```{toctree} +:hidden: +:caption: USE NIGHTSCOUT +nightscout/discover/ +nightscout/reports/ +nightscout/security/ +nightscout/admin_tools/ +nightscout/close_loop/ +nightscout/ifttt/ +nightscout/pushover/ +troubleshoot/troubleshoot/ +update/update/ +update/dev_branch/ +update/downgrade/ +``` + +```{toctree} +:hidden: +:caption: ADVANCED DIY +nightscout/advanced/ +vendors/VPS/ubuntu/ +vendors/VPS/docker/ +vendors/NAS/synology/ +``` + +```{toctree} +:hidden: +:caption: VENDORS +vendors/heroku/migrate/ +nightscout/multiadmin/ +vendors/github/update/ +update/redeploy/ +troubleshoot/github/ +troubleshoot/atlas/ +troubleshoot/azure/ +troubleshoot/northflank/ +troubleshoot/railway/ +troubleshoot/heroku/ +vendors/heroku/ecoplan/ +vendors/heroku/hobbyplan/ +vendors/heroku/mfa/ +update/upd_stack/ +troubleshoot/fly.io/ +troubleshoot/render/ +``` + +```{toctree} +:hidden: +:caption: CLINICIANS +clinicians/home/ +clinicians/setup/ +clinicians/reports/ +``` + +```{toctree} +:hidden: +:caption: TRANSLATE +translate/ +``` diff --git a/_sources/nightscout/admin_tools.md.txt b/_sources/nightscout/admin_tools.md.txt new file mode 100644 index 00000000..53c30484 --- /dev/null +++ b/_sources/nightscout/admin_tools.md.txt @@ -0,0 +1,66 @@ +# Admin Tools + +
+ +## Subjects and Roles + +```{include} /nightscout/tokens.md + +``` + +
+ +## Database Maintenance + +If you use a small or a free database (like MongoDB Atlas), it will require maintenance as nothing in Nightscout is setup to perform cleanup and unless you planned for a larger size database, it will eventually fill-up. + +```{warning} +Make sure you leave [`dbsize`](/nightscout/setup_variables.md#dbsize-database-size) visible on your page to keep it under control. +``` + +
+ +This panel will give access to basic maintenance actions on various database collections. + +
+ +### Mongo `status` Database + +
+ +Your status database contains battery, pump, ... extra information as those defined in [devicestatus](/nightscout/setup_variables.md#devicestatus-device-status) that you can safely delete when necessary. + + + +
+ +When it comes to `treatments` and `entries`, deleting data is something you need to carefully evaluate if you like Nightscout to be the main repository for your history. + +### Mongo `treatments` Database + +
+ + + +
+ +### Mongo `entries` Database + +
+ + + +
+ +### Remove future items from Database + +
+ +Future treatments and entries generated by an incorrect time zone, daylight saving time change, or any other mistake can completely block your site. Using this feature will purge the database of these unwanted values automatically. Detected issues will appear in `Database contains `*`x`*` future records` and should be fixed. + +
+ + + +
+ diff --git a/_sources/nightscout/advanced.md.txt b/_sources/nightscout/advanced.md.txt new file mode 100644 index 00000000..1aadf9a1 --- /dev/null +++ b/_sources/nightscout/advanced.md.txt @@ -0,0 +1,63 @@ +# Advanced Nightscout deployments + +
+ +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +## Building Nightscout DIY in a cloud platform + +You can run your Nightscout site in several vendors platforms, using free or paid accounts. + +We documented Heroku, Azure, Railway, Northflank and Fly.io. There are probably others, don't hesitate to [open an issue in the documentation](https://github.com/nightscout/nightscout.github.io/issues) with the easiest deployment method if you want to see them named here. + +
+ +## Building Nightscout DIY in a virtual server + +You can run your Nightscout site in physical or virtual private servers, using free or paid accounts. +The [original](https://github.com/jasoncalabrese/project-glu/blob/master/README.md) Nightscout project was also developed to run in Digital Ocean. + +You can use step by step Linux commands or deploy with a **simple** scripted install. + +Below is a list of some VPS. There are probably others, don't hesitate to [open an issue in the documentation](https://github.com/nightscout/nightscout.github.io/issues) with the easiest deployment method if you want to see them named here. + +[Google Cloud](https://navid200.github.io/xDrip/docs/Nightscout/GoogleCloud.html) with a Scripted deployment (one command). +[Oracle](https://www.dropbox.com/s/5twlqrndofqno0t/0-amber-oracle.pdf) and extensive documentation (npm and Docker). +[Amazon Web Service](https://github.com/rajdeut/terraform-aws-nightscout#readme) + +Some common deployment methods: + +[Ubuntu](/vendors/VPS/ubuntu) commands. +[Docker](/vendors/VPS/docker) container. + +
+ +(nas)= + +## Building Nightscout inside your NAS + +Don't buy a NAS device just for this, but if you already have one that's worth a try! + +You can host your Nightscout site in your [Synology](/vendors/NAS/synology) NAS. +You can also try with your [QNAP](https://docs.google.com/document/d/1zpF6Y3kPQqc9KOsClIQt686HDLhGfFxwz4vGfq8E254/edit) NAS. + +
+ +## Building Nightscout with a Raspberry PI 4 + +If you own one, you can use it to host your Nightscout, see [here](https://gist.github.com/Andries-Smit/daac75cd4c06af78cde68c5dec941705). + +
+ +## Home Assistant Add-On for Nightscout + +This add-on is a wrapper around nightscout/cgm-remote-monitor. It includes a Mongo Database which is used to store the uploaded values. + +See [here](https://github.com/marciogranzotto/addon-nightscout). + +
diff --git a/_sources/nightscout/close_loop.md.txt b/_sources/nightscout/close_loop.md.txt new file mode 100644 index 00000000..5a8979bd --- /dev/null +++ b/_sources/nightscout/close_loop.md.txt @@ -0,0 +1,50 @@ +# Closed loop systems + +
+ +Nightscout is integrated with DIY closed loop systems. + +Look into the specific app documentation to know more about optimal Nightscout settings. + +The heading for each section is a link to the Nightscout overview page for that closed-loop system. + +You will also find general support in **Loop and Learn**. + +* [The *Loop and Learn* Website](https://www.loopandlearn.org/) +* [The *Loop and Learn* *Facebook* group](https://www.facebook.com/groups/LOOPandLEARN) + +
+ +## [Loop](https://loopkit.github.io/loopdocs) + +[Loop](https://loopdocs.org) is an iOS app that assists in the many insulin dosing decisions people with diabetes face every day. You enter your own settings for desired correction range, basal schedule, insulin sensitivity factor (ISF), carbohydrate ratio (CR) and the type of insulin you are using. The glucose predictions, using your settings and meal entries, provide Loop with the information needed to modify insulin delivery to attain a targeted glucose range in the future. + +**See [here](https://loopkit.github.io/loopdocs/loop-3/services/#nightscout-login) how to configure Loop to upload to Nightscout.** + +Facebook group: [Looped](https://www.facebook.com/groups/TheLoopedGroup) + +
+ +## [AAPS](https://androidaps.readthedocs.io/en/latest/index.html) + +AndroidAPS is an open source app for people living with insulin-dependent diabetes that acts as an artificial pancreas system (APS) on Google Android smartphones. AAPS uses an openAPS software algorithm. + +**See [here](https://androidaps.readthedocs.io/en/latest/Configuration/Preferences.html#nsclient) how to configure AAPS NSClient to upload to Nightscout.** + +Facebook group: [Android APS Users](https://www.facebook.com/groups/AndroidAPSUsers) + +
+ +## [iAPS](https://iaps.readthedocs.io/en/main/) + +iAPS is a open source artificial pancreas system based on the OpenAPS algorithm. + +Facebook group: [iAPS](https://www.facebook.com/groups/1351938092206709) + +
+ +## [OpenAPS](https://openaps.org/) + +*Mind the documentation is not up to date for Nightscout DIY options.* + +The Open Source Artificial Pancreas System (OpenAPS) is a safe but powerful, advanced but easily understandable, Artificial Pancreas System (APS) designed to automatically adjust an insulin pump’s insulin delivery to keep blood glucose (BG) in a safe range at all times. It does this by communicating with an insulin pump to obtain details of all recent insulin dosing (basal and boluses), by communicating with a Continuous Glucose Monitor (CGM) to obtain current and recent BG estimates, and by issuing commands to the insulin pump to adjust insulin dosing as needed. diff --git a/_sources/nightscout/database.md.txt b/_sources/nightscout/database.md.txt new file mode 100644 index 00000000..0eedb049 --- /dev/null +++ b/_sources/nightscout/database.md.txt @@ -0,0 +1,113 @@ +# Choose your database + +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +You must create a database unless it's already included in the platform you selected, check below. + +````{tab-set} + +:::{tab-item} Select your platform -> +
+::: + +:::{tab-item} Heroku/Railway/Azure/Northflank/Fly.io +You need to create a database. +::: + +:::{tab-item} Google Cloud script +You don't need to create a database: continue [**here**](https://navid200.github.io/xDrip/docs/Nightscout/GoogleCloud.html) +::: + +:::{tab-item} Hosted +You don't need to create a database: go directly to the [hosting site](/index.md#nightscout-as-a-service). +::: + +```` + +
+ +Find a list of commonly used database hosting services below, decide which one you'll want to use and create your database. + +
+ +```{warning} +Using a free, limited size database (like M0 Atlas) means you will have to maintain it.
+Since it will regularly grow with the data you send to Nightscout, take a note to perform **regular cleanup** to avoid your site crashing. +``` + +```{card} +## MongoDB Atlas Database +![MongoDB Atlas](/vendors/img/Atlas.png) +^^^ +MongoDB bought [mLab](https://twitter.com/chrisckchang/status/506959446753284096) in 2018 and shutdown its service in 2020. Most users migrated to MongoDB Atlas, using a free M0 database with a limited 512MB capacity. + +**Pros**: +* The M0 cluster is free +* Nightscout was adapted to MongoDB Atlas + +**Cons**: +* M0 clusters are designed for learning and testing, not production: performance and availability are not guaranteed +* There is no warranty the M0 cluster will remain in the future +* A larger M2 cluster costs 9$ per month (not competitive against hosted solutions) +* A full M0 database crashes Nightscout, this is a common issue for DIY closed loop system users ++++ +Follow [these instructions](/vendors/mongodb/atlas.md) to build a small database to host your Nightscout data if you don't already have one. +``` + +```{card} +## Railway Mongo Database +![Railway](/vendors/img/Railway.png) ![MongoDB](/vendors/img/MongoDB.png) +^^^ +Railway offers a Mongo database. + +**Pros**: +* Simple to create +* Less overhead than Atlas (more space) + +**Cons**: +* Requires a 5$/month hobby plan as billing starting amount +* Running a database together with a Railway Nightscout site will increase billing above ~200MiB used +* Simple Mongo 4.4 database ++++ +Follow [these instructions](/vendors/railway/database.md) to create a database in Railway. +``` + +```{card} +## Northflank Mongo Database +![Northflank](/vendors/img/Northflank.png) ![MongoDB](/vendors/img/MongoDB.png) +^^^ +Northflank offers a Mongo database. + +**Pros**: +* Simple to create +* Economic reliable database +* High quality Mongo database with a replica set + +**Cons**: +* Billing will occur but the cost is really limited: 0.3$ per GiB (it usually takes years to reach 1GB for Nightscout) +* There is no warranty this offer will be maintained in the future ++++ +Follow [these instructions](/vendors/northflank/database.md) to create a database in Northflank. +``` + +```{card} +## VPS Mongo Database +![MongoDB](/vendors/img/MongoDB.png) +^^^ +You can create a Mongo Database in a Virtual Private Server, either using a free plan (Oracle, Google) or a paid account (Digital Ocean and so many others ...). + +**Pros**: +* Lot of space +* Standard community method largely supported by IT specialists + +**Cons**: +* Requires commands to be typed and some IT knowledge ++++ +Waiting for something easier (work in progress) [these are the instruction](https://www.mongodb.com/docs/manual/administration/install-on-linux). +``` + diff --git a/_sources/nightscout/discover.md.txt b/_sources/nightscout/discover.md.txt new file mode 100644 index 00000000..05e20778 --- /dev/null +++ b/_sources/nightscout/discover.md.txt @@ -0,0 +1,308 @@ +# Discover your Nightscout site + +
+ +```{admonition} Privacy +:class: tip +Having the URL of your Nightscout site, anybody can view your BG and run reports of your data. It it strongly recommended that you [secure](/nightscout/security) your site. +``` + +
+ +It should look very similar to this when your [uploader](/uploader/setup.md) has added some data. + + + +
+ +The central part will show your recent BG, you can select how many hours you want to be displayed with `Hours: 2 3 4 6 12 24`. The pale blue dots are the AR2 prevision as explained [here](/nightscout/setup_variables.md#ar2-ar2-forecasting). The lower part will display the last 48 hours and you can use the lower right selection to browse your old data. + + + +
+ +In the upper part you'll see the current time of your site, your current BG (and how long ago it was measured) plus the delta with the previous measurement and a trend arrow. More explanations [here](/nightscout/setup_variables.md#default-plugins). + +Optionally you will see other indications (pills) that can be personalized in your variables and plugins like detailed [here](/nightscout/setup_variables.md#plugins). + + + +
+ +## Authenticate yourself + +By default you site opens read only, you need to authenticate using your [API secret](api-secret) in order to modify settings and add treatments. Click on the lock icon, enter your API secret and click `Update`. + + + +This will unlock your `careportal` ([if enabled](/nightscout/setup_variables.md#careportal-careportal)) and `edit` ([if enabled](/nightscout/setup_variables.md#edit_mode-on)). + + + +
+ +## Add a treatment (`careportal`) + +Some uploaders will send treatments to Nightscout but others won't. If you whish to do this manually, `careportal` is here for that. + +`+` will open an interface to manually enter treatments. + + + +
+ +In the `Event Type` drop down menu, you can select the treatment type you want to add. Additional available entries will depend on the [plugins you enabled](/nightscout/setup_variables.md#advanced-plugins) like Loop and OpenAPS/AAPS. + +### BG Check + +`BG check` allows you to enter a blood glucose reading value from your `Meter`. With a CGM using `Sensor` reading doesn't add much value. + +Keep in mind the value will be inserted now (unless you modify the event time) and might not match your CGM value for non stable BG due to capillary time lag. + + + +
+ +### Correction Bolus + +`Correction Bolus` allows you to enter the amount of insulin units injected for a correction. + +It will show as a circle with the lower half blue, with its size depending on the amount of units, UI indicated below (depending on [bolus rendering](/nightscout/setup_variables.md#bolus_render) setting). + + + +
+ +### Meal Bolus + +### Carb Correction + +### Snack Bolus + +These treatments allow you to enter the amount of food you eat (and eventually the matching insulin treatment). + +It will show as a circle with the higher half white (if including carbs), with its size depending on the amount of food. Without carbs the upper half will not be filled with the white color. If you add proteins and fat, the amount will display in this order: `carbs/proteins/fat`. With insulin the lower half of the circle will fill in blue and units will be indicated below. + +You can select the timing of carbs absorption in `Carb Time` (i.e. when did you or will you actually eat these carbs) + + + +
+ +### Combo Bolus + +Combo bolus allows you to insert the corresponding bolus if you use a pump. Insert the total amount of insulin in `Insulin Given` then break down in `Split` with the percentage administered `now` and the `extended` amount. Enter the`Duration` of the extended bolus below. + +It will display as a classic bolus at treatment time and [basal](/nightscout/setup_variables.md#basal-basal-profile) will reflect the extended amount for the selected duration. + + + +
+ +### Announcement + +Announcements are used to change your page title in order to alert viewers. + +Entering another treatment will acknowledge the announcement and return your page title to [default](/nightscout/setup_variables.md#custom_title-nightscout). + + + +
+ +### Note + +### Question + +Notes and questions are a way to add comments and interact with others using your Nightscout page. + + + +
+ +### Exercise + +You can log physical activities and specify the duration. + + + +
+ +### Pump Site Change `cage` + +### CGM Sensor Start `sage` + +### CGM Sensor Insert + +### CGM Sensor Stop + +### Pump Battery Change `bage` + +### Insulin Cartridge Change `iage` + +Logging these events will help you remember various expirations dates and will update the [corresponding pills](/nightscout/setup_variables.md#age-pills) if enabled. + + + +
+ +### Temp Basal Start + +### Temp Basal Stop + +You can indicate temporary basal rate changes using either a percentage change in `Percent` or the absolute rate in `Basal value`. You need [basal](/nightscout/setup_variables.md#basal-basal-profile) to be enabled to visualize it. + + + +
+ +### Profile Switch + +If you have more than one profile stored, you can switch profile to keep your profile parameters synchronized. + +For a temporary switch (like for physical activities) you can select the duration. + + + +
+ +### D.A.D. Alert + +Log a Diabetic Alert Dog event. + + + +
+ +## Edit Mode (`edit`) + +For values still present on your display (last 48 hours), you can use Edit to move or delete bolus and correction treatments. + + will change color to red in edit mode . + +1. Drag the treatment in the past or future in the black area to move both food and insulin. +2. If you want to move only insulin drop in the blue area. +3. For carbs only, in the white area. +4. To delete a complete treatment drop it in the red delete area. + +Once done, exit the edit mode by de-selecting it (white on black background). + + + +
+ +## Drawer Menu + +Once authenticated (click the lock icon up right) you'll find many features in the drawer menu like access to advanced plugins and customizations of your web page (local view only, in order to modify the default view look into your Heroku variables [here](/nightscout/setup_variables/)). + + + +`Reports` will drive you to a powerful reporting toolset detailed [here](/nightscout/reports/). + +`Profile Editor` will allow you to modify and add profiles, see [here](/nightscout/profile_editor/). + +`Food Editor` handles your customized [food database](/nightscout/setup_variables.md#food-custom-foods). + +`Admin Tools` gives you access control and database tools, see [here](/nightscout/admin_tools). + +
+ +### Simple views: + + + +
+ +- `Clock` - Shows current BG, trend arrow, and time of day. Grey text on a black background. + + + +- `Color` - Shows current BG and trend arrow. White text on a color background. + + + +- `Simple` - Shows current BG. Grey text on a black background. + +- `[+]` - Create custom, simplified views using a predefined set of elements. + + + +
+ +List of available items: + +- `SGV` - Sensor Glucose Value +- `SGV age` - time since the last SGV read +- `SGV delta` - change of SGV in the last 5 minutes +- `Trend arrow` - icon of the SG trend +- `Time` - current time +- `Line break` - invisible item that will move following items to the next line (by default all are showing on the same level) + +All visible items have `Size` property which allows to customize the view even more. Also, all items may appear multiple times on the view. + +Apart from adding items, it is possible to customize other aspects of the views, like selecting `Color` or `Black` background. The first one will indicate current BG threshold (green = in range; blue = below range; yellow = above range; red = urgent below/above). `Show SGV age` option will make `SGV age` item appear `Always` or only if the predefined threshold is reached: `Only after threshold`. Breaching `SGV age threshold` will also make `Color` background turn grey and strike through `SGV`. `Clock view configurator` will generate an URL (available under `Open my clock view!` link) that could be bookmarked. + +If you launch one of these views in a fullscreen view in iOS, you can use a left-to-right swipe gesture to exit the view. + +
+ +### Settings: + + + +
+ +You can customize your view using Settings. Changes will only be applied to your current browser view, if you want to make these settings default for any browser you need to change directly the corresponding [system variables](/nightscout/setup_variables) indicated below and add the corresponding plugins in [`SHOW_PLUGINS`](/nightscout/setup_variables.md#plugins). + +You need to [authenticate](#authenticate-yourself) to save your settings. + +#### [**Units `DISPLAY_UNITS`**](display-units) + +#### [**Date Format `TIME_FORMAT`**](/nightscout/setup_variables.md#time_format-12) + +#### [**Language `LANGUAGE`**](/nightscout/setup_variables.md#language-en) + +#### [**Scale `SCALE_Y`**](/nightscout/setup_variables.md#scale_y-log) + +#### [**Render Basal `BASAL_RENDER`**](/nightscout/setup_variables.md#basal-basal-profile) + +#### [**Render Bolus Amount `BOLUS_RENDER`**](/nightscout/setup_variables.md#bolus_render) + +#### [**Alarms `ALARM`**](/nightscout/setup_variables.md#alarms) + +
+ + + +
+ +#### [**Edit Mode `EDIT`**](/nightscout/discover.md#edit-mode-edit) + +#### [**Show Raw BG Data `rawbg`**](/nightscout/setup_variables.md#rawbg-raw-bg) + +#### [**Custom Title `CUSTOM_TITLE`**](/nightscout/setup_variables.md#custom_title-nightscout) + +#### [**Theme `THEME`**](/nightscout/setup_variables.md#theme-colors) + +#### [**Show Plugins `SHOW_PLUGINS`**](/nightscout/setup_variables.md#plugins) + +
+ + + +
+ +In order to `Save` your changes you need to Authenticate, click `Authenticate` and enter your [API Secret](api-secret). + +`Reset, and use defaults` will reverse your changes to defaults from your [config variables](/nightscout/setup_variables.md#nightscout-config-vars). + +In `About` you'll see your current Nightscout version. + +
+ +### API + +You can find information about your site API at: + +https://{url}/api-docs[?token=TOKEN] + +https://{url}/api/v2/properties.json[?token=TOKEN] diff --git a/_sources/nightscout/dns.md.txt b/_sources/nightscout/dns.md.txt new file mode 100644 index 00000000..5c041a34 --- /dev/null +++ b/_sources/nightscout/dns.md.txt @@ -0,0 +1,129 @@ +--- +orphan: true +--- + +```{warning} +Nightscout developers advice: not a good idea. +``` + +# Use a Dynamic DNS + +
+ +Either because running a VPS, Northflank or simply because you'd like an alternate name to your Nightscout page, you can use either you own DNS name or free services like those below. + +```{warning} +Adding a free DNS service to your Nightscout setup increases the possibility of unexpected outage.
+Paid DNS services are available at 1$ per month. +``` + +
+ +## No-IP + +No-IP provides one free dynamic DNS hostname. + +```{warning} +Using No-IP for free requires you to **confirm your hostname every month**. +``` + + + +1. Sign up to [No-IP](https://www.noip.com/sign-up). Do not create a `Hostname` yet. + +
+ +2. From the dashboard, in `Dynamic DNS`, `No-IP hostnames` click `Create Hostname`. + + +
+ +3. Invent your `Hostname` and select a `Domain` in the `Free Domain` list. This will be the URL you will be able to browse from any computer to your Nightscout site. + + +
+ +4. If you're using a VPS or you know the IP address of your current Nightscout, select `DNS Host (A)` and enter it in `IPv4 Address`. + + +
+ +5. Else, if you only know your current Nightscout site name, select `DNS Alias (CNAME)` and enter it in `Target`. + + +
+ +6. Click `Create Hostname` bottom right. + +
+ +You now can use this URL when accessing your Nightscout site, in any browser and also for your uploaders and followers. + +
+ +## Dynu + +1. Sign up to [Dynu](https://www.dynu.com/en-US/ControlPanel/CreateAccount). + +
+ +2. From the `Control Panel`, select `DDNS Services`. + + +
+ +3. Invent your `Host` name and select a `Top Level` domain in the list. This will be the URL you will be able to browse from any computer to your Nightscout site. + + +
+ +4. Click `Add`. + +
+ +5. Replace the proposed IP address in `IPv4 Address` by your own Nightscout IP, (you can disable IPv6 features) and click `Save`. + + +
+ +You now can use this URL when accessing your Nightscout site, in any browser and also for your uploaders and followers. + +
+ +## FreeDNS + +FreeDNS proposes thousands of free DNS names, with the issue that many are flagged as dangerous when you'll want to browse them from your cellular or within public/private networks. You'll find one that fits your needs but you might need several attempts. + +```{warning} +Using FreeDNS for free requires you to **login to confirm your account every six months**. +``` + + + +1. Sign up to [FreeDNS](https://freedns.afraid.org/signup/?plan=starter). Enter all required information and click `Send activation email`. + + +
+ +2. Check your inbox (search Spam if you don't receive the email) and click on the activation link. + + +
+ +3. Select `Subdomains` in the menu, then `Add a subdomain`. + + +
+ +4. Invent your host name in `Subdomain`, select a domain name in the list (there are more than you can see) and put your Nightscout IP in the `Destination` field. Write the text in the image and click `Save`. + + + Note: you might want to select a less popular name than those proposed by selecting Registry in the left menu (example below for us.to). + + +
+ +5. You now can use this URL when accessing your Nightscout site, in any browser and also for your uploaders and followers. + + +
\ No newline at end of file diff --git a/_sources/nightscout/docker.md.txt b/_sources/nightscout/docker.md.txt new file mode 100644 index 00000000..0139bc29 --- /dev/null +++ b/_sources/nightscout/docker.md.txt @@ -0,0 +1,8 @@ +--- +orphan: true +--- + + + + + diff --git a/_sources/nightscout/downloaders.md.txt b/_sources/nightscout/downloaders.md.txt new file mode 100644 index 00000000..ac4a3f3e --- /dev/null +++ b/_sources/nightscout/downloaders.md.txt @@ -0,0 +1,252 @@ +# Setup Downloaders - Followers + +
+ +```{admonition} Smartwatches +:class: tip + +See the dedicated page [**here**](/nightscout/wearable.md). + +``` + +
+ +Note: indicates applications compliant to [Nightscout access tokens](/nightscout/security.md). + +
+ +## Android + +### [xDrip+](https://github.com/NightscoutFoundation/xDrip/releases) + + + + + +Select the Nightscout Follower data source and type your Nightscout URL: + +*Example:* `https://name.domain.tld` + +For a secured site add the token and @ before: + + *Example:* `https://token@name.domain.tld` + + + +Facebook group [xDrip](https://www.facebook.com/groups/xDripG5/) + +
+ +### [AndroidAPS NSClient](https://github.com/nightscout/AndroidAPS/releases) + + + +Facebook group [AndroidAPS Users](https://www.facebook.com/groups/AndroidAPSUsers) + +
+ +### [Nightwatch](https://play.google.com/store/apps/details?id=se.cornixit.nightwatch) (Google Play Store) + + + +Monitor your Nightscout glucose levels on your Android phone or tablet. Dark UI, large readings and buttons, designed for usage at night. + + + +
+ +### [Nightwatch](https://github.com/StephenBlackWasAlreadyTaken/NightWatch/releases) (legacy) + + + +CGM data on your Android Phone and Android Wear Watch! + +Nightwatch is not maintained anymore and might not work with recent Android versions. Switching to xDrip+ is recommended. + +
+ +### [Glimp](https://play.google.com/store/apps/details?id=it.ct.glicemia) + + + +In Settings, Cloud, Nightscout, select Download only and type your Nightscout URL. Use a token or API_SECRET for a secure site. + + + +
+ +### [Diabox](https://www.bubblan.org/diabox/) + + + +In Settings, set Data Collection to Follower, select Nightscout and type your Nightscout URL. + + + +
+ +## iOS + +### [Nightscout X](https://apps.apple.com/us/app/nightscout-x/id1333154219) + + + + + +
+ +### [Nightguard](https://apps.apple.com/us/app/nightguard/id1116430352) + + + +[GitHub](https://github.com/nightscout/nightguard) + + + +
+ +### [Nightscouter](https://testflight.apple.com/join/UczafrJp) + + + +[GitHub](https://github.com/someoneAnyone/Nightscouter) + +
+ +### [Loop Follow](https://www.loopandlearn.org/loop-follow/) + + + +
+ +### [Spike](https://spike-app.com/) + + + + + +Look [here](https://github.com/SpikeApp/Spike/wiki/Spike-Follower-Mode#configure-spike-follower-manually). + +
+ +### [xDrip4iOS](https://xdrip4ios.readthedocs.io/en/latest/) + + + +Set xDrip4iOS to follower mode and enable Nightscout, type your Nightscout URL. +If you're using a secured Nightscout site, enter your token in the matching field. + + + +Facebook group [xDrip4iOS](https://www.facebook.com/groups/853994615056838) + +
+ +### [sugarmate](https://sugarmate.io/) + +```{admonition} Important limitation +:class: warning +**Sugarmate doesn't allow Nightscout as a data source if you included `bridge` in `ENABLE`.** +If you need this data source: enable [obscuration](/nightscout/setup_variables.md#bridge-share2nightscout-bridge) variables. +``` + + + + + +Add Nightscout as a data source, type your Nightscout URL. + + + +
+ +### [Diabetes Cockpit](https://apps.apple.com/us/app/diabetes-cockpit/id1580577116) + + + + + +
+ +### [Gluco-Tracker](https://apps.apple.com/it/app/gluco-tracker/id1526976290) + + + + + +
+ +### [NightscoutMenuBar](https://github.com/mpangburn/NightscoutMenuBar) + +### [BitBar Nightscout](https://github.com/pdaddyo/bitbar-nightscout) + +
+ +## Mac + +### [Nightscout MacOS Menu Bar](https://github.com/adamd9/Nightscout-MacOS-Menu-Bar) + +Show your current BG in the system bar at the top of your screen on Mac (including Loop details). Available directly through the [Apple Store](https://apps.apple.com/au/app/nightscout-menu-bar/id1639776072?mt=12). + + + +
+ +## Windows + +### [FloatingGlucose](https://github.com/dabear/FloatingGlucose) (archived) + + + + + +
+ +### [Owlet](https://github.com/kashamalasha/nightscout-widget-electron) + + + + + +
+ +### [NS2Win](https://github.com/emp-00/NS2Win) + + + + + +
+ +## Displays + +### [M5Stack NightscoutMon](https://github.com/mlukasek/M5_NightscoutMon/wiki) + + Facebook group [M5STACK NIGHTSCOUT](https://www.facebook.com/groups/606295776549008) + + + +### [M5Stick NightscoutMon](https://github.com/mlukasek/M5StickC_NightscoutMon) + + + +
+ +
+ +### [BGBuddy](https://github.com/VeryKross/BGBuddy) + + + +
+ +### [SugarPiDisplay](https://github.com/bassettb/SugarPiDisplay) + + + +
+ +## Other + +[Home assistant](https://www.home-assistant.io/integrations/nightscout/) + diff --git a/_sources/nightscout/first_setup.md.txt b/_sources/nightscout/first_setup.md.txt new file mode 100644 index 00000000..f978009f --- /dev/null +++ b/_sources/nightscout/first_setup.md.txt @@ -0,0 +1,69 @@ +--- +orphan: true +--- + +## New Nightscout Setup + +
+ +a) Your Nightscout site should open and direct you to a new profile creation. + + + +
+ +b) Setup your `Time zone` and eventually all other fields. Do not leave any fields empty. If you don't know which value to use, just use the default value. You can change these values later at any time. + + + +
+ +c) Browse down to `Authentication status` and click `Authenticate`. Enter your API secret. Click `Update`. + + + +
+ +d) Click `Save`. + + + +
+ +e) If the following pop-up shows up click `OK`, and check status (upper right of the window). + + + +
+ +f) If you need to modify your profile after this, authenticate with the lock icon (top right of the page): enter your API secret. Then click on the hamburger menu and select `Profile Editor`. + + + +
+ +```{admonition} Privacy warning +:class: warning +Anyone with access to the URL of your Nightscout site, can view your BG and run reports of your data. It it strongly recommended that you enable [security](/nightscout/security) to your site once you're done with the setup +``` + +
+ +g) Dexcom Share users should see data flowing in after some minutes. +xDrip+ users (including Medtronic [CareLink followers](/uploader/setup.md#medtronic-carelink)) should setup the uploader as shown [**here**](/uploader/setup.md#xdrip). +xDrip4iOS users [here](https://xdrip4ios.readthedocs.io/en/latest/connect/cgm/#nightscout-upload). +[AAPS](https://androidaps.readthedocs.io/en/latest/Configuration/Preferences.html#nsclient) and [Loop](https://loopkit.github.io/loopdocs/operation/loop-settings/services/): consult the relative documentation. + + + +
+ +------ + +You have completed a new Nightscout site creation. You can continue [here](/nightscout/discover) now. + +The following section provides more information that you might not need to use now. + +------ + +
diff --git a/_sources/nightscout/github.md.txt b/_sources/nightscout/github.md.txt new file mode 100644 index 00000000..a8611182 --- /dev/null +++ b/_sources/nightscout/github.md.txt @@ -0,0 +1,36 @@ +--- +orphan: true +--- + +# GitHub + +You will need your own GitHub account if you want to deploy Nightscout in some platforms (check below). + +````{tab-set} + +:::{tab-item} Select your platform -> +
+::: + +:::{tab-item} Heroku/Railway/Northflank +You need your own GitHub account and `cgm-remote-monitor` fork (copy). +::: + +:::{tab-item} Fly.io +A GitHub account and `cgm-remote-monitor` fork (copy) is not mandatory but it is recommended. +::: + +:::{tab-item} Google Cloud (xDrip+ script) +You don't need a GitHub account. +::: + +```` + +
+ +## Create a GitHub account + +```{include} /vendors/github/create.md +``` + +
diff --git a/_sources/nightscout/ifttt.md.txt b/_sources/nightscout/ifttt.md.txt new file mode 100644 index 00000000..68f766c2 --- /dev/null +++ b/_sources/nightscout/ifttt.md.txt @@ -0,0 +1,200 @@ +# IFTTT Integration + +If This, Then That (IFTTT) is a useful Nightscout integration. By using IFTTT, you can have single button presses on your iPhone that will set an override, log a cannula change, log a sensor change and much more. + + +## Step 1: Get your API Secret Hash + +First we need to gather one thing called your "hashed API Secret". In your internet browser, open a "console" window while viewing your Nightscout site. Make sure you have "authenticated" your site by using your API secret in the Nightscout settings area (hint: if you see a little padlock in the upper left corner of the site, you haven't authenticated it). Refresh the site and your hashed secret key will be shown as "apisecrethash: "xxxxxxxxxx..."" + +**For Safari users on Mac**, you can open the console window by selecting "Develop" from the Safari top menu, and then "Show Page Source" (if you do not see "Develop" in the top menu, activate it by going to Safari > Preferences... > Advanced, and checking the "Show Develop menu in menu bar" option). If you're having problems seeing the apisecrethash, click the little grey triangle next to the "status isAuthenticated" line and the objects below it will display (see screenshot). Your hashed API secret can be copied and pasted from that line, as shown below. Save that somewhere easy to get to again, because you will be using it later. + + + +**For Chrome users**, the console window is found through the View >> Developer >> View Source. Click on the Console tab and scroll to find the "status isAuthenticated" row to find your apisecrethash. Copy your API hash to somewhere you can retreive it again, we will be copy/pasting it in Step 2. + + + + +## Step 2: Create your "Applets" + +IFTTT calls their little actions that you'll create an "applet". I have no idea why. But, I will go along and use their terminology so we are all consistent. We are basically interested in creating applets that will be buttons on your phone to do cool things in Nightscout. So, you'll have a button that will log when you changed your sensor last...letting you see in Nightscout easily just how old a sensor is at any given time. Or you can create a button that will turn on an "exercise" override that you already programmed into your kid's Loop app. So, let's make our first applet (aka button). + +* Get an [IFTTT account](https://ifttt.com/join) + + + + + +* Login to your IFTTT.com account and select click [this link](https://ifttt.com/create) to get to the page for creating your first "New Applet". (You can also get to this Applet creation page by selecting your Account icon in the upper right of the IFTTT website, then clicking on "Create".) + +* In the screen that appears, click on the black "+this" part of the screen + + + + + + +* In the next screen, type "button" in the search field and then click on the red box labelled "ButtonWidget" + + + + + + +* Connect the button widget by clicking on the large black"connect" button twice, once on the main screen and then second on the pop-up window that will appear immediately after that. (You will only have to "connect" the widgets for the first applet you make. After that the widgets will already connected to your IFTTT account.) + + + + + + +* Click on the large red "button press" box + + + + + +* Click on the black "+that" text + + + + + + +* Enter "Webhooks" in the search field and click on the Webhooks app + + + + + + +* Connect the Webhooks app + + + + + +* Select the blue "Make a Web Request" box + + + + + +* Now you will have a blank web request template to complete. Screenshot below is an example of a completed recipe for eating soon IFTTT action. There are four parts you will need to fill in, and they are described below the screenshot. + + + +```{danger} URL +`https://yoursite.platform.fqd/api/v1/treatments.json`
(for all IFTTT recipes that are NOT remote overrides...so things like cannula changes, sensor changes, pump battery changes, etc.)

+ Change the your URL to your actual site's info. +``` + +```{warning} Method +The method will be `POST` +``` + +```{hint} Content Type +The content type will be `application/json`. +``` + +```{danger} Body +The content of the body will depend on the action that you would like this particular button press to perform. While many recipes are available, any recipe that log carbs to NS will only display the carbs in Nightscout...Loop will not "use" those carbs in treatment or prediction math. The display of carbs in NS though may still be helpful for remote care givers to leave an indication that a low is being noticed and treated. Some sample content for actions that may be useful in Loop:

+ **Pump Site Change**
+ {"enteredBy": "IFTTT-button", "eventType": "Site Change", "duration": 0, "secret": "your_hashed_api_goes_here!!!"}

+ **CGM Sensor Start**
+ {"enteredBy": "IFTTT-button", "eventType": "Sensor Start", "duration": 0, "secret": "your_hashed_api_goes_here!!!"}

+ **Note**
+ {"enteredBy": "IFTTT-button", "eventType": "Note", "notes": "Hi mom, please don't text me for a bit. I'm taking a test.", "secret": "your_hashed_api_goes_here!!!"}

+``` + +```{warning} Special note for IFTTT to set a Remote Override with dev branch +Triggering a remote override with IFTTT takes a couple considerations;

+1. You have followed [the directions for setting up remote overrides](https://loopkit.github.io/loopdocs/nightscout/remote-overrides/) in Nightscout already.

+2. Remote overrides will use **`https://yoursite.herokuapp.com/api/v2/notifications/loop`** for the URL line of the applet. Notice that is different from the other type of applets' URL.

+3. The Body message of the applet needs to match the override already programmed in Loop app; the reason, reasonDisplay, and duration all need to match what is preset in your Loop app. The "duration" is giving in minutes in the body message (vs hours in Loop), and if the override is one that is "enabled indefinitely" then the duration is "infinite". The "reason" is the name of the override but NO EMOJI, and the "reasonDisplay" is the override name with the emoji. Check out the samples Body messages for overrides below. You will have to edit your body messages to match your reason and reasonDisplay. The target range and duration of the override does not need to be specified.

+**Body message for override named "hormones"**
+{"eventType": "Temporary Override", "reason": "hormones", "reasonDisplay": "🧟‍♀️ hormones", "secret": "your_hashed_api_goes_here!!!"}

+**Body message for override named "running"**
+{"eventType": "Temporary Override", "reason": "running", "reasonDisplay": "🏃‍♀️ running", "secret": "your_hashed_api_goes_here!!!"}

+**Body message for override named "Low Treatment"**
+{"eventType": "Temporary Override", "reason": "Low Treatment", "reasonDisplay": "🍬 Low Treatment", "secret": "your_hashed_api_goes_here!!!"}

+**Body message to cancel any override**
+{"eventType": "Temporary Override Cancel", "secret": "your_hashed_api_goes_here!!!"}

+``` + + +* Click the `Create Action` button on the bottom of the screen when you finish. + +* Now is your chance to change the title of your applet now to something meaningful. You can turn on notifications, too, using the slider shown. If you turn on the notifications, you will get an alert on your phone and pebble watch when the button press has been successfully deployed. Finish the IFTTT button by clicking on the Finish button that appears. + + + + + +* Repeat the setup for new applets for as many automated actions/overrides as you would like to setup. + + + + + +## Step 3: Enable IFTTT in your Nightscout site + +Now that we have cool applets made, we need to give Nightscout some information so that it will accept commands from our applets. It's pretty simple to do...just a couple additions to your Heroku settings. + +* Find your Maker Key by going to your IFTTT account icon in upper right corner, choose "My services" and then click on the Webhooks service, settings. + +******** + + + + +* You will see your Maker Key as the last part of the URL after the `use/`; copy and paste that last part (the red circled part as shown) + + + + + +* Login to your Nightscout site host (azure or heroku) and (1) add your Maker Key to the MAKER_KEY line and (2) add "maker" to your ENABLE line. + + + + + + + + + +## Step 4: Install IFTTT app on your iPhone/Android + +Now that all the hard work is done, we can take easy street and just add that work to the phone via the IFTTT app. By accessing the IFTTT widget on your iPhone, you'll be able to easily and quickly access the useful buttons you've just created. + +* Download the IFTTT app on your phone and log in using your IFTTT account. + +* For iPhone users, if you swipe right from your iPhone's home screen, you will have the Today view showing. Scroll to the bottom, click "edit". This should show a list of existing widgets, followed by a list of "more widgets" with green + signs. Click on the IFTTT's green circle and the widget will be moved to the top, active widgets area. You can hold your finger on the three left lines of the IFTTT widget row to drag it to the top of your widget panel, if you prefer to have it as the top-most widget. + + + + + +If you end up with more than four IFTTT applets, they will appear in reverse-order of when they were created...which may not be the same as you'd prefer them to appear on your widget bar. If you'd like to reorder them: + + * go into your iPhone's IFTTT app + * click on My Applets + * click on the gear icon in upper left of screen + * click on Widgets + * click on the pencil icon in upper right of screen + * click and hold the three lines that appear on the right side of the widget that you want to move. Drag the widget to the order in the list that you'd like it to appear in your widget quickscreen. + + + + + +## Extra Credit: Alexa integration +* Since you have IFTTT/Maker requests working, you can get it to work with anything that supports IFTTT, including Alexa. You will need to add "alexa" to your ENABLE line in your Heroku settings. And then repeat the steps above, but instead of using "ButtonWidget" service we started with earlier (the "+if" part of the setup)...you will use the "AmazonAlexa" service. + + + + + + * Alexa requests do not need underscores, FYI. diff --git a/_sources/nightscout/multiadmin.md.txt b/_sources/nightscout/multiadmin.md.txt new file mode 100644 index 00000000..489485a0 --- /dev/null +++ b/_sources/nightscout/multiadmin.md.txt @@ -0,0 +1,231 @@ +# Multiple sites and support + +
+ +You might need to have access to multiple accounts without having to juggle between logins and passwords. Below are described some centralizing methods reducing the administrative burden. + +
+ +## Remote support and security + +Giving username and passwords to someone in order to obtain help to fix Nightscout raises serious security issues. Malicious code can be added to your Nightscout project by ill-intentioned people. Always make sure the version deployed is a fork of the official project. After receiving help, good practice is to change your passwords (if shared) and your API secret. + +When possible prefer inviting collaborators (see below) and remove them once the issue is fixed. + +
+ +## Github + +You need only one Github account since you can connect multiple web apps to the same GitHub account. + +Using this strategy you only need to update one GitHub account when a new Nightscout version is released and you will be able to deploy it in all your web apps. + +```{hint} +If you have several web apps connected to the same GitHub repository you must use the [standard update method](/update/update/). +**Not redeploy** (else you'll break all the links to the repository). +``` + +
+ +### Enable automatic deploys in Heroku + +Automatic deploys will allow you to update automatically your Heroku apps when you update the GitHub repository: you will not need to login into Heroku and perform Manual Deploy, as soon as a new version will be merged into GitHub an automated deploy will trigger in all enabled Heroku apps. + +- To enable automatic deploy, [log in Heroku](https://dashboard.heroku.com/apps/) and select your app, then `Deploy`. Verify GitHub and your `cgm-remote-monitor` app are connected. + + + +
+ +- Verify the `master` branch is selected and click `Enable Automatic Deploys`. + + + +
+ +- Your Heroku site will update automatically every time you update the GitHub repository. + + + +
+ +### Automatic deploys in Railway and Northflank + +You don't need to do anything as all your web apps will upgrade automatically when you upgrade GitHub. + +
+ +## Heroku + +You can setup multiple Nightscout sites per Heroku account. You be charged the Eco/Basic plan fee for **each app**. + +You can setup collaborators in Heroku. This is very useful for remote support. + +
+ +### Invite someone as a collaborator + +- Log into your Heroku account and select your app. + + + +
+ +- Select `Access`. + + + +
+ +- Click `Add collaborator` and enter the email address of the person supporting you (that is the email address he used to setup his own Heroku account). + + + +
+ +- You will now see it as a collaborator. Using the pen icon you can modify it or delete it (useful when asking for support, once everything is working). + + + +
+ +### Being a collaborator + +*Note: you will receive an email with the invitation.* + +- Log in your Heroku account. You will see the apps you are collaborating to in the same list than your primary app. You can now perform most tasks directly in that one Heroku account (deploys, change variables, ...). + + + +
+ +## Atlas + +You can invite another user in your organization in order to manage several organizations from the same Atlas account. This is very useful for remote support. + +### Invite another user + +[Log into](https://account.mongodb.com/account/login) your Atlas account. + +
+ +- Top menu, click `Access Manager` and select `Organization Access` from the drop down menu + + + +
+ +- Click `Invite Users` + + + +
+ +- Enter the email address of the person supporting you (that is the email address he used to setup his own Atlas account). + + + +
+ +- Select `Organization Owner` then click `Invite to Organization`. + +```{warning} +**Make sure you enable `Organization Owner` for the invited user!** +``` + + + +
+ +### Being invited + +*Note: you will receive an email with the invitation.* + +- Log in your own Atlas account. + +- Top left, from the drop down menu click the caret and select `View all Organizations` + + + +
+ +- In the left menu, click `Invitations` then click `ACCEPT` the invitation. + + + +
+ +- Going back to all your organizations you can now see and administer both of them from this account. In the example below `Nightscout` is your own organization and `My Org 2020-09-20` is a guest organization. + + + +
+ +```{hint} +You can rename your organizations from the top left cog (Settings) then clicking the pen icon. +``` + + + +
+ +## Northflank + +You can setup two Nightscout sites per Northflank account. The 20$ per month credit applies. + +You can setup teammates in Northflank. + +
+ +### Invite a teammate + +- Log into your Northflank account and select `Overview`, in `Members` click **`+`** to add a teammate. + + + +
+ +- Enter the email address of the person supporting you (that is the email address he used to setup his own Northflank account). Add `Admin` privileges if you want him to interact with your data, leave `Default` for an observer. + + + +
+ +- You can manage teammates in `Members`: change privileges and delete them, or revoke invitations. + +
+ +### Being invited + +You will receive an email with the invitation. + +You will see the invitee project with yours. + +
+ +## Railway + +- Open your Railway [dashboard](https://railway.app/dashboard) and select your project. + + + +
+ +- Top right select `Settings` and `Members`. +- Enter the email address of the person supporting you (that is the email address he used to setup his own Railway account). Select `Can Edit` privileges if you want him to interact with your data, leave `Can View` for an observer. + + + +- Confirm the invite with `Invite to project`. + + + +
+ +### Being invited + +You will receive an email with the invitation. + +You will see the invitee project with yours. + +
diff --git a/_sources/nightscout/new_user.md.txt b/_sources/nightscout/new_user.md.txt new file mode 100644 index 00000000..b402f6f8 --- /dev/null +++ b/_sources/nightscout/new_user.md.txt @@ -0,0 +1,96 @@ +# New Nightscout Users + +*"What is great is there will be multiple options for those interested in setting up the system! #wearenotwaiting" J.A.* + +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](project:/index.md#nightscout-as-a-service). +``` + +```{admonition} Confusing? +:class: hint +**[Need help to choose? +Try the wizard](wizard)**. + +``` + +## Basic concepts + +Even if knowing how it works is not mandatory, it is very useful to understand a few background concepts before starting DIY Nightscout. + +1. The **code** available open source in [GitHub](https://github.com/nightscout/cgm-remote-monitor) or packaged for you in [Docker](https://hub.docker.com/u/nightscout) is the set of instruction that will be used to make your Nightscout. You don't need to understand it or be a programmer to use it. +2. Your Nightscout will usually be running a **web application** in the internet cloud, meaning that somewhere on the planet, a computer or another will spend some of its time to keep your Nightscout active. This is the engine of Nightscout: it will make sure to be ready to accept the data you will send to it (BG, treatments, ...) or to answer to data requests when you ask them (BG, reports, ...) and even send alarms when instructed to do so. You will not see the engine work but you will see its frontpage: the web URL of your Nightscout site, which will be available on any device connected to the internet. +3. Since you will need to store a lot of data, Nightscout must have a **database**. This database will also be in the cloud, meaning data will be stored on one or more computers, somewhere. The Nightscout engine mentioned above will store and read data from this database whenever required. + + + +**From this you understand there are three main pieces necessary to build your Nightscout:** + +1. **The Nightscout code also known as cgm-remote-monitor** +2. **A cloud platform running the Nightscout web app** +3. **A cloud database storing Nightscout data** + +Some platforms offer both engine and database like Azure, Railway, Northflank and all VPS servers. But you can use an external database if you want. Some others like Heroku or Fly.io don't propose a database and require you to use an external one. Traditionally the database holding Nightscout data is hosted by another provider (mLab, now MongoDB Atlas) but it might not be the most reliable solution. + +
+ +## Building Nightscout DIY in a cloud platform + +You can run your Nightscout site in several vendors platforms, using free or paid accounts. Try the [wizard](wizard) to see which options can match your needs. + +Below is a list of most used platforms. There are probably others, don't hesitate to [open an issue in the documentation](https://github.com/nightscout/nightscout.github.io/issues) with the easiest deployment method if you want to see them named here. + +
+ +## Vendors comparison table + +```{note} +Hosted services include everything: platform, database and support. +``` + +[T1Pal](https://t1pal.com/), [NS10BE](https://ns.10be.de/de/index.html), [Nightscout Pro](https://nightscout.pro/), [Serendipity Bio](https://serendipitybio.com/), [Nightscout4u](https://www.nightscout4u.com/) + + + +
+ +## Free DIY + +These are the current solutions not involving, or limiting to a strict minimum, costs. + +```{note} +Most vendors will require a credit card to authenticate users and avoid abuse. +``` + +[Azure](/vendors/azure/new_user), [Northflank](/vendors/northflank/new_user), [Fly.io](/vendors/fly.io/new_user), [Render](/vendors/render/new_user), [Atlas](/vendors/mongodb/atlas), [Google Cloud](https://navid200.github.io/xDrip/docs/Nightscout/GoogleCloud.html), [Oracle](https://www.dropbox.com/s/5twlqrndofqno0t/0-amber-oracle.pdf) + + + +
+ +## Paid DIY + +These solutions require a monthly fee. + +```{note} +Paying for a platform doesn't imply your database is included and covered by the plan. +``` + +[Heroku](/vendors/heroku/new_user), [Railway](/vendors/railway/new_user) with [database](/vendors/railway/database), [Northflank database](/vendors/northflank/database) or [NAS](nas) + + + +
+ +## Security and safekeeping + + +- Do not use the same password for all your accounts, and choose passwords that are not easy to guess. +- Do not use the `API_SECRET` for the Atlas database password. +- Do not use your Dexcom or CareLink user name or password for Nightscout components. +- Do not share the `API_SECRET` or other passwords of your accounts to others. +- Do not use Nightscout or any related applications on rooted and/or otherwise compromised devices, and ensure you always have the latest operating system and virus protection updates installed. + +If you want to read more about Nightscout security, including about additional configuration options to make your installation more secure, please check our [security guide](/nightscout/security.md). + +
diff --git a/_sources/nightscout/platform.md.txt b/_sources/nightscout/platform.md.txt new file mode 100644 index 00000000..288b11a0 --- /dev/null +++ b/_sources/nightscout/platform.md.txt @@ -0,0 +1,159 @@ +# Choose your platform + +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +Various platforms are available to host your Nightscout site in the cloud. + +```{warning} +**Creating a [database](/nightscout/database) is mandatory if you want to use: Heroku, Railway, Northflank, Fly.io or Azure.** +Make sure you have one before creating a Nightscout web app in these platforms. +``` + +Find a list of commonly used hosting services below, decide which one you'll want to use. + +
+ +```{card} +## Heroku +![Heroku Eco](/vendors/img/Heroku.png) +^^^ +Since the [beginning](https://github.com/nightscout/cgm-remote-monitor/pull/98) Heroku has been a very popular platform for Nightscout. Most of the documentation was based on a Heroku Nightscout. +On August 25th 2022, Salesforce decided to [drop the free plan](https://blog.heroku.com/next-chapter). +You can [create your new Nightscout site with Heroku](/vendors/heroku/new_user) using an [Eco plan](https://www.heroku.com/pricing) (5$/month). + +**Pros**: +* Large platform with a reliable history +* Well documented, well known by the community + +**Cons**: +* The Eco plan has the same limitations than the previous Free plan, for 5$ per month +* For a Nightscout site a 7$ per month Basic plan is not really worth it (compared to hosted solutions) +* **Doesn't include a database** + ++++ +Follow [these instructions](/vendors/heroku/new_user.md) to build your Nightscout site in Heroku. +``` + +```{card} +## Azure +![Azure](/vendors/img/Azure.png) +^^^ +Nightscout DIY was [originally](https://github.com/rnpenguin/cgm-remote-monitor) created with Azure but most users dropped it after costs increased. +A new deployment method fitting in the [free tier](https://azure.microsoft.com/en-us/pricing/free-services) has [been created using a Docker container](/vendors/azure/new_user). + +**Pros**: +* Large platform with a reliable history +* Well known by the community IT specialists +* Using a basic plan and free services keep it free + +**Cons**: +* Trial account lasts maximum 12 months +* Basic plan and pay as you go is free if you stay within quotas +* The F1 free app service plan is designed for testing, not production +* **The Cosmos database doesn't integrate correctly with Nightscout** + ++++ +Follow [these instructions](/vendors/azure/new_user.md) to build your Nightscout site in Azure. +``` + +```{card} +## Railway.app +![Railway](/vendors/img/Railway.png) +^^^ +You can easily create a new Railway Nightscout site with a MongoDB Atlas or a Railway MongoDB database. The [Hobby plan](https://railway.app/pricing) (5$ per month) allows one Nightscout site and a small database. + +**Pros**: +* Easy to deploy or migrate an existing site from Heroku (but not worth it without free tier) +* Simple to use and troubleshoot +* Can use a reliable native Railway MongoDB database, the cost will add-up within the subscription ($) + +**Cons**: +* The free tier has been removed, only active developers can have 5$ credit per month +* The railway.app domain is blocked for safety by some companies +* Railway network model causes issues with some follower app and devices + ++++ +Follow [these instructions](/vendors/railway/new_user.md) to build your Nightscout site in Railway. +``` + +```{card} +## Northflank +![](/vendors/img/Northflank.png) +^^^ +You can create your new [free](https://northflank.com/pricing) Northflank Nightscout site, with its own Northflank database or with a MongoDB Atlas database. + +**Pros**: +* Nightscout fits in the free tier +* Easy to deploy or migrate an existing site from Heroku +* Simple to use and troubleshoot +* Can use a professional native Northflank MongoDB database ($) + +**Cons**: +* The Nightscout address generated for your site is impossible to remember + ++++ +Follow [these instructions](/vendors/northflank/new_user.md) to build your Nightscout site in Northflank. +``` + +```{card} +## Fly.io +![Fly.io](/vendors/img/Fly.io.png) +^^^ +Fly.io proposed a simple migration wizard from Heroku and you can create your new Nightscout site in Fly.io. Using a computer is mandatory with Fly.io as managing your site will require the use of a command line utility. Not recommended for beginners. + +**Pros**: +* Nightscout fits in the free tier +* Easy to migrate an existing site from Heroku + +**Cons**: +* **Maintaining your site requires the use of command line instructions, not very intuitive** +* **Doesn't include a database** + ++++ +Follow [these instructions](/vendors/fly.io/new_user.md) to build your Nightscout site in Fly.io. +``` + +```{card} +## Google Cloud +![xDrip+](/vendors/img/GoogleCloud.png) +^^^ +A scripted Nightscout installation in Google Cloud is a new complete solution proposed by the xDrip+ developers team. Whilst deploying Nightscout manually in Ubuntu can be complex, their approach makes is rather simple for non-technical people. + +**Pros**: +* Complete solution offering a large free database +* A web interface to edit your variables +* Tools provided to migrate the database from another platform +* Virtually free (<5c/month) + +**Cons**: +* Not available for free for Australia and Cina users +* Relying on a free DNS provider + ++++ +Follow [these instructions](https://navid200.github.io/xDrip/docs/Nightscout/GoogleCloud.html) to build your Nightscout site in Google Cloud. +``` + +```{card} +## Render +![xDrip+](/vendors/img/Render.png) +^^^ +A free solution with little experience. + +**Pros**: +* No credit card required + +**Cons**: +* The free plan doesn't guarantee any reliability +* App will sleep after 15 minutes +* Render URLs are considered unsafe by some internet providers +* **Doesn't include a database** + ++++ +Follow [these instructions](/vendors/render/new_user.md) to build your Nightscout site in Render. +``` + diff --git a/_sources/nightscout/plugins-old.md.txt b/_sources/nightscout/plugins-old.md.txt new file mode 100644 index 00000000..dfb08c82 --- /dev/null +++ b/_sources/nightscout/plugins-old.md.txt @@ -0,0 +1,4 @@ +--- +orphan: true +--- + diff --git a/_sources/nightscout/plugins-v15.md.txt b/_sources/nightscout/plugins-v15.md.txt new file mode 100644 index 00000000..1adfd179 --- /dev/null +++ b/_sources/nightscout/plugins-v15.md.txt @@ -0,0 +1,68 @@ +--- +orphan: true +--- + +# [Nightscout-connect](https://github.com/nightscout/nightscout-connect) + +As the dependencies of the historical plugins (`bridge` and `mmconnect`) have been deprecated, a new plugin has being created to allow long term sustaining and increase the number of supported cloud providers. + +This plugin is under test and is currently only available in the `dev` branch of Nightscout ([version 15.0](https://github.com/nightscout/cgm-remote-monitor/tree/dev)). + +## Prerequisites + +You need to use the development branch of Nightscout. + +```{admonition} AAPS users +:class: warning +Do not upgrade Nightscout to V15 unless you use the `dev` version of AAPS. +``` + +Follow [these guidelines](/update/dev_branch) to update your Nightscout app to `dev`. + +
+ +In order to enable the `nightscout-connect` plugin you need to add `connect` in your ENABLE variable. + +Edit your variables following [these instructions](/nightscout/setup_variables.md#nightscout-configuration), search the `ENABLE` variable, modify its contents to add the word `connect`, separated by a space, at the end of the line. + +
+ +## `dexcomshare` + +`dexcomshare` is the replacement of `bridge`. + +In order to use it you need to add the following variables in your [Nightscout configuration](/nightscout/setup_variables.md#nightscout-configuration): + +Remove the word `bridge` from the `ENABLE` variable list. + +`CONNECT_SOURCE=dexcomshare` + +`CONNECT_SHARE_SERVER=ous` Add this variable **only** if you're not in the US. **Else don't add it (us).** + +`CONNECT_SHARE_ACCOUNT_NAME=` The username on your master device (the one connected to the sensor) + +`CONNECT_SHARE_PASSWORD=` The password matching the username above. + +
+ +## `minimedcarelink` + +`minimedcarelink` is the replacement of `mmconnect`. + +In order to use it you need to add the following variables in your [Nightscout configuration](/nightscout/setup_variables.md#nightscout-configuration): + +Remove the word `mmconnnect` from the `ENABLE` variable list. + +`CONNECT_SOURCE=minimedcarelink` + +`CONNECT_CARELINK_REGION=us` or `eu` Match the area with minimed.carelink.**eu** or .com (i.e. **us**) + +`CONNECT_CARELINK_USERNAME=` The username on your master device Minimed app + +`CONNECT_CARELINK_PASSWORD=` The password matching the username above. + +If you are caregiver of more than one patient also add: + +`CONNECT_CARELINK_PATIENT_USERNAME=` The name of the patient whom data you'll want in Nightscout. + +
diff --git a/_sources/nightscout/profile_editor.md.txt b/_sources/nightscout/profile_editor.md.txt new file mode 100644 index 00000000..7b483c5a --- /dev/null +++ b/_sources/nightscout/profile_editor.md.txt @@ -0,0 +1,67 @@ +# Setup your Profile + + + +The top part will show your site settings: [`Title`](/nightscout/setup_variables.md#custom_title-nightscout), [`Units`](display-units) and [`Date Format`](/nightscout/setup_variables.md#time_format-12). + + + +
+ +## Profile view + +Profile Editor will display your active profile. If you created more than one profile you can select the one you want with the drop down menu `Stored Profiles`. + +You can add a profile with `+`, delete it with `X` and duplicate (clone) it to create a new one starting with the values in the current one. + +Note: changing profile selection keeps the modifications you've made in other profiles. + + + +
+ +Each profile has a `Name`, a `Timezone` and a `DIA` that you can modify. If you don't know which DIA to use, ask you endocrinologist since this is a complex subject. See also [here](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4454113/). + + + +
+ +For each profile you can define `Insulin to carb ratio (I:C)`, `Insulin sensitivity factor (ISF)` and `Carbs absorption rate`. Both `I:C` and `ISF` can be defined for specific times of the day by slices of 30 minutes, click the `+` sign to add another interval. + +These values are key to diabetes management. Ask your endocrinologist about them if you don't know where to start. + +Look [here](https://diyps.org/2014/05/29/determining-your-carbohydrate-absorption-rate-diyps-lessons-learned/) for calculating the carbs absorption rate. + + + +
+ +If your uploader doesn't send pump `basal` values to Nightscout, you can duplicate the information in `Basal rates` in order to match your current basal profile (and Nightscout is also a nice place to save this information). Basal rates can be defined by 30 minutes intervals, click `+` to add another one . + + + +
+ +You can also define your `Target BG range` Low and High for various moments of the day. + + + +
+ +After you defined your profile you need to `Authenticate` with your API Secret in order to be able to save it. + +For modifications, read the next paragraph and make sure you understand the `Database records` mechanism. + + + +
+ +## Modifying a profile and Database records + +When you modify a profile and save it, the whole database record will be updated to reflect the profile change. This means all periods of time using this specific profile since the database record `Valid time and date` will be updated to your profile modification. If you don't want this to happen, you should create a new database record and recreate your profiles in this new record. + +You can add a record with `+`, delete one with `X` (it will delete the corresponding profiles information in the time frame of the record) and duplicate (clone) it. + + + +
\ No newline at end of file diff --git a/_sources/nightscout/pushover.md.txt b/_sources/nightscout/pushover.md.txt new file mode 100644 index 00000000..3c3ec8c0 --- /dev/null +++ b/_sources/nightscout/pushover.md.txt @@ -0,0 +1,349 @@ +# Remote notifications + +While Loop app currently sends notifications locally on Loop user's iPhone, parents and caregivers likely want those messages on their phones, too. We can achieve this functionality through a combination of Nightscout, IFTTT, Google, and Pushover. + +Traditionally, most people may already know of Pushover alerts through their NS site. The old Loop docs had set up for how to add your `PUSHOVER_ANNOUNCEMENT_KEY` , `PUSHOVER_API_TOKEN`, and `PUSHOVER_USER_KEY` in your Heroku settings to get notifications on the non-looping phones of parents and caregivers. The drawback for that method is that you could not necessarily fine-tune the alerts (maybe you wanted battery alarms on your NS website, but not get pushovers for them...a bit hard to separate out the environments that way) and Pushover had a demanding acknowledgment requirement. If you failed to acknowledge an alert, you may end up getting alarm fatigue fairly quickly as the alarm repeated itself. + +Using Pushover **THROUGH** IFTTT however, we can improve the possible notifications and who receives which ones. For example, a teenage Looper may want notifications when his/her pump site needs changing and when his/her Dexcom is about to expire in the next day. S/he already gets local notifications on his/her phone via Loop for low reservoir volumes, low pump battery, and Loop failures. Dexcom app provides high/low BG notifications locally, too. If s/he were to get those same alarms via Pushover, s/he would inevitably get alarm fatigue. A remotely-monitoring parent may want additional information, like a pushover alert when the school nurse boluses for lunch, as well as Loop failures, low iPhone battery level for the child, low pump battery, and other such information that might be useful. Perhaps there's also an emergency contact person that you only want to get high/low BG alerts...you can set that up as well quite easily. + +The basic concept is that NS puts out an event that triggers the IFTTT service called Webhooks (old name was "Maker Webhooks" hence you may see references to "maker" in NS docs). Actually, there are several types of events that NS has programmed in all ready to use in IFTTT. + + + + + +For this setup, we are going to use the most general logging event called `ns-event`. You'll get all the alarms and notifications logged, and then you can decide in subsequent steps which ones you'd actually like to send to your phone for pushover notification. + +As a brief roadmap for what we are going to do: + +1. Get necessary accounts setup +2. Add a folder to your Google Drive +3. Make an IFTTT applet to log NS events to your Google Spreadsheets +4. Enable NS to work with that new IFTTT applet +5. Make an IFTTT applet to send Pushover alert when the Google Spreadsheet is updated + +## Get Prepped + +If you don't already have these steps done, you will need them. Skip any that you already have done. + +* Setup a Nightscout site +* Get an [IFTTT account](https://ifttt.com) +* Get a [Pushover Account](https://pushover.net) +* Get a [Google Account](https://accounts.google.com/SignUp) +* Download the Pushover app onto your phone, and any other phone you'd like to receive Pushover alerts +* Download the IFTTT app onto your phone, and any other phone you'd like to use IFTTT applets on +* Login to the Pushover and IFTTT apps with your login information + +## Add a Google Drive folder + +* Login to your Google account and select Google Drive + + + + + +* Click on the blue "New" button and create a new folder named IFTTT. + + + + + +* Double click on the newly created IFTTT folder, select the blue "New" button again, and create a new subfolder called "Nightscout-Alarms" + + + + + +This IFTTT/Nightscout-Alarms folder will eventually contain numerous Google Spreadsheets, one for each NS alarm or information that is logged. As new alarms are triggered, the IFTTT applet we are about to write will add a row to the appropriate spreadsheet logging the time of the alarm and any other reported details that go with the entry. For now though, your drive will be blank...screenshot below just to give you an idea of where we are going. + + + + + +## Make 1st IFTTT Applet to Log NS Alarms + +* Login to your IFTTT.com account and select the "New Applet" button. + + + + + +* In the screen that appears, click on the blue "+this" part of the screen + + + + + +* In the next screen, type "webhooks" in the search field and then click on the blue connect button + + + + + +* If this is the first time you are using IFTTT Webhooks service, you will have a "Connect" button to select. If you already have IFTTT applets using Webhooks, you won't see this screen...just move to the next bullet. + + + + + +* Click on the "receive a web request" blue box, and then fill in the Event Name as `ns-event` and then press the "Create trigger" button. (Side note: the event name used here corresponds to the triggers discussed above for core events that NS already has integrated for IFTTT users. If you want to, instead, use the other triggers such as ns-warn or ns-urgent, you can. This example is using the most general trigger so that the options are wider for most users.) + + + + + +* Click on the blue "+that" text + + + + + +* Enter `google` in the search field and click on the Google Sheets icon + + + + + +* Select the green "Add row to spreadsheet" box + + + + + +* Delete the contents of the "Spreadsheet Name" and "Drive folder path". For the "Spreadsheet Name", click the "Add Ingredient" button and select the "Value1". For the "Drive folder path", enter `IFTTT/Nightscout-Alarms`. You do not have to modify the "Formatted row" box's contents. Click the "Create action" button at the bottom. + + + + + +* Turn off the toggle for receiving notifications when the applet runs, and then click the Finish button + + + + + +* You'll now have the finished IFTTT applet that will cause a row to be added to a Google spreadsheet...tracking all your NS notifications and alarms. If it is the first time that alarm has been logged, the applet will also create the spreadsheet itself. After a while, your IFTTT/Nightscout-Alarms folder will start to look like the screenshot posted above with numerous spreadsheets for each alarm type. + + + + + +## Enable IFTTT Webhooks in your Nightscout site + +```{note} +If you already have created IFTTT buttons previously to work with your NS site, you can skip this section. If those buttons are working, then you've already added your MAKER_KEY and "maker" to your ENABLE line in Heroku. +``` + +* To actually make that first applet work, we need to enter a "Maker Key" to get NS and IFTTT talking to each other. Find your Maker Key by going to your IFTTT account, Services and then clicking on Webhooks. (Your screen may not have as many services showing; the example account below just happens to already use several services.) + + + + +******** + + + + +* You will see your Maker Key as the last part of the URL; copy that last part (the red circled part) + + + + + +* Navigate to your Heroku account's settings tab, "reveal config vars" and (1) add your Maker Key to the MAKER_KEY line and (2) add "maker" to your ENABLE line. + + + + + + + + + +## Make 2nd IFTTT Applet to send Pushover notifications + +* In your IFTTT account, select the "New Applet" button. + + + + + +* In the screen that appears, click on the blue "+this" part of the screen + + + + + +* In the next screen, type "google" in the search field and then click on the "Google Sheets" logo. + + + + + +* Click on the "New row added to spreadsheet" as the trigger. + + + + + +* Enter the following information: Folder path is `IFTTT/Nightscout-Alarms` and for the filename you are going to enter the name of the particular NS alarm or information that you would like to get pushover alerts for. Click on the "Create trigger" button to save the trigger. + + + + +```{note} +This applet can't be created unless your filename (alarm spreadsheet) already exists. If your 1st applet we created above hasn't run for a long time, the spreadsheets may not exist yet because the alarms haven't triggered. You have two options...(1) manually create the file in your Google Drive so that you can finish the applet now or (2) wait several days/weeks for the alarms to happen and that will automatically create the files in your Google drive.

+If you choose option 1, here's a partial list of some of the filenames you could create in advance: +``` + + * Loop isn't looping + * Cannula age 48 hours + * Cannula age 72 hours + * Meal Bolus + * Warning, Pump Reservoir Low + * Warning Uploader Battery is Low + * Temporary Override + + Depending on your alert levels you specified in NS, some of the hours in the titles may vary to match your settings + +* Click on the blue "+that" text + + + + + +* Enter `pushover` in the search field and click on the Pushover icon. If this is your first time linking your IFTTT to Pushover, you will be prompted to enter your Pushover account login and allow IFTTT access. This only needs to be done once. + + + + + +* Select the "Send a Pushover notification" box + + + + + +* Delete the contents of the "Title" and "Message" and "URL" boxes. For the Title, click the "Add Ingredient" button and add `ColumnC`. For the "Message", click the "Add Ingredient" button and add the values of various columns from your spreadsheet for the information you would like to include. For the alerts: `ColumnC` contains the alarm name, `ColumnA` is the date/time of the alarm, and `ColumnD` has more detailed information about the info/alarm. This is a pretty decent recipe to follow to get the useful information in your notification. + + + + +* Select the "Message Priority" that you would like for this particular alarm type. + + + + + +* Select the "Device" that you would like to receive this particular alarm type. The devices listed will be all your devices that have Pushover app installed and logged into. Click "Create Action" when you are finished. + + + + + +* You'll now have made the IFTTT applet that will cause a Pushover notification to a particular device for a particular NS alarm, once the first applet records the alarm in the google spreadsheet. Keep the "receive notification when this Applet runs" toggled off and click the Finish button. + + + + + +## Revisit Nightscout Alert Levels + +Putting all these notifications together may cause you to want to revisit the alert levels you have set in your Heroku settings. Here's a short summary of NS for the looping-related alerts (Note: the last row, Upbat, is the Looping iPhone battery level for Loop users; or the rig's battery level for OpenAPS users.) If you'd like some of these alarms for your site and don't currently have them activated (they are all off by default unless specifically turned on), the lines you'd need to add are in the last column. If you like the default values of the WARN and/or URGENT, you don't have to add those extra lines...just the line to enable the alerts will be sufficient. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SETTINGDEFAULT
WARN
DEFAULT
URGENT
HEROKU
SETTINGS
CAGE4872CAGE_ENABLE_ALERTS = true
CAGE_WARN=XX
CAGE_URGENT=XX
SAGE164168SAGE_ENABLE_ALERTS = true
SAGE_WARN=XX
SAGE_URGENT=XX
IAGE4872IAGE_ENABLE_ALERTS = true
IAGE_WARN=XX
IAGE_URGENT=XX
LOOP3060LOOP_ENABLE_ALERTS = true
LOOP_WARN=XX
LOOP_URGENT=XX
OPENAPS3060OPENAPS_ENABLE_ALERTS = true
OPENAPS_WARN=XX
OPENAPS_URGENT=XX
PUMP_CLOCK3060PUMP_ENABLE_ALERTS = true
PUMP_WARN_CLOCK=XX
PUMP_URGENT_CLOCK=XX
PUMP_RES105PUMP_ENABLE_ALERTS = true
PUMP_WARN_RES=XX
PUMP_URGENT_RES=XX
PUMP_BATT_P3020PUMP_ENABLE_ALERTS = true
PUMP_WARN_BATT_P=XX
PUMP_URGENT_BATT_P=XX
PUMP_BATT_V1.351.30PUMP_ENABLE_ALERTS = true
PUMP_WARN_BATT_V=XX
PUMP_URGENT_BATT_V=XX
UPBAT3020UPBAT_ENABLE_ALERTS = true
UPBAT_WARN=XX
UPBAT_URGENT=XX
+ + +## Final notes + +* You can use other notification services than Pushover in the last part of the second applet. For example, you could use the SMS service to send text notifications to your iPhone instead of Pushover. The downside for that is that the SMS service is limited to 100 message each month...some users may exceed that pretty easily. Another alternative notification would be IFTTT's own Notification service. This would work well, but does not have the ability to distinguish between devices the way Pushover allows. If you use IFTTT's Notifications service, every phone using your IFTTT account will get the notices. + +* To be clear, you do **NOT** need to have pushover on your ENABLE line nor have `PUSHOVER_USER_KEY`, `PUSHOVER_API_TOKEN`, or `PUSHOVER_ANNOUNCEMENT_KEY` entered into your Heroku settings in order for any of the above to work. This is not the same Pushover as NS has integrated into its code. This is actually through IFTTT services, you just need a Pushover account to link to during the 2nd applet setup. + +* To create more notifications, simply repeat the steps for the 2nd applet you created, only this time use a new filename that corresponds to the spreadsheet tracking the alert you'd like notifications for. You'll end up with multiple applets of the dark blue type (the pushover notifiers) and only a single light blue (NS alarm general collector). + + + + + +* Here are examples of the Meal Bolus and Temp Basal ns-event logging spreadsheets + + + + + + + +* The 1st applet can only create up to 2000 active rows in a given spreadsheet. After that, the applet will automatically create a new spreadsheet. For most alarms, it may take quite some time to reach 2000 rows of info. For other alerts, such as temp basals being set, that may fill up rather fast for the average looper. You can either clean out the data rows periodically to make room, or update your filename in the 2nd applet periodically when a new spreadsheet is made. + diff --git a/_sources/nightscout/reports.md.txt b/_sources/nightscout/reports.md.txt new file mode 100644 index 00000000..7eb8a7c8 --- /dev/null +++ b/_sources/nightscout/reports.md.txt @@ -0,0 +1,217 @@ +# Create Reports + +Nightscout offers some fantastic data-crunching report tools in the drawer menu, + + + +
+ +An interesting video on how to use them [with Gary Scheiner](https://www.youtube.com/watch?v=hfzuFumN03o). + +
+ +Select `Reports` to open the reports page. + + + +
+ +First select the report type you'd like to see (see below for an overview). + +`Day to day`, `Week to week`, `Daily Stats`, `Distribution`, `Hourly stats`, `Percentile Chart`, `Weekly Distribution`, `Calibrations`, `Treatments`, `Profiles` or `Loopalyzer` + +Then select the period for which you want your data analyzed. + +Enable the check box and either select `From:` and `To: `dates or `Today`, `Last 2 days`, `Last 3 days`, `Last week`, `Last 2 weeks`, `Last Month`, `Last 3 months`. + + + +
+ +You can filter your data using key `Notes` or `Event type` (select one in the drop down list). + + + +
+ +You can select which week days to use in order to better analyze patterns. + + + +
+ +Confirm your `Target BT range` `bottom` and `top` for your TIR and graph range lines. + +You can also sort the report from older to newer or newer first. + + + +
+ +Click `SHOW` and wait for data to load and rendering to complete. This might take some time if the period is long. + + + +
+ +## Day To day + +This report will show your BG, day by day, including the treatments you select. + + + +
+ +If you want to change selections, you need to click again `SHOW` to update the view. + + + +
+ +If you select `Insulin distribution` you will get a short report. + +Note: You need `Basal rate` enabled to see bolus vs basal information. + + + +
+ +You can change the vertical scale to `Logarithmic` or `Linear`. + +You can change the graph `Size`. + + + +
+ +## Week to Week + +This report will give you a week by week view, with color code for week days selected. + + + +
+ +## Daily stats + +This report will give you a daily distribution view. + + + +
+ +## Distribution + +This report will give you a complete distribution view with a lot of information on the dates range you selected. + +You also can filter by hours (scroll to the bottom of the page). + + + + + +A1c is only a rough estimation that can be very inaccurate and does not replace actual blood testing. The formula used is taken from:Nathan, David M., et al. "Translating the A1C assay into estimated average glucose values." *Diabetes care* 31.8 (2008): 1473-1478. + +Time in fluctuation and Time in rapid fluctuation measure the % of time during the examined period, during which the blood glucose has been changing relatively fast or rapidly. Lower values are better. + +Mean Total Daily Change is a sum of the absolute value of all glucose excursions for the examined period, divided by the number of days. Lower is better. + +Mean Hourly Change is a sum of the absolute value of all glucose excursions for the examined period, divided by the number of hours in the period. Lower is better. + +Out of Range RMS is calculated by squaring the distance out of range for all glucose readings for the examined period, summing them, dividing by the count and taking the square root. This metric is similar to in-range percentage but weights readings far out of range higher. Lower values are better. + +GVI (Glycemic Variability Index) and PGS (Patient Glycemic Status) are measures developed by Dexcom, details [can be found here](https://web.archive.org/web/20160523152519/http://www.healthline.com/diabetesmine/a-new-view-of-glycemic-variability-how-long-is-your-line). + +
+ +## Hourly stats + +This report will give you an hourly distribution view with a box plot and additional hour by hour statistics. + + + +
+ +## Percentile Chart + +This report will give you a percentile distribution view of the range you selected. + + + +
+ +## Weekly Distribution + +This report will give you a weekly view of your statistics. + + + +
+ +## Calibrations + +This will give you a table of your calibrations, if your uploader sends the correct event and data. + + + +
+ +## Treatments + +This will give you a table of your treatments, day by day. + + + +
+ +## Profiles + +This report will display [profiles](/nightscout/profile_editor.md) used in the time range. + + + +
+ +## Loopalyzer + +Loopalyzer is an utility made to help analyze and tune closed loop systems. It may work with other setups as well, both closed and open loop, and non loop. + +Select the period on which you want to run the report then click `Show`. A set of graphs will display top to bottom your basal profile, blood glucose, loop deviation from basal (that should be minimized for an optimized closed loop system), insulin on board and carbs on board. On the last two graphs, treatments are represented by vertical black bars. + + + +
+ +Using the dedicated menu you can display your profiles below the graph and use `Timeshift`. Click `Show` to update the display when changing the options. + +You can navigate day to day with `< Previous day` and `Next day >` or by period length with `<< Previous` and `Next >>` (i.e. if you selected a week it will go backwards and forward week by week). + + + +`Timeshift` will allow you to synchronize meals within a time range in order to better analyze your data. Obviously the rest of the day will not make sense since the shift only highlights the time range you are analyzing now. For example below: dinner analysis. + + + +
+ +You might also be interested by [AutoTune](https://autotuneweb.azurewebsites.net/). + +```{warning} +Make sure to temporarily [disable authentication](/nightscout/security.md#how-to-turn-off-unauthorized-access) before running AutoTune. +``` + +
+ +## Nightscout Reporter + +[https://nightrep.zreptil.de/](https://nightrep.zreptil.de/) can be used to generate PDF documents with the data stored at Nightscout. + +You need to add [`cors`](/nightscout/setup_variables.md#cors-cors) to your [`ENABLE`](enable) variables + +Facebook group [Nightscout Reporter](https://www.facebook.com/nightrep) + +
+ +## Power BI + +Facebook group [Nightscout Power BI Reporting](https://www.facebook.com/groups/857487091295727) diff --git a/_sources/nightscout/security.md.txt b/_sources/nightscout/security.md.txt new file mode 100644 index 00000000..e14860dd --- /dev/null +++ b/_sources/nightscout/security.md.txt @@ -0,0 +1,134 @@ + +# Nightscout Security and Privacy + +Nightscout security model is based on the following assumptions: + +* The users of Nightscout only use it to process information about themselves or someone they're legally responsible for and thus own all of the data being stored in Nightscout. +* Given the user / operator of Nightscout is assumed to have full ownership of the data stored in Nightscout, it is assumed the user has full responsibility around the use and sharing of the data. +* Nightscout provides a set of APIs for reading and writing data into the Nightscout database. Nightscout itself does not directly interface with any devices. Nightscout users should verify any applications using the APIs to process the data in Nightscout have been implemented in a secure fashion and have data validation processes in place in case an unauthorized user gains access to Nightscout and alters the data. +* If unauthorized users gain access to the server being used to host Nightscout, the database used with Nightscout or any device used to access the Nightscout APIs, the entire system's security has to be considered compromised and the user must assume any data stored in the system might be altered and thus should not be trusted. + +```{admonition} Personal use only +:class: warning +The system has not been designed for scenarios where a third party operates a Nightscout installation on behalf of others and if such installations are made, both the users and operators of such installations need to understand there is a large body of legislation across the world that covers use cases and data storage enabled by Nightscout and the liability issues around such installations are extremely complicated. +``` + +
+ +## Security and safekeeping + +- Use the same email address for all accounts so you'll have access to all your accounts after installation. **Do not use a disposable email address** - use something you know you can access later. +- Use a safe password for all accounts related to Nightscout, including the password for the email account for the accounts. We highly recommend using a password manager such as 1Password and allowing it to generate the passwords for you. +- Do not reuse the same password for all your accounts. +- Do not use your Dexcom or CareLink user name or password for Nightscout components. +- Do not use the API_SECRET for the Atlas database password. +- Do not share the API_SECRET or access tokens with administration privileges to anyone, ever. If you need to grant access to Nightscout, see below for instructions how to create access tokens for this purpose. +- Do not use Nightscout or any related applications on rooted and/or otherwise compromised devices, and ensure you always have the latest operating system and virus protection updates installed. + +
+ +## HTTPS and certificate errors + +One of the core security mechanisms on web is the SSL encryption applied to HTTP connections. When installed to Heroku, Nightscout by default forces connections to use HTTPS, thus ensuring the connection is encrypted. For secure Nightscout use, it's crucial that you assume something is wrong if you ever see your browser complain the SSL certificate of your Nightscout site does not match or work as expected by the browser. This can be a sign of a so called Man In The Middle (MITM) attack and proceeding with the problematic certificate will subsequently compromise your Nightscout site. If you see an error related to SSL, you should immediately rename the site (see below for instructions). + +
+ +## Administration messages + +Nightscout 14.2 introduced a new feature called Admin Notifies, which can warn you about issues with Nightscout installation and security issues. + +If you see the red megaphone in your navigation bar, it means you have messages in the queue. + + + +You have to be authenticated to Nightscout using the API_SECRET or an authentication token that has administration access to read the messages. + + + +There are multiple types of messages that might be shown: + +
+ +### I'm seeing a message about the API_SECRET being weak + + + +This message is shown when cryptographic analysis if the API_SECRET shows the secret is easily guessable by a computer and should be changed. Things you can do to have this message go away: + +* The API_SECRET must be at least 12 characters long, but making it even longer makes it more secure +* Use a mix of small and CAPITAL letters, numbers and non-alphanumeric characters such as !#%&/()= in the API_SECRET + *Note: make sure your uploader and downloaders can handle special characters, you might need to express them using [Percent encoding](https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_reserved_characters) for example an API_SECRET like `D0n't*H4ck@M3%` would be expressed as: `D0n%27t%2AH4ck%40M3%25`* +* Consider generating the API_SECRET using a password manager + +
+ +### I'm seeing a message about authentication failures + + + +This is highly likely caused by you having installed an app on some device with the wrong API_SECRET or access token, and the app trying to authenticate to your Nightscout, or you or one of the family members have just tried to sign into Nightscout with wrong credentials. + +If you have apps running that use the Nightscout REST API, check you have the correct API_SECRET and/or access token configured to each. + +If the message keeps appearing unexpectedly or is reported against multiple IP numbers, it's possible someone is trying to brute force attack your installation and guess your API_SECRET to be able to modify data in your Nightscout. In this situation, we highly recommend you rename the Nightscout site to change it's address and pick a name that's hard to guess. + +
+ +### I'm seeing a message Nightscout is readable by the world + + + +This means the site shows the CGM data to users who can guess the site address without authentication. Note Nightscout never allows data to be saved or edited without authentication, so this is not necessarily a problem depending on how hard your site address is to guess and how you want the information to be shared. + +If you want to have the site require authentication, read the "How to Turn Off Unauthorized Access" section below. + +
+ +## Renaming the Nightscout site + +See the instructions in the specific platform section for a new Nightscout creation. + +Once done, make sure all apps (uploaders and downloaders) are updated accordingly. + +
+ +## How to Turn Off Unauthorized Access + +```{admonition} Privacy warning +In a default setup, **anyone** with your Nightscout URL can view your site. +``` + +```{hint} +Make sure [the app you use to see your data](/nightscout/downloaders) can handle a secured Nightscout site. +``` + +To Take Advantage of Roles, Turn Off Unauthorized Access to Your Site: + +If you want to ensure that ONLY someone with permission to view your site (e.g., a token) is able to view the data, you should configure the [`AUTH_DEFAULT_ROLES`](auth_default_roles) variable. Set the value as: `denied`. + +Edit (or add) this variable and set it to `denied` (see [here](/nightscout/setup_variables.md#nightscout-configuration) how to edit variables). + + + +This creates a scenario in which a token will be required for all access (even only view). + + + +In order to make your site visible to anybody, set [`AUTH_DEFAULT_ROLES`](auth_default_roles) variable to `readable`. + +
+ +## Create Authentication Tokens for Users + +```{include} /nightscout/tokens.md + +``` + +## Developers: API authorization + +See [this page](https://github.com/nightscout/cgm-remote-monitor/wiki/API-v1-Security) for how to authenticate your app in the API V1 calls. + +The API documentation is visible on your Nightscout site using this extension to your site address: + +https://YOUR-SITE.com/api-docs/ and https://YOUR-SITE.com/api3-docs/. + diff --git a/_sources/nightscout/setup_variables.md.txt b/_sources/nightscout/setup_variables.md.txt new file mode 100644 index 00000000..b33c7334 --- /dev/null +++ b/_sources/nightscout/setup_variables.md.txt @@ -0,0 +1,1040 @@ +# Nightscout Configuration + +Nightscout configuration is held in variables , their content can be modified to change and customize the behavior (data source, security, alarms, ...) and appearance (language, colors, visible items, ...). When deploying your Nightscout, most are left with default values and with time you might want to tune your site. + +**Variables location will depend on the platform you use:** + +````{tab-set} + +:::{tab-item} Select your platform -> +
+::: + +:::{tab-item} Heroku +[**→ Here**](/vendors/heroku/new_user.md#editing-config-vars-in-heroku) +::: + +:::{tab-item} Railway +[**→ Here**](/vendors/railway/new_user.md#editing-variables-in-railway) +::: + +:::{tab-item} Northflank +[**→ Here**](/vendors/northflank/new_user.md#editing-variables-in-northflank) +::: + +:::{tab-item} Azure +[**→ Here**](/vendors/azure/new_user.md#editing-config-vars-in-azure) +::: + +:::{tab-item} Render +[**→ Here**](/vendors/render/new_user.md#editing-variables-in-render) +::: + +:::{tab-item} Fly.io +[**→ Here**](editing-config-vars-in-fly-io) +::: + +:::{tab-item} Google Cloud +[**→ Here**](https://navid200.github.io/xDrip/docs/Nightscout/NS_Variables.html) +::: + +:::{tab-item} Hosted Nightscout +If you use a hosted service, open the vendor web interface to access your Nightcsout site variables configuration or contact support. +::: + +```` + +------ + +
+ +```{hint} +Only most used variables are explained below.
+For the full list consult the [main repository ReadMe](https://github.com/nightscout/cgm-remote-monitor#environment). +``` + +
+ +## Nightscout Config Vars + +
+ +### Required variables + +#### `MONGODB_URI` (Database connection string) + +The connection string required to access your [Mongo database](/nightscout/new_user.md#basic-concepts) (where all your data is stored in the cloud). + +```{warning} +**`MONGODB_URI` is handled automatically if you use a hosted service or Google Cloud xDrip+ method.** In these cases you don't need to worry about it and can't or shouldn't change it.
+This string is vital to your Nightscout functioning. A wrong connection string will prevent your site from opening and your data uploading in Nightscout. +``` + +An [Atlas database string](/troubleshoot/atlas.md#meet-your-connection-string) will look like this: + +`mongodb+svr://sally:sallypass@cluster0.abcdef.mongodb.net/nightscout?retryWrites=true&w=majority` + +A traditional MongoDB string will look like this: + +`mongodb://sally:sallypass@myhosteddb.fqd/nightscout` + +```{hint} +If you migrated from mLab, this variable might be `MONGO_CONNECTION`. +Only one of these two variables must be present: `MONGODB_URI` or `MONGO_CONNECTION`. +``` + +
+ +(api-secret)= + +#### `API_SECRET` (Nightscout password) + +```{admonition} This is an important password +:class: warning +Knowing your site's API Secret gives anybody full access to your Nightscout data, allows uploading to your site and uncontrolled access. Make sure you keep this password secret and avoid exposing it publicly. +``` + +A passphrase that must be at least 12 characters long, for example: + +``` +MyV3ry53cr37 +``` + +```{hint} +Don't make it too long and **do not put special characters in it** (better stick to letters and numbers).
It is case-sensitive.
+If you need to share Nightscout access but control the access, use an `admin` [token](/nightscout/security.md#create-authentication-tokens-for-users). +``` + +
+ +(display-units)= + +#### `DISPLAY_UNITS` (Units to use) + +Preferred BG units for the site: `mg/dl` or `mmol/L` (or just `mmol`). Setting to `mmol/L` puts the entire server into `mmol/L` mode by default, no further settings needed. Make sure it matches you uploader and followers. + +
+ +------ + +### Features + +(enable)= + +#### `ENABLE` (Enable Plugins) + +```{hint} +Select the right plugins! Better too many than not enough. +``` + +Select which [Plugins](#plugins) to enable for your site, this is the current list: + +- `careportal` (Careportal) +- `boluscalc` (Bolus Wizard) +- `food` (Custom Foods) +- `rawbg` (Raw BG) +- `iob` (Insulin-on-Board) +- `cob` (Carbs-on-Board) +- `bwp` (Bolus Wizard Preview) +- `cage` (Cannula Age) +- `sage` (Sensor Age) +- `iage` (Insulin Age) +- `bage` (Battery Age) +- `treatmentnotify` (Treatment Notifications) +- `basal` (Basal Profile) +- `bolus` (Bolus Rendering) +- `connect` (Nightscout Connect) - Beta +- `bridge` (Share2Nightscout bridge) - Deprecated +- `mmconnect` (MiniMed Connect bridge) - Deprecated: not functional +- `pump` (Pump Monitoring) +- `openaps` (OpenAPS) +- `loop` (Loop) +- `override` (Override Mode) +- `xdripjs` (xDrip-js) +- `alexa` (Amazon Alexa) +- `googlehome` (Google Home/DialogFLow) +- `speech` (Speech) +- `cors` (CORS) + +Must be a space-delimited, lower-case list. + +`careportal basal dbsize` + +Include the word `bridge` here if you are receiving data from the Dexcom Share service. + +`careportal basal dbsize bridge` + +If you don't want to decide now, add all the followings, you can disable them if you don't need them: + +`careportal basal dbsize rawbg iob maker bridge cob bwp cage iage sage boluscalc pushover treatmentnotify mmconnect loop pump profile food openaps bage alexa override cors` + +Note: `mmconnect` is not functional with Heroku (if you wanted to bridge from the MiniMed CareLink service you will need another device to send data to Nightscout). If you are sending data to CareLink do **NOT** enable `mmconnect`. + +
+ +#### `DISABLE` (Disable Plugins) + +Used to disable ***default*** features, expects a space delimited list. + +For example this will disable the direction arrow and uploader battery information: + +`direction upbat` + +
+ +(auth_default_roles)= + +#### `AUTH_DEFAULT_ROLES` (Authentication) + +Possible values `readable`, `denied`, or any valid role name. When `readable`, anyone can view Nightscout without a token. Setting it to `denied` will require a token from every visit, using `status-only` will enable api-secret based login. + +More information on how to setup tokens [here](/nightscout/security.md#create-authentication-tokens-for-users). + +
+ +### Alarms + +These alarm setting affect all delivery methods (browser, Pushover, IFTTT, etc.). Values and settings entered here will be the defaults for new browser views, but will be overridden if different choices are made in the settings UI. + +#### `ALARM_TYPES` + +```{admonition} TYPES +:class: hint +Keep the `simple` type if you want `BG_` parameters (setup below) to be used. +``` + +`simple` and/or `predict`. + +Simple alarms trigger when BG crosses the various thresholds set below. + +Predict alarms uses highly tuned formula that forecasts where the BG is going based on its trend. You will ***not*** get warnings when crossing any of the `BG_` thresholds set below when using ***only*** the predict type. + +```{admonition} BG Thresholds +:class: hint +These values are the ones that will trigger `simple` alarms. They are expressed in the unit you selected with `DISPLAY_UNITS`. +``` + +#### `BG_HIGH` + +Urgent High BG threshold, triggers the `ALARM_URGENT_HIGH` alarm. + +#### `BG_LOW` + +Urgent Low BG threshold, triggers the `ALARM_URGENT_LOW` alarm. + +#### `BG_TARGET_BOTTOM` + +Low BG threshold, triggers the `ALARM_LOW` alarm. + +#### `BG_TARGET_TOP` + +High BG threshold, triggers the `ALARM_HIGH` alarm. + +
+ +```{admonition} ALARM_* and ALARM_URGENT_* +:class: hint +You can setup alarms, so that when your Nightscout page is open and the alarm enabled, above (`HIGH`) or below (`LOW`) a certain threshold, a sound might play. +``` + +#### `ALARM_URGENT_HIGH` + +Default setting for new browser views, for the Urgent High alarm (triggered when BG crosses `BG_HIGH`). (`on` or `off`) + +#### `ALARM_HIGH` + +Default setting for new browser views, for the High alarm (triggered when BG crosses `BG_TARGET_TOP`). (`on` or `off`) + +#### `ALARM_LOW` + +Default setting for new browser views, for the Low alarm (triggered when BG crosses `BG_TARGET_BOTTOM`). (`on` or `off`) + +#### `ALARM_URGENT_LOW` + +Default setting for new browser views, for the Urgent Low alarm (triggered when BG crosses `BG_LOW`). (`on` or `off`) + +#### Other Alarms on by Default + +These other two alarms are on by default, so set them to 'off' if you prefer no alarms. + +* `ALARM_TIMEAGO_WARN` +* `ALARM_TIMEAGO_URGENT` + +
+ +```{admonition} Pushover +:class: hint +`ALARM_*_MINS`: Only the first value of the space separated list, for options in browser, will be used for pushover. +``` + +#### `ALARM_URGENT_HIGH_MINS` + +Number of minutes to snooze urgent high alarms. + +#### `ALARM_HIGH_MINS` + +Number of minutes to snooze high alarms. + +#### `ALARM_LOW_MINS` + +Number of minutes to snooze low alarms. + +#### `ALARM_URGENT_LOW_MINS` + +Number of minutes to snooze urgent low alarms. + +#### `ALARM_URGENT_MINS` + +Number of minutes to snooze urgent alarms (that aren't tagged as high or low). + +#### `ALARM_WARN_MINS` + +Number of minutes to snooze warning alarms (that aren't tagged as high or low). + +
+ +```{admonition} TIMEAGO +:class: hint +Missing data alarms can also be setup, so that when your Nightscout page is open and the alarm enabled, after a certain time without receiving BG, a sound might play. +``` + +#### `ALARM_TIMEAGO_URGENT` + +Default setting for new browser views, for an urgent alarm when CGM data hasn't been received in the number of minutes set in `ALARM_TIMEAGO_URGENT_MINS`. (`on` or `off`) + +#### `ALARM_TIMEAGO_URGENT_MINS` + +Default setting for new browser views, for the number of minutes since the last CGM reading to trigger an `ALARM_TIMEAGO_URGENT` alarm. + +#### `ALARM_TIMEAGO_WARN` + +Default setting for new browser views, for a warning alarm when CGM data hasn't been received in the number of minutes set in `ALARM_TIMEAGO_WARN_MINS`. (`on` or `off`) + +#### `ALARM_TIMEAGO_WARN_MINS` + +Default setting for new browser views, for the number of minutes since the last CGM reading to trigger an `ALARM_TIMEAGO_WARN` alarm. + +
+ +------ + +### Predefined values for your browser settings (default) + +#### `TIME_FORMAT` (`12`) + +Possible values `12` or `24`. This defines the horizontal timeline expressed as AM/PM or 0-24. + +
+ +#### `NIGHT_MODE` (`off`) + +Possible values `on` or `off`. Night mode has a lower brightness and contrast. + +
+ +#### `SHOW_RAWBG` (`never`) + +Display of raw CGM data (this is a legacy feature). (`always`, `never`, or `noise`) + + + +
+ +#### `CUSTOM_TITLE` (`Nightscout`) + +The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer. + + + +#### `THEME` (`colors`) + +Color theme of the CGM graph. + +`default` + + + +`colors` + + + +`colorblindfriendly` + + + +
+ +#### `SHOW_PLUGINS` + +Default setting for whether or not these plugins are checked (active) by default, not merely enabled. Include plugins here as in the `ENABLE` line; space-separated and lower-case. + +When you `ENABLE` a plugin, it will be used by Nightscout but might not be visible unless you select it in the [drawer menu](/nightscout/discover.md#settings). If you want a plugin to display by default you need to add it to the `SHOW_PLUGINS` list. + +More details [below](#plugins). + +
+ +#### `SHOW_FORECAST` (`ar2`) + +Plugin forecasts that should be shown by default, supports space delimited values such as: +`ar2 openaps loop false` + +Note the ar2 forecast is selected by default so if no value is set, it will be AR2. AR2 is an early attempt at forecasting BG and you should not base any medical decisions on it's predictions. + +If you are looping, you can chose instead to use either `loop` or `openaps` which will use the appropriate algorithm. + +You should also add the parameter to the `SHOW_PLUGINS` and `ENABLE` variables. + +For example, if you are using the Loop app for iPhone, you should have the following settings (In addition to any others outlined in the docs): + +``` +ENABLE=loop +SHOW_PLUGINS=loop +SHOW_FORECAST=loop +``` + +
+ +#### `LANGUAGE` (`en`) + +Language of Nightscout. If not available English is used. + +Currently supported language codes are: `bg` (Български), `cs` (Čeština), `de` (Deutsch), `dk` (Dansk), `el` (Ελληνικά), `en` (English), `es` (Español), `fi` (Suomi), `fr` (Français), `he` (עברית), `hr` (Hrvatski), `it` (Italiano), `ko` (한국어), `nb` (Norsk (Bokmål)), `nl` (Nederlands), `pl` (Polski), `pt` (Português (Brasil)), `ro` (Română), `ru` (Русский), `sk` (Slovenčina), `sv` (Svenska), `tr` (Turkish), `zh_cn` (中文(简体)), `zh_tw` (中文(繁體)) + +
+ +#### `SCALE_Y` (`log`) + +The type of scaling used for the Y axis of the charts system wide. + +The default `log` (logarithmic) option will let you see more detail towards the lower range, while still showing the full CGM range. + + + +The `linear` option has equidistant tick marks; the range used is dynamic so that space at the top of chart isn't wasted. + + + +The `log-dynamic` is similar to the default `log` options, but uses the same dynamic range and the `linear` scale. + + + +
+ +#### `EDIT_MODE` (`on`) + +Possible values `on` or `off`. Enables the icon allowing for editing of treatments in the main view. More about edit [here](/nightscout/discover.md#edit-mode-edit). + + + +
+ +#### `BOLUS_RENDER` + +Settings to configure Bolus rendering + +`BOLUS_RENDER_OVER` (`0`) - U value over which the bolus labels use the format defined in `BOLUS_RENDER_FORMAT`. This value can be an integer or a float, e.g. `0.3`, `1.5`, `2`, etc. + +`BOLUS_RENDER_FORMAT` (`default`) - Possible values are `hidden`, `default` (with leading zero and U), `concise` (with U, without leading zero), and `minimal` (without leading zero and U). + +`BOLUS_RENDER_FORMAT_SMALL` (`default`) - Possible values are `hidden`, `default` (with leading zero and U), `concise` (with U, without leading zero), and `minimal` (without leading zero and U). + + + +
+ +------ + +### Split View + +Some users will need easy access to multiple Nightscout views at the same time. We have a special view for this case, accessed on /split path on your Nightscout URL. The view supports any number of sites between 1 to 8 way split, where the content for the screen can be loaded from multiple Nightscout instances. Note you still need to host separate instances for each Nightscout being monitored including the one that hosts the split view page - these variables only add the ability to load multiple views into one browser page. To set the URLs from which the content is loaded, set: + +`FRAME_URL_1` - URL where content is loaded, for the first view (increment the number up to 8 to get more views) + +`FRAME_NAME_1` - Name for the first split view portion of the screen (increment the number to name more views) + +
+ +For example: + +`FRAME_URL_1` `https://janecgm.myurl.fqd` + +`FRAME_NAME_1` `Jane` + +`FRAME_URL_2` `https://joecgm.myurl.fqd` + +`FRAME_NAME_2` `Joe` + +
+ +To display the split view browse to: + +`https://myAppName.myurl.fqd/split` + +
+ +8 split view example: + + + +
+ +------ + +## Plugins + +Plugins are used to extend the way information is displayed, how notifications are sent, alarms are triggered, and more. + +If you want the `ENABLE`'d plugins to **show by default on any browser**, you should put them in the `SHOW_PLUGINS` variable. + +If you want to specifically disable a plugin (mainly a default plugin) you should place it in the `DISABLE` variable. + +You also can decide to visualize them or not on your Nightscout view with the drawer menu. `Authenticate` and `Save` the settings on your browser. Your site variables will not be modified and only default view will be seen on a new browser window. + + + +
+ +### Default Plugins + +Below some default plugins: `timeago`, `upbat`, `direction` and `delta`. + + + +
+ +Hovering the mouse on (computer) or touching (touch screen) some plugins will give you additional information. + +#### `delta` (BG Delta) + +Calculates and displays the change between the last 2 BG values. Delta shows a `*` if time difference is more than 5 minutes. + +#### `direction` (BG Direction) + +Displays the trend direction, the arrow change is only based on the difference from the current to the latest measurement. + +#### `upbat` (Uploader Battery) + +Displays the most recent battery status from the uploader phone(s) and bridge. Use these extended setting to adjust behavior: + +`UPBAT_ENABLE_ALERTS` (`false`) - Set to `true` to enable uploader battery alarms via Pushover and IFTTT. + +`UPBAT_WARN` (`30`) - Minimum battery percent to trigger warning. + +`UPBAT_URGENT` (`20`) - Minimum battery percent to trigger urgent alarm. + +
+ +#### `timeago` (Time Ago) + +Displays the time since last CGM entry. Use these extended setting to adjust behavior: + +`TIMEAGO_ENABLE_ALERTS` (`false`) - Set to `true` to enable stale data alarms via Pushover and IFTTT. + +`ALARM_TIMEAGO_WARN` (`on`) - possible values `on` or `off` + +`ALARM_TIMEAGO_WARN_MINS` (`15`) - minutes since the last reading to trigger a warning + +`ALARM_TIMEAGO_URGENT` (`on`) - possible values `on` or `off` + +`ALARM_TIMEAGO_URGENT_MINS` (`30`) - minutes since the last reading to trigger a urgent alarm + +
+ +#### `devicestatus` (Device Status) + +Used by `upbat` and other plugins to display device status info. Supports the `DEVICESTATUS_ADVANCED="true"` extended setting to send all device statuses to the client for retrospective use and to support other plugins. + +Example: `upbat` information using `devicestatus`. + + + +
+ +#### `errorcodes` (CGM Error Codes) + +Generates alarms for CGM codes `9` (hourglass) and `10` (???). + +Use extended settings to adjust what errorcodes trigger notifications and alarms: + +- `ERRORCODES_INFO` (`1 2 3 4 5 6 7 8`) - By default the needs calibration (blood drop) and other codes below 9 generate an info level notification, set to a space separate list of number or `off` to disable + +- `ERRORCODES_WARN` (`off`) - By default there are no warning configured, set to a space separate list of numbers or `off` to disable + +- `ERRORCODES_URGENT` (`9 10`) - By default the hourglass and ??? generate an urgent alarm, set to a space separate list of numbers or `off` to disable + +
+ +#### `ar2` (AR2 Forecasting) + +Generates alarms based on forecasted values. + +- Enabled by default if no thresholds are set **OR** `ALARM_TYPES` includes `predict`. + - You can permanently disable AR2 setting the `SHOW_FORECAST` variable to `false` (or removing `ar2` if you use it for `openaps` or `loop`). + +- `AR2` forecasting display can be enabled/disabled from `... ` +- Use extended settings to adjust AR2 behavior: + - `AR2_CONE_FACTOR` (`2`) - to adjust size of cone, use `0` for a single line. + + + +
+ +#### `simplealarms` (Simple BG Alarms) + +- Uses `BG_HIGH`, `BG_TARGET_TOP`, `BG_TARGET_BOTTOM`, `BG_LOW` thresholds to generate alarms. + + Simple alarms are enabled by default if one of the `BG_HIGH`, `BG_TARGET_TOP`, `BG_TARGET_BOTTOM`, `BG_LOW` thresholds is set or `ALARM_TYPES` includes `simple`. + + You'll find the plugin in the drawer menu. You can change thresholds in `Profile editor`. + + You can click the loudspeaker icon to test the alarms volume or to snooze an active alarm. If you want to use sound alarms, you should click the icon to enable playback at least once after opening your Nightscout page in order to allow the browser to play it. + + + +
+ +#### `profile` (Treatment Profile) + +Add a link in the drawer menu to [Profile Editor](/nightscout/profile_editor/) and allows to enter treatment profile settings. Also uses the extended setting: + +- `PROFILE_HISTORY` (`off`) - possible values `on` or `off`. Enable/disable NS ability to keep history of your profiles (still experimental) +- `PROFILE_MULTIPLE` (`off`) - possible values `on` or `off`. Enable/disable NS ability to handle and switch between multiple treatment profiles + +More variables of your profile will be used by Nightscout plugins like treatments, see below or [here](https://github.com/nightscout/cgm-remote-monitor#treatment-profile). + + + +
+ +#### `dbsize` (Database Size) + +Show size of Nightscout Database, as a percentage of declared available space or in MiB. + + + +
+ +Many deployments of Nightscout use free tier of MongoDB Atlas on Heroku, which is limited in size to 512MiB. After some time, as volume of stored data grows, it may happen that this limit is reached and system is unable to store new data. This plugin provides pill that indicates size of Database and shows (when configured) alarms regarding reaching space limit. + +```{admonition} IMPORTANT +This plugin can only check how much space database already takes, *but cannot infer* max size available on server for it. To have correct alarms and realistic percentage, `DBSIZE_MAX` need to be properly set - according to your own mongoDB hosting configuration. +``` + +**NOTE:** This plugin rely on db.stats() for reporting *logical* size of database, which may be different than *physical* size of database on server. It may work for free tier of MongoDB on Atlas, since it calculate quota according to logical size too, but may fail for other hostings or self-hosted database with quota based on physical size. + +**NOTE:** MongoDB Atlas quota is for **all** databases in cluster, while each instance will get only size of **its own database only**. It is ok when you only have **one** database in cluster (most common scenario) but will not work for multiple parallel databases. In such case, spliting known quota equally beetween databases and setting `DBSIZE_MAX` to that fraction may help, but wont be precise. + +All sizes are expressed as integers, in *Mebibytes* `1 MiB == 1024 KiB == 1024*1024 B` + +Extended settings available: + +- `DBSIZE_MAX` (`496`) - Maximal allowed size of database on your mongoDB server, in MiB. You need to adjust that value to match your database hosting limits - default value is for standard Heroku mongoDB free tier. +- `DBSIZE_WARN_PERCENTAGE` (`60`) - Threshold to show first warning about database size. When database reach this percentage of `DBSIZE_MAX` size - pill will show size in yellow. +- `DBSIZE_URGENT_PERCENTAGE` (`75`) - Threshold to show urgent warning about database size. When database reach this percentage of `DBSIZE_MAX` size, it is urgent to do backup and clean up old data. At this percentage info pill turns red. +- `DBSIZE_ENABLE_ALERTS` (`false`) - Set to `true` to enable notifications about database size. +- `DBSIZE_IN_MIB` (`false`) - Set to `true` to display size of database in MiB-s instead of default percentage. + +
+ +------ + +### Advanced Plugins: + +#### `careportal` (Careportal) + +An optional form to enter treatments. + +Care Portal is an important plugin that gives access to the `Log a treatment` interface. Unlock it entering your API secret with the lock icon top right, then use the `+` icon to log a treatment. More information [here](/nightscout/discover.md#add-a-treatment-careportal). + + + +
+ +#### `boluscalc` (Bolus Wizard) + +Bolus Wizard plugin gives access to the `Bolus Wizard` interface. You can access it with the calculator icon top right. + + + +
+ +#### `food` (Custom Foods) + +Custom Foods enabled by the variable `food` allows to to customize your food database and adds a `Food Editor` entry in the menu. + + + +
+ +#### `rawbg` (Raw BG) + +Calculates BG using sensor and calibration records from and displays an alternate BG values and noise levels. Defaults that can be adjusted with extended setting. Raw BG will only display if your sensor provides this data, your bridge device transfers it and your uploader sends it to Nightscout. + +- `DISPLAY`(`unsmoothed`) - Allows the user to control which algorithm is used to calculate the displayed raw BG values using the most recent calibration record. + + - ​ `unfiltered` - Raw BG is calculated by applying the calibration to the glucose record's unfiltered value. + + - `filtered` - Raw BG is calculated by applying the calibration to the glucose record's filtered value. The glucose record's filtered values are generally produced by the CGM by a running average of the unfiltered values to produce a smoothed value when the sensor noise is high. + + - `unsmoothed` - Raw BG is calculated by first finding the ratio of the calculated filtered value (the same value calculated by the `filtered` setting) to the reported glucose value. The displayed raw BG value is calculated by dividing the calculated unfiltered value (the same value calculated by the `unfiltered` setting) by the ratio. The effect is to exaggerate changes in trend direction so the trend changes are more noticeable to the user. This is the legacy raw BG calculation algorithm. + + + +
+ +#### `iob` (Insulin-on-Board) - `cob` (Carbs-on-Board) + + + +
+ +#### `iob` (Insulin-on-Board) + +Adds the IOB pill visualization in the client and calculates values that used by other plugins. Uses treatments with insulin doses and the `dia` and `sens` fields from the treatment profile. + +#### `cob` (Carbs-on-Board) + +Adds the COB pill visualization in the client and calculates values that used by other plugins. Uses treatments with carb doses and the `carbs_hr`, `carbratio`, and `sens` fields from the treatment profile. + +When you enter the information with the Care Portal or Nightscout receives if from the uploader, you can see remaining insulin on board and carbs. + +
+ +#### `bwp` (Bolus Wizard Preview) + +This plugin in intended for the purpose of automatically snoozing alarms when the CGM indicates high blood sugar but there is also insulin on board (IOB) and secondly, alerting to user that it might be beneficial to measure the blood sugar using a glucometer and dosing insulin as calculated by the pump or instructed by trained medicare professionals. ***The values provided by the plugin are provided as a reference based on CGM data and insulin sensitivity you have configured, and are not intended to be used as a reference for bolus calculation.*** The plugin calculates the bolus amount when above your target, generates alarms when you should consider checking and bolusing, and snoozes alarms when there is enough IOB to cover a high BG. Uses the results of the `iob` plugin and `sens`, `target_high`, and `target_low` fields from the [treatment profile](/nightscout/profile_editor/). Defaults that can be adjusted with extended settings + +- `BWP_WARN` (`0.50`) - If `BWP` is > `BWP_WARN` a warning alarm will be triggered. +- `BWP_URGENT` (`1.00`) - If `BWP` is > `BWP_URGENT` an urgent alarm will be triggered. +- `BWP_SNOOZE_MINS` (`10`) - minutes to snooze when there is enough IOB to cover a high BG. +- `BWP_SNOOZE` - (`0.10`) If BG is higher then the `target_high` and `BWP` < `BWP_SNOOZE` alarms will be snoozed for `BWP_SNOOZE_MINS`. + + + +
+ +#### Age pills + + + +
+ +#### `cage` (Cannula Age) + +Calculates the number of hours since the last `Site Change` treatment that was recorded. + +- `CAGE_ENABLE_ALERTS` (`false`) - Set to `true` to enable notifications to remind you of upcoming cannula change. +- `CAGE_INFO` (`44`) - If time since last `Site Change` matches `CAGE_INFO`, user will be warned of upcoming cannula change +- `CAGE_WARN` (`48`) - If time since last `Site Change` matches `CAGE_WARN`, user will be alarmed to to change the cannula +- `CAGE_URGENT` (`72`) - If time since last `Site Change` matches `CAGE_URGENT`, user will be issued a persistent warning of overdue change. +- `CAGE_DISPLAY` (`hours`) - Possible values are `hours` or `days`. If `days` is selected and age of canula is greater than 24h number is displayed in days and hours + +#### `sage` (Sensor Age) + +Calculates the number of days and hours since the last `Sensor Start` and `Sensor Change` treatment that was recorded. + +- `SAGE_ENABLE_ALERTS` (`false`) - Set to `true` to enable notifications to remind you of upcoming sensor change. +- `SAGE_INFO` (`144`) - If time since last sensor event matches `SAGE_INFO`, user will be warned of upcoming sensor change +- `SAGE_WARN` (`164`) - If time since last sensor event matches `SAGE_WARN`, user will be alarmed to to change/restart the sensor +- `SAGE_URGENT` (`166`) - If time since last sensor event matches `SAGE_URGENT`, user will be issued a persistent warning of overdue change. + +#### `iage` (Insulin Age) + +Calculates the number of days and hours since the last `Insulin Change` treatment that was recorded. + +- `IAGE_ENABLE_ALERTS` (`false`) - Set to `true` to enable notifications to remind you of upcoming insulin reservoir change. +- `IAGE_INFO` (`44`) - If time since last `Insulin Change` matches `IAGE_INFO`, user will be warned of upcoming insulin reservoir change +- `IAGE_WARN` (`48`) - If time since last `Insulin Change` matches `IAGE_WARN`, user will be alarmed to to change the insulin reservoir +- `IAGE_URGENT` (`72`) - If time since last `Insulin Change` matches `IAGE_URGENT`, user will be issued a persistent warning of overdue change. + +#### `bage` (Battery Age) + +Calculates the number of days and hours since the last `Pump Battery Change` treatment that was recorded. + +- `BAGE_ENABLE_ALERTS` (`false`) - Set to `true` to enable notifications to remind you of upcoming pump battery change. + +- `BAGE_DISPLAY` (`days`) - Set to `hours` to display time since last `Pump Battery Change` in hours only. + +- `BAGE_INFO` (`312`) - If time since last `Pump Battery Change` matches `BAGE_INFO` hours, user will be warned of upcoming pump battery change (default of 312 hours is 13 days). + +- `BAGE_WARN` (`336`) - If time since last `Pump Battery Change` matches `BAGE_WARN` hours, user will be alarmed to to change the pump battery (default of 336 hours is 14 days). + +- `BAGE_URGENT` (`360`) - If time since last `Pump Battery Change` matches `BAGE_URGENT` hours, user will be issued a persistent warning of overdue change (default of 360 hours is 15 days). + +
+ +#### `treatmentnotify` (Treatment Notifications) + +Generates notifications when a treatment has been entered and snoozes alarms minutes after a treatment. Default snooze is 10 minutes, and can be set using the `TREATMENTNOTIFY_SNOOZE_MINS` extended setting. + +
+ +#### `basal` (Basal Profile) + + + +
+ +Adds the Basal pill visualization to display the basal rate for the current time. Also enables the `bwp` plugin to calculate correction temp basal suggestions. Uses the `basal` field from the [treatment profile](https://github.com/nightscout/cgm-remote-monitor#treatment-profile). Also uses the extended settings: + +- `BASAL_RENDER` (`none`) + +Possible values are `none`, + +`default`, + + + +or `icicle` (inverted) + + + +
+ +#### `bridge` (Share2Nightscout bridge) + +Glucose reading directly from the Dexcom Share service, uses these extended settings (***** mandatory): + +- `BRIDGE_USER_NAME` - Your username for the Share service. ***** +- `BRIDGE_PASSWORD` - Your password for the Share service. ***** +- `BRIDGE_INTERVAL` (`150000` *2.5 minutes*) - The time (in milliseconds) to wait between each update. +- `BRIDGE_MAX_COUNT` (`1`) - The number of records to attempt to fetch per update. +- `BRIDGE_FIRST_FETCH_COUNT` (`3`) - Changes max count during the very first update only. +- `BRIDGE_MAX_FAILURES` (`3`) - How many failures before giving up. +- `BRIDGE_MINUTES` (`1400`) - The time window to search for new data per update (the default value is one day in minutes). +- `BRIDGE_SERVER` (`US`) - Set to `US` to fetch data from Dexcom servers in the US. Set to (`EU`) to fetch from non US servers instead. ***** + +- `OBSCURED` (`bridge`) - Obscure data source when using `bridge` uploader. +- `OBSCURE_DEVICE_PROVENANCE` (`dexcom-dont-own-my-body-data`) - Self explanatory. + +
+ +#### `mmconnect` (MiniMed Connect bridge) + +```{warning} +This plugin is **NOT** functional with 7xx pumps do not enable it. +``` + +Transfer real-time MiniMed Connect data from the Medtronic CareLink server into Nightscout ([read more](https://github.com/nightscout/minimed-connect-to-nightscout)) (***** mandatory) with the following extended settings: + +- `MMCONNECT_USER_NAME` - Your user name for CareLink Connect. ***** +- `MMCONNECT_PASSWORD` - Your password for CareLink Connect. ***** +- `MMCONNECT_INTERVAL` (`60000` *1 minute*) - Number of milliseconds to wait between requests to the CareLink server. +- `MMCONNECT_MAX_RETRY_DURATION` (`32`) - Maximum number of total seconds to spend retrying failed requests before giving up. +- `MMCONNECT_SGV_LIMIT` (`24`) - Maximum number of recent sensor glucose values to send to Nightscout on each request. +- `MMCONNECT_VERBOSE` - Set this to "true" to log CareLink request information to the console. +- `MMCONNECT_STORE_RAW_DATA` - Set this to "true" to store raw data returned from CareLink as `type: "carelink_raw"` database entries (useful for development). +- `MMCONNECT_SERVER` - Set this to `EU` if you're using the European Medtronic services ***** + +
+ +#### `pump` (Pump Monitoring) + + + +
+ +Generic Pump Monitoring for OpenAPS, MiniMed Connect, RileyLink, t:slim, ... + +- Requires `DEVICESTATUS_ADVANCED="true"` to be set +- `PUMP_ENABLE_ALERTS` (`false`) - Set to `true` to enable notifications for Pump battery and reservoir. +- `PUMP_WARN_ON_SUSPEND` (`false`) - Set to `true` to get an alarm when the pump is suspended. +- `PUMP_FIELDS` (`reservoir battery`) - The fields to display by default. Any of the following fields: `reservoir`, `battery`, `clock`, `status`, and `device` +- `PUMP_RETRO_FIELDS` (`reservoir battery clock`) - The fields to display in retro mode. Any of the above fields. +- `PUMP_WARN_CLOCK` (`30`) - The number of minutes ago that needs to be exceed before an alert is triggered. +- `PUMP_URGENT_CLOCK` (`60`) - The number of minutes ago that needs to be exceed before an urgent alarm is triggered. +- `PUMP_WARN_RES` (`10`) - The number of units remaining, a warning will be triggered when dropping below this threshold. +- `PUMP_URGENT_RES` (`5`) - The number of units remaining, an urgent alarm will be triggered when dropping below this threshold. +- `PUMP_WARN_BATT_P` (`30`) - The % of the pump battery remaining, a warning will be triggered when dropping below this threshold. +- `PUMP_URGENT_BATT_P` (`20`) - The % of the pump battery remaining, an urgent alarm will be triggered when dropping below this threshold. +- `PUMP_WARN_BATT_V` (`1.35`) - The voltage (if percent isn't available) of the pump battery, a warning will be triggered when dropping below this threshold. +- `PUMP_URGENT_BATT_V` (`1.30`) - The voltage (if percent isn't available) of the pump battery, an urgent alarm will be triggered when dropping below this threshold. + +
+ +------ + +#### `openaps` (OpenAPS) + + + +
+ +Integrated OpenAPS loop monitoring, uses these extended setting: + +- Requires `DEVICESTATUS_ADVANCED="true"` to be set +- `OPENAPS_ENABLE_ALERTS` (`false`) - Set to `true` to enable notifications when OpenAPS isn't looping. If OpenAPS is going to offline for a period of time, you can add an `OpenAPS Offline` event for the expected duration from Careportal to avoid getting alerts. +- `OPENAPS_WARN` (`30`) - The number of minutes since the last loop that needs to be exceed before an alert is triggered +- `OPENAPS_URGENT` (`60`) - The number of minutes since the last loop that needs to be exceed before an urgent alarm is triggered +- `OPENAPS_FIELDS` (`status-symbol status-label iob meal-assist rssi`) - The fields to display by default. Any of the following fields: `status-symbol`, `status-label`, `iob`, `meal-assist`, `freq`, and `rssi` +- `OPENAPS_RETRO_FIELDS` (`status-symbol status-label iob meal-assist rssi`) - The fields to display in retro mode. Any of the above fields. +- `OPENAPS_PRED_IOB_COLOR` (`#1e88e5`) - The color to use for IOB prediction lines. Colors can be in `#RRGGBB` format, but [other CSS color units](https://www.w3.org/TR/css-color-3/#colorunits) may be used as well. +- `OPENAPS_PRED_COB_COLOR` (`#FB8C00`) - The color to use for COB prediction lines. Same format as above. +- `OPENAPS_PRED_ACOB_COLOR` (`#FB8C00`) - The color to use for ACOB prediction lines. Same format as above. +- `OPENAPS_PRED_ZT_COLOR` (`#00d2d2`) - The color to use for ZT prediction lines. Same format as above. +- `OPENAPS_PRED_UAM_COLOR` (`#c9bd60`) - The color to use for UAM prediction lines. Same format as above. +- `OPENAPS_COLOR_PREDICTION_LINES` (`true`) - Enables / disables the colored lines vs the classic purple color. + +Also see [Pushover](https://github.com/nightscout/cgm-remote-monitor#pushover) and [IFTTT Maker](https://github.com/nightscout/cgm-remote-monitor#ifttt-maker). + +
+ +------ + +#### `loop` (Loop) + + + +
+ +iOS Loop app monitoring, uses these extended settings: + +- Requires `DEVICESTATUS_ADVANCED="true"` to be set +- `LOOP_ENABLE_ALERTS` (`false`) - Set to `true` to enable notifications when Loop isn't looping. +- `LOOP_WARN` (`30`) - The number of minutes since the last loop that needs to be exceeded before an alert is triggered +- `LOOP_URGENT` (`60`) - The number of minutes since the last loop that needs to be exceeded before an urgent alarm is triggered +- Add `loop` to `SHOW_FORECAST` to show forecasted BG. + +For remote overrides, the following extended settings must be configured: + +- `LOOP_APNS_KEY` - Apple Push Notifications service (APNs) Key, created in the Apple Developer website. +- `LOOP_APNS_KEY_ID` - The Key ID for the above key. +- `LOOP_DEVELOPER_TEAM_ID` - Your Apple developer team ID. +- `LOOP_PUSH_SERVER_ENVIRONMENT` - (optional) Set this to `production` if you are using a provisioning profile that specifies production aps-environment, such as when distributing builds via TestFlight. + +
+ +#### `override` (Override Mode) + +Additional monitoring for DIY automated insulin delivery systems to display real-time overrides such as Eating Soon or Exercise Mode: + +- Requires `DEVICESTATUS_ADVANCED="true"` to be set + +
+ +#### `xdripjs` (xDrip-js) + +Integrated xDrip-js monitoring, uses these extended settings: + +- Requires `DEVICESTATUS_ADVANCED="true"` to be set + +- `XDRIPJS_ENABLE_ALERTS` (`false`) - Set to `true` to enable notifications when CGM state is not OK or battery voltages fall below threshold. + +- `XDRIPJS_STATE_NOTIFY_INTRVL` (`0.5`) - Set to number of hours between CGM state notifications + +- `XDRIPJS_WARN_BAT_V` (`300`) - The voltage of either transmitter battery, a warning will be triggered when dropping below this threshold. + +
+ +#### `alexa` (Amazon Alexa) + +Integration with Amazon Alexa, [detailed setup instructions](https://github.com/nightscout/cgm-remote-monitor/blob/master/docs/plugins/alexa-plugin.md) + +
+ +#### `googlehome` (Google Home/DialogFlow) + +Integration with Google Home (via DialogFlow), [detailed setup instructions](https://github.com/nightscout/cgm-remote-monitor/blob/master/docs/plugins/googlehome-plugin.md) + +
+ +#### `speech` (Speech) + +Speech synthesis plugin. When enabled, speaks out the blood glucose values, IOB and alarms. Note you have to set the LANGUAGE setting on the server to get all translated alarms. + +
+ +#### `cors` (CORS) + +Enabled [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) so other websites can make request to your Nightscout site, uses these extended settings: + +- `CORS_ALLOW_ORIGIN` (`*`) - The list of sites that are allow to make requests + +
+ +------ + +## Extended Settings + +Some plugins support additional configuration using extra environment variables. These are prefixed with the name of the plugin and a `_`. For example setting `MYPLUGIN_EXAMPLE_VALUE=1234` would make `extendedSettings.exampleValue` available to the `MYPLUGIN` plugin. + +Plugins only have access to their own extended settings, all the extended settings of client plugins will be sent to the browser. + +- `DEVICESTATUS_ADVANCED` (`true`) - Defaults to true. Users who only have a single device uploading data to Nightscout can set this to false to reduce the data use of the site. +- `DEVICESTATUS_DAYS` (`1`) - Defaults to 1, can optionally be set to 2. Users can use this to show 48 hours of device status data for in retro mode, rather than the default 24 hours. Setting this value to 2 will roughly double the bandwidth usage of nightscout, so users with a data cap may not want to update this setting. + +
+ +### [Pushover](/nightscout/pushover) + +In addition to the normal web based alarms, there is also support for [Pushover](https://pushover.net/) based alarms and notifications. + +To get started install the Pushover application on your iOS or Android device and create an account. + +Using that account login to [Pushover](https://pushover.net/), in the top left you’ll see your User Key, you’ll need this plus an application API Token/Key to complete this setup. + +You’ll need to [Create a Pushover Application](https://pushover.net/apps/build). You only need to set the Application name, you can ignore all the other settings, but setting an Icon is a nice touch. Maybe you'd like to use [this one](https://raw.githubusercontent.com/nightscout/cgm-remote-monitor/master/static/images/large.png)? + +Pushover is configured using the following Environment Variables: + +``` +* `ENABLE` - `pushover` should be added to the list of plugin, for example: `ENABLE="pushover"`. +* `PUSHOVER_API_TOKEN` - Used to enable pushover notifications, this token is specific to the application you create from in [Pushover](https://pushover.net/), ***[additional pushover information](#pushover)*** below. +* `PUSHOVER_USER_KEY` - Your Pushover user key, can be found in the top left of the [Pushover](https://pushover.net/) site, this can also be a pushover delivery group key to send to a group rather than just a single user. This also supports a space delimited list of keys. To disable `INFO` level pushes set this to `off`. +* `PUSHOVER_ALARM_KEY` - An optional Pushover user/group key, will be used for system wide alarms (level > `WARN`). If not defined this will fallback to `PUSHOVER_USER_KEY`. A possible use for this is sending important messages and alarms to a CWD that you don't want to send all notification too. This also support a space delimited list of keys. To disable Alarm pushes set this to `off`. +* `PUSHOVER_ANNOUNCEMENT_KEY` - An optional Pushover user/group key, will be used for system wide user generated announcements. If not defined this will fallback to `PUSHOVER_USER_KEY` or `PUSHOVER_ALARM_KEY`. This also support a space delimited list of keys. To disable Announcement pushes set this to `off`. +* `BASE_URL` - Used for pushover callbacks, usually the URL of your Nightscout site, use https when possible. +* `API_SECRET` - Used for signing the pushover callback request for acknowledgments. + +If you never want to get info level notifications (treatments) use `PUSHOVER_USER_KEY="off"` +If you never want to get an alarm via pushover use `PUSHOVER_ALARM_KEY="off"` +If you never want to get an announcement via pushover use `PUSHOVER_ANNOUNCEMENT_KEY="off"` + +If only `PUSHOVER_USER_KEY` is set it will be used for all info notifications, alarms, and announcements + +For testing/development try [localtunnel](http://localtunnel.me/). +``` + +
+ +### [IFTTT Maker](/nightscout/ifttt) + +In addition to the normal web based alarms, and pushover, there is also integration for [IFTTT Webhooks](https://ifttt.com/maker_webhooks). + +With Maker you are able to integrate with all the other [IFTTT Services](https://ifttt.com/services). For example you can send a tweet when there is an alarm, change the color of hue light, send an email, send and sms, and so much more. + +1. Setup IFTTT account: [login](https://ifttt.com/login) or [create an account](https://ifttt.com/join) +2. Follow the [Detailed IFTTT setup Instructions](https://github.com/nightscout/cgm-remote-monitor/blob/master/docs/plugins/maker-setup.md) +3. Configure Nightscout by setting these webpage environment variables: + +- `ENABLE` - `maker` should be added to the list of plugins, for example: `ENABLE="maker"`. +- `MAKER_KEY` - Set this to your secret key (see [[Detailed Instructions](https://github.com/nightscout/cgm-remote-monitor/blob/master/docs/plugins/maker-setup.md) ) `MAKER_KEY="abcMyExampleabc123defjt1DeNSiftttmak-XQb69p"` This also supports a space delimited list of keys. +- `MAKER_ANNOUNCEMENT_KEY` - An optional Maker key, will be used for system wide user generated announcements. If not defined this will fallback to `MAKER_KEY`. A possible use for this is sending important messages and alarms to another device that you don't want to send all notification too. This also support a space delimited list of keys. + +Plugins can create custom events, but all events sent to IFTTT webhooks will be prefixed with `ns-`. The core events are: + +- `ns-event` - This event is sent to the maker service for all alarms and notifications. This is good catch all event for general logging. +- `ns-allclear` - This event is sent to the maker service when an alarm has been acknowledged or when the server starts up without triggering any alarms. For example, you could use this event to turn a light to green. +- `ns-info` - Plugins that generate notifications at the info level will cause this event to also be triggered. It will be sent in addition to `ns-event`. +- `ns-warning` - Alarms at the warning level with cause this event to also be triggered. It will be sent in addition to `ns-event`. +- `ns-urgent` - Alarms at the urgent level with cause this event to also be triggered. It will be sent in addition to `ns-event`. +- see the [full list of events](https://github.com/nightscout/cgm-remote-monitor/blob/master/docs/plugins/maker-setup.md#events) + +
+ +### Treatment Profile + +Some of the [plugins](#plugins) make use of a treatment profile that can be edited using the [Profile Editor](/nightscout/profile_editor/). + +Treatment Profile Fields: + +- `timezone` (Time Zone) - time zone local to the patient. *Should be set.* +- `units` (Profile Units) - blood glucose units used in the profile, either "mg/dl" or "mmol" +- `dia` (Insulin duration) - value should be the duration of insulin action to use in calculating how much insulin is left active. Defaults to 3 hours. +- `carbs_hr` (Carbs per Hour) - The number of carbs that are processed per hour, for more information see [#DIYPS](http://diyps.org/2014/05/29/determining-your-carbohydrate-absorption-rate-diyps-lessons-learned/). +- `carbratio` (Carb Ratio) - grams per unit of insulin. +- `sens` (Insulin sensitivity) How much one unit of insulin will normally lower blood glucose. +- `basal` The basal rate set on the pump. +- `target_high` - Upper target for correction boluses. +- `target_low` - Lower target for correction boluses. diff --git a/_sources/nightscout/stringhelp.md.txt b/_sources/nightscout/stringhelp.md.txt new file mode 100644 index 00000000..f7916ff1 --- /dev/null +++ b/_sources/nightscout/stringhelp.md.txt @@ -0,0 +1,8 @@ +--- +orphan: true +--- + + + + + diff --git a/_sources/nightscout/tokens.md.txt b/_sources/nightscout/tokens.md.txt new file mode 100644 index 00000000..165b55b0 --- /dev/null +++ b/_sources/nightscout/tokens.md.txt @@ -0,0 +1,79 @@ +--- +orphan: true +--- + +***Note: authentication tokens are also called access tokens*** + +```{admonition} Changing API_SECRET +If you change your [`API_SECRET`](api-secret) all your tokens will change. Make sure you update your devices and send the new token link to those you allowed to access your Nightscout +``` + +To access the Authentication options, click the settings panel (three horizontal bars in the top right) in your website and select Admin Tools. The Authentication options are at the top of the Admin page. (Note: you must be logged in with your `API SECRET` to access these tools.) + + + +
+ +You will see several predefined roles: + + + +
+ +### Roles + +- **`admin`**: full access +- **`careportal`**: can view the site and make CarePortal/treatment entries +- **`readable`**: read-only access; no ability to make CarePortal/treatment entries. This user CAN see reports and profile information. +- **`denied`**: no access (this role only works if the `AUTH_DEFAULT_ROLES` setting is also `denied`. You can’t have a site that is readable to everyone and create a “denied” token for a specific user.) +- **`devicestatus-upload`**: used by devices + +```{hint} +There is currently no way to limit a user so that he cannot view the Reports section if he has access to the site. Time/date-based roles are not currently possible. +``` + +
+ +### Create a Token + +- Click the “Add New Subject” button. + + + +
+ +- Fill in the name of the subject and the “role” you are giving this subject (from the list of roles shown above). Note you should only grant the `readable` role for users who do not need to save or edit data in Nightscout. For example, you might want to share the site to a school nurse, but not have him able edit the data. + + + +- An `admin` token is necessary for AAPS to upload using the API V3. + + + +
+ +- Click save. +- The token will be shown. You can use it in two different ways: + - Copy the token URL (right-click on it in the browser and select the option to copy the link address) and provide it to the user (e.g., paste it into an email). If the user enters the entire URL (with token), the token will be in effect. + - Copy the token string (in the example below `school-a595d5f0aeff64c0`) and use it for authentication at site opening, instead of the API secret (Nightscout minimum version 14.1.0 required). + + + +
+ +You can also add the token to the site URL to authenticate using a token. Your site link with token will look like this: + +`https://yoursitename.yourplatform.com/?token=school-a595d5f0aeff64c0` + +Anybody with this link can use your Nightscout with the role defined for this token. + +```{hint} +If the user copies only your core URL into a browser, and your site is readable by default, the token will be bypassed. (Possible strategies to ensure the user puts the role-based URL into a browser include using a [tinyurl](https://tinyur.com/app) or [bit.ly](https://bitly.com).) +``` + +- You can edit a subject by clicking the edit icon, making changes, and saving. +- You can delete a subject by clicking the red **`X`** icon to remove the subject from the list. + +See [how to setup your downloaders (followers)](/nightscout/downloaders) with a secured site. + +
\ No newline at end of file diff --git a/_sources/nightscout/ubuntu.md.txt b/_sources/nightscout/ubuntu.md.txt new file mode 100644 index 00000000..39c9205a --- /dev/null +++ b/_sources/nightscout/ubuntu.md.txt @@ -0,0 +1,8 @@ +--- +orphan: true +--- + + + + + diff --git a/_sources/nightscout/wearable.md.txt b/_sources/nightscout/wearable.md.txt new file mode 100644 index 00000000..794e6aca --- /dev/null +++ b/_sources/nightscout/wearable.md.txt @@ -0,0 +1,252 @@ +# Nightscout on your Watch + +
+ +## Pebble Smartwatches + + + +Pebble smartwatch use is a historic milestone of CGM in the Cloud. Pebble has been bought by Fitbit in 2016 and necessary resources have moved to archives and [rebble.io](https://rebble.io/). Pebble support is still maintained in Loop, AndroidAPS, FreeAPS and xDrip+. + +You still can find the Pebble app for iOS in the [Apple Store](https://apps.apple.com/us/app/pebble/id957997620). For Android you need to download it from [APKMirror](https://www.apkmirror.com/apk/pebble-technology-corp/pebble/pebble-4-4-2-1405-62d45d7d7-endframe-release/pebble-4-4-2-1405-62d45d7d7-endframe-android-apk-download/) or [APKPure](https://apkpure.com/it/pebble/com.getpebble.android.basalt). + +For authentication and getting the watchfaces, the original server closed so you'll need to register with [Rebble](https://auth.rebble.io/auth/). + +You'll find Nightscout watchfaces [here](https://apps.rebble.io/en_US/search/watchfaces/1). Search for Nightscout, CGM, ... + +Configure the watchface with your Nightscout site URL. + +
+ +### [urchin](https://github.com/mddub/urchin-cgm) + +A Pebble watchface to view data from a continuous glucose monitor in graph format. + +
+ +If you want to use your Pebble with Loop look [here](https://loopkit.github.io/loopdocs/nightscout/pebble/), for AndroidAPS [here](https://androidaps.readthedocs.io/en/latest/EN/Configuration/Watchfaces.html#pebble) and FreeAPS [here](https://github.com/mddub/pancreabble). + +
+ +### [xDrip+](https://github.com/NightscoutFoundation/xDrip/releases) + +Enable Pebble Integration in Smartwatch features. + + + +
+ +You can answer no to default watchface install so that you will be able to select another one. You can then decide to install or not the snooze control. + + + +
+ +## [Android Wear OS smartwatches](https://wearos.google.com/#hands-free-help) + +With an Android smartphone. + +````{tab-set} + +:::{tab-item} Android Wear 1 +- Recommended: Install an old version of Android Wear on your phone (search APKMirror for example: Android Wear 2.9.0.185084575.gms) and pair your watch. Make sure to allow GPS and Wear OS access to position on the watch. Allow Wear OS to run in background on your phone. + +***Note:If you installed Wear OS, you will need to manually update the watch Google Play Services see [here](https://androidaps.readthedocs.io/en/latest/EN/Usage/SonySW3.html).*** + + - Once your smartwatch Google Play Service has been updated to a version above 9.x you can safely update Android Wear to Wear OS. + - Change the watchface to match your app (in Wear OS or on your watch). +::: + +:::{tab-item} Android Wear 2 +- Install [Wear OS](https://play.google.com/store/apps/details?id=com.google.android.wearable.app) on your phone and pair your watch. Make sure to allow GPS and Wear OS access to position on the watch. Allow Wear OS to run in background on your phone. + +- [Install](https://support.google.com/wearos/answer/7314014?hl=en) your app wear extension from the smartwatch Google Play store, selecting the apps installed on your phone.*Note: Newer versions of Wear OS do not support this feature anymore, use [Wear Installer](https://youtu.be/8HsfWPTFGQI) or Use [GeminiMan Wear OS Manager](https://play.google.com/store/apps/details?id=com.geminiman.wearosmanager) or [Easy Fire Tools](https://play.google.com/store/apps/details?id=de.agondev.easyfiretools).* + +- Change the watchface to match your app (in Wear OS or on your watch). +::: + +:::{tab-item} Android Wear 3 +- Install [Wear OS](https://play.google.com/store/apps/details?id=com.google.android.wearable.app) on your phone and pair your watch. Make sure to allow GPS and Wear OS access to position on the watch. Allow Wear OS to run in background on your phone. + +- Use [Wear Installer](https://youtu.be/8HsfWPTFGQI) or Use [GeminiMan Wear OS Manager](https://play.google.com/store/apps/details?id=com.geminiman.wearosmanager) or [Easy Fire Tools](https://play.google.com/store/apps/details?id=de.agondev.easyfiretools). + +- Change the watchface to match your app (in Wear OS or on your watch). +::: + + + +```` + +
+ +### [xDrip+](https://github.com/NightscoutFoundation/xDrip/releases) + +Enable Android Wear Integration to send xDrip+ BG to the smartwatch. Do not enable neither Collection nor Force Collection. + + + +Full xDrip+ wear documentation [here](https://github.com/jamorham/xDrip-plus/blob/master/Documentation/WatchGuide.md). + +*NB: you can also use [Tasker](#xdrip-with-tasker).* + +### [AndroidAPS](https://androidaps.readthedocs.io/en/latest/EN/Installing-AndroidAPS/Building-APK.html) + +For AndroidAPS [here](https://androidaps.readthedocs.io/en/latest/EN/Configuration/Watchfaces.html#aaps-on-wear-os-smartwatch). + +### [Glimp](https://play.google.com/store/apps/details?id=it.ct.glicemia) + +Select your Wearable device and enable the Glimp watchface. + + + +### [NightWear](https://github.com/rahim/nightwear) + +NightWear is a minimal Wear OS watch face and complication available in the [Google Play Store](https://play.google.com/store/apps/details?id=im.rah.nightwear) directly from your watch. + +It uses Wear's standalone app support, so requires no companion app installed on the phone, or no phone at all as long as the watch has an internet connection. This also means it's possible to display Nightscout data on a Google Wear OS watch paired with an Apple iPhone. + +
+ +## Amazfit Pace & Stratos + +### [xDrip+](https://github.com/NightscoutFoundation/xDrip/releases) + +- Install the [Amazfit watch app](https://play.google.com/store/apps/details?id=com.huami.watch.hmwatchmanager) on your phone. +- Install the [Amazfit tool](https://forum.xda-developers.com/t/tool-pace-stratos-verge-tool-all-in-one-drivers-unlock-twrp-factory-image.3874802/) on a Windows PC. +- Download the [widget](https://github.com/Klaus3d3/XdripWidgetForAmazfit-Klaus/releases) from the project author (Klaus3d3) GitHub [repository](https://github.com/Klaus3d3/XdripWidgetForAmazfit-Klaus). +- OEM unlock and enable USB debug on the watch, run TOOL ALL IN ONE and click the APK Installer button, select the widget apk file and INSTALL it. Close the install window and click Reboot System. +- In xDrip+, enable the Amazfit service and select the options you want to enable. + + + +*Original instructions [here](https://crazyinfo.de/2018/07/25/xdrip-smartwatch-widget-fuer-amazfit-pace-stratos).* + +
+ +## Xiaomi MiBand 2, 3, 4, 5 and 6 + +## Amazfit Band 5, Bip, Bip Lite, Bip S and Bip S lite, T-Rex Pro + +## Amazfit GTR2, GTR2e, GTS2, GTS 2 mini, GTS2e, GTR42 and 47 + +### xDrip+ + +Follow Artem's instructions [here](https://bigdigital.home.blog/). + +
+ +## Apple Watch + +### [Nightguard](https://apps.apple.com/us/app/nightguard/id1116430352#?platform=appleWatch) + +Apple Watch series 3 and above. + +[GitHub](https://github.com/nightscout/nightguard) + +
+ +### [sugarmate](https://sugarmate.io/) + +```{admonition} Important limitation +:class: warning +**Sugarmate doesn't allow Nightscout as a data source if you included `bridge` in `ENABLE`.** +If you need this data source: enable [obscuration](/nightscout/setup_variables.md#bridge-share2nightscout-bridge) variables. +``` + +You can setup sugarmate as a calendar complication to display Nightscout on your Apple watch. + +
+ +### [Gluco-Tracker](https://apps.apple.com/it/app/gluco-tracker/id1526976290?platform=appleWatch) + +
+ +### [Loop Follow](https://www.loopandlearn.org/loop-follow/) + +You can setup Loop Follow as a calendar complication to display Nightscout on your Apple watch. + +
+ +## Fitbit + +### [Nightscout Monitor](https://gallery.fitbit.com/details/eaed806d-9ff5-4aa9-a2c8-518f1f852f5a) + +Ionic/Sense/Versa/Versa 2/Versa 3/Versa Lite + +[Repository](https://github.com/sulkaharo/nsfitbit) + +
+ +### [Glance](https://gallery.fitbit.com/details/7b5d9822-7e8e-41f9-a2a7-e823548c001c) + +Ionic/Sense/Versa/Versa 2/Versa 3/Versa 4/Versa Lite + +[Web site](https://glancewatchface.com/) + +
+ +### [Sentinel](https://gallery.fitbit.com/developer/b50ac7f5-b932-441a-be18-e258b17c736b) + +Ionic/Sense/Versa/Versa 2/Versa Lite + +Facebook group: [Sentinel](https://www.facebook.com/groups/3185325128159614) + +
+ +### [Marclock](https://gallery.fitbit.com/details/9eacf714-5b23-40c8-9621-ded74bd9edf9) + +Ionic/Sense/Versa/Versa 2/Versa Lite + +[Instructions](https://github.com/cramis1/Marclock-with-CGM-weather/blob/master/README.md) + +
+ +### Analog watchfaces + +#### [Analog CGM](https://gallery.fitbit.com/details/4d7b46b1-aaba-49b4-aa10-183321014dd3) + +#### [Orbits NS](https://gallery.fitbit.com/details/44de5c81-b77c-4f90-baa8-38f3e3d28695) + +#### [Radial CGM](https://gallery.fitbit.com/details/0173730e-5381-4495-bc6e-6ec93c8df029) + +Ionic/Versa/Versa 2/Versa Lite/Versa 3/Sense + +
+ +## Samsung Gear Smartwatches + +### xDrip+ with Tasker + +*Note: also available for Android Wear devices* + +[Instructions](https://github.com/FreDiabetics/xDrip--Tasker-Tizen-Watchface-Integration/blob/master/README.md) + +
+ +### [G-Watch app](https://play.google.com/store/apps/details?id=sk.trupici.g_watch) + +Facebook group: [G-Watch App](https://www.facebook.com/gwatchapp) + +
+ +## Garmin Smartwatches and Computers + +By [Phimby](https://apps.garmin.com/en-US/developer/74d80f40-f80a-45c2-b934-321cc86f9dac/apps) + +By [Horsetooth](https://apps.garmin.com/en-US/developer/e985e9ec-bcf6-4aef-bfe9-77c1c93fc854/apps) + +By [andreas-may](https://apps.garmin.com/en-US/developer/f9420c47-810f-47ac-a7dd-9fa7b8ecd22d/apps) + +By [Fredrik_S](https://apps.garmin.com/en-US/developer/c3842ca7-a645-4758-b9ed-4ee6f8e3abec/apps) + +By [John_](https://apps.garmin.com/en-US/developer/b2d30711-2708-4f3a-8e83-009c16d07081/apps) + +By [floheigl](https://apps.garmin.com/en-US/apps/488ffa72-5994-4d0f-90ff-3eeb99f3ea41) + +
+ +## Karoo/Karoo 2 + +By [Henry Haspden](https://github.com/haspden/INFLITE-TYPE-ONE-Hammerhead-CGM#readme) + +
diff --git a/_sources/nightscout/wizard.md.txt b/_sources/nightscout/wizard.md.txt new file mode 100644 index 00000000..3592a01e --- /dev/null +++ b/_sources/nightscout/wizard.md.txt @@ -0,0 +1,143 @@ +# Help me choose + + + +## Welcome to the Nightscout new user wizard. + +This set of questions will hopefully help choose the best solution for you, or at least give you hints on where to start. + +```{hint} +*This wizard is thought for one Nightscout site (one patient with diabetes). If you need more Nightscout sites you might need more accounts. Some hosted providers provide discounts, T1Pal support up to 5 patients per subscription.* +``` + +
+ +| I want to contribute to Nightscout research and development.
| +| ------------------------------------------------------------ | +| **What is the maximum acceptable cost per month per site?**
| +| **How much of an issue is it when Nightscout is down?**
| +| **How much time are you ready to spend on creating and maintaining it?**
| + + + + + + + +
+ +Now click SHOW below to validate your choices. +If you change any option above, validate again to update.

+ + +```{card} +### **Database options** +^^^ +

-

+``` + +```{card} +### **Nightscout options** +^^^ +

-

+``` + +Made you mind? Have a look at your options: + +## Hosted + +[T1Pal](/index.md#t1pal) +[NS10BE](/index.md#ns10be) +[Nightscout Pro](/index.md#nightscout-pro) +[Serendipity Bio](/index.md#serendipity-bio) +[Nightscout4u](/index.md#nightscout4u) + +## Database + +[MongoDB Atlas](/vendors/mongodb/atlas.md) +[Railway Mongo Database](/vendors/railway/database.md) +[Northflank Mongo Database](/vendors/northflank/database.md) +VPS Mongo Database + +## Provider + +[Heroku Eco plan](/vendors/heroku/new_user.md) +[Railway](/vendors/railway/new_user.md) +[Northflank](/vendors/northflank/new_user.md) +[Fly.io](/vendors/fly.io/new_user.md) +[Azure](/vendors/azure/new_user.md) +[Render](/vendors/render/new_user.md) + +## VPS + +[Google Cloud](/vendors/google/new_user.md) +[Oracle Cloud](https://www.dropbox.com/s/5twlqrndofqno0t/0-amber-oracle.pdf) +[Advanced DIY](/nightscout/advanced) diff --git a/_sources/nightscout/xdripteam.md.txt b/_sources/nightscout/xdripteam.md.txt new file mode 100644 index 00000000..6b87e85f --- /dev/null +++ b/_sources/nightscout/xdripteam.md.txt @@ -0,0 +1,8 @@ +--- +orphan: true +--- + + + + + \ No newline at end of file diff --git a/_sources/pages/configure/index.md.txt b/_sources/pages/configure/index.md.txt new file mode 100644 index 00000000..06b8aa02 --- /dev/null +++ b/_sources/pages/configure/index.md.txt @@ -0,0 +1,456 @@ +--- +orphan: true +--- +```{warning} +Historical pages +``` + + Auto Configure Nightscout? + + + + + + + + +
+
+

How do we configure Nightscout?

+
+ +
+
+
+ +

Step 1: Sign up for an account at CloudMQTT

+

Click here to sign up and create your MQTT server

+

Step 2: Enter your MQTT server information below +

+
+
+ + +
+
+ +
+
+
+ +
+
+ +
+
+
+
+
+
+ REST API + + +

Enter your API_SECRET and REST API URL below.

+

Your API_SECRET must be 12 characters or more

+

Your REST API URL format should be https://foobar.azurewebsites.net/api/v1

+

Change foobar to your personal site name, and don't forget to add /api/v1 to the end of the URL.

+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +

Step 1: Sign up for a Mongolab account and create a database

+

+ Detailed instructions are available at nightscout.info. If you already have a Mongo database for Nightscout, skip this step. +

+

Step 2: Enter your Mongo server, port and database name

+

For example: ds012345.mongolab.com:12345/databasename

+
+ + +
+
+
+

Step 3: Enter the db username and password for your database

+ +
+ +
+
+ +
+
+
+

+

+ + + : + + @ + + / + + + +
+
+
+ + + + + + + + + + + + + + + + + +
+

Required

+
+ MONGO_CONNECTION + + + Custom +
+

Required for REST API

+
+ API_SECRET + + + Custom +
+
+
+
+
+
+
+
+

+ +

+
+

+      
+
+
+ + + +
+
+ + +
+ + diff --git a/_sources/pages/mongostring/index.md.txt b/_sources/pages/mongostring/index.md.txt new file mode 100644 index 00000000..7541caea --- /dev/null +++ b/_sources/pages/mongostring/index.md.txt @@ -0,0 +1,209 @@ +--- +orphan: true +--- + +```{warning} +Historical pages +``` + + + What's my mongodb URI? + + + + + + + +
+
+

What is my MONGODB URI?

+
+ Create database +

Step 1: Sign up for an account to manage your database

+

+ Mongolab has a free sign up. +

+

Step 2: Create a database

+
+ + +
+
+
+

Step 3: Create a user for your new database

+ Create a user for the database +
+ +
+
+ +
+
+
+

+

+ + + : + + @ + + / + + + +
+
+
+

+ +

+
+
+
+
+ + + +
+
+ + +
diff --git a/_sources/pages/update-fork/index.md.txt b/_sources/pages/update-fork/index.md.txt new file mode 100644 index 00000000..ad18ca10 --- /dev/null +++ b/_sources/pages/update-fork/index.md.txt @@ -0,0 +1,26 @@ +--- +orphan: true +--- + +# Update your Nightscout + +
+ +## The latest release is [15.0.2](https://github.com/nightscout/cgm-remote-monitor/releases/tag/15.0.0). + +
+ +| Platform | Link | +| -------------------------------------------------------- | ------------------------------------------------------------ | +| | Contact [T1Pal](https://t1pal.com/) | +| | Change branch in your [server](https://ns.10be.de/en/profile/server.html) | +| Nightscout.pro | Contact [Nightscout.pro](https://nightscout.pro/#contact) | +| | [Update](/update/update/) | +| | [Update](/update/update/) | +| | [Update](/update/update/) | +| | Google Cloud xDrip+
Continue [here](https://navid200.github.io/xDrip/docs/Nightscout/update_nightscout.html) | +| | [Update](/update/update/) | +| | [Update](/update/update/) | +| | [Update](/update/update/) | +| | Contact [Nightscout4u](https://www.nightscout4u.com/index.php/contact) | + diff --git a/_sources/translate.md.txt b/_sources/translate.md.txt new file mode 100644 index 00000000..0c679203 --- /dev/null +++ b/_sources/translate.md.txt @@ -0,0 +1,54 @@ +# Google Translate links + +عربي + +Български + +Čeština + +Deutsch + +Dansk + +Ελληνικά + +English + +Español + +日本 + +Suomi + +Français + +עברית + +Hrvatski + +Italiano + +한국어 + +Norsk + +Nederlands + +Polski + +Português + +Română + +Русский + +Slovenčina + +Svenska + +Turkish + +中文(简体 + +中文(繁體 + diff --git a/_sources/troubleshoot/atlas.md.txt b/_sources/troubleshoot/atlas.md.txt new file mode 100644 index 00000000..ba766586 --- /dev/null +++ b/_sources/troubleshoot/atlas.md.txt @@ -0,0 +1,903 @@ +# Troubleshoot MongoDB Atlas + +
+ +## Limit of one free cluster. + +When creating a new site or migrating (usually not the first attempt), when reaching `Target Cluster`. + + + +- Click the leaf top left in your Atlas account. Look at the `Project Name` you wanted to use when creating your new cluster, it shouldn't contain a cluster yet (like the example below, I tried to create a new Nightscout site but there is already a cluster inside the project I wanted to use). You can't have two clusters in a free project. Click your `Project Name`. +- This should not happen in normal conditions. Before deleting a cluster, check it doesn't contain your data! + + + +- Click on `Collections` in the cluster you selected. + + + +- Click on `entries` + + + +- In the case there is data, like in the example below, **don't use this cluster**. Leave it like this and create a new one. + + + +- **If there no data**, you can safely delete it. + + + +- In this cluster you want to delete click `...` then `Terminate` + + + +- Copy the cluster name to confirm then click `Terminate` + + + +- Wait until the operation completes. +- You can now use this project name to create a new site. + +
+ +## Meet your connection string + +For technical details look [here](https://docs.mongodb.com/manual/reference/connection-string/#mongodb-uri). + +A typical mLab migrated string will look like this: + +`mongodb+srv://heroku_0v50k8rf:ddfsjcpfu8fcoj9n6dueabfd5u@cluster0.g03wh.mongodb.net/ ` +`heroku_0v50k8rf?retryWrites=true&w=majority` + +A typical new string created with Atlas will look like this: + +`mongodb+srv://johndoe:V3ry53cr3t@cluster0.a01bc.mongodb.net/myCGMiC?retryWrites=true&w=majority` + +- It will start by `mongodb+srv://` with `mongodb` a **standard prefix** for a connection string, and `+srv` adding a security layer. + +- After `://` you'll find your **database username**, that is not your Atlas account username. In the examples above `heroku_0v50k8rf` or `johndoe`. + +- Following the username, a separator `:` and your **database password** that is not your Atlas account password. In the examples above a typical 26 characters password created automatically with the mLab add-on `ddfsjcpfu8fcoj9n6dueabfd5u` and a user created password `V3ry53cr3t`. + +- Following the password, a separator `@` then the **host name** that was provided by Atlas after you created you cluster. typically it will look like `cluster0.`*`a1b2c3`*`.mongodb.net` + +- [Optional] After the host name and the separator `/` you'll see your Nightscout **database name**. If you migrated from mLab it will be identical to your database username (unless you modified it). If you created your Atlas cluster it will be the one you decided. In the examples above `heroku_0v50k8rf` or `myCGMiC`. + +- Another separator `?` and you'll see two options: `retryWrites=true&w=majority` + +
+ +## Unable to connect to Mongo + + + +Common reasons: + +- The database is not available. If you don't have a database yet, create a new one. + If you do have a database, check it's functional then restart your web app: + +```{tab-set} + +:::{tab-item} Heroku +[Restart all dynos](/troubleshoot/heroku.md#restart-all-dynos) +::: + +:::{tab-item} Railway +[Restart your web app](/troubleshoot/railway.md#restart-your-app) +::: + +:::{tab-item} Azure +[Restart app](/troubleshoot/azure.md#restart-app) +::: + +:::{tab-item} Northflank +[Restart](/troubleshoot/northflank.md#restart) +::: + +:::{tab-item} Fly.io +[Restart your app](/troubleshoot/fly.io.md#restart-your-app) +::: + +:::{tab-item} Render +[Restart service](/troubleshoot/render.md#restart-service) +::: + +``` + +- Your Atlas connection string is incorrect. Check [here](#bad-connection-string). + +### MongoDB paused + +- If you haven't been using Nightscout for a while but it was working before, check the database didn't go to sleep mode. If it did, select `Resume` to restart it. +- Once done: + +```{tab-set} + +:::{tab-item} Heroku +[Restart all dynos](/troubleshoot/heroku.md#restart-all-dynos) +::: + +:::{tab-item} Railway +[Restart your web app](/troubleshoot/railway.md#restart-your-app) +::: + +:::{tab-item} Azure +[Restart app](/troubleshoot/azure.md#restart-app) +::: + +:::{tab-item} Northflank +[Restart](/troubleshoot/northflank.md#restart) +::: + +:::{tab-item} Fly.io +[Restart your app](/troubleshoot/fly.io.md#restart-your-app) +::: + +:::{tab-item} Render +[Restart service](/troubleshoot/render.md#restart-service) +::: + +``` + + + +
+ +If you see this message + + + +- [Update to latest version](/vendors/github/update/) and come back after you have a more accurate error message. + +
+ +## MongoDB in read only mode + +If you see this message: + + + +- Verify your database is not read only, else click `Edit` + + + +- Change the permissions to `Atlas Admin` and `Update User` + + + +- Once done: + +```{tab-set} + +:::{tab-item} Heroku +[Restart all dynos](/troubleshoot/heroku.md#restart-all-dynos) +::: + +:::{tab-item} Railway +[Restart your web app](/troubleshoot/railway.md#restart-your-app) +::: + +:::{tab-item} Azure +[Restart app](/troubleshoot/azure.md#restart-app) +::: + +:::{tab-item} Northflank +[Restart](/troubleshoot/northflank.md#restart) +::: + +:::{tab-item} Fly.io +[Restart your app](/troubleshoot/fly.io.md#restart-your-app) +::: + +:::{tab-item} Render +[Restart service](/troubleshoot/render.md#restart-service) +::: + +``` + +
+ +## `MONGODB_URI` missing + +If you see this message: + + + +- If you don't have a database yet, create a new one. +- It might be a transient error in MongoDB Atlas, try to restartyour web app: + +```{tab-set} + +:::{tab-item} Heroku +[Restart all dynos](/troubleshoot/heroku.md#restart-all-dynos) +::: + +:::{tab-item} Railway +[Restart your web app](/troubleshoot/railway.md#restart-your-app) +::: + +:::{tab-item} Azure +[Restart app](/troubleshoot/azure.md#restart-app) +::: + +:::{tab-item} Northflank +[Restart](/troubleshoot/northflank.md#restart) +::: + +:::{tab-item} Fly.io +[Restart your app](/troubleshoot/fly.io.md#restart-your-app) +::: + +:::{tab-item} Render +[Restart service](/troubleshoot/render.md#restart-service) +::: + +``` + +- Check your [database is not full](#database-full)! +- If your Nightscout was still functional after November 11th 2020, continue [below](#bad-connection-string) to recover: + +
+ +## Generic Unable to connect to Mongo + +If you see this message: + + + +- Check you authorized all IPs to access your Atlas database: +- Open your Atlas cluster and select your Nightscout project, then `Network access` + + + +- If you see an IP (in red above) instead of 0.0.0.0/0 click `Edit` select `ALLOW ACCESS FROM ANYWHERE` then `Confirm`. + + + +- Once done: + +```{tab-set} + +:::{tab-item} Heroku +[Restart all dynos](/troubleshoot/heroku.md#restart-all-dynos) +::: + +:::{tab-item} Railway +[Restart your web app](/troubleshoot/railway.md#restart-your-app) +::: + +:::{tab-item} Azure +[Restart app](/troubleshoot/azure.md#restart-app) +::: + +:::{tab-item} Northflank +[Restart](/troubleshoot/northflank.md#restart) +::: + +:::{tab-item} Fly.io +[Restart your app](/troubleshoot/fly.io.md#restart-your-app) +::: + +:::{tab-item} Render +[Restart service](/troubleshoot/render.md#restart-service) +::: + +``` + +
+ +## Bad connection string + +If you see this message: + + + +
+ +- [Edit your Nightscout configuration](/nightscout/setup_variables) and search for a variable called `MONGODB_URI` or `MONGO_CONNECTION`. + +- If you find none, go [here](#recover-your-connection-string). + +```{admonition} MONGODB_URI or MONGO_CONNECTION +:class: warning +There should be at least one and only one of them, not both. +``` + +If you migrated from mLab Heroku add-on it is usually `MONGO_CONNECTION` + +if you deployed a brand new Nightscout it should be `MONGODB_URI` + +- Verify it is looking like this: + +`mongodb+srv://atlasusername:atlaspassword@cluster0.zzzzz.mongodb.net/dbname?retryWrites=true&w=majority` + +Note that your `atlasusername`, `atlaspassword` and `dbname` will be different from the example above. + +- Paste the string in the box below: + + +
+ +- Click the `Analyze` text below: + + + +

Analysis result will appear here.

+ +If the analysis result doesn't show any error, check below the data is what you actually wanted: + +**Database Username:**

...

+**Database Password:**

...

+**Database name:**

...

(No database name is not an error) + + + +```{hint} +If you migrated from Heroku mLab add-on, your database username and database name should be identical. +``` + + + +
+ +If you've just created a new site, try to use [this help page](/_static/stringhelp.html) to verify or recreate it. + +
+ +If you're still in trouble continue below: + +
+ +## Recover your connection string + +If you've tried several times to deploy or migrate, you might end-up with many useless items in your accounts. At this point, you could benefit doing some cleanup in order to identify the correct Atlas database you want to connect to. Consider [cleanup](#cleanup) before continuing. + +
+ +a) Go to your MongDB account. Log in if necessary [https://cloud.mongodb.com/](https://cloud.mongodb.com/) + +b) Click `Connect` below your cluster name (in the example below `Cluster0`, but it might have another name) + + + +
+ +c) Click `Connect your application` + + + +
+ +d) A new view opens, in `(2) Add your connection string into your application code` you will find your `MONGODB_URI` or `MONGO_CONNECTION` string. + +Click `Copy` then `Close` + + + +
+ +e) Paste it into a place where you can edit the text (i.e. a Word or a Notepad document). + +Edit your string so that you add the database user password after the database user info. You defined them during your MongoDB Atlas database creation, when you reached [step **e)**](/vendors/mongodb/atlas/). + +Here’s an example of how the string is built up (`myFirstDatabase` might not show, this is normal): + +`mongodb+srv://` `nightscout` `:`**``**`@cluster0.xxxxx.mongodb.net/`**`myFirstDatabase`**`?retryWrites=true&w=majority` + +
+ +f) Edit your string in order to replace `` with your database password. + +g) If you don't remember your Atlas database password (which should not be your mongoDB Atlas account password) invent a new one (only letters and numbers). + +Your string will now look like this: (do not use the same password as the example). Note there are no remaining `<` and `>`. +If you don't see a database name like `myFirstDatabase` before the question mark, just ignore it. + +`mongodb+srv://nightscout:soo5ecret@cluster0.xxxxx.mongodb.net/myFirstDatabase?retryWrites=true&w=majority` + +
+ +h) Copy this resulting string above into your `MONGODB_URI` or `MONGO_CONNECTION` variable. There must be only one of these variables, not both. + +See [here](/nightscout/setup_variables) how to edit your configuration variables. + +i) If there is neither one nor the other create a new `MONGODB_URI` variable and paste the string in the value field. + +j) If you remembered your password restart your web app, and you should be done. + +k) If you changed your password or your Nightscout page still fails to open continue. + +
+ +## Change your Atlas database password + +- If you changed the password in the string you will need to change it in the database too: + +- Click `Database Access` + + + +
+ +- At the end of the line, click `Edit` + + + +
+ +- In `Password` click `Edit Password` + +```{hint} +*Take a look at the top of this view, after `Edit User` you can see your database user name before `@`. Check it's matching the one in your connection string.* +``` + + + +
+ +- If you forgot your password invent a new one (use only letters and numbers: no special characters) or better: use `Autogenerate Secure Password` and click `Copy` +- Else make it the same than the one in your `MONGODB_URI` connection string variable + + + +
+ +- Click `Update User` + + + +
+ +- Make sure the password matches in your connection string variable `MONGODB_URI` or `MONGO_CONNECTION` + +
+ +## Database full + +Free databases like M0 Sandbox provided by Atlas will only hold a limited amount of data (512MB) and you will eventually need to manually cleanup. You can extend the capacity to 2 and 5GB paying for an M2 or M5 Shared cluster. + +**Note:** *If you consider paying for a database upgrade, also think about a [paid hosting service](/index.md#nightscout-as-a-service).* + +```{warning} +Make sure your Nightscout site has `Database Size` enabled to monitor database capacity.
+In order to have the database size pill, add `dbsize` in the `ENABLE` variable.
+Look [here](/nightscout/setup_variables.md#dbsize-database-size) for more information on this plugin. +``` + + + +
+ +```{hint} +Your database size might not decrease immediately (it might even increase temporarily) after you perform cleanup with Admin Tools (see below: Normal cleanup). Allow a few hours to see the effects. In the meantime your site should recover functionality.
If your site keeps crashing, go ahead to emergency cleanup. +``` + +
+ +### Restart + +**Try to recover temporary access to Nightscout to perform normal cleanup:** + +```{tab-set} + +:::{tab-item} Select your platform -> +
+::: + +:::{tab-item} Heroku +[Restart all dynos](/troubleshoot/heroku.md#restart-all-dynos) +::: + +:::{tab-item} Railway +[Restart your web app](/troubleshoot/railway.md#restart-your-app) +::: + +:::{tab-item} Azure +[Restart app](/troubleshoot/azure.md#restart-app) +::: + +:::{tab-item} Northflank +[Restart](/troubleshoot/northflank.md#restart) +::: + +:::{tab-item} Fly.io +[Restart your app](/troubleshoot/fly.io.md#restart-your-app) +::: + +:::{tab-item} Render +[Restart service](/troubleshoot/render.md#restart-service) +::: + +:::{tab-item} Google Cloud +The probability your database is full is very low, make sure you selected the maximum disk size for your compute engine. See [Here](https://navid200.github.io/xDrip/docs/Nightscout/FullDisk.html). +::: + +:::{tab-item} Hosted services +Contact your provider. The probability your database is full is virtually null. +::: + +``` + +### Normal cleanup + +You can cleanup (enter the number of days to keep) or delete your devices status (recommended as a first recovery action): + + + +Same for `Treatments`: + + + +And `Glucose entries`. If you are reluctant to lose historical data you should consider opting for a paid database solution or [hosted](/index.md#nightscout-as-a-service) Nightscout. + + + +If your Nightscout page doesn't open after restarting your app and you want to rule out a full database, you can try an emergency cleanup of the less important part of your Nightscout site: `devicestatus`. + +
+ +### Emergency cleanup + +- Log in [Atlas](https://account.mongodb.com/account/login) +- Open your Nightscout database and select `Browse collections` in `Database` + + + +- Select the `devicestatus` collection and click the bin icon to delete it. + +- You will lose all device status history (battery, ..) but **you won't lose neither BG, treatments nor profiles**. + + + +- Write `devicestatus` in the box then click `Drop` + + + + +- [Restart](#restart) your site and when it opens, consider again [cleanup](#normal-cleanup) from Admin Tools if your database size exceeds 80%. + +
+ +### Atlas database size verification + +- Log in [Atlas](https://account.mongodb.com/account/login) +- Open your Nightscout database and select `Collections` + + + +
+ +- Click your database name (hidden left). Check the`DATABASE SIZE` is indeed close to or at the limit (512MB) then look at these three collections `Documents size`: `devicestatus`, `entries` and `treatments`. + + + +- Open Nightscout [`Admin tools`](/nightscout/discover.md#drawer-menu). If your site doesn't open jump to [Emergency cleanup](#emergency-cleanup). +- Depending on the collection you identified above, choose which of the following you want to cleanup. + +
+ +## Reports slow loading or timeout + +Loopers might experience Nightscout taking an extremely long time or even timing out when creating reports due to the profiles collection database growing too big. + +Two solutions are available: + +1. Follow this video (set it full screen in 720p) to selectively delete profiles [https://www.youtube.com/watch?v=iipp0MfPKNQ](https://www.youtube.com/watch?v=iipp0MfPKNQ) +2. Delete all profiles in Atlas + +Log in to Atlas [https://account.mongodb.com/account/login](https://account.mongodb.com/account/login) + +Select your cluster then `COLLECTIONS` + + + +
+ +Select the `profile` collection and click the bin icon to delete all profiles. + + + +
+ +Write `profile` in the box then click `Drop` + + + +
+ +Open your Nightscout and create a new profile (mind the time zone!), authenticate and save it. + +If you are using Loop, temporarily change a basal rate in Loop, and confirm your profiles now show up in Nightscout. + +
+ +## Data in the future + +First try to [remove future items with the Admin Tools](/nightscout/admin_tools.md#remove-future-items-from-database). + +If it doesn't give the expected result: + +- Check in [Atlas](https://account.mongodb.com/account/login) + +- Open your Nightscout cluster and select `Collections` + + + +
+ +- In `Entries` type `{date:-1}` and click `Find` + + + +
+ +- Delete the entries in the future (manually) with the bin icon + + + +
+ +## Cleanup + +It is very easy to get lost in Atlas. + +The structure from top to bottom is: Organization, Projects and Databases. You can have several organizations, each of them several projects and each of them several databases. + +```{hint} +If you are deploying a brand new Nightscout make sure you have one organization, one project and one cluster created. No more no less. +``` + +If you want to cleanup Atlas, unless you don't have data, you must first find out which database contains your data. For this, start from `View All Organizations`: + + + +You can delete empty organizations (those without any project inside). + + + +Select the organization, then top left the cog wheel to go in `Settings`, then scroll down to `Delete Organization`: `Delete`. + + + +Deleting an organization without projects will not delete your data. + + + +------ + +Once inside an organization, you will see its projects. You can safely delete projects without clusters. + + + +Deleting an empty project doesn't delete your Nightscout data. + + + +For non-empty projects continue reading before deciding to delete them. + +------ + +You can then move to your project (select it) and check its database(s) selecting `COLLECTIONS` + + + +An empty project will look like below, and this is typically what you have before deploying Nightscout. Once Nightscout is deployed in a project, a new database will be created there. + + + +The database currently used by your Nightscout is the one specified in the connection string, in the example below `dbname`. Whenever you change the database name in the connection string, a new database will be created in your project. + +`mongodb+srv://atlasusername:atlaspassword@cluster0.zzzzz.mongodb.net/`**`dbname`**`?retryWrites=true&w=majority` + +There is usually one database for Nightscout, if there are several, select one and then the other(s) to understand which one contains your data. For this, select `entries`. + + + +A large database is most probably one you want to keep. + + + +You can safely delete empty databases (check the size first). + + + +```{warning} +If you're not sure you're deleting the right database, just leave it. +``` + +Hover on the database name and click the bin icon. Confirm deletion by copying the database name and click `Drop`. + + + +If your database gets recreated after you deleted it this means your `MONGODB_URI` or `MONGO_CONNECTION` string is pointing to it. + +
+ +If you want to delete a non-empty Project you need to terminate all clusters belonging to it. + + + +```{warning} +Terminating a cluster will delete all information and databases in this cluster! +``` + +Confirm with your cluster name and wait until shutdown is complete. + + + +You can then delete the empty project. + +
+ +## Backup your database + +```{admonition} Not a normal operation +:class: warning +Making a backup of your database is either a good idea or necessary if you want to migrate it to another database. +This is not an easy operation and requires command line instructions using a computer. +``` + +### Install the database tools + +Follow [this link](https://www.mongodb.com/docs/database-tools/installation/installation/) to install the CLI tool on your computer. + +### Dump your database + +Get your `MONGODB_URI` handy to find the missing pieces (password and database name). + +Log in your MongoDB account [https://cloud.mongodb.com/](https://cloud.mongodb.com/). + +1. Select your organization +2. Select your database +3. In the advanced options menu, select `Command line tools` + + + +
+ +Scroll down to `Binary import and Export tools`, copy the `mongodump` command line. + + + +Paste the command line in a text editor. + +Look into your `MONGODB_URI` and replace `` with your database password and entually (if you have one) `` with your database name. + + + +
+ +Open a command line utility (CMD, Terminal, ...) and make your way to the utility folder (if you don't want to include it in your system path). +For example in Windows 64bits it's in `C:\Program Files\MongoDB\Tools\100\bin`. + +Copy and paste your `mongodump` command, run it. + + + +
+ +You will find the database dump in a subfolder called `dump` with your database name in a subfolder. + + + +
\ No newline at end of file diff --git a/_sources/troubleshoot/azure.md.txt b/_sources/troubleshoot/azure.md.txt new file mode 100644 index 00000000..3118b0b1 --- /dev/null +++ b/_sources/troubleshoot/azure.md.txt @@ -0,0 +1,36 @@ +# Troubleshoot Azure + +
+ +## Error 403 + +This usually happens when you reach free credits limit. +Make sure you have an active [Basic plan subscription](https://azure.microsoft.com/en-us/pricing/purchase-options/pay-as-you-go/). If you only used free services as specified in the installation guide, you shouldn't be billed. + + + +

+ +## Restart app + +Log in [Azure](https://portal.azure.com/#home) and select your App Service (`cgmitc` in the picture is an example, yours will have a different name). + + + +
+ +Click on Restart and confirm. Wait a few minutes until restart completes. + + + +

+ +## Billing occurred + +Make sure you didn't add technical support. + +Check [here](https://portal.azure.com/#view/Microsoft_Azure_Support/HelpAndSupportBlade/~/overview) and click the link at the top of the page: Choose the right support plan. + +You should have a Basic support plan, that is free. + +
\ No newline at end of file diff --git a/_sources/troubleshoot/cleanup.md.txt b/_sources/troubleshoot/cleanup.md.txt new file mode 100644 index 00000000..97ec4d38 --- /dev/null +++ b/_sources/troubleshoot/cleanup.md.txt @@ -0,0 +1,38 @@ +--- +orphan: true +--- + +# Cleanup + +After unsuccessful attempts you might want to cleanup the various accounts to avoid confusion. + +If you're still trying to deploy your first Nightscout, ignore all data loss recommendations below. + +If you have a large amount of CGM data, be extra cautious when performing Atlas cleanup. + +
+ +## [GitHub](https://github.com/login) + +The most efficient way to cleanup GitHub and restart with an up-to-date Nightscout project is to [redeploy](/update/redeploy.md) it. + +You will then need to reconnect your repository to [Heroku](/troubleshoot/heroku.md#cannot-find-cgm-remote-monitor-in-heroku-item-cannot-be-retrieved) or [Railway](/troubleshoot/railway.md#reconnect-github-to-your-project). + +
+ +## [Heroku](https://id.heroku.com/) + +Look [here](/troubleshoot/heroku.md#cleanup). + +
+ +## [Atlas](https://account.mongodb.com/account/login) + +Look [here](/troubleshoot/atlas.md#cleanup). + +
+ +## [Railway](https://railway.app) + +Look [here](/troubleshoot/railway.md#cleanup). + diff --git a/_sources/troubleshoot/connection_string.md.txt b/_sources/troubleshoot/connection_string.md.txt new file mode 100644 index 00000000..6ef2af92 --- /dev/null +++ b/_sources/troubleshoot/connection_string.md.txt @@ -0,0 +1,7 @@ +--- +orphan: true +--- + +# Connection string + +Moved [here](/troubleshoot/atlas.md#unable-to-connect-to-mongo). \ No newline at end of file diff --git a/_sources/troubleshoot/dexcom_bridge.md.txt b/_sources/troubleshoot/dexcom_bridge.md.txt new file mode 100644 index 00000000..20947fb4 --- /dev/null +++ b/_sources/troubleshoot/dexcom_bridge.md.txt @@ -0,0 +1,159 @@ +# Troubleshoot Dexcom Share + +
+ +## Username and password + +Your Dexcom account is the one that identifies you to access all services: Store, Clarity and mobile apps. In order to make sure you're accessing the right account, log into Clarity to check your credentials are valid. + +For US account: [https://clarity.dexcom.com/](https://clarity.dexcom.com/) +For all others: [https://clarity.dexcom.eu/](https://clarity.dexcom.eu/) + + + +In the case you have linked accounts, check you are using the right credentials for the profile you want to `bridge` to Nightscout. + +**Verify you actually have current data in this profile/account!** You want to put the username and password of the account that has CGM data in `BRIDGE`, this is usually the credentials you are using with the master phone (the one connected to the sensor). + + + +```{admonition} Password +:class: tip +Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters. +``` + +```{admonition} Changing password +:class: warning +Before you decide to change your password, make sure to update your Nightscout variables accordingly and make sure you have recent data in Clarity before exiting maintenance mode. +``` + +
+ +## Username is an email + +Newly created Dexcom users do not have an username but only an email address. + + + +This can be an issue if you want to use `bridge` to have your data directly in Nightscout. Make sure you're using the [latest release](/update/update/) if you experience problems. + +Common symptoms are: + +- no data in Nightscout even with correct credentials +- account locking once or more per day even with correct credentials + +
+ +## Username is a phone number + +New users might have the phone app setup with their phone number including country code and the symbol `+`. This is not supported by Nightscout. Continue below and create a dependent account with an alphanumerical username. + +
+ +## Obtaining a username + +Dependent accounts can have a username. + + + +You can create your Dexcom account and add dependent accounts for children, wife, ... + +Some dependent accounts with an email address can generate problems when trying to connect directly to Nightscout. + +
+ +## Account lock + +You can check if your account is locked by trying to log into Clarity. + + + +If you see this message, you must disable (enter an empty username for example) all devices and apps trying to get data from or push data into Dexcom share. + +In order to recover from an account lock, it is usually enough to wait for 10-15 minutes after you disabled all devices and apps trying to access the account with a wrong password. + +Do not forget any app or device! + +- Nightscout +- Smartwatches apps +- Sugarmate, Happy Bob, xDrip+,... +- ... + +
+ +## Dexcom Share + +Make sure you have Dexcom Share turned ON in your Dexcom app. In the Dexcom app's main screen, find the triangle made of dots. If the dots are grey, you do not have Share turned on. Tap the triangle, and follow the directions to add a follower (yourself if you don't have someone else you'd like to invite) and turn on Share. + + + +
+ +If you are using a Dexcom system, and your data is not appearing in Nightscout, there are only a limited number of reasons for that. You should check your (1) Heroku settings and (2) Dexcom Share. + +NOTE: The #1 reason why BGs aren't showing is that you have mismatched password and user names in Heroku settings and Dexcom. + +### Verify your configuration + +Variables location will depend on the platform you use: + +````{tab-set} + +:::{tab-item} Heroku +[**→ Here**](/vendors/heroku/new_user.md#editing-config-vars-in-heroku) +::: + +:::{tab-item} Railway +[**→ Here**](/vendors/railway/new_user.md#editing-variables-in-railway) +::: + +:::{tab-item} Northflank +[**→ Here**](/vendors/northflank/new_user.md#editing-variables-in-northflank) +::: + +:::{tab-item} Azure +[**→ Here**](/vendors/azure/new_user.md#editing-config-vars-in-azure) +::: + +:::{tab-item} Fly.io +[**→ Here**](editing-config-vars-in-fly-io) +::: + +:::{tab-item} Google Cloud +[**→ Here**](https://navid200.github.io/xDrip/docs/Nightscout/NS_Variables.html) +::: + +```` + +
+ +1. You must use the same `BRIDGE_PASSWORD` or `BRIDGE_USER_NAME` that your Dexcom mobile app is using. +2. You must have `bridge` and `careportal` on the `ENABLE` line (you can have other values there...but don't forget these two). +3. If you are outside the USA, you must add `BRIDGE_SERVER` set to `EU` in Heroku settings. +4. Your `careportal` must be one word in the `ENABLE` line, sometimes autocorrect makes it two words. +5. If using `mmol`, make sure you have spelled that value correctly in the `DISPLAY_UNITS`. + +
+ +### Authentication errors + +One thing that can happen if you have an incorrect Dexcom login/password in your Share account settings and/or in your Nightscout `BRIDGE` settings is that Dexcom will lock your account...and you won't see CGM data in Nightscout. If you notice your CGM readings disappeared, but everything else is flowing... +Check your Heroku logs that are viewable by selecting `View Logs` from the drop-down menu underneath the `More` option. + + + +With Railway they are available selecting your app, then `Deployments` and `View Logs` at the end of the top (last) deployment line. + + + +
+ +Do your logs have "`SSO authentication errors`" like in the red box highlighted above? If you do, then: + +1. Delete your `BRIDGE` entries within Heroku settings. Don't delete the variables, just delete the values of `BRIDGE_PASSWORD` and `BRIDGE_USER_NAME`. +2. Wait 15 minutes and then follow the directions below. It is important to wait 15 minutes: the reason you can't log in right now is that your Dexcom account has a temporary lock from the passwords in the step above being incorrect. The temporary lock will expire after 10-15 minutes of giving the account login a break from the incorrect logins. So, definitely wait or else you'll just keep prolonging the issue. + +```{hint} About your Bridge password and user name +The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom's Clarity page (check [here for USA accounts](https://clarity.dexcom.com) and [here for the others](https://clarity.dexcom.eu)) and try logging in to your Dexcom account. If your account info isn't valid, or you don't see any data in your Clarity account... you need to figure out your actual credentials before moving ahead. +``` + diff --git a/_sources/troubleshoot/fly.io.md.txt b/_sources/troubleshoot/fly.io.md.txt new file mode 100644 index 00000000..cfa0c2a6 --- /dev/null +++ b/_sources/troubleshoot/fly.io.md.txt @@ -0,0 +1,272 @@ +# Troubleshoot Fly.io + +
+ +```{warning} +The web terminal feature was removed from Fly.io. +You need a computer with flyctl. +``` + +Follow [these instructions](https://fly.io/docs/hands-on/install-flyctl/) to install `flyctl` on your computer. You also need to [install git](https://git-scm.com/downloads) if you're using a Windows computer. + +*Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.* + +

+ +## Restart your app + +Follow [these instructions](https://fly.io/docs/hands-on/install-flyctl/) to install `flyctl` on your computer. + +*Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.* + +- Log in Fly.io: + +`flyctl auth login` + +- Verify your Nightscout app name + +`flyctl app list` + +- Restart your app (replace `example-ns` by the name of your Nightscout app in Fly.io) + +`flyctl machine restart --app example-ns` + +
+ +(recover-fly-toml)= + +## Recover `fly.toml` + +Follow [these instructions](https://fly.io/docs/hands-on/install-flyctl/) to install `flyctl` on your computer. + +*Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.* + +- Log in Fly.io: + +`flyctl auth login` + +- Verify your Nightscout app name + +`flyctl app list` + +- Copy your Nightscout app (replace `example-ns` with your own) configuration file `fly.toml`. + +`flyctl config save --app example-ns` + +- Keep this file in a safe place as you'll need it to redeploy or upgrade your Nightscout. + +
+ +## Cleanup + +After several failed attempts to deploy or migrate, you might need to delete some apps. + +Log into Fly.io [https://fly.io/app/sign-in](https://fly.io/app/sign-in) (GitHub recommended) + + + +In normal running condition you will see only two apps on your dashboard: +The first one is your Nightscout site and the second one the builder (necessary). +If you used the migration wizard you will see another builder (three apps). + + + +
+ +Clicking on your site you will see if it's healthy and running. This is where you go to open your site. + + + +
+ +### Delete an app + +Select an app from the dashboard. Then click `Settings`. +Click `Delete app`. + + + +Confirm copying the app name below, then click `Yes, delete it`. + + + +You have deleted your app. + +If you delete the builder (like in the picture above) you won't be able to deploy anymore. + +
+ +### Delete your local repository + +#### If you deployed with your own computer. + +```{warning} +Make a backup of the `fly.toml` file present in the `cgm-remote-monitor` folder! +This is essential to make your site maintainable! +``` + +You can delete the `cgm-remote-monitor` folder on your computer and fork it again. + +Exit the folder before deleting it, in task manager end the `flyctl.exe` task. + +#### If you deployed from the web terminal. + +You don't have a local repository. + +
+ +## Downscale your app + +Follow [these instructions](https://fly.io/docs/hands-on/install-flyctl/) to install `flyctl` on your computer. + +*Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.* + +
+ +March 31st 2023, apps deploy in V2 and V1 apps are automatically migrated too. +This causes some issues as V2 automatically deploys in a more than one machine, your Nightscout site might not work correctly. + +Type the following command in the terminal (replace ***`example-ns`*** with your own app name): + +- Authenticate in Fly.io: + + +`flyctl auth login` + +- Verify your Nightscout app name + +`flyctl app list` + +- Downscale your app: + +`flyctl scale --app `***`example-ns`***` count 1` + + + +- Your app should now only be running on one machine. Check [here](https://fly.io/dashboard/personal/machines). + + +***Note:*** *the builder app is normal, it is stopped: don't worry about it.* + + + +
+ +## Obtain a free shared IP + +Follow [these instructions](https://fly.io/docs/hands-on/install-flyctl/) to install `flyctl` on your computer. + +*Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.* + +
+ +Apps migrated from Heroku will use a dedicated IP billed $1.90/month. + +If you want to run your Nightscout site in Fly.io for free, you will need to release the IP and request a shared IP. + +Follow the instructions below. The IP `137.66.11.78` and the site name `example-ns` are examples, yours will be different. Use your own IP and site name. + +Open a browser and authenticate: + +`flyctl auth login` + +List the apps to see the name of your Nightscout project: + +`flyctl app list` + +``` +NAME OWNER STATUS PLATFORM LATEST DEPLOY +example-ns personal deployed machines 2023-05-26T07:24:51Z +``` + +List the IPs used by your app (replace *`example-ns`* by your own): + +`flyctl ips list -a example-ns` + +``` +VERSION IP TYPE REGION CREATED AT +v4 137.66.11.78 public global 2022-09-13T14:17:58Z +v6 3b09:8280:1::3:723c public global 2022-09-13T14:18:00Z +``` + +Release the dedicated IP you found above (example: 137.66.11.78): + +`flyctl ips release 137.66.11.78 -a example-ns` + +``` +Released 137.66.11.78 from example-ns +``` + +Assign a shared IP to your Nightscout site: + +`flyctl ips allocate-v4 --shared -a example-ns` + +``` +v4 shared global +``` + +You do not need to remember your new IP, just continue using your site name as before: https://yoursitename.fly.dev + +
+ +## Migrate from Heroku + +```{warning} +Turboku has been removed from the CLI. This section is obsolete. +``` + +Log into Heroku. + +- Write down your Nightscout app name from the [dashboard](https://dashboard.heroku.com/apps). +- Get your **API Key** from your [account settings](https://dashboard.heroku.com/account). Do not share it publicly. + +Look into [this list](https://fly.io/docs/reference/regions/) and find a free region close to where you live. This is a 3 letters code, for example `ams`. + +Open a terminal or an elevated command prompt. + +*Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.* + +- Log in Fly.io: + +`flyctl auth login` + +- Replace `example-ns` with your Nightscout app from Heroku, `API-Key` with your Heroku API Key and `xxx` with the region you selected. + +`flyctl turboku example-ns API-Key --region xxx` + +- Your Heroku app will deploy in Fly.io. Wait until deployment completes. +- You'll see the name of your new Nightscout site with Fly.io. + +``` +Finished launching new machines +------- + ✔ Machine 784e290f461048 [app] update finished: success +------- +Visit your newly deployed app at https://example-ns.fly.dev/ +``` + +- Downscale the app, confirm when requested. + +`flyctl scale --app example-ns count 1` + +- Turn your Heroku site off (the switch `web node lib/server/server.js`) and check your new Fly.io Nightscout is running. +- Log into Fly.io, [select your app](https://fly.io/apps) and verify it's using a share V4 IP, release the V6 IP. + +
+ +```{warning} +Make a backup of your fly.toml! +This is essential to make your site maintainable! +``` + +- Fly deployment created a folder with your app name, you'll find your `fly.toml` file inside. This file is all what you need to redeploy your project. You will need it to upgrade your Nightscout site or redeploy it. + + + +```{warning} +Make a [backup of your Heroku variables](/troubleshoot/heroku.md#backup-your-site-variables)! +Fly.io will store then as secrets and you won't be able to read them! +``` + +
+ diff --git a/_sources/troubleshoot/github.md.txt b/_sources/troubleshoot/github.md.txt new file mode 100644 index 00000000..6a375ccf --- /dev/null +++ b/_sources/troubleshoot/github.md.txt @@ -0,0 +1,37 @@ +# Troubleshoot GitHub + +
+ +## Lost access to GitHub + +Not a big problem, just create another account if you can't recover access to the original one: + +### Create a GitHub account + +```{include} /vendors/github/create.md + +``` + +You'll need to reconnect your app to GitHub. + +
+ +------- + +## Cannot update GitHub + +When encountering update issues with GitHub, the easiest method it to delete it and fork the project again. + +### Delete your own fork of cgm-remote-monitor + +```{include} /vendors/github/delete.md + +``` + +### [Fork the Nightscout project](/troubleshoot/github.md#fork-the-nightscout-project) + +
+ +You'll need to reconnect your app to GitHub. + +
diff --git a/_sources/troubleshoot/heroku.md.txt b/_sources/troubleshoot/heroku.md.txt new file mode 100644 index 00000000..640a8d5a --- /dev/null +++ b/_sources/troubleshoot/heroku.md.txt @@ -0,0 +1,284 @@ +# Troubleshoot Heroku + +
+ +(heroku-nothing-here)= + +## There's nothing here + + + +If you didn't upgrade Heroku to an Eco or Basic plan, you need to [create a new Nightscout site](/nightscout/new_user) and [recover your MongoDB Atlas connection string](/troubleshoot/atlas.md#recover-your-connection-string). + +If you just upgraded to an Eco or Basic plan, make sure you enabled the web app (that turned off when the Free plan was removed). + + + +If you just tried to deploy a new Nightscout site, something went wrong. [Cleanup](#cleanup) your Heroku apps and retry... + +
+ +## Application Error + + + + [Update Nightscout to latest release](/update/update.md). It might not fix your issue but it will help find a solution. + +- Check your MongoDB Atlas [database is not full](/troubleshoot/atlas.md#database-full). +- If you're creating a new Nightscout site, it might have failed because of a [wrong connection string](/troubleshoot/atlas.md#unable-to-connect-to-mongo). +- If you don't see any good reason [restart all dynos](#restart-all-dynos). + +
+ +## A valid GitHub Directory could not be found. + +When trying to deploy a new Nightscout site, this message appears when clicking `Deploy to Heroku`. + + + +- Change browser and retry. + +
+ +(heroku-nogit)= + +## Cannot find cgm-remote-monitor in Heroku / No GitHub source visible + +When updating Nightscout, `cgm-remote-monitor` doesn't appear automatically in Heroku under your repository name. + + + +When updating Nightscout, your repository name doesn't appear in `Manual Deploy` so that you can't select the `master` branch. + + + +- `Disconnect` and re-`Connect` like this: + + + + + +- If it doesn't help try to re-authorize as explained below: + +
+ +## Cannot find cgm-remote-monitor in Heroku: Item cannot be retrieved + +When updating Nightscout, `cgm-remote-monitor` doesn't appear automatically in Heroku under your repository name and an error message appears when you try to connect to GitHub. + + + +- In Heroku, go to `Account Settings` + + + +- Select `Applications` and click `Re-authorize` + + + +- Click `Authorize GitHub` in the pop-up. +- If it doesn't help, you can also try to `Revoke access`... before going back to Re-`Connect` your GitHub account. This is necessary if someone else did setup Nightscout for you and left his own GitHub connected to your Heroku account. + +
+ +## I can't log into Heroku + +If you lost your password use the [password reset option](https://id.heroku.com/account/password/reset). + +If you lost your authenticator use the recovery codes (that you hopefully saved when [securing your account)](/vendors/heroku/mfa). + +If you lost or don't have anymore access to the email you used to create your Heroku account you will need to deploy a new Nightscout site. You can use the same GitHub account and the same MongodB Atlas database you currently have but will have to use another Nightscout site name in Heroku as the current one is already in use. First [recover your connection string](/troubleshoot/atlas.md#recover-your-connection-string), and proceed to [creating a new Nightscout](/vendors/heroku/new_user/) **skipping Step 3**. + +
+ +## Restart all dynos + +- Log in Heroku, go to `Settings`, `More`, `Restart all dynos`. + + + +
+ +## Sleeping app + +Check you app didn't fall asleep: + + + +
+ +A sleeping app can be due to your Heroku Eco plan: a Basic plan makes the app never sleep. [https://www.heroku.com/pricing](https://www.heroku.com/pricing) + +Another reason for a sleeping app can be due to a failure to obtain data from Dexcom Share, check the logs to understand the reasons. + +
+ +## Cleanup + +If you experience issues during deployment you might end up with many apps. Make sure you keep the last one that was functional or [delete](#delete-an-app) all before attempting a new deployment. This will just make it easier to find which app you're trying to build. Keeping sleeping apps doesn't have any negative impact but no real advantage unless you do it on purpose. + +Make sure the app you're using for Nightscout is running on an Eco/Basic tier. + +If you're not convinced you want to delete an app, make sure to put it in maintenance mode to understand if you use it as the related Nightscout site will report offline for maintenance. + +
+ +### Maintenance mode + +Maintenance mode is useful to troubleshoot Dexcom and CareLink accounts locked and also if you need to modify several variables without having Nightscout restarting every change. + +You can also put your Nightscout in maintenance mode if you won't use it for an extended period of time. + +```{warning} +**Putting your site in maintenance mode won't stop billing!**

+You also need to disable the web service for this.

+ +``` + +Be aware that your MongoDB Atlas database might also go in sleep mode and you will need to [restart it manually](/troubleshoot/atlas.md#mongodb-paused). + + + +
+ +### Delete an app + +Deleting an Heroku app does **not** delete your Nightscout data, but you might want to write down your variables (definitely backup your connection string) if your site was functional before. Note that you can also rename an app (unless the name is already in use in heroku.com). + + + +To delete an app, select it and go to `Settings`, scroll down to `Delete App` + + + +Copy and paste your app name to confirm deletion, + + + +
+ +## Backup your site variables + +Having a copy of your variables is very important since some of them are vital to your site like MONGODB_URI and your access to it like API_SECRET. + +### Method 1 - Spreadsheet + +Log into [Heroku](https://dashboard.heroku.com/apps), select your app. +Reveal your Heroku Nightscout app [Config Vars](/vendors/heroku/new_user.md#editing-config-vars-in-heroku) and copy all variables names and values in a spreadsheet. + +### Method 2 - Export + +Log into [Heroku](https://dashboard.heroku.com/apps), select your app. +Click on the top right `More` button and select `Run console`. + + + +In the console command line type the command below, then click `Run`. + +``` +export `heroku config -s` +``` + + + +Wait until the command completes. + + + +Save the session: it contains all your variables and values (and a few useless things). + + + +Edit the file with a text editor and remove the first line `(bash: line 1: heroku: command not found)`. +Using find and replace, get rid of all `declare -x`. +Delete the following Heroku specific variables: + +`DYNO="run.6309" +HOME="/app" +MEMORY_AVAILABLE="512" +NODE_ENV="production" +NODE_HOME="/app/.heroku/node" +OLDPWD +PATH="/app/.heroku/node/bin:/app/.heroku/yarn/bin:/usr/local/bin:/usr/bin:/bin:/app/bin:/app/node_modules/.bin" +PORT="6489" +PS1="\\[\\033[01;34m\\]\\w\\[\\033[00m\\] \\[\\033[01;32m\\]\$ \\[\\033[00m\\]" +PWD="/app" +SHLVL="1" +TERM="xterm-256color" +WEB_CONCURRENCY="1" +WEB_MEMORY="512"` + +```{warning} +Save this file in a safe place +``` + +
+ +## Roll back Heroku + +
+ +Roll back can be really useful in case of mistakes and when awaiting bug fixes in minor releases. + +```{warning} +You can only roll back to a version that was previously deployed to your Heroku app. +``` + +Heroku keeps history of variables modifications and previous deploys so that you can return to a previous state easily in the cases of a configuration mistake or a bad deploy (like a bugged version). When rolling back to a previous deploy keep in mind all variables modified in the mean time will return to the value they had at that time. + +Since the database is external to Heroku, it will not be impacted by a roll back. + +
+ +- Log into [Heroku](https://id.heroku.com/login). +- Select your Nightscout app and go to `Activity` + + + +
+ +- You will see a list of events called `Activity Feed` and some indicated as possible roll-back points. Identify the last good situation and select `Roll back to here` + + + +
+ +- Identify and eventually write down the values of the variables that were changed in the meantime (arrows in the picture below) before selecting `Rollback`. + + + +
+ +Upon completion your Heroku will be returned to the state it was at the selected rollback point. + +You can use it like this or upgrade to the latest released version later on. + +
+ +- If you change your mind later you can rollback prior to your rollback and return to the starting point. + + + +
+ +## Stop using Heroku + +If you want to migrate your data, it is recommended that you do it **before** switching off your Heroku Nightscout. + +To stop using Heroku and suspend billing, you only need to switch off all apps like this: + +- [Log](https://id.heroku.com/login) into Heroku. +- Select your app(s) in the dashboard. + + + +- In `Resources`, edit (pen icon) and turn off the `web` server switch. + + + +- Your Heroku Nightscout site will stop and **only the current month** will be billed. +- You can keep your Heroku account and leave the credit card, once no app is active billing will stop. +- Your data will not be deleted, make a copy of the `MONGODB_URI` variable if you want to reuse it with another platform, or migrate your database. +- If you decide you will not use it anymore, once last billing has occurred, you can delete your app(s), credit card and Heroku account. + +
diff --git a/_sources/troubleshoot/northflank.md.txt b/_sources/troubleshoot/northflank.md.txt new file mode 100644 index 00000000..063105d5 --- /dev/null +++ b/_sources/troubleshoot/northflank.md.txt @@ -0,0 +1,34 @@ +--- +orphan: true +--- + +# Troubleshoot Northflank + +
+ +## Site doesn't open after build + +`upstream connect error or disconnect/reset before headers. retried and the latest reset reason: remote connection failure, transport failure reason: delayed connect error: 111` + +You probably need to wait until the deploy is finished. Refresh the page after 5 minutes. + +
+ +## Restart + +a) [Log into Northflank](https://app.northflank.com/) and select your Nightscout `project`, then its `service`. + + + +
+ +b) Click `Rollout Restart` and confirm `Restart Service`. +Wait until restart is complete with the cloud status `Running`. + + + +
+ +If your site crashes again shortly after, verify your [database is not full](/troubleshoot/atlas.md#database-full) if you use MongoDB Atlas. + +
\ No newline at end of file diff --git a/_sources/troubleshoot/railway.md.txt b/_sources/troubleshoot/railway.md.txt new file mode 100644 index 00000000..57020b80 --- /dev/null +++ b/_sources/troubleshoot/railway.md.txt @@ -0,0 +1,176 @@ +# Troubleshoot Railway + +
+ +## Nothing here + +
+ +```{warning} +The free plan has been removed Jul 3rd for new users and Aug 1st for existing users. +``` + +
+ +It has been running fine for the first 200/500 hours and now it's gone. Even the project disappeared in Railway. + + + +This is usually because you need a Developer plan to run your Nightscout app in Railway. + +
+ +## Restart your app + +a) Open the [Railway Dashboard](https://railway.app/dashboard) and select your project then your app. + + + +
+ +b) In your `web` deployments select the current one (top of the list) and in the three dots menu on the right, `Restart`. + + + +
+ +b) Confirm Restart. Wait a moment and check your Nightscout site state clicking the URL. +If your site crashes again shortly after, verify your [database is not full](/troubleshoot/atlas.md#database-full) if you use MongoDB Atlas. + + + +
+ +## Reconnect GitHub to your project + +a) Open [Railway](https://railway.app) and click `login`. Login with GitHub. + + + + + +
+ +b) Select your Nightscout project. + + + +
+ +c) Select your web app. + + + +
+ +d) Select `Settings` and scroll down to `Service`. +Disconnect your `Source Repo` with the cross at the end of the line. + + + +
+ +e) Confirm `Disconnect`. + + + +
+ +f) Select `Connect Repo`. + + + +You should be able to select your GitHub `cgm-remote-monitor` repository. +You have now successfully reconnected your GitHub project to Railway. +If your GitHub repository `cgm-remote-monitor` was changed (updated for example), your Railway app will automatically redeploy. + + + +If you don't see the picture above: continue below. + +
+ +g) If you redeployed (deleted and recreated) `cgm-remote-monitor` in GitHub select `Configure GitHub app`. + + + +
+ +h) Select your GitHub account. + + + +
+ +i) Click `Only Select repositories` and from the `Select Repositories button` choose your `cgm-remote-monitor` Nightscout project. Click then `Install & Authorize`. + + + +You have now successfully reconnected your GitHub project to Railway. +If your GitHub repository `cgm-remote-monitor` was changed (updated for example), your Railway app will automatically redeploy. + +
+ +## Cleanup + +After several deployment attempts your Railway account might show more than one app. Since there is a 5$ limit to hobby plan before increased billing, depending on how you use it, it is important to make sure you don't have useless apps wasting CPU time and memory. + +Open [Railway](https://railway.app) and click `login`. Login with GitHub. + + + +
+ +If you see more than one (or two if you have a local database) projects on your dashboard, you should delete those unused. + + + +
+ +### Empty projects + +You can safely delete empty projects (in red in the picture above). + +Select your project then click on `Settings`. + + + +
+ +Click on `Danger`. + + + +
+ +Then `Delete project`. + + + +
+ +Copy and paste the project name in the box below and click `Delete`. + + + +
+ +### Databases + +Before deleting a database you need to check it's empty. + +Click twice on the database project and select `Data`. + +This example below is not an empty database. You need to check it's not being used by Nightscout before deleting it. +You can see data inside: `profile`, `devicestatus`, etc... + + + +
+ +This example below is empty, you can safely delete it (like shown above for an empty project). +There is no data inside this database. When you pull down the `Database tab`, there is only `test` and it's empty. + + + +
diff --git a/_sources/troubleshoot/render.md.txt b/_sources/troubleshoot/render.md.txt new file mode 100644 index 00000000..56550cfe --- /dev/null +++ b/_sources/troubleshoot/render.md.txt @@ -0,0 +1,20 @@ +# Troubleshoot Render + +
+ +## Restart service + +If your site is not responding (doesn't open), you can try to restart it. +Mind it might only have fallen asleep and would need an uptime robot to stay awake. + +* Sign in [Render](https://dashboard.render.com/) with GitHub + +
+ +* Select your web service + + + +* In the `Dashboard`, open the `Manual Deploy` drop down menu and select `Restart service`. + + \ No newline at end of file diff --git a/_sources/troubleshoot/troublehoot.md.txt b/_sources/troubleshoot/troublehoot.md.txt new file mode 100644 index 00000000..6fc728cb --- /dev/null +++ b/_sources/troubleshoot/troublehoot.md.txt @@ -0,0 +1,9 @@ +--- +orphan: true +--- + + + + + + diff --git a/_sources/troubleshoot/troubleshoot.md.txt b/_sources/troubleshoot/troubleshoot.md.txt new file mode 100644 index 00000000..37a3acdc --- /dev/null +++ b/_sources/troubleshoot/troubleshoot.md.txt @@ -0,0 +1,190 @@ +# Troubleshooting Nightscout + +
+ +## Before troubleshooting + +1. **Check your email (maybe you missed an important announcement)** + +2. **Check your internet provider / SIM credit (can all devices browse internet?)** + +3. **Try another browser/computer (if building your Nightscout site)** + +
+ +## Overall third party services + +Check the services you're using are available + +| Vendor | Check here: | +| ---------------------------------------------------------- | ------------------------------------------------------------ | +| **Dexcom**
Dexcom US account
Dexcom non-US account | [https://status.dexcom.com/](https://status.dexcom.com/)
[https://clarity.dexcom.com/](https://clarity.dexcom.com/)
[https://clarity.dexcom.eu/](https://clarity.dexcom.eu/) | +| Carelink US account
Carelink non-US account | [https://carelink.minimed.com/](https://carelink.minimed.com/)
[https://carelink.minimed.eu/app/login](https://carelink.minimed.eu/app/login) | +| GitHub | [https://www.githubstatus.com/](https://www.githubstatus.com/) | +| Heroku | [https://status.heroku.com/](https://status.heroku.com/) | +| Railway | [https://railway.instatus.com/](https://railway.instatus.com/) | +| MongoDB Atlas | [https://status.cloud.mongodb.com/](https://status.cloud.mongodb.com/) | +| Northflank | [https://status.northflank.com/](https://status.northflank.com/) | +| Azure | [https://azure.status.microsoft/](https://azure.status.microsoft/) | +| NS10BE | [https://ns.10be.de/en/status.html](https://ns.10be.de/en/status.html) | + +
+ +------ + +## Application crashed + +Not knowing if it's a permanent issue, first try to restart it... + +```{tab-set} + +:::{tab-item} Heroku +[Restart all dynos](/troubleshoot/heroku.md#restart-all-dynos) +::: + +:::{tab-item} Railway +[Restart your web app](/troubleshoot/railway.md#restart-your-app) +::: + +:::{tab-item} Azure +[Restart app](/troubleshoot/azure.md#restart-app) +::: + +:::{tab-item} Northflank +[Restart](/troubleshoot/northflank.md#restart) +::: + +:::{tab-item} Fly.io +[Restart your app](/troubleshoot/fly.io.md#restart-your-app) +::: + +:::{tab-item} Render +[Restart service](/troubleshoot/render.md#restart-service) +::: + +``` + +----------- + +## GitHub + +Follow [these](/troubleshoot/github) instructions. + +## Heroku + +Search your issue [there](/troubleshoot/heroku). + +[There's nothing here, yet](heroku-nothing-here) can be due to billing issues. + +An [Application error](/troubleshoot/heroku.md#application-error) means Heroku crashed. Restart it and check database size. + +## Atlas + +Issues during database creation look [there](/troubleshoot/atlas). + +The usual reason for failure at build time is a [bad connection string](/troubleshoot/atlas.md#bad-connection-string) (Atlas). + +If you encounter a [Boot Error - Unable to connect to Mongo](/troubleshoot/atlas.md#unable-to-connect-to-mongo) it might be due to a [Database Full](/troubleshoot/atlas.md#database-full) + +## Railway + +Mind you [can't deploy Railway](/vendors/railway/new_user.md#step-1-fork-cgm-remote-monitor) if you just created a new GitHub account. + +[Nothing there](/troubleshoot/railway.md#nothing-here) is usually because you forgot to subscribe to a Developer plan. + +Else go [there](/troubleshoot/railway). + +## Fly.io + +Fly.io troubleshooting is complex if you didn't save your `fly.toml` configuration. Check in your local clone of the `cgm-remote-monitor` project. If you can't find it, [recover it](recover-fly-toml) first. + +Try to redeploy your app. + +Once done, issues are most probably due to your `fly.toml` contents or variables. + +
+ +------ + +## Other issues + +### Reports + +[Reports slow loading or timeout](/troubleshoot/atlas.md#reports-slow-loading-or-timeout) + +### No data in Nightscout + +Check your [uploader](/uploader/setup) is configured correctly. + +Make sure your Nightscout [time zone](/nightscout/profile_editor/) is correct. + +If you use a [DIY closed loop](/nightscout/close_loop) system make sure it's setup correctly. + +### Dexcom data not showing + +See [this dedicated page](/troubleshoot/dexcom_bridge/). + +### Dexcom or CareLink data stopping after a while + +```{hint} +CareLink with mmconnect data source stopped functioning for 7xx pumps. +**Remove the `mmconnect` plugin from `ENABLE`. +``` + +
+ +First verify you can see your BG in Clarity. + +If you're using Heroku, check the web app is not [sleeping](/troubleshoot/heroku.md#sleeping-app). +You might need to setup an Uptime robot for Heroku Eco plan and Render. + +```{admonition} UpTime Robot +Using an uptime robot with a bad password, or other issues originating from Nightscout can lead to a locked account ([Dexcom](/troubleshoot/dexcom_bridge.md#account-lock)). +``` + +
+ +### Data timing issues + +#### Basal is shifted in time + +- Check the time zone is correct for your currently active profile in your Nightscout [`Profile editor`](/nightscout/profile_editor/). + + + +
+ +#### Data in the future + +- Check you don't have data in the future with the `Admin tools`. Remove them if existing. + + + +
+ +- If this isn't working, or shows no future data, check in your database (Atlas see [here](/troubleshoot/atlas.md#data-in-the-future)) + +
+ +#### Basal / IOB / COB missing after DST + +- Setup again your time zone in [profile editor](/nightscout/profile_editor/) (authenticate and save). + +
+ +### Error code instead of a BG value + +Nightscout implements Dexcom error codes as listed below: + +| Code | Corresponding error | +| ----- | --------------------- | +| `?SN` | Sensor not active | +| `?MD` | Minimal deviation | +| `?NA` | No antenna | +| `?NC` | Sensor not calibrated | +| `?CD` | Counts deviation | +| `?AD` | Absolute deviation | +| `???` | Power deviation | +| `?RF` | Bad RF | + +
\ No newline at end of file diff --git a/_sources/update/dev_branch.md.txt b/_sources/update/dev_branch.md.txt new file mode 100644 index 00000000..900b8c15 --- /dev/null +++ b/_sources/update/dev_branch.md.txt @@ -0,0 +1,241 @@ +# Deploy another version + +If you need to return to the previous Nightscout version, or in rare occasions, like testing a specific fix or a feature that is not released yet (i.e. not in the `master` branch), you might need to deploy another branch like `dev` in the example below. + +Do not deploy `dev` or a branch other than `master` unless directed to do so (except if you know why you are doing so). + +## Step 1: Update your repository in GitHub + +Select your platform below: + +````{tab-set} + +:::{tab-item} Select your platform -> +
+::: + +:::{tab-item} Heroku, Railway, Northflank (GitHub) +
- Click here to log in at GitHub: [https://github.com/login](https://github.com/login).

+- Enter your username or email and your password. Click `Sign in`

+

+- Select your own `cgm-remote-monitor` project (**not `nightscout/cgm-remote-monitor`**)

+

+- Your repository will open.

+

+- In the branch drop down menu (normally showing `master`) select `dev`

+

+- Click`Fetch upstream` to update it, then `Fetch and merge`

+

+- After a moment, your repository should display `This branch is up to date with nightscout:dev`

+

+- If you ran into trouble, try to [Redeploy](/update/redeploy.md) (and this is **mandatory** if you don't see `dev` in GitHub.)

+::: + +:::{tab-item} Google Cloud, Docker (Azure, Northflank, Railway, Render) +
You don't need to update your GitHub repository.

+::: + +:::{tab-item} Fly.io +
You don't need to update your GitHub repository if you deployed from [https://github.com/nightscout/cgm-remote-monitor](https://github.com/nightscout/cgm-remote-monitor).

+::: + + +```` + +
+ +## Step 2: Deploy + +Select your platform below: + +````{tab-set} + +:::{tab-item} Select your platform -> +
+::: + +:::{tab-item} Google Cloud +[Here](https://navid200.github.io/xDrip/docs/Nightscout/Customize.html)
+::: + +:::{tab-item} Heroku +- Log in Heroku [https://id.heroku.com/login](https://id.heroku.com/login)

+

+- Select your app (hidden in yellow)

+

+- Click on `Deploy`

+

+- Verify Heroku is connected to GitHub, if not, click `Connect to GitHub`

+

+- If Heroku is not connected to GitHub, scroll down and click `Connect to GitHub`, if a popup window opens and requires authorization, click `Authorize Heroku`

+

+- Verify your app `cgm-remote-monitor` is connected to GitHub

+

+- If it isn't, In `Connect to GitHub`, type `cgm-remote-monitor` and click `Search ` then click `Connect`

+

+- If you have trouble connecting your app, click `Disconnect` and reconnect it as shown above

+

+- Scroll down to the bottom of the page, select the `dev` branch and click `Deploy Branch`

+

+- Build will start and information will scroll in the log window. Do not leave the page, do not interfere and wait for completion. It might take more than 10 minutes. Interrupting the process will lead to a broken site and you'll need to restart deployment.

+

+- Wait until the deploy process completes and click `View` (if nothing happens click `Manage App` then upper right `Open App`)

+

+::: + +:::{tab-item} Railway (GitHub) +- Open [Railway](https://railway.app) and click `login`. Login with GitHub.

+

+

+- Select your Nightscout project.

+

+- Select your web app.

+

+- Still in `Settings` look at `Environment`.
+- Change the `Deployment Trigger` with `dev` (it was showing `master`).

+

+- If you only see `master` in the list you need to [redeploy](/update/redeploy.md) **taking care to select all branches and not only `master`**.
+

+- Once `dev` selected Railway will deploy automatically.
+::: + +:::{tab-item} Railway (Docker) +
a) Open [Railway](https://railway.app) and click `login`. Login with GitHub.

+

+

+b) Select your Nightscout project.

+

+c) Select your Docker service.

+

+d) Click on `Settings`, disconnect the source image.

+

+e) Select `Connect image` and replace `nightscout/cgm-remote-monitor:latest` with the [version](https://hub.docker.com/r/nightscout/cgm-remote-monitor/tags) you want to deploy (for example `nightscout/cgm-remote-monitor:latest_dev`).

+

+

+f) On the top left of the screen `Deploy`.

+

+- Your site will redeploy with the latest version.

+::: + +:::{tab-item} Northflank (GitHub) +- Log into Northflank: [https://app.northflank.com/login](https://app.northflank.com/login)
+- Select your Nightscout project

+

+- Select your Nightscout service

+

+- Click on the pen icon after the current branch (example below: `master`)

+

+- In the branch list, select the version you want to deploy, then click `Update Build Source`

+

+- Your site will redeploy with the selected branch
+::: + +:::{tab-item} Northflank (Docker) +- Log into Northflank: [https://app.northflank.com/login](https://app.northflank.com/login)
+- Select your Nightscout project

+

+- Select your Nightscout service

+

+- In Overview, Edit deployment

+

+- In the image path, replace `nightscout/cgm-remote-monitor:latest` with the [version](https://hub.docker.com/r/nightscout/cgm-remote-monitor/tags) you want to deploy (for example `nightscout/cgm-remote-monitor:latest_dev`), then click `Update & rollout restart`

+

+- Your site will redeploy with the selected branch
+::: + +:::{tab-item} Azure +- Log into Azure : [https://portal.azure.com/](https://portal.azure.com/)
+- Select your App service, your Nightscout site name (you should see it in recent resources)

+

+- If you didn't find it, it will show in App Services

+

+- In the left menu select Deployment Center, in Full Image Name and Tag change the version to:

+`nightscout/cgm-remote-monitor:latest_dev` (example for dev)

+Or whichever version (change `filter tag` find the version) in the [list](https://hub.docker.com/r/nightscout/cgm-remote-monitor/tags).

+`nightscout/cgm-remote-monitor:14.2.6` (example for 14.2.6)

+

+- Click Save (or Discard if you don't want to save).
+ Your site will redeploy if you changed the configuration. Expect a few minutes before it comes back online.

+

+::: + +:::{tab-item} Fly.io +Follow [these instructions](https://fly.io/docs/hands-on/install-flyctl/) to install `flyctl` on your computer. You also need to [install git](https://git-scm.com/downloads) if you're using a Windows computer.

+*Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.*

+- Log in Fly.io:

+`flyctl auth login`

+- Verify your Nightscout app name, use it to replace `example-ns` in the following lines.

+`flyctl app list`

+- Verify your app current region (three letters code) and make sure it's in the [free tier](https://fly.io/docs/reference/regions/#fly-io-regions).

+`flyctl app list`

+- Navigate to the `cgm-remote-monitor` folder from which you deployed Nightscout on your computer. Verify it contains the `fly.toml` configuration file you used to deploy your site.

+ - If you don't see this file, recover it:

+ `flyctl config save --app example-ns`

+- If you migrated from Heroku using the wizard, or if you can't find this folder on your computer, follow the next steps to recover your Fly.io configuration:

+ - Fork a copy of the Nightscout repository and change directory

+ `git clone https://github.com/nightscout/cgm-remote-monitor`

+ `cd cgm-remote-monitor`

+ - Download a default `fly.toml` configuration file

+ `flyctl config save --app example-ns`

+- Update your Nightscout repository

+`git config pull.rebase true`

+`git pull origin dev`

+- Edit your `fly.toml` configuration and search this section:
+``` +[[services]] + protocol = "tcp" + internal_port = 8080 + processes = ["app"] +``` +- Change the internal port value to 1337, do not change anything else, do not remove the spaces before `internal_port`.

+`internal_port = 1337`

+- Save the `fly.toml` file.

+- Deploy Nightscout:

+`flyctl launch`

+- Wait until completion, you site should now be running the latest Nightscout version.
+``` +Updating existing machines in 'example-ns' with rolling strategy + +------- + ✔ Machine 1781944ae46438 [app] update succeeded +------- + +Visit your newly deployed app at https://example-ns.fly.dev/ +``` +- Don't forget to downscale the app if you haven't yet!

+`flyctl scale --app example-ns count 1`

+
+::: + +:::{tab-item} Render (Docker) +- Log into Render: [https://dashboard.render.com/](https://dashboard.render.com/)
+- Select your Nightscout project

+

+- Go to `Settings` and scroll down to `Deploy`. Edit the URL of the image deployed

+

+- Change it to:

+`nightscout/cgm-remote-monitor:latest_dev` (example for dev)
+Or whichever version (change `filter tag` find the version) in the [list](https://hub.docker.com/r/nightscout/cgm-remote-monitor/tags).
+`nightscout/cgm-remote-monitor:14.2.6` (example for 14.2.6)

+

+- Click `Save changes`.

+- Your site will redeploy with the selected branch
+::: + +```` + +
+ +Check your [profile time zone](/nightscout/profile_editor.md#profile-view) is correct. You're done! + +
+ +
+ +## How to return to the `master` release + +If things don't go as expected you can simply redeploy your `master` branch performing the same steps and using `master` instead of `dev`. + +When the dev branch gets merged into release, just follow the [classic update method](/update/update.md). + +
\ No newline at end of file diff --git a/_sources/update/downgrade.md.txt b/_sources/update/downgrade.md.txt new file mode 100644 index 00000000..aa0c5edc --- /dev/null +++ b/_sources/update/downgrade.md.txt @@ -0,0 +1,53 @@ +# Downgrade Nightscout + +
+ +There is usually no good reason to downgrade Nightscout unless being instructed to do so. + +First try to deploy another version if available: see [Deploy another version](/update/dev_branch). + +If you use Heroku and you want to return to the previous version, see [Roll back Heroku](/troubleshoot/heroku.md#roll-back-heroku). + +
+ +## Deploy an old release + +
+ +### **Docker** + +You deployed a Docker container: you're not using GitHub (Azure, Northflank, Railway, Render) use [this method](/update/dev_branch). + +
+ +### GitHub + +You forked Nightscout in your own GitHub account and used it to deploy. + +**Experienced users only - not recommended** + +Deploying an archived release of Nightscout is complex and involves using Git on your computer (You need to [install git](https://git-scm.com/downloads) if you're using a Windows computer). + +Before starting you need to have the project `nightscout/cgm-remote-monitor` forked in your GitHub repository, with not only the master fork copied (look out for the check box!). It is recommended to [redeploy](/update/redeploy) paying attention to this step. + +Clone it locally (navigate to the folder where you'll want it saved locally before cloning). Replace YOUR-USERNAME by your GitHub user name. + +`git clone https://github.com/YOUR-USERNAME/cgm-remote-monitor` + +First identify the commit matching the release you want to use, look into the [released versions](https://github.com/nightscout/cgm-remote-monitor/releases). + + + +
+ +Then create a branch out of this commit (replace BRANCH by the branch name you want and indicate the COMMIT matching the one you need, in the case above b627d31): + +`git checkout -b BRANCH COMMIT` + +Push this new branch to your repository + +`git push --set-upstream origin BRANCH` + +
+ +You can now [deploy](/update/dev_branch.md#step-2-deploy) it in your web app, selecting it in the drop down menu. diff --git a/_sources/update/redeploy.md.txt b/_sources/update/redeploy.md.txt new file mode 100644 index 00000000..920bd8d8 --- /dev/null +++ b/_sources/update/redeploy.md.txt @@ -0,0 +1,13 @@ +# Redeploy with GitHub + +When encountering update issues with GitHub, the easiest method it to delete it and fork the project again. + +## Delete your own fork of cgm-remote-monitor + +```{include} /vendors/github/delete.md + +``` + +## [Fork the Nightscout project](/troubleshoot/github.md#fork-the-nightscout-project) + +
diff --git a/_sources/update/upd_stack.md.txt b/_sources/update/upd_stack.md.txt new file mode 100644 index 00000000..d2c00413 --- /dev/null +++ b/_sources/update/upd_stack.md.txt @@ -0,0 +1,79 @@ +# Update the Heroku stack + +
+ +AAPS users: mind the [compatibility matrix](../nightscout/close_loop.md#aaps)! + +
+ +It is good practice to maintain your Heroku stack up to date. Either when you receive an email from Heroku or when you [update your Nightscout site](/update/update) (which is also a good habit). + +
+ +- Log in Heroku [https://id.heroku.com/login](https://id.heroku.com/login) + +
+ + + +
+ +- Select your app + + + +
+ +- Click `Settings` + + + +
+ +- If present select `Upgrade Stack` + + + +
+ +- `Confirm` the upgrade + + + +
+ +- Now you need to deploy to upgrade the stack + + + +
+ +- Click on `Deploy` + + + +
+ +- Scroll down to the bottom of the page, select the `master` branch and click `Deploy Branch` + +```{hint} +If you can't select the `master` branch or `Deploy Branch` doesn't do anything [reconnect GitHub](heroku-nogit). +``` + + + +
+ +- Build will start and information will scroll in the log window. Do not leave the page, do not interfere and wait for completion. It might take more than 10 minutes. Interrupting the process will lead to a broken site and you'll need to restart deployment. + + + +
+ +- Wait until the deploy process completes and click `View` (if nothing happens click `Manage App` then upper right `Open App`) + + + +
+ +You have upgraded your Heroku stack. \ No newline at end of file diff --git a/_sources/update/update.md.txt b/_sources/update/update.md.txt new file mode 100644 index 00000000..14b5bf98 --- /dev/null +++ b/_sources/update/update.md.txt @@ -0,0 +1,203 @@ +# Update Nightscout + +```{tip} +You don't need to follow these instructions if you use a hosted service.
Contact the vendor to learn more about possible updates. +``` + +
+ +[See here which is the current released version](https://github.com/nightscout/cgm-remote-monitor/releases) before updating. + +
+ +## Step 1: Update your repository in GitHub + +Select your current platform below: + +````{tab-set} + +:::{tab-item} Select your platform -> +
+::: + +:::{tab-item} Heroku, Railway, Northflank (GitHub) +
- Click here to log in at GitHub: [https://github.com/login](https://github.com/login).

+- Enter your username or email and your password. Click `Sign in`

+

+- Select your own `cgm-remote-monitor` project (**not `nightscout/cgm-remote-monitor`**)

+

+- Your repository will open.

+

+- In the branch drop down menu (normally showing `master`) select `dev`

+

+- Click`Fetch upstream` to update it, then `Fetch and merge`

+

+- After a moment, your repository should display `This branch is up to date with nightscout:latest`

+

+- If you ran into trouble, try to [Redeploy](/update/redeploy.md)

+::: + +:::{tab-item} Google Cloud, Docker (Azure, Northflank, Railway, Render) +
You don't need to update your GitHub repository.

+::: + +:::{tab-item} Fly.io +
You don't need to update your GitHub repository if you deployed from [https://github.com/nightscout/cgm-remote-monitor](https://github.com/nightscout/cgm-remote-monitor).

+::: + + +```` + +
+ +## Step 2: Deploy + +````{tab-set} + +:::{tab-item} Select your platform -> +
+::: + +:::{tab-item} Google Cloud +
Continue [here](https://navid200.github.io/xDrip/docs/Nightscout/update_nightscout.html)

+::: + +:::{tab-item} Heroku +- Log in Heroku [https://id.heroku.com/login](https://id.heroku.com/login)
+


+- Select your app (hidden in yellow)
+


+- Click on `Deploy`
+


+- Verify Heroku is connected to GitHub, if not, click`Connect to GitHub`
+


+- If Heroku is not connected to GitHub, scroll down and click `Connect to GitHub`, if a popup window opens and requires authorization, click `Authorize Heroku`
+


+- Verify your app `cgm-remote-monitor` is connected to GitHub
+


+- If it isn't, In `Connect to GitHub`, type `cgm-remote-monitor` and click `Search` then click `Connect`
+


+- If you have trouble connecting your app, click `Disconnect` and reconnect it as shown above
+


+- Scroll down to the bottom of the page, select the `master` branch and click `Deploy Branch`
+


+- Build will start and information will scroll in the log window. Do not leave the page, do not interfere and wait for completion. It might take more than 10 minutes.
Interrupting the process will lead to a broken site and you'll need to restart deployment.
+


+- Wait until the deploy process completes and click `View` (if nothing happens click `Manage App` then upper right `Open App`)
+


+- Your site will open and should be at the latest version.
+- Check your [profile time zone](/nightscout/profile_editor.md#profile-view) is correct. You're done!
+If you ran into trouble, try the [Redeploy](/update/redeploy.md) method
+::: + +:::{tab-item} Azure +- Log into Azure : [https://portal.azure.com/](https://portal.azure.com/)
+- Select your App service, your Nightscout site name (you should see it in recent resources)
+


+- If you didn't find it, it will show in App Services
+


+- In the left menu select Deployment Center and change Continuous Deployment to **On**.
+


+- Click Save (or Discard if you don't want to update). + Your site will redeploy with the latest cgm-remote-monitor version. + Expect a few minutes before it comes back online.
+



+- You can leave Continuous Deployment On if you want upgrades to happen automatically, or turn it back to Off (and save) to control upgrades manually yourself. +
+::: + +:::{tab-item} Fly.io +Follow [these instructions](https://fly.io/docs/hands-on/install-flyctl/) to install `flyctl` on your computer. You also need to [install git](https://git-scm.com/downloads) if you're using a Windows computer.

+*Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.*

+- Log in Fly.io:

+`flyctl auth login`

+- Verify your Nightscout app name, use it to replace `example-ns` in the following lines.

+`flyctl app list`

+- Verify your app current region (three letters code) and make sure it's in the [free tier](https://fly.io/docs/reference/regions/#fly-io-regions).

+`flyctl app list`

+- Navigate to the `cgm-remote-monitor` folder from which you deployed Nightscout on your computer. Verify it contains the `fly.toml` configuration file you used to deploy your site.

+ - If you don't see this file, recover it:

+ `flyctl config save --app example-ns`

+- If you migrated from Heroku using the wizard, or if you can't find this folder on your computer, follow the next steps to recover your Fly.io configuration:

+ - Fork a copy of the Nightscout repository and change directory

+ `git clone https://github.com/nightscout/cgm-remote-monitor`

+ `cd cgm-remote-monitor`

+ - Download a default `fly.toml` configuration file

+ `flyctl config save --app example-ns`

+- Update your Nightscout repository

+`git pull`

+- Edit your `fly.toml` configuration and search this section:
+``` +[[services]] + protocol = "tcp" + internal_port = 8080 + processes = ["app"] +``` +- Change the internal port value to 1337, do not change anything else, do not remove the spaces before `internal_port`.

+`internal_port = 1337`

+- Save the `fly.toml` file.

+- Deploy Nightscout:

+`flyctl launch`

+- Wait until completion, you site should now be running the latest Nightscout version.
+``` +Updating existing machines in 'example-ns' with rolling strategy + +------- + ✔ Machine 1781944ae46438 [app] update succeeded +------- + +Visit your newly deployed app at https://example-ns.fly.dev/ +``` +- Downscale the app if you haven't yet +`flyctl scale --app example-ns count 1` +
+::: + +:::{tab-item} Railway Northflank Render (GitHub) +
Once GitHub updated, your Nightscout should automatically deploy with the latest version.

+::: + +:::{tab-item} Northflank (Docker) +
- Log into Northflank: [https://app.northflank.com/login](https://app.northflank.com/login)
+- Select your Nightscout project

+

+- Select your Nightscout service

+

+- In Overview, Edit deployment

+

+- In the image path, check the image is `nightscout/cgm-remote-monitor:latest` (modify if necessary), then click `Update & rollout restart`

+

+- Your site will redeploy with the latest version.


+::: + +:::{tab-item} Railway (Docker) +
a) Open [Railway](https://railway.app) and click `login`. Login with GitHub.

+

+

+b) Select your Nightscout project.

+

+c) Select your Docker service.

+

+d) Click on `Settings`, disconnect the source image.

+

+e) Select `Connect image` and type `nightscout/cgm-remote-monitor:latest` then press enter.

+

+

+f) Go to the `Deployment` tab and from the three dots menu of the top deployment select `Redeploy`.

+

+- Your site will redeploy with the latest version.

+::: + +:::{tab-item} Render (Docker) +- Log into Render: [https://dashboard.render.com/](https://dashboard.render.com/)
+- Select your Nightscout project

+

+- Go to `Settings` and top right expand `Manual Deploy`, Select `Deploy latest reference`

+

+- Your site will redeploy with the updated Nightscout version
+::: + +```` + +
+ diff --git a/_sources/uploader/setup.md.txt b/_sources/uploader/setup.md.txt new file mode 100644 index 00000000..81845261 --- /dev/null +++ b/_sources/uploader/setup.md.txt @@ -0,0 +1,254 @@ +# Setup Uploaders + +
+ +```{hint} +You usually should express the Nightscout URL in secure `**https://**`, not only `http://`. +(Unless you set `INSECURE_USE_HTTP` to `true`) +``` + +## What is my Nightscout URL? + +This is the address you type in any browser to display your Nightscout web site. + +If you're using a hosted service, ask the vendor. + +````{tab-set} + +:::{tab-item} Select your platform -> +
+::: + +:::{tab-item} Heroku +Your `Nightscout URL` defined in Heroku by your App name, is the one that shows when you open your Nightscout site in a browser. +It usually looks like: `https://yoursitename.herokuapp.com` + + +::: + +:::{tab-item} Railway +Your `Nightscout URL` is defined in Railway by your Web app name, as shown in your [Dashboard](https://railway.app/dashboard). +It usually looks like: `https://yoursitename.up.railway.app` + + +::: + +:::{tab-item} Northflank +Your `Nightscout URL` is defined in Northflank by your Web app name, as shown in your project services. +It usually looks like: `https://port-name--service-name--project-name--entity-dns-id.code.run` + + +::: + +:::{tab-item} Azure +Your `Nightscout URL` is defined in Azure by your Web app name, as shown in your App services. +It usually looks like: `https://yoursitename.azurewebsites.net` + + +::: + +:::{tab-item} Fly.io +Your `Nightscout URL` is defined in Fly.io by the `app` variable in your `fly.toml` file. +You can also find it in your Dashboard. +It usually looks like: `https://yoursitename.fly.dev` + + +::: + +:::{tab-item} Google Cloud +Your `Nightscout URL` is defined in FreeDNS. +You can find it in [Status - Hostname](https://navid200.github.io/xDrip/docs/Nightscout/Hostname.html). +::: + +```` + +
+ +## Dexcom + +You need at least one follower to use Nightscout `share` or `nightscout-connect` plugins. + +```{hint} +If you use a DIY closed loop system it is recommended that you let it upload to Nightscout instead of importing data using Dexcom Share and a Nightscout plugin. +``` + +On your master phone, touch the Share icon, enable Sharing. If you have no follower, add one. You can also invite yourself. + + + +
+ +```{tab-set} + +:::{tab-item} Select Nightscout version -> +
+::: + +:::{tab-item} 14 and previous +Verify, update or add these variables:

+`BRIDGE_USER_NAME`
+`BRIDGE_PASSWORD`
+`BRIDGE_SERVER`
+
+You need to add `bridge` in the `ENABLE` variable. Do not delete other entries, just add `bridge` after a space. +::: + +:::{tab-item} 15 +Verify, update or add these variables:

+`CONNECT_SOURCE` set to `dexcomshare`
+`CONNECT_SHARE_ACCOUNT_NAME`
+`CONNECT_SHARE_PASSWORD`
+`CONNECT_SHARE_REGION` (must be set to `ous` if outside of the US, else don't add this variable)
+
+You need to add `connect` in the `ENABLE` variable. Do not delete other entries, just add `connect` after a space. +::: + +``` + +
+ +```{admonition} MOST COMMON ERRORS +:class: hint +The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom's Clarity page (check [here for USA accounts](https://clarity.dexcom.com) and [here for the others](https://clarity.dexcom.eu)) and try logging in to your Dexcom account. If your account info isn't valid, or you don't see any data in your Clarity account... you need to figure out your actual credentials before moving ahead. See [here](/troubleshoot/dexcom_bridge/) for troubleshooting tips and information on your Dexcom account. +``` + +```{admonition} Password +:class: note +*Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.* +``` + +
+ +## Medtronic CareLink + +```{warning} +The `mmconnect` plugin is **NOT** functional anymore with recent pumps (7xx). +``` + +You can use an Android phone with xDrip+. See [**here**](../../uploader/xdripcarelink) how to set it up. + +
+ +```{tab-set} + +:::{tab-item} Select Nightscout version -> +
+::: + +:::{tab-item} 14 and previous +Verify, update or add these variables:

+`CARELINK_USER_NAME`
+`CARELINK_PASSWORD`
+`MMCONNECT_SERVER`(must be set to `US` if inside the US, or else `EU`)
+
+You need to add `mmconnect` in the `ENABLE` variable. Do not delete other entries, just add `mmconnect` after a space. +::: + +:::{tab-item} 15 +Verify, update or add these variables:

+`CONNECT_SOURCE` set to `minimedcarelink`
+`CONNECT_CARELINK_USERNAME`
+`CONNECT_CARELINK_PASSWORD`
+`CONNECT_CARELINK_REGION` (must be set to `us` if inside the US, or else `eu`)
+`CONNECT_CARELINK_PATIENT_USERNAME` must be set to the patient name if more than one in present in Carelink.
+
+You need to add `connect` in the `ENABLE` variable. Do not delete other entries, just add `connect` after a space. +::: + +``` + +
+ +## [Medtronic 600 Series with uploader](http://pazaan.github.io/600SeriesAndroidUploader/) + + + +You can also use [this QR code generator](https://nightscout.github.io/pages/configure/) and the menu item `Scan NS-Autoconfig QR Code` to copy the information. + +For hosted Nightscout you'll find the QR code generator in [Uploaders](https://www.t1pal.com/account/sites/my#Uploaders), select the `HTTP` tab. + +You might want to setup [additional fields](https://github.com/nightscout/cgm-remote-monitor/#pump-pump-monitoring) for your pump. + +Facebook Group [Nightscout for Medtronic](https://www.facebook.com/groups/NightscoutForMedtronic) + +
+ +## [xDrip+](https://jamorham.github.io/#xdrip-plus) + +```{admonition} Mind the syntax! +:class: warning +**`https://API_SECRET@my_nightscout_url/api/v1/`** +`my_nightscout_url` will depend on where your site is hosted (see top of this page) +You will find your `API_SECRET`in your site variables. +``` + +Here is how it will look like for some vendors: + +```html +https://API_SECRET@yoursite.herokuapp.com/api/v1/ +https://API_SECRET@yoursite.up.railway.app/api/v1/ +https://API_SECRET@yoursite.guest.t1pal.com/api/v1/ +https://API_SECRET@yoursite.10be.de/api/v1/ +``` + +
+ + + +Facebook Group [xDrip](https://www.facebook.com/groups/xDripG5) + +
+ +## [Glimp](https://play.google.com/store/apps/details?id=it.ct.glicemia) + + + +
+ +## [Juggluco](http://jkaltes.byethost16.com/Juggluco/mgdL/index.html) + + + +
+ +## [Diabox](https://www.bubblan.org/diabox/) + + + +
+ +## [LinkBluCon](https://www.ambrosiasys.com/our-products/linkblucon/) + + + +
+ +## [Tomato](http://tomato.cool/) + + + +
+ +## [Spike](https://spike-app.com/) + +Look [here](https://github.com/SpikeApp/Spike/wiki/Spike-Follower-Mode#configure-spike-master). + + + +Facebook group [Spike App](https://www.facebook.com/groups/spikeapp) + +
+ +## [xDrip4iOS](https://xdrip4ios.readthedocs.io/en/latest/) + + + +Facebook group [xDrip4iOS](https://www.facebook.com/groups/853994615056838/) + +
+ +## DIY Closed Loop + +See the app documentation in the [dedicated page](/nightscout/close_loop.md). + +
\ No newline at end of file diff --git a/_sources/uploader/uploaders.md.txt b/_sources/uploader/uploaders.md.txt new file mode 100644 index 00000000..eff4b725 --- /dev/null +++ b/_sources/uploader/uploaders.md.txt @@ -0,0 +1,115 @@ +# Supported Uploaders + +An **Uploader** is a mechanism or system for uploading the CGM data from your sensor to your Nightscout site. This can be either an electronic solution (usually for older devices), a simple app installed on your phone (for most newer systems) that connects to the sensor/pump and then uploads this data but also another app in the cloud acting as a "bridge" and mirroring data to Nightscout. + +The type of Uploader needed will depend on the type of CGM system being used. In this page, we will break the different systems down by manufacturer, then further by sensor type. + +Once you are clear about the type of sensor and upload system you will be using, you can find detailed configuration information for each one [here](/uploader/setup.md). +
+ +If you're developing an uploader, you'll find the API information in your own Nightscout site at `/api-docs` and `/api3-docs`. + +
+ +## DIY Closed loop Systems + +Only your loop app should upload BG to Nightscout. + +See this [dedicated page](/nightscout/close_loop) for setup links. + +
+ +## Dexcom + +### Dexcom G5/G6/ONE/G7 + + + +If you are using the Dexcom sensor (except ONE) connected to the Dexcom app on your phone, it will upload directly to the Dexcom servers (also still known as "Dexcom Share") and you won't need to use any extra uploader or master device. + +```{note} +Dexcom Share is not available with Dexcom ONE. Use xDrip+ or xDrip4iOS. +``` + +For this to work, Nightscout must be configured to use the `bridge` plug-in and will then automatically pull the CGM information directly from the Dexcom servers in real-time. + +```{note} +If you use a [DIY closed loop system](/nightscout/close_loop) it is recommended that you let it upload to Nightscout instead of importing data using Dexcom Share and the `bridge` plugin. +``` + +*Please note that at this time (end 2023), the Dexcom G5 system is effectively obsolete but some people are still using stocks of old sensors and transmitters.* + +If you don't want to use the official Dexcom apps, you can use **open-source software** apps for your Dexcom sensor to connect, display, alarm and also upload to Nightscout: + +**Android**: xDrip+ for G5, G6, ONE and G7. + +**iOS**: + Spike for G5 and older G6 transmitters (**not Firefly**) + xDrip4iOS for G5, G6 and ONE transmitters + + + +```{admonition} Dexcom "Firefly" Transmitters +:class: hint +Most of the useable transmitters that fall into this category at the present time are generally rebatteried or rechargeable/modified transmitters. +``` + +## Medtronic + +If your sensor system is able to directly upload to CareLink then Nightscout might be able to get the information directly from the cloud using the `mmconnect` (deprecated) plugin. Unfortunately, this is **not possible anymore with recent pumps (7xx series and above)**. + + + + + +If this isn't an option and your sensor/transmitter is connected to your pump (Medtronic 600 series pumps), then you'll need an Android phone connected with an OTG cable to your pump's connected glucose meter. The phone will need to run the [600 Series Uploader](http://pazaan.github.io/600SeriesAndroidUploader/) app. + + + +## Glucomen Day + +You can forward your data from GlucoLog Web using an AWS bridge documented [here](https://github.com/yaronkhazai/gmns-bridge/tree/main/guides). + +## Tandem t:slim X2 + +You can synchronize your treatments one way from your Tandem Diabetes t:connect web/mobile application to Nightscout using a bridge app running via **Pipenv** or **Docker** as documented [here](https://github.com/jwoglom/tconnectsync). + +## Abbott Freestyle Libre + +### Libre 1 + +Non Bluetooth-enabled Freestyle Libre sensors will need an additional transmitter device fixed on top of the sensor to send readings to the uploader device. In release order here are some transmitter options: [LimiTTer](https://github.com/JoernL/LimiTTer), BlueReader, Blucon, MiaoMiao, Bubble, Droplet and Atom. + +```{admonition} Transmitter Compatibility +:class: warning +The Libre environment is complex and evolves quickly. Before buying a transmitter, please join the respective Facebook groups and make sure that the transmitter you are planning to buy is compatible with your sensor type. +``` + +Most of the transmitters have their own proprietary apps. Nearly all of these support the uploading of data to Nightscout (LinkBluCon, Tomato, Diabox, eDroplet, ...). Again, check the transmitter manufacturer's website and the relevant Facebook support groups for information. + +**Open-source apps** such as **xDrip+**, **Juggluco**, **Spike** and **xDrip4iOS** also support some of the above transmitter devices. + +### Libre 2 + +You can connect to the Libre 2 sensor (**EU only**) without an additional transmitter using [xDrip+](https://www.minimallooper.com/post/how-to-setup-freestyle-libre-2-and-oop2-to-use-a-native-bluetooth-connection-in-xdrip), and [xDrip4iOS](https://xdrip4ios.readthedocs.io/en/latest/connect/cgm/#libre). +Other Libre 2 sensors can be used directly with [Juggluco](http://jkaltes.byethost16.com/Juggluco/mgdL/index.html) and Diabox. + +### Libre 2/3 + +You can use the sensor connected with [Juggluco](http://jkaltes.byethost16.com/Juggluco/mgdL/index.html) or upload to Nightscout automatically from LibreView servers deploying [this](https://github.com/timoschlueter/nightscout-librelink-up) project, or use xDrip+ to perform this operation. + +A new plugin in Nightscout 15 (under development) will integrate the project above. + +## Eversense + +In order to get data from the Eversense CGM system, you will need to use the [ESEL](https://github.com/BernhardRo/Esel/blob/master/apk/debug/app-debug.apk) app running on an Android phone with the [modified](https://cr4ck3d3v3r53n53.club/) vendor app. + + + +## Diasend + +[disaend-nightscout-bridge](https://github.com/burnedikt/diasend-nightscout-bridge) synchronizes treatments (insulin boli, temp basal changes) as well as continuous glucose values (CGV) from Diasend to Nightscout. This can help CamAPS FX users to view their treatments and glucose values via Nightscout. A 30 minutes delay might occur. + +A new plugin in Nightscout 15 (under development) will integrate the project above. + +
\ No newline at end of file diff --git a/_sources/uploader/xdripcarelink.md.txt b/_sources/uploader/xdripcarelink.md.txt new file mode 100644 index 00000000..d393ea7c --- /dev/null +++ b/_sources/uploader/xdripcarelink.md.txt @@ -0,0 +1,35 @@ +# xDrip+ for CareLink + +Since the `mmconnect` plugin is not functional anymore, the best solution to upload automatically your data from CareLink to Nightscout is to use xDrip+. + +Download xDrip+ from **[here](https://github.com/NightscoutFoundation/xDrip/releases)** (use the latest pre-release). +Once downloaded, install xDrip+ (you can find information [here](https://xdrip.readthedocs.io/en/latest/install/install)). + +
+ +## Using CareLink follower + +You can use an Android device to act as a bridge from CareLink to Nightscout. +It can be either the phone you use with the CareLink app, or any other phone or tablet connected to the internet. You don't need to carry it with you. It only needs to be switched on and connected. + +There will be a delay between your pump readings and xDrip+/Nightscout. This is due to various polling times and should be less than 10 minutes. + +Make sure you setup a Share Partner on your CareLink Connect app. + +Select [CareLink follower](https://xdrip.readthedocs.io/en/latest/install/carelinkfollow/) as the data source. + +Once you have data in xDrip+ you can upload them to Nightscout using Cloud Upload, [Nightscout Sync](https://xdrip.readthedocs.io/en/latest/use/cloud/#nightscout-sync-rest-api). + +Leave Download treatments disabled. + +
+ +## Using Companion app + +If the phone you use with the CareLink, Guardian or Minimed app is Android, you can setup xDrip+ to read its notifications and send blood glucose values to Nightscout. + + Select [Companion app](https://xdrip.readthedocs.io/en/latest/install/companion/) as the data source. + +Once you have data in xDrip+ you can upload them to Nightscout using Cloud Upload, [Nightscout Sync](https://xdrip.readthedocs.io/en/latest/use/cloud/#nightscout-sync-rest-api). + +Leave Download treatments disabled. diff --git a/_sources/vendors/10BE.md.txt b/_sources/vendors/10BE.md.txt new file mode 100644 index 00000000..43a21d9b --- /dev/null +++ b/_sources/vendors/10BE.md.txt @@ -0,0 +1,7 @@ +--- +orphan: true +--- + + + + diff --git a/_sources/vendors/NAS/synology.md.txt b/_sources/vendors/NAS/synology.md.txt new file mode 100644 index 00000000..e9af165d --- /dev/null +++ b/_sources/vendors/NAS/synology.md.txt @@ -0,0 +1,13 @@ +# Nightscout in your Synology NAS + +
+ +Even if this is a valid solution for knowledgeable people, there is little detailed documentation except for https://t1d.dzienia.pl/nightscout_synology_tutorial/. + +More links below. + +[Nightscout on Synology + model, initially for the technically minded only](https://docs.google.com/document/d/1WWq6f_U2BSs3A_Ij312M5OmXCH-BaIxdC6FY3NenlzY/edit) + +https://github.com/vanelsberg/NightScoutSynology + +
diff --git a/_sources/vendors/T1Pal/new_user.md.txt b/_sources/vendors/T1Pal/new_user.md.txt new file mode 100644 index 00000000..194f95b8 --- /dev/null +++ b/_sources/vendors/T1Pal/new_user.md.txt @@ -0,0 +1,8 @@ +--- +orphan: true +--- + + + + + diff --git a/_sources/vendors/VPS/docker.md.txt b/_sources/vendors/VPS/docker.md.txt new file mode 100644 index 00000000..93c04e11 --- /dev/null +++ b/_sources/vendors/VPS/docker.md.txt @@ -0,0 +1,263 @@ +# Building Nightscout with Docker + +
+ +```{tip} +The most complete guide for building your site step by step is the one used for [Oracle Cloud](https://www.dropbox.com/s/5twlqrndofqno0t/0-amber-oracle.pdf). +If you use another hosting provider, skip Oracle specific instructions and follow the flow. +``` + +
+ +Original documentation from [Jason](https://github.com/nightscout/nightscout-docker). +More from [Andries](https://gist.github.com/Andries-Smit/daac75cd4c06af78cde68c5dec941705) and [Peter](https://github.com/peterleimbach/TestNightscoutDockerUbuntuServer22.04LTS) (traefik as below), [justmara](https://github.com/justmara/ns-setup) and [Ireneusz](https://github.com/ireneusz-ptak/ns-docker). + +If you want to deploy with CoreOS look [here](https://danielscrivano.com/blog/posts/nightscout/). + +A comprehensive description of the yaml file for mongo and Nightscout setup [here](https://github.com/LostOnTheLine/Nightscout_Docker-Compose). + +If you don't own a domain name, get a DDNS name now: see [here](/nightscout/dns). + +You can also use [Caddy as reverse proxy](https://github.com/Alderskog/nightscout-in-OCN). + +
+ +## Update your system + +Update your Ubuntu system (you should type this is a command every 3 or 6 months to keep it updated). + +```bash +sudo apt update +sudo apt upgrade -y +sudo apt clean +``` + +You will see it's completed when the terminal stops scrolling text and you're returned to the prompt. + +**If you see the following message: `*** System restart required ***` you will need to reboot**. Do not skip this step: reboot and wait a minute before opening again the console. + +```bash +sudo reboot +``` + +You must probably already have nano installed. If necessary: + +```bash +sudo apt install nano -y +``` + +
+ +## Deploy a single instance + +### Step 1 - Install Docker + +*Note: instructions from the [vendor](https://docs.docker.com/engine/install/ubuntu/)* + +a) Install keys + +```bash +sudo apt-get -y install ca-certificates curl gnupg lsb-release +sudo mkdir -p /etc/apt/keyrings +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg --yes +``` + +b) Install Docker + +```bash +echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null +sudo apt-get update +sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin +``` + +
+ +### Step 2 - Configure Nightscout + +a) If you're running your VPS as root: Create a new user. Else go to d) +Don't try to run Nightscout as root, it will not work. +**Replace `mainuser`** with a name of your choice, like your name, only lowercase letters. + +```bash +sudo adduser mainuser +``` + +You need to invent a password for your new user. +Confirm it then just hit `Enter` for the following lines, when done key `Y` then `Enter`. + + b) Make your user an administrator. + +**Replace `mainuser`** with your new user name. + +```bash +sudo usermod -aG sudo mainuser +``` + +c) Enable current user and make docker startup automatically. +**Replace `mainuser`** with your new user name. + +```bash +sudo groupadd docker +sudo usermod -aG docker mainuser +sudo systemctl enable docker +``` + +d) Login to the VPS using the account we just created. + +!!!warning "Do not run Nightscout as root" + From now on use your Nightscout user. + +**Replace `mainuser`** with your new user name. + +``` +sudo -u mainuser -s +``` + +Log out (`Ctrl-D` or `⌘-D`) or type `logout`, and log in with with your new user. + +e) Customize your Docker Compose configuration file + +You can use the default [docker-compose.yml](https://raw.githubusercontent.com/nightscout/cgm-remote-monitor/master/docker-compose.yml) file from the Nightscout repository or download [this one](/_static/docker-compose.yml). + +There are few information you need to update: + +- Which version of Nightscout you want to deploy. + You can find the list here: [https://hub.docker.com/r/nightscout/cgm-remote-monitor/tags](https://hub.docker.com/r/nightscout/cgm-remote-monitor/tags) and the tag is specified in the line below (example: `latest` is the latest release). + +``` +image: nightscout/cgm-remote-monitor:latest +``` + +- You need to specify your [time zone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List) + +``` +TZ: YOUR_TIMEZONE +``` + +- Your Nightscout site `API_SECRET` password. + +``` +API_SECRET: YOUR_API_SECRET +``` + +*Note: now you've also seen where your Nightscout variables are defined.* + +- You need to update your Nightscout site URL (your DDNS name looking like `name.domain.tld`) + +``` +- 'traefik.http.routers.nightscout.rule=Host(`YOUR_PUBLIC_HOST_URL`)' +``` + +- You need to put a valid email too for important certificate emails (i.e. probably never) + +``` +- '--certificatesresolvers.le.acme.email=YOUR_EMAIL' +``` + +
+ +### Step 3 - Build and run Nightscout + +To start your Nightscout: + +``` +sudo docker compose up -d +``` + +Or, if you want to start it in background (once everything is working as you won't see the log): + +``` +nohup sudo docker compose up -d & +``` + +To stop it (if you didn't select `always` restart for your containers): + +``` +sudo docker compose down +``` + +Note that you need to start it if you modify your `docker-compose.yml` configuration (to validate the changes). + +
+ +## Update or downgrade + +Edit your `docker-compose.yml` configuration and change the image to whichever you want in the [community maintained images](https://hub.docker.com/r/nightscout/cgm-remote-monitor/tags). + +If you're using `image: nightscout/cgm-remote-monitor:latest` and you want to upgrade it to latest release, don't change anything. You can update to `cgm-remote-monitor:latest_dev` or choose an older version like `cgm-remote-monitor:14.2.6` + +``` +sudo docker compose down +sudo docker compose pull +nohup sudo docker compose up -d & +``` + +
+ +## Deploy multiple instances + +Hints from [justmara](https://github.com/justmara) + +Portainer configuration used in docker-compose: + +``` + portainer: + image: portainer/portainer-ee:latest + container_name: portainer + restart: unless-stopped + volumes: + - ./portainer-data:/data + - /var/run/docker.sock:/var/run/docker.sock + labels: + - 'traefik.enable=true' + - 'traefik.http.routers.portainer.rule=Host(`portainer.`)' + - 'traefik.http.routers.portainer.entrypoints=web' + - 'traefik.http.routers.portainer.service=portainer-service' + - 'traefik.http.services.portainer-service.loadbalancer.server.port=9000' + ports: + - "8000:8000" + - "9443:9443" + - "9000:9000" + networks: + - dia +``` + +Portainer custom template used to start new Nightscout instances: + +``` +version: '3.9' + +x-ns-common-env: &ns-common-env + NODE_ENV: production + TZ: Europe/Moscow + TIME_FORMAT: 24 + INSECURE_USE_HTTP: 'true' + ENABLE: basal iob cob boluscalc cage sage iage bage pump openaps pushover food rawbg + SHOW_FORECAST: openaps + PUMP_FIELDS: clock reservoir + DISPLAY_UNITS: mmol + AUTH_DEFAULT_ROLES: denied + +services: + nightscout-{{ns-name}}: + image: nightscout/cgm-remote-monitor:latest + container_name: dia-ns-{{ns-name}} + restart: always + depends_on: + - mongo + labels: + - 'traefik.enable=true' + - 'traefik.http.routers.ns-{{ns-name}}.rule=Host(`{{ns-name}}.`)' + - 'traefik.http.routers.ns-{{ns-name}}.entrypoints=web' + environment: + <<: *ns-common-env + MONGO_CONNECTION: mongodb://mongo:27017/ns-{{ns-name}} + API_SECRET: {{ns-secret}} + networks: + - dia + +networks: + dia: + external: true +``` + diff --git a/_sources/vendors/VPS/ubuntu.md.txt b/_sources/vendors/VPS/ubuntu.md.txt new file mode 100644 index 00000000..806ac9d4 --- /dev/null +++ b/_sources/vendors/VPS/ubuntu.md.txt @@ -0,0 +1,372 @@ +# Building Nightscout in Ubuntu + +
+ +```{tip} +The most complete guide for building your site step by step is the one used for [Oracle Cloud](https://www.dropbox.com/s/5twlqrndofqno0t/0-amber-oracle.pdf). +If you use another hosting provider, skip Oracle specific instructions and follow the flow. +``` + +
+ +Deploying in Ubuntu is very popular for skilled people, see also [here](https://gist.github.com/DrCR77/eb08b830d4f31092cf65a8a9976dc0a6) and [here](https://www.michael-schloemp.de/2021/10/25/nightscout-installation-auf-ubuntu-20-04-1blu-vps/).
+ +If you don't own a domain, get one now, see [here](/nightscout/dns). + +
+ +## Update your system + +Update your Ubuntu system (you should type this is a command every 3 or 6 months to keep it updated). + +```bash +sudo apt update +sudo apt upgrade -y +sudo apt clean +``` + +You will see it's completed when the terminal stops scrolling text and you're returned to the prompt. + +**If you see the following message: `*** System restart required ***` you will need to reboot**. Do not skip this step: reboot and wait a minute before opening again the console. + +```bash +sudo reboot +``` + +You must probably already have nano installed. If necessary: + +```bash +sudo apt install nano -y +``` + +
+ +## Step 1 - Install MongoDB + +a) Follow the vendor instructions + +[MongoDB 5 with Ubuntu 20.04](https://www.mongodb.com/docs/v5.0/tutorial/install-mongodb-on-ubuntu/) or [MongoDB 6 with Ubuntu 22.04](https://www.mongodb.com/docs/v6.0/tutorial/install-mongodb-on-ubuntu/) + +b) Enter in Mongo shell + +```bash +mongo --port 27017 +``` + +You will know you've entered the mongo shell when the prompt `>` is displayed. + +c) Create an admin user. Decide on a name and a password. +Avoid reusing other usernames and passwords. + +Replace `ADMIN_NAME` and `ADMIN_PASSWORD` with those your own. Keep all `" "`. + +``` +use admin +``` + +```bash +db.createUser({user: "ADMIN_NAME", pwd: "ADMIN_PASSWORD", roles: [ { role: "userAdminAnyDatabase", db: "admin" }] }) +``` + +Exit mongo. + +```bash +exit +``` + +Mongo will answer `bye` and you'll be back to Ubuntu's command prompt. + +
+ +d) Turn Mongo security on + +```bash +sudo nano /etc/mongodb.conf +``` + +Go to the line reading `#auth = true` and remove the comment `#`. +Save the modified file: + +1. Press `Ctrl-O` (the letter O not zero) +2. Press `Enter` +3. Press `Ctrl-X` + +*Note: if you use a Mac the `Ctrl` key is `⌘`* + +e) Restart Mongo with this command: + +```bash +sudo service mongodb restart +``` + +You have installed the MongoDB application. + +
+ +## Step 2 - Create a new database + +a) Login into Mongo as an admin +**Replace** `ADMIN_NAME` with your own database administrator name. + +```bash +mongo -u ADMIN_NAME -p --authenticationDatabase admin +``` + +You will be asked to enter the password matching your admin user. + +b) Create a database name. +Make it simple (letters), this is just the place your Nightscout data will be stored. +**Replace** `MONGO_NS_DB` with your own database name. + +```bash +use MONGO_NS_DB +``` + +c) Create a database user. +Invent a name (letters and numbers) and a password (letters and numbers, uppercase and lowercase). +**Replace** `MONGO_NS_USER` with your database user name, `MONGO_NS_PASSWORD` with its matching password and `MONGO_NS_DB` with the database name you created above. + +```bash +db.createUser({user: "MONGO_NS_USER", pwd: "MONGO_NS_PASSWORD", roles: [ { role: "readWrite", db: "MONGO_NS_DB" }]}) +``` + +Exit the shell + +```bash +exit +``` + +d) Check you can login into Mongo with this user +**Replace** `MONGO_NS_USER` with your own database administrator name, and replace `MONGO_NS_DB` with your own database name. + +```bash +mongo -u MONGO_NS_USER -p --authenticationDatabase MONGO_NS_DB +``` + +You will be asked to enter the password matching your user. + +Exit the shell. + +```bash +exit +``` + +You have created your Nightscout MongoDB database and its user. + +
+ +## Step 3 - Install Nightscout + +a) Create a new user. +Don't try to run Nightscout as root, it will not work. +**Replace `mainuser`** with a name of your choice, like your name, only lowercase letters. + +```bash +sudo adduser mainuser +``` + +You need to invent a password for your new user. +Confirm it then just hit `Enter` for the following lines, when done key `Y` then `Enter`. + + b) Make your user an administrator. + +**Replace `mainuser`** with your new user name. + +```bash +sudo usermod -aG sudo mainuser +``` + +c) Login to the machine using the account we just created. + +!!!warning "Do not run Nightscout as root" + From now on use your Nightscout user. + +**Replace `mainuser`** with your new user name. + +``` +sudo -u mainuser -s +``` + +d) Install `nodejs` and `npm`. + +**Mind some small VPS will not be powerful enough to deploy with npm, consider using a [Docker container](/vendors/VPS/docker) in this case.** + +The example below is with the **latest supported npm version**: 16.20.1 + +``` +sudo apt install nodejs +sudo apt install build-essential checkinstall +sudo apt install libssl-dev +wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash +source /etc/profile +nvm install 16.20.1 +nvm use 16.20.1 +``` + +Once complete, install npm + +``` +sudo apt-get install -y npm +``` + +
+ +e) Clone the Nightscout repository `cgm-remote-monitor`. + +``` +cd +git clone https://github.com/nightscout/cgm-remote-monitor.git +ln -s cgm-remote-monitor nightscout +cd nightscout +``` + +```{admonition} Make sure you're in your nightscout directory +:class: warning +Should you exit your terminal and resume working later make sure to return to this state. + 1- you're using your nightscout user + 2- you are in your nightscout directory +``` + +f) Install Nightscout. + +``` +npm install +``` + +It will take a long time to complete. Be patient. +On some lightweight virtual computers install might fail or hang, especially if you installed the default latest node.js version. +You can try to interrupt and run another time `npm install`. + +
+ +## Step 4 - Configure Nightscout + +a) Edit the configuration file. + +```bash +nano my.env +``` + +You can use the [**helper page**](/_static/NightscoutVariablesUbuntu.html) in a new browser tab. + +File all necessary fields, click on the Validate button at the bottom of the form, if no error is seen you will have all variables displayed in the text box at the bottom, click on the Copy All button. + +```{admonition} Variables format +:class: tip +1- do not add`export` before the variable name +2- safe format is `VARIABLE="value"` +3- all spaces in the values must be replaced by `%20` +``` + +b) Return to the text editor. Paste the result in `nano`. + +c) Save the modified file: + +1. Press `Ctrl-O` (the letter O not zero) +2. Press `Enter` +3. Press `Ctrl-X` + +*Note: if you use a Mac the `Ctrl` key is `⌘`* + +
+ +### Manage Nightscout startup + +d) Install `pm2` + +``` +sudo npm install pm2 -g +``` + +e) Start cgm-remote-monitor with `pm2`. + +``` +env $(cat my.env) PORT=1337 pm2 start server.js +``` + +f) Make `pm2` start cgm-remote-monitor on startup + +``` +pm2 startup +``` + +This will give you a command you need to run as superuser to allow pm2 to start the app on reboot. +The command will be something like: `sudo su -c "env PATH=$PATH:/usr/bin pm2 startup ..."` + +Copy the tailored command, paste and execute it. + +g) Save it. + +``` +pm2 save +``` + +Your Nightscout site is now available at `http://` and the IP address of your computer/VPS but it's not secured so most browsers will refuse it. + +
+ +## Step 5 - Open and secure your access + +a) Create a reverse [nginx](https://nginx.org/en/) proxy + +``` +sudo apt-get install nginx +``` + +b) Delete and replace the original `/etc/nginx/sites-available/default` with this one. +**Replace `MY_FULLYQUALIFIEDNAME`** with your own (it will look like `name.domain.tld`). You don't have one? Look [here](/nightscout/dns/). + +``` +server { + listen 80; + server_name MY_FULLYQUALIFIEDNAME; + location / { + proxy_pass http://127.0.0.1:1337; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + proxy_set_header X-Forwarded-Proto "https"; + } +} +``` + +Your Nightscout site is now available at `http://MY_FULLYQUALIFIEDNAME` but it's not secured so most browsers will refuse it. + +c) If your VPS doesn't provide a firewall you should install and configure ufw. +**Make sure to open ssh if you don't have KVM access!** + +``` +sudo apt install ufw +sudo ufw allow 'Nginx Full' +sudo ufw allow OpenSSH +sudo ufw enable +``` + +d) Obtain a certificate for your site name. + +``` +sudo apt install certbot python3-certbot-nginx -y +sudo certbot --nginx -d "MY_FULLYQUALIFIEDNAME" --redirect --agree-tos --no-eff-email +``` + +You can increase ssl security with a strong Diffie-Hellman group ([src](https://gist.github.com/johnmales/1b3c927f2a56aae640b4b2cd0298b1e7)): + +``` +sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048 +``` + +e) Make sure certbot takes care of renewing your certificate: + +``` +sudo certbot renew --dry-run +``` + +f) Restart the service: + +``` +sudo service nginx restart +``` + +Upon success you will be able to access your Nightscout site from any browser using `https://`. diff --git a/_sources/vendors/azure/migrate.md.txt b/_sources/vendors/azure/migrate.md.txt new file mode 100644 index 00000000..91e55d8b --- /dev/null +++ b/_sources/vendors/azure/migrate.md.txt @@ -0,0 +1,5 @@ +--- +orphan: true +--- + +Now included in the main [Nightscout with Azure](/vendors/azure/new_user) page! \ No newline at end of file diff --git a/_sources/vendors/azure/new_user.md.txt b/_sources/vendors/azure/new_user.md.txt new file mode 100644 index 00000000..532863d3 --- /dev/null +++ b/_sources/vendors/azure/new_user.md.txt @@ -0,0 +1,295 @@ +# Nightscout in Azure (Docker) + +
+ +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +```{card} +## Azure +![Azure](/vendors/img/Azure.png) +^^^ +Nightscout DIY was [originally](https://github.com/rnpenguin/cgm-remote-monitor) created with Azure but most users dropped it after costs increased. +A new deployment method has been created using a Docker container. + +**Pros**: +* Large platform with a reliable history +* Well known by the community IT specialists +* Using a basic plan and free services keep it free + +**Cons**: +* Trial account lasts maximum 12 months +* Basic plan and pay as you go is free if you stay within quotas +* The F1 free app service plan is designed for testing, not production +* **The Cosmos database doesn't integrate correctly with Nightscout** +``` + +
+ +This is a transcript of the original video which cannot be used as-is anymore because the **Cosmos (MongDB) database which was used at the time of the video isn't fully compatible with Nightscout and can't be deployed in some geographical areas**. For reference the obsolete video is [here](https://www.youtube.com/watch?v=EDADrteGBnY). + +
+ +## Step 0: Create a database + +```{note} +Make sure you [created one](/nightscout/database) before starting your Nightscout web app creation with Azure. +Come back here when you have a MONGODB_URI connection string. +``` + +```{admonition} Migrating? +:class: tip +Copy the connection string from your previous platform: [edit the variables](/nightscout/setup_variables.md#nightscout-configuration) and look for `MONGODB_URI`. +If you don't see `MONGODB_URI` but see `MONGO_CONNECTION` (**NOT** `MONGO_COLLECTION`): use its value. +``` + +
+ +## Step 1: Create an Azure account + +a) Open a web page in [https://azure.microsoft.com/en-us/free/](https://azure.microsoft.com/en-us/free/) and click Start Free. + + + +
+ +b) Sign in with your Microsoft account if you have one, else use GitHub. + + + +
+ +c) Agree and click Next. +Perform necessary authentication. + + + +
+ +## Step 2: Create your Nightscout web app + +a) From the top left ☰ menu or the Azure Services icons, select + Create a resource. + + + +
+ +b) Search Web app and click Create. + + + +
+ +c) Check you're still using your Free Trial or 3-Month free Trial. +Open the list in Resource group and pick your group (the one you created in Step 2.f.). + + + +If your free trial expired, select Pay-As-You-Go. It will be free if you use free resources like the Free F1 resource (see below). + +
+ +d) Decide your site name (only lowercase and you can use `-` as a separator). +It must be unique: check the tick box at the end of the line is green. +If it isn't: you need to choose another name... + + + +
+ +e) Now select a Docker container, in Linux. + +Pick a place close to where you live in the Region selection. +Make sure it is the same than the database region you selected in Step 2.g. + + + +
+ +f) Select the free F1 plan. + + + +```{admonition} Limited CPU usage +:class: warning +The Free F1 plan includes 60 CPU minutes per day. It usually is enough for a moderate Nightscout usage but can also be insufficient and provoke interruptions in your Nightscout site. Not recommended for FreeAPS X and OpenAPS users. +If you want a more reliable CPU, consider another plan like Shared D1 ($). +``` + +
+ +g) Click Next: Database > down in the page. + + + +
+ +g) Do not change anything and click Next: Docker > down in the page. + + + +
+ +h) In Image source select **Docker Hub** instead of Quickstart. + + + +
+ +i) In Image and tag paste the following name: + +`nightscout/cgm-remote-monitor:latest` + + + +
+ +j) Click Review + create in the lower left of the page. + + + +
+ +k) Verify the summary information: +Free sku +Check the site Name is what you wanted +then click Create. + + + +
+ +Wait for the deployment to complete. Do not interfere. + + + +
+ +Congratulations, you have created your Nightscout web app. + +
+ +## Step 3: Configure your Nightscout web app + +> Now you need to tell it where the database is and other important information + +a) Click Go to resource + + + +
+ +b) In the left menu select Configuration + + + +
+ +**Check which deployment you're doing now!:** + +```{tab-set} + +:::{tab-item} I'm building a new Azure site +:::{include} /vendors/azure/new_user_a.md +::: + +:::{tab-item} I'm migrating from another platform +:::{include} /vendors/azure/new_user_b.md +::: + +``` + +j) From the menu select Overview, then Browse. + + + +It will take some time before the window opens. + +
+ +```{include} /nightscout/first_setup.md + +``` + +
+ +## Editing Config Vars in Azure + +
+ +a) Log into Azure : [https://portal.azure.com/](https://portal.azure.com/) + +b) Select your App service, your Nightscout site name (you should see it in recent resources) + + + +If you didn't find it, it will show in App Services + + + +c) In the left menu select Environment variables + + + +### View a variable value + +Click the eye icon to display the hidden value + + + +### Modify a variable + +Identify the line with the variable you want to change and click the pen icon at the end of the line +Click OK to save it when finished +Remember to save modifications when done with your variables! + + + +### Delete a variable + +Identify the line with the variable you want to delete and click the bin icon at the end of the line +Remember to save modifications when done with your variables! + + + +### Add a variable + +Select New Application Setting and type variable name and value +Remember to save modifications when done with your variables! + + + +~~~{note} +Multiple lines values with `\n` should be edited manually as the character `\` will be duplicated.
+Example: `LOOP_APNS_KEY`
+``` +----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGBygGSM49AwEHBHkwdwIBAQQg7c8w00t5ju7N980r\nerN8N+isnJoec+ohIEuD0teRbPmgCgYIKoZIzj0DAQehRANCAAREnRISLSiFgdn4\nLbf44yIKspXKr7GpPBVshv3ShOms2qHTdAFriXXRPmbq7eAJuFrxpYOduU1dl9vo\nouciW0je\n-----END PRIVATE KEY----- +``` +~~~ + +Insert the value like you've done for all the others. + + + +At the top of the Environment variables view, select Advanced edit. + + + +Scroll down the list to your variable name and delete all duplicated `\` so that there will be no more `\\n` separators but only `\n`. + + + +Click `OK` to save the modified variable. + +
+ +### Save your modifications + +When you're done modifying your variables, click Save (or Discard if you don't want to save). +Your site will redeploy if you changed the configuration. Expect a few minutes before it comes back online. + + diff --git a/_sources/vendors/azure/new_user_a.md.txt b/_sources/vendors/azure/new_user_a.md.txt new file mode 100644 index 00000000..321d83b7 --- /dev/null +++ b/_sources/vendors/azure/new_user_a.md.txt @@ -0,0 +1,104 @@ +--- +orphan: true +--- + +c) Click + New application setting + +
+ +
+ +d) In Name write `MONGODB_URI` + +**Mind your database type!** + +```{tab-set} + +:::{tab-item} I have an Atlas/Railway/Northflank database
+In the line below, Value, paste the connection string you obtained after creating your database.

+::: + +:::{tab-item} I have a Cosmos database
+In the line below, Value, paste the connection string **with socketTimeoutMS**.

+::: + +``` + +

+Then click OK. + +
+ +e) Click again + New application setting (like in c. above) and write `API_SECRET` in Name. +`API_SECRET` will be your Nightscout site password, it needs to be at least 12 characters long and you should **NOT use spaces** if you use @ or ! symbols remember you will probably need to express them using [Percent encoding](https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_reserved_characters) in your uploader and downloader apps. If you're not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits. + +```{warning} +The API_SECRET is the **main password allowing full access to your Nightscout site**. Make sure it's reasonably secure (mix uppercase and lowercase letters, plus digits) and **do no not share it publicly**. If you think you exposed it by mistake, it is recommended that you **change it**. +``` + +
+ +Click OK. + +
+ +f) Click again + New application setting and write `DISPLAY_UNITS` in Name. +Acceptable choices for the units used in Nightscout are `mg/dl` or `mmol/L` (or just `mmol`). + +
+ +Click OK. + +
+ +g) Click again + New application setting and write `ENABLE` in Name. +If you don't use Dexcom Share to get your BG data in Nightscout, copy the line below to Value: + +`careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors` + +If you want to use Dexcom Share as a data source copy this one (it includes the keyword `bridge`): + +`careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge` + +Click OK. + +
+ +h) If you want to use Dexcom Share to have your data in Nightscout directly, you will need to add these three variable Names: + +`BRIDGE_USER_NAME` Your Dexcom account username to receive CGM data from the Dexcom Share service. +`BRIDGE_PASSWORD` Your Dexcom account password to receive CGM data from the Dexcom Share service. +`BRIDGE_SERVER` US if your Dexcom account is in the US, or, if you are bridging from the Dexcom Share service and are anywhere *outside* the US change this to EU. + +!!!note + If you use a DIY closed loop system it is recommended that you let it upload to Nightscout instead of importing using Dexcom Share and the `bridge` plugin. + +
+ +
+ +**Remember to add `bridge` at the end of the `enable` variable in the list below.** + +
+ +```{admonition} MOST COMMON ERRORS +:class: hint +The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom's Clarity page (check [here for USA accounts](https://clarity.dexcom.com) and [here for the others](https://clarity.dexcom.eu)) and try logging in to your Dexcom account. If your account info isn't valid, or you don't see any data in your Clarity account... you need to figure out your actual credentials before moving ahead. See [here](/troubleshoot/dexcom_bridge/) for troubleshooting tips and information on your Dexcom account. +``` + +```{admonition} Password +:class: note +*Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.* +``` + +```{hint} +You need to have at least one follower to use Dexcom Share. See [here](/uploader/setup.md#dexcom). +``` + +
+ +i) Click Save, then Continue. + +
+ +
\ No newline at end of file diff --git a/_sources/vendors/azure/new_user_b.md.txt b/_sources/vendors/azure/new_user_b.md.txt new file mode 100644 index 00000000..d616e522 --- /dev/null +++ b/_sources/vendors/azure/new_user_b.md.txt @@ -0,0 +1,86 @@ +--- +orphan: true +--- + +```{tab-set} + +:::{tab-item} Migrating from Heroku +c) Open a new browser tab or window and Log in [Heroku](https://id.heroku.com/login), select your app

+

+d) Click `Settings`

+

+e) Scroll down and click `Reveal Config Vars`

+

+f) Put the two windows Heroku and Azure side by side

+

+Now for every (no, not necessarily, read until **i** and come back) variable you need to do the following:

+::: + +:::{tab-item} Migrating from Railway +c) Open [Railway](https://railway.app) and click `login`. Login with GitHub.

+

+

+d) Select your Nightscout project.

+

+Select your web app.

+

+e) Click on `Variables`.

+

+Click on `RAW Editor` top right

+

+f) Put the two windows Railway and Azure side by side

+

+Now for every variable you need to do the following:

+::: + +``` + +
+ +g) Click + New application setting + +
+ +
+ +h) In Name write the variable name from the first column in Heroku or the one in red with Railway +Then, in the line below, Value, paste the value from the second column in Heroku or the one in green with Railway. + +
+ +Then click OK and go for the next one. + +
+ +You might not need to copy ALL the values, if you know which ones you need you can go ahead. +If you don't really know which ones you want to copy there's only few that are strictly necessary: + +**`API_SECRET`** +**`MONGODB_URI`** *Note: if you don't see `MONGODB_URI` but see `MONGO_CONNECTION` (NOT `MONGO_COLLECTION`) use its value.* +**`DISPLAY_UNITS`** + +in `ENABLE` paste this: + +If you don't use Dexcom Share to get your BG data in Nightscout, copy the line below to Value: + +`careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors` + +If you want to use Dexcom Share as a data source copy this one (it includes the keyword `bridge`): + +`careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge` + +If you have your data coming directly from Dexcom share those three: + +`BRIDGE_USER_NAME` +`BRIDGE_PASSWORD` +`BRIDGE_SERVER` + +
+ +
+ +i) When you're done copying, click Save, then Continue. + +
+ +
\ No newline at end of file diff --git a/_sources/vendors/digitalocean/new_user.md.txt b/_sources/vendors/digitalocean/new_user.md.txt new file mode 100644 index 00000000..462bede2 --- /dev/null +++ b/_sources/vendors/digitalocean/new_user.md.txt @@ -0,0 +1,8 @@ +--- +orphan: true +--- + + + + + diff --git a/_sources/vendors/fly.io/new_user.md.txt b/_sources/vendors/fly.io/new_user.md.txt new file mode 100644 index 00000000..911c35b9 --- /dev/null +++ b/_sources/vendors/fly.io/new_user.md.txt @@ -0,0 +1,659 @@ + +# Nightscout in Fly.io + +
+ +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +```{card} +## Fly.io +![Fly.io](/vendors/img/Fly.io.png) +^^^ +You can create your new Nightscout site in Fly.io. + +**Pros**: +* Nightscout fits in the free tier + +**Cons**: +* **Maintaining your site requires the use of command line instructions, not very intuitive** +* Fly.io stores variables as secrets: you cannot read them +* Relying on the MongoDB Atlas database +``` + +

+ +## Step 0: Create a database + +```{tab-set} + +:::{tab-item} I don't have a database yet +
Make sure you [create one](/nightscout/database) before starting your Nightscout web app creation with Fly.io.

+Come back here when you have a `MONGODB_URI` connection string.

+::: + +:::{tab-item} I already have a database +
Copy the connection string from your previous platform: [edit the variables](/nightscout/setup_variables.md#nightscout-configuration) and look for `MONGODB_URI`.

+If you don't see `MONGODB_URI` but see `MONGO_CONNECTION` (**NOT** `MONGO_COLLECTION`): use its value.

+::: + +``` + +

+ +## Step 1: Create a fly.io account + +[Sign up](https://fly.io/app/sign-up) to Fly.io. + +
+ +You will need to add credit card information to get Nightscout running. +Whenever requested, add one to prove you're a real person: + + + + + +
+ +Nightscout should run for free within the [allowances](https://fly.io/docs/about/pricing/#free-allowances). If you get billed, please report costs [here](https://github.com/nightscout/nightscout.github.io/issues/new) to have the documentation updated. + +

+ +## Step 2: Install `flyctl` + +```{warning} +The web terminal feature was removed from Fly.io. +You need a computer with flyctl. +``` + +Follow [these instructions](https://fly.io/docs/hands-on/install-flyctl/) to install `flyctl` on your computer. + +*Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.* + +

+ +## Step 3: Prepare the Nightscout project + +Type (or copy and paste) the following command in the terminal:
+ +a) Authenticate in Fly.io: + +`flyctl auth login` + +Clone the official Nightscout repository: + +`git clone https://github.com/nightscout/cgm-remote-monitor` + +
+ +b) Navigate to the Nightscout code directory copied locally with: + +`cd cgm-remote-monitor` + +
+ +c) Deploy your site with Fly.io. + +`flyctl launch` + + + +
+ +To the question `Would you like to tweak these setting before proceeding?` answer `Y` (yes). + +A web page to your new project will open in Fly.io. + + d) Type your new Nightscout site name, make sure it is valid and isn't already used by someone else. + + + +
+ +e) Select the region closest to where you live, but make sure it doesn't require a paid plan. + + + + + +
+ +f) In services set the port to `1337`. + + + +
+ +g) Make sure to select a `shared CPU 1x` with only `256MB` of memory to remain within the [free allowances](https://fly.io/docs/about/pricing/#free-allowances) limits. + + + +
+ +h) Don't select any database and `Confirm Settings`. + + + +
+ +i) Deployment will start. Wait until it completes. + + + + + +

+ +## Step 5: Set your Nightscout secrets + +a) Compile the information below. + +File all necessary fields, click on the Validate button at the bottom of the form, if no error is seen you will have all variables displayed in the text box at the bottom, click on the Copy All button. + +
+ +### **Mandatory variables** + +These three variables below must have a value. + +**MONGODB_URI** + +The MongoDB Connection String to connect to your MongoDB cluster. If you don't have this from your Mongo database, please re-read installation instructions at [Nightscout database](https://nightscout.github.io/nightscout/database) before continuing + +
+ +**API_SECRET** + +
+ +A passphrase that must be at least 12 characters long. Avoid special characters, which can cause problems in some cases + +**DISPLAY_UNITS** + +
+ + +
Preferred BG units for the site: `mg/dl` or `mmol/l` (or just `mmol`) + +
+ +### **Customizations** + +Leave default values if you don't want to change them + +**CUSTOM_TITLE** + +
+ +The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer + +**THEME** + +
+ + +
Default setting for new browser views for the color theme of the CGM graph. (`default` `colors` or `colorblindfriendly`) + +**ENABLE** + +
+ +Plugins to enable for your site. Must be a space-delimited lower-case list. Include the word `bridge` here if you are receiving data from the Dexcom Share service + +**SHOW_PLUGINS** + +
+ +Default setting for whether or not these plugins are checked (active) by default not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case + +**TIME_FORMAT** + +
+ + +
Default setting for new browser views for the time mode. (`12` or `24`) + +**NIGHT_MODE** + +
+ + +
Default setting for new browser views for whether Night Mode should be enabled. (`on` or `off`) + +**BOLUS_RENDER_OVER** + +
+ +U value over which the bolus values are rendered on the chart if the `x U and Over` option is selected + +
+ +### **Dexcom Share** + +If you want Nightscout to import directly from Dexcom Share + +**BRIDGE_USER_NAME** + +
+ +Your Dexcom account username to receive CGM data from the Dexcom Share service. Also make sure to include `bridge` in your ENABLE line. + +**BRIDGE_PASSWORD** + +
+ +Your Dexcom account password to receive CGM data from the Dexcom Share service. Also make sure to include `bridge` in your ENABLE line + +**BRIDGE_SERVER** + +
+ + +
If you are bridging from the Dexcom Share service and are anywhere *outside* the US change this to EU. (`US` or `EU`) + +
+ +### **Alarms** + +You can customize alarms or leave them to default values + +**ALARM_TYPES** + +
+ + +
`simple` and/or `predict`v. Simple alarms trigger when BG crosses the various thresholds set below. Predict alarms use a formula that forecasts where the BG is going based on its trend. You will *not* get warnings when crossing the BG thresholds set below when using the predict type + +**ALARM_URGENT_HIGH** + +
+ +Urgent High BG threshold triggers the `ALARM_URGENT_HIGH` alarm. Set in mg/dL or mmol/L as set in `DISPLAY_UNITS` variable + +**ALARM_URGENT_LOW** + +
+ +Urgent Low BG threshold triggers the `ALARM_URGENT_LOW` alarm. Set in mg/dL or mmol/L as set in `DISPLAY_UNITS` variable + +**ALARM_HIGH** + +
+ +High BG threshold triggers the `ALARM_HIGH` alarm. Set in mg/dL or mmol/L as set in `DISPLAY_UNITS` variable + +**ALARM_LOW** + +
+ +Low BG threshold triggers the `ALARM_LOW` alarm. Set in mg/dL or mmol/L as set in `DISPLAY_UNITS` variable + +**ALARM_TIMEAGO_URGENT** + +
+ +Default setting for new browser views for the number of minutes since the last CGM reading to trigger an `ALARM_TIMEAGO_URGENT` alarm + +**ALARM_TIMEAGO_WARN** + +
+ +Default setting for new browser views for the number of minutes since the last CGM reading to trigger an `ALARM_TIMEAGO_WARN` alarm + + + + + + +Now click on the Validate button below + + + +If errors show up below, please correct them and click Validate again. + +

Click the button Validate above.

+

+

+ +
+

+ +

+ +```{admonition} Save this! +:class: warning +What you just copied is the secrets configuration used to build your site.
+This is important information to maintain your Nightscout.
+**Make sure you keep a copy of it somewhere safe.** +``` + +
+ +b) Click on the `Copy all` button above. + +```{tip} +Now do not copy anything else!
+If you do another copy/paste after you clicked the `Copy All` button, click again **now** before pasting the configuration! +``` + +
+ +c) Then, in the terminal, paste what you copied above, hit `Enter` + + + +
+ +Wait until setting secrets complete. + + + +

+ +## Step 6: Deploy Nightscout + +a) In the terminal type: + +`flyctl deploy` + +You app will deploy. It will take time (about 10 minutes). + + + +
+ +Do not interrupt the process. + +
+ +When deploy completes you should see your new Nightscout site name. + + + +
+ +b) Last but not least: downscale your app typing the following command (replace *`myflynightscout`* with your own name): + +`flyctl scale --app `*`myflynightscout`*` count 1` + +Confirm with `y` when asked. + + + +
+ +c) You can now see your site in the fly.io dashboard at [https://fly.io/dashboard](https://fly.io/dashboard) click on the application (not the builder): + + + +
+ +d) Inside your app you should see that it is running and has a clickable hostname. + + + +


+ +```{include} /nightscout/first_setup.md + +``` + +
+ +(editing-config-vars-in-fly-io)= + +## Editing Config Vars in Fly.io + +```{warning} +The web terminal feature was removed from Fly.io. +You need a computer with flyctl. +``` + +Follow [these instructions](https://fly.io/docs/hands-on/install-flyctl/) to install `flyctl` on your computer. + +*Note for Windows: do not use Git Bash on your PC, prefer a PowerShell terminal.* + +Authenticate in Fly.io: + +`flyctl auth login` + +

+ +```{admonition} Secrets +:class: warning +Fly.io variables are `Secrets`, you **cannot see the values of your secret variables**.
+You can only delete them and set them: you **cannot edit them**.
+Please make sure you write them down somewhere! +``` + +
+ +If you want to create a new secret or modify an existing one you need to use the `flyctl secrets set` command. + +In the command line below replace `yourappname` by the app name (usually your Nightscout site name: **`yourappname`**`.fly.dev`). +For example if you want to set your Nightscout site vertical scale to linear: + +`flyctl secrets set SCALE_Y="linear" -a `*`yourappname`*` + +If your `SCALE_Y` secret was already set to `linear` you will see the following message: + +``` +Error No change detected to secrets. Skipping release. +``` + +When changing a secret, the app will automatically redeploy. You will see this sequence (it will take a few minutes): + +``` +Release v1 created +==> Monitoring deployment + + 1 desired, 1 placed, 1 healthy, 0 unhealthy [health checks: 1 total, 1 passing] +--> v1 deployed successfully +``` + +
+ +```{hint} +If you know you will change several secrets, add `--stage` to all the lines except the last one. +

+`flyctl secrets set SCALE_Y="linear" -a yourappname --stage` +
+`flyctl secrets set SCALE_Y="linear" -a yourappname --stage` +
+... +
+`flyctl secrets set SCALE_Y="linear" -a yourappname` +

+This will avoid your app to redeploy every time. +``` + +
+ +If the app didn't deploy automatically continue [here](#step-6-deploy-nightscout). diff --git a/_sources/vendors/github/create.md.txt b/_sources/vendors/github/create.md.txt new file mode 100644 index 00000000..da543d64 --- /dev/null +++ b/_sources/vendors/github/create.md.txt @@ -0,0 +1,65 @@ +--- +orphan: true +--- + +a) Click this link to create a GitHub account: [https://github.com/](https://github.com/) + +Enter your email and click `Sign up for GitHub`
+ +
+ +b) Enter a password and a username (anything you want and that is accepted, not very important). + Type `n` to decline advertisement emails.
+ +
+ +c) Play and solve the puzzle then click `Create account`
+ +
+ +d) GitHub will send you a verification code. Open your mail and check your inbox (check your spam-folder if not received after a couple of minutes).
+ +
+ +e) If a personalization sequence starts, click `Skip personalization ` at the bottom.
+ +
+ +f) Leave the page that opened as it is. Don't close it.
+ +
+ +You have created your GitHub account. Now fork the Nightscout project.
+ +
+ +### Fork the Nightscout project + +a) Click here to log in at GitHub: [https://github.com/login](https://github.com/login). + Enter your username or email and your password. Click `Sign in`
+ +
+ +```{admonition} If you already have a fork of cgm-remote-monitor in GitHub +[**Delete**](/update/redeploy.md#delete-your-own-fork-of-cgm-remote-monitor) or [**update**](/vendors/github/update.md#update-your-nightscout-fork) your current cgm-remote-monitor fork before continuing.
+``` + +b) Open this link [https://github.com/nightscout/cgm-remote-monitor](https://github.com/nightscout/cgm-remote-monitor). Click on `Fork`
+ +
+ +Confirm with `Create fork`
+ +```{warning} +Make sure you deselect `Copy the master branch only`. +``` + +
+ +c) Wait for a moment
+ +
+ +d) You now have a copy (fork) of the Nightscout project repository in your own GitHub.
+ +
diff --git a/_sources/vendors/github/delete.md.txt b/_sources/vendors/github/delete.md.txt new file mode 100644 index 00000000..97b2ffe5 --- /dev/null +++ b/_sources/vendors/github/delete.md.txt @@ -0,0 +1,47 @@ +--- +orphan: true +--- + +```{admonition} Delete Nightscout? +:class: note +Your GitHub only contains a copy of the code necessary to create a Nightscout site. +Deleting your fork of cgm-remote-monitor will not impact or stop your Nightscout site. +Even if it sounds scary to delete it, you can do it safely and copy (fork) it again from the main repository. +**You cannot delete the main Nightscout (nightscout/cgm-remote.monitor) repository.** +> Obviously if you're a Nightscout developer and you customized or modified the repository code, you know better than anybody else you don't want to delete it... (this documentation is not for you). +``` + +a) Click here to log in at GitHub: [https://github.com/login](https://github.com/login). +Enter your username or email and your password. Click `Sign in` + + + +
+ +b) Select your own `cgm-remote-monitor` project (not `nightscout/cgm-remote-monitor`) + + + +
+ +c) Click `Settings` + + + +
+ +d) Scroll down to `Danger zone` and click `Delete this repository` + + + +
+ +e) Copy and paste your full repository name to confirm then click `I understand...` + + + +
+ +You have successfully deleted your copy of the `cgm-remote-monitor` project. + +
\ No newline at end of file diff --git a/_sources/vendors/github/update.md.txt b/_sources/vendors/github/update.md.txt new file mode 100644 index 00000000..e60c2581 --- /dev/null +++ b/_sources/vendors/github/update.md.txt @@ -0,0 +1,29 @@ +# Update GitHub + +
+ +## Update your Nightscout fork + +```{tab-set} + +:::{tab-item} Heroku Railway Northflank Render +
You need to update your GitHub repository. +
+:::{include} /vendors/github/update_b.md +
+::: + +:::{tab-item} Fly.io +
If you're using Fly.io with the original cgm-remote-monitor repository you don't need to update in GitHub.

+Else you need to update your GitHub repository.

+:::{include} /vendors/github/update_b.md +
+::: + +:::{tab-item} Azure, Google Cloud +
You don't need to update your GitHub repository.

+::: + +``` + +
diff --git a/_sources/vendors/github/update_b.md.txt b/_sources/vendors/github/update_b.md.txt new file mode 100644 index 00000000..93ce4198 --- /dev/null +++ b/_sources/vendors/github/update_b.md.txt @@ -0,0 +1,33 @@ +--- +orphan: true +--- + +- Click here to log in at GitHub: [https://github.com/login](https://github.com/login). +- Enter your username or email and your password. Click `Sign in`
+ +
+ +- Select your own `cgm-remote-monitor` project (**not `nightscout/cgm-remote-monitor`**)
+ +
+ +- Your repository will open. If you see `This branch is xxx commits behind nightscout:master` you need to update. +- Select `Fetch upstream`
+ +
+ +- Select `Fetch and merge`
+ +
+ +- After a moment, your repository should display `This branch is up to date with nightscout:master`
+ +
+ +You have now updated your GitHub cgm-remote-monitor repository. + +
+ +If you ran into trouble, you can [redeploy](/update/redeploy) the project. + +
\ No newline at end of file diff --git a/_sources/vendors/google/new_user.md.txt b/_sources/vendors/google/new_user.md.txt new file mode 100644 index 00000000..848530d7 --- /dev/null +++ b/_sources/vendors/google/new_user.md.txt @@ -0,0 +1,31 @@ +# Nightscout in Google Cloud + +
+ +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +```{card} +## Google Cloud Nightscout +![](/vendors/img/GCNS.png) +^^^ + +**Pros**: +* Complete solution offering a large, > 10GB, free database +* Tools provided to migrate the database from other platforms +* A web interface for editing variables +* Option of multiple Nightscout accounts, one per Google account + +**Cons**: +* Not free! To keep the cost below $0.05 a month, outgoing traffic must be kept below 1GB per month. +* In Australia or China, cost can be more than $0.50 a month. +``` + +
+ +### [Instructions](https://navid200.github.io/xDrip/docs/Nightscout/GoogleCloud.html) + diff --git a/_sources/vendors/heroku.md.txt b/_sources/vendors/heroku.md.txt new file mode 100644 index 00000000..ef2e6aa9 --- /dev/null +++ b/_sources/vendors/heroku.md.txt @@ -0,0 +1,8 @@ +--- +orphan: true +--- + + + + + diff --git a/_sources/vendors/heroku/ecoplan.md.txt b/_sources/vendors/heroku/ecoplan.md.txt new file mode 100644 index 00000000..42f50bde --- /dev/null +++ b/_sources/vendors/heroku/ecoplan.md.txt @@ -0,0 +1,101 @@ +# Heroku Eco plan + +
+ +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +```{card} +## Heroku +![Heroku Eco](/vendors/img/Heroku.png) +^^^ +Since the [beginning](https://github.com/nightscout/cgm-remote-monitor/pull/98) Heroku has been a very popular platform for Nightscout. Most of the documentation was based on a Heroku Nightscout. +On August 25th 2022, Salesforce decided to [drop the free plan](https://blog.heroku.com/next-chapter). +You can create your new Nightscout site with Heroku using an Eco plan (5$/month). + +**Pros**: +* Large platform with a reliable history +* Well documented, well known by the community + +**Cons**: +* The Eco plan has the same limitations than the previous Free plan, for 5$ per month +* For a Nightscout site a 7$ per month Basic plan is not really worth it (compared to hosted solutions) +* Relying on the MongoDB Atlas database +``` + +
+ +## Enable a 5$/month Eco Plan + +
+ +```{warning} +Heroku billing is monthly.
+One minute of Eco plan will be billed 5$ in the current month.
+Switching billable plan during the same month with add another plan billing for the whole month. +``` + +
+ +- Log in Heroku [https://id.heroku.com/login](https://id.heroku.com/login) + + + +
+ +- Select your app (hidden in yellow) + + + +
+ +- Click `Resources` then select `Change Dyno Type` + + + +
+ +- Select `Eco ($5 for 1000 Dyno Hours/Month)` then click `Save` + + + +
+ +- Your Nightscout Heroku app is now using an `Eco` plan. + + + +- **Make sure your credit card information is up to date!** + Go to your `Account settings`. + + + +- `Billing` + + + +- Verify the credit card you used is still valid, in case of doubt `Change credit card` and enter a valid credit card. + + + +
+ +
+ +### Prevent your Nightscout app from falling asleep + +```{admonition} Use with caution +:class: warning +If an app fails and crashes at startup (database full), if you entered wrong credentials and the app stops for missing data activity, using this trick to keep it alive will not help. It might even make things worse in the case of wrong Dexcom credentials and lead to a locked account. +``` + +This is necessary if you don't have an uploader sending data to Nightscout, or a follower polling data from it. +For example using the bridge plugin. + +- You can use monitoring webapps like Uptime Robot, New Relic, ... + +
diff --git a/_sources/vendors/heroku/hobbyplan.md.txt b/_sources/vendors/heroku/hobbyplan.md.txt new file mode 100644 index 00000000..b85047b3 --- /dev/null +++ b/_sources/vendors/heroku/hobbyplan.md.txt @@ -0,0 +1,92 @@ +# Heroku Basic plan + +
+ +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +```{card} +## Heroku +![Heroku Eco](/vendors/img/Heroku.png) +^^^ +Since the [beginning](https://github.com/nightscout/cgm-remote-monitor/pull/98) Heroku has been a very popular platform for Nightscout. Most of the documentation was based on a Heroku Nightscout. +On August 25th 2022, Salesforce decided to [drop the free plan](https://blog.heroku.com/next-chapter). +You can create your new Nightscout site with Heroku using an Eco plan (5$/month). + +**Pros**: +* Large platform with a reliable history +* Well documented, well known by the community + +**Cons**: +* The Eco plan has the same limitations than the previous Free plan, for 5$ per month +* For a Nightscout site a 7$ per month Basic plan is not really worth it (compared to hosted solutions) +* Relying on the MongoDB Atlas database +``` + +
+ +## Upgrade to 7$/month Basic Plan + +
+ +```{admonition} 5$/month Eco Plan +You can also select a more economic [eco plan upgrade](/vendors/heroku/ecoplan). +``` + +
+ +```{warning} +Heroku billing is monthly.
+One minute of Eco plan will be billed 5$ in the current month.
+Switching billable plan during the same month with add another plan billing for the whole month. +``` + +
+ +- Log in Heroku [https://id.heroku.com/login](https://id.heroku.com/login) + + + +
+ +- Select your app (hidden in yellow) + + + +
+ +- Click `Resources` then select `Change Dyno Type` + + + +
+ +- Select `Basic ($7/dyno/month)` then click `Save` + + + +
+ +- Your Nightscout Heroku app is now using a `Basic` plan. + + + +- **Make sure your credit card information is up to date!** + Go to your `Account settings`. + + + +- `Billing` + + + +- Verify the credit card you used is still valid, in case of doubt `Change credit card` and enter a valid credit card. + + + +
+ diff --git a/_sources/vendors/heroku/mfa.md.txt b/_sources/vendors/heroku/mfa.md.txt new file mode 100644 index 00000000..e9e70615 --- /dev/null +++ b/_sources/vendors/heroku/mfa.md.txt @@ -0,0 +1,135 @@ +# Heroku MFA + +Multiple factor authentication (MFA) also called 2 factors authentication (2FA) is a safety feature preventing malicious access to an account. Once authenticated with your login and password you will be required to confirm your identity with another method, a second factor authentication. + +```{admonition} Losing access +:class: warning +It is recommended to setup at least two MFAs, **one being a copy of the recovery codes**. Salesforce take security very seriously and recovering your account after losing access might range from very complex to impossible. For increased safety, setup more than one authentication method on more than one device. +``` + +
+ +To setup MFA and secure your account select `Continue`. +If you don't want to secure your account, select `Later`. + +If you want to enter your account without setting MFA just select `Later`. + + + +
+ +You will also find the possibility to perform this operation from your Heroku account settings. + + + + + +
+ +You will be proposed various authentication options, see the explanation below. + +You should select at least one (Salesforce Authenticator is recommended) but might use more than one (registering a build in authenticator like a fingerprint reader is also a good idea) and you should print your Recovery Codes and keep them together with your Nightscout information. + + + +
+ +## Salesforce Authenticator + +Salesforce Authenticator relies on an additional app you will need to install on your phone. It is available in the [Google Play Store](https://play.google.com/store/apps/details?id=com.salesforce.authenticator) and the [Apple Store](https://apps.apple.com/us/app/salesforce-authenticator/id782057975). + +```{admonition} Losing or removing the Authenticator app +It is recommended to setup at least two MFAs, **one being a copy of the recovery codes**. If your only authentication method is this app you will lose access if you remove it or lose/change phone! +``` + +If you select this option (use the `Add` button) you will need to install the app to get the passcode called Two-Word Phrase + +Install the app and `Add an Account`. + + + +
+ +The app will give you a Two-Word Phrase (`perfect guide` in the example below) + + + +
+ +Copy it or type it into the authentication connection window in Salesforce Heroku and select `Connect`. + + + +
+ +In the app, confirm with `Connect` then `Got It`. + + + + + +
+ +You will now see Heroku in the app, with a single use code (that you usually won't need). + + + +
+ +Now, every time you will log into Heroku, you will have to confirm using your phone. Just accept the access. + +
+ +Once the account added into Salesforce Authenticator you will be able to add another option that is Built-In Authenticator (like a fingerprint reader). + + + +
+ +## Built-In Authenticator + +You need Salesforce Authenticator setup in order to use this method (see above). + +Adding a built in authenticator will allow you to use your device biometric devices like a fingerprint reader. + +Select `Register` to add this identification method as a second factor. You will not be required to use the Salesforce Authenticator after registration. You can now remove it if you wish (not recommended). + + + +Note that you won't be able to use your fingerprint if created on a computer to unlock your account when using your phone and vice versa. You should add one fingerprint per device type. + +
+ +## One-Time Password Generator + +You can use other apps to create your second factor, like Google Authenticator or Microsoft Authenticator apps. You will find both these apps in the Google Play Store and the Apple Store. + +First install one of these apps on your mobile device, then select `Add`. + +Scan the QR code with the app and `Connect`. + + + +
+ +Your Heroku will now be connected to this second factor authentication method and you will have to approve access, when logging into Heroku, with the app you selected. + + + +
+ +## Security Key + +Security key authentication requires you to use a hardware key. You probably won't be reading this if you own one. + + + +
+ +## Recovery Codes + +You should enable and keep a copy of your recovery codes. This might eventually be the only way to recover your account access if something goes wrong with the other authentication method. Print a copy and keep it with your Nightscout information together with your diabetes documentation. + + + + diff --git a/_sources/vendors/heroku/migrate.md.txt b/_sources/vendors/heroku/migrate.md.txt new file mode 100644 index 00000000..f913d5ab --- /dev/null +++ b/_sources/vendors/heroku/migrate.md.txt @@ -0,0 +1,86 @@ +# Migration? + +As Heroku and Railway stopped their free plan, if you would like to revive your site, one question remains: "What should I do with my Nightscout, should I migrate, where? What is recommended?" + +There is no universal solution. So, you'll have to read between the lines and understand what's the best strategy for you, as we have different needs, skills and budgets. + +## **[TANSTAAFL](https://en.wiktionary.org/wiki/TANSTAAFL)** + +This is an important concept everybody needs to understand: what we call free means we don't have to pay for it but it also means someone else is paying for it. It doesn't mean it's bad, we all know the price of T1D is already too high for us and our kids but we can't **pretend** that someone else will pay for it. Whoever offers a free service should have our respect and gratitude, and when they understand the weight of free users is too high and decide to start billing, we should accept it. + +```{admonition} Confusing? +:class: hint +**[Need help to choose? +Try the wizard](/nightscout/wizard)**. + +``` + +## **[T1Pal](/index.md#t1pal)** + +***You need a simple reliable Nightscout but don't want to build it and maintain it?*** + +T1Pal is made by developers who contribute to Nightscout development, it doesn't include all bells and whistles (see the differences [here](https://t1pal.com/legal/faq_8_18_2020_13_38#compare-to-nightscout)) but you won't have to worry about security, upgrades or database size. If you will want to pay a vendor for your DIY Nightscout you should seriously consider T1Pal. Also, if you need to support multiple T1D people in a family that's surely something to think about as you can have up to 5 sites in one subscription. Data migration is not available, contact T1Pal support for settings migration. + +## **[NS10BE](/index.md#ns10be)** + +***You need a simple reliable Nightscout but don't want to build it and maintain it?*** + +You can create Nightscout with a few clicks and won't have to worry about maintenance, updates, database space and CPU limits. Some features are not available for legal reasons and if you need extra variables setup you can contact NS10BE support. You will need to copy your Nightscout settings but can migrate your Mongo database easily in NS10BE. + +## **[Nightscout.Pro](/index.md#nightscout-pro)** + +***You need a simple reliable Nightscout but don't want to build it and maintain it?*** + +A completely 'hands-off' approach to Nightscout. Simply subscribe via the [website](https://nightscout.pro/) and you'll receive an email once your site is ready. Enjoy unlimited database and resources and do not have to worry about updating your nightscout site as it all taken care of for you. + +## [**Google Cloud**](https://navid200.github.io/xDrip/docs/Nightscout/GoogleCloud) + +***You're not scared to innovate with a new easy and reliable way to build and maintain your Nightscout? Give this a try!*** + +With the xDrip+ team trying to make it so easy that the solutions above will look difficult, you need to try it to believe it. + +*Note: You can use this method to deploy in Digital Ocean and other VPS* + +## **[Azure](/vendors/azure/new_user)** + +***You need a reliable engine for your Nightscout site, well Azure sure is the way to go.*** + +Azure is back hurrah hurrah. Wait, why did we leave it some years ago? Ah, sure, costs. But we believe we have a free solution thanks to Scott. Shame the Cosmos database doesn't always meet expectations... And keep in mind the free tier is designed for testing, not production. + +## **[Heroku](/vendors/heroku/ecoplan)** + +***You liked the Heroku experience and don't want to change? An Eco plan subscription is all it takes to continue like that.*** + +Heroku is still a valid choice for running Nightscout. Someone reminded me they've been offering a free account to many of us for years so there's no reason not to pay for an Eco account and let it go as before. Still, it is not set it and forget it and you will need to keep it updated yourself. And that MongoDB Atlas database still is a weak point. + +## [**MongoDB Atlas**](/vendors/mongodb/atlas) + +***You need a small free database? An M0 Atlas does that and nothing more.*** + +Since they bought mLab, most have a database in MongoDB. This is a weak point of Nightscout DIY and forced our developers to do a lot of work to cope with it. An M0 free database is very limited in size and DIY Loopers/AAPS'ers should be very careful to keep the database below 512MB before their site crashes. Also, recently MongoDB Atlas is recording us this is a sandbox database (i.e. for testing) and not for production (continuous use). An M2 database only removes size limitations and is not worth the cost versus hosted solutions. + +## **[Railway](/vendors/railway/new_user)** + +***You want an alternative to Heroku? Railway costs the same than the Eco plan.*** + +We really liked the Railway solution when we found it: it's very simple to migrate from Heroku and the platform is simple to use. Still, we discovered some Nightscout followers are suffering network related issues. The free plan has been removed and the Hobby plan is starting at 5$ per month (which should be enough for a single Nightscout site). + +## **[Northflank](/vendors/northflank/new_user)** + +***Everybody else is going for Railway and you prefer a safer alternative because you're not afraid of an ugly Nightscout site name? Northflank is a good idea.*** + +Not very sponsored, Northflank is also a good option, simple of use and offering a migration utility. The only issue is trying to remember your Nightscout site name (try `night--spicy-steam--nightscout--ci95-l9xw.code.run` for example). Still, Northflank is a reliable provider. But they will most probably review their free plan in the future. + +## **Fly.io** + +***Fly.io still offers a free tier but if you don't like typing commands on your computer you'll short be facing a hard stop.*** + +Fly.io was immediately popular due to the ease of migration from Heroku (the migration wizard has been removed). Now, if you want to maintain your site you'll have to use command line instructions in the web terminal. On the other hand, it is a good solution. + +## [**Oracle Cloud**](https://www.dropbox.com/s/5twlqrndofqno0t/0-amber-oracle.pdf) + +***You're ready to type commands in a terminal window, following an accurate step by step guide? Oracle Cloud solution is worth a try.*** + +Follow this very detailed guide to build your Nightscout site. It also contains a lot of reference information for VPS DIY Nightscout, including Docker. + +
diff --git a/_sources/vendors/heroku/new_user.md.txt b/_sources/vendors/heroku/new_user.md.txt new file mode 100644 index 00000000..86949f0f --- /dev/null +++ b/_sources/vendors/heroku/new_user.md.txt @@ -0,0 +1,402 @@ +# Nightscout in Heroku + +
+ +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +```{card} +## Heroku +![Heroku Eco](/vendors/img/Heroku.png) +^^^ +Since the [beginning](https://github.com/nightscout/cgm-remote-monitor/pull/98) Heroku has been a very popular platform for Nightscout. Most of the documentation was based on a Heroku Nightscout. +On August 25th 2022, Salesforce decided to [drop the free plan](https://blog.heroku.com/next-chapter). +You can create your new Nightscout site with Heroku using an Eco plan (5$/month). + +**Pros**: +* Large platform with a reliable history +* Well documented, well known by the community + +**Cons**: +* The Eco plan has the same limitations than the previous Free plan, for 5$ per month +* For a Nightscout site a 7$ per month Basic plan is not really worth it (compared to hosted solutions) +* Relying on the MongoDB Atlas database +* New sites naming add an identifier after the app name making it harder to remember +``` + +
+ +------ + +**Create your Heroku account from a computer.** + +Do not change device/computer/browser during the setup process! + +```{hint} +If you have unexpected issues when creating your site, restart with another browser. +``` + +```{admonition} If this is not your first attempt to deploy Nightscout +:class: warning +You might want to do some [cleanup](/troubleshoot/heroku.md#cleanup) before. +``` + +
+ + +## Step 0: Create a database + +```{admonition} Heroku doesn't include a database +:class: note +Make sure you [created one](/nightscout/database) before starting your Nightscout web app creation with Heroku. +Come back here when you have a MONGODB_URI connection string. +``` + + + +```{admonition} Migrating? +:class: tip +Copy the connection string from your previous platform: [edit the variables](/nightscout/setup_variables.md#nightscout-configuration) and look for `MONGODB_URI`. +If you don't see `MONGODB_URI` but see `MONGO_CONNECTION` (**NOT** `MONGO_COLLECTION`): use its value. +``` + +
+ +## Step 1: Create a GitHub account and fork the Nightscout project + +```{tab-set} + +:::{tab-item} I don't have a GitHub Account +### Create a GitHub account +::: {include} /vendors/github/create.md +::: + +:::{tab-item} I already have a GitHub Account +### Update your Nightscout fork +:::{include} /vendors/github/update_b.md +::: + +``` + +
+ +## Step 2: Create a Heroku account + +
+ +```{admonition} Multiple factor authentication +:class: warning +Salesforce will insist you should enable multiple factor authentication. +While this is indeed a good idea to increase safety, should you decide to enable it, make sure: +- To **print your recovery codes** and keep them in a safe place +- To **never** delete the authenticator app on your phone. +Failure to follow these rules will end up in an account you can't log into, hance can't restart and maintain your Nightscout site. +More information [here](/vendors/heroku/mfa.md). +``` + +
+ +a) Click this link to create an Heroku account: [https://signup.heroku.com/login](https://signup.heroku.com/login) + +b) Enter mandatory data (*) and click `CREATE FREE ACCOUNT` + + + +
+ +c) Heroku will send a confirmation email, open your mail and check your inbox (check your spam-folder if not received after a couple of minutes). + + + +
+ +d) Click on the activation link + + + +
+ +e) Create a password, it is important that you write it down for later usage. Click `SET PASSWORD AND LOG IN` + + + +
+ +f) Click `CLICK HERE TO PROCEED` + + + +Read and accept Salesforce terms of service. + +Se sei residente in Italia, abilita l'interruttore `Are you domiciled in Italy`, leggi e accetta le condizioni supplementari. + + + +
+ +g) Your Heroku page will open, click on your profile picture, in the top right corner, and select `Account Settings` + + + +
+ +h) Click on `Billing` + + + +
+ +i) Click `Add credit card` + + + +
+ +j) Enter your credit card information and click `Save Details` + +
+ + + +
+ +k) Subscribe to the `Eco plan` for 5$ per month. You can upgrade to Basic later if you wish. + + + +
+ +l) You should now have 2 pages open: Heroku and GitHub. Leave them open.

+ +## Step 3: Fork and deploy cgm-remote-monitor + +a) [Fork the Nightscout cgm-remote-monitor project](/nightscout/github.md#fork-the-nightscout-project). + +
+ +b) Click the `Deploy to Heroku` button below: + + + +
+ +```{admonition} You're getting into the core setup of your site +:class: note +Below you'll see the minimum required configuration, you can modify the variables later in Heroku. +``` + +
+ +c) Enter your CGM in the Cloud site name: invent a name you will use to see your BG in the cloud. Confirm that the name is available. + +```{hint} +Starting June 14th 2023, site names will include an [application name identifier](https://devcenter.heroku.com/articles/custom-domains) after your app name. +``` + +d) Don’t change the region. + + + +
+ +Scroll down and setup the following variables: + +
+ +e) `API_SECRET` will be your Nightscout site password, it needs to be at least 12 characters long and you should **NOT use spaces** if you use @ or ! symbols remember you will probably need to express them using [Percent encoding](https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_reserved_characters) in your uploader and downloader apps. If you're not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits. + +```{warning} +The API_SECRET is the **main password allowing full access to your Nightscout site**. Make sure it's reasonably secure (mix uppercase and lowercase letters, plus digits) and **do no not share it publicly**. If you think you exposed it by mistake, it is recommended that you **change it**. +``` + + + +
+ +f) If you want to link your Dexcom Share account as a data source, complete the following lines: + +```{note} + If you use a DIY closed loop system it is recommended that you let it upload to Nightscout instead of importing using Dexcom Share and the `bridge` plugin. +``` + + + +
+ +```{admonition} MOST COMMON ERRORS +:class: hint +The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom's Clarity page (check [here for USA accounts](https://clarity.dexcom.com) and [here for the others](https://clarity.dexcom.eu)) and try logging in to your Dexcom account. If your account info isn't valid, or you don't see any data in your Clarity account... you need to figure out your actual credentials before moving ahead. See [here](/troubleshoot/dexcom_bridge/) for troubleshooting tips and information on your Dexcom account. +``` + +```{admonition} Password +:class: note +*Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.* +``` + +```{hint} +You need to have at least one follower to use Dexcom Share. See [here](/uploader/setup.md#dexcom). +``` + +
+ +g) Linking your CareLink account as a data source is **not possible anymore using cloud hosted Nightscout sites**. +Use an Android bridge device with a private version of xDrip+. +More information **[here](/uploader/xdripcarelink)**. + + + +
+ +j) Select the units you’re using in `DISPLAY_UNITS` acceptable choices are `mg/dl` or `mmol/L` (or just `mmol`). + + + +
+ +h) In `ENABLE`, copy and paste the following words (separated by a space) so that won't have to think about which you want now: + +`careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors` + +**If you are using your Dexcom share account as a data source** also add `bridge` at the end, after a space like this: + +`careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge` + + + +```{admonition} ENABLE words +You find more information about the `ENABLE` words on the: [Setup page](/nightscout/setup_variables) +``` + +
+ +i) Now you need the connection string you defined during the database creation (as the example below, but not the string below). Copy and paste it in the `MONGODB_URI` variable field. + + + +Make sure it looks like this one below and **NOTE: THERE ARE NO < AND > CHARACTERS**: + +Example for MongoDB Atlas: + +`mongodb+srv://nightscout:soo5ecret@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority` + +Example for a MongoDB database: + +`mongodb://nightscout:soo5ecret@mydbhosting.fqd/mydatabase` + +
+ +j) Scroll down to the end of the list and click `Deploy app` + + + +
+ +k) **WAIT** until completion (will take some time). Do not interrupt the process until it's complete. + + + +
+ +l) Then click `View` (if nothing happens, click `Manage App` -> `Open App`, in upper right corner) + + + +
+ +```{include} /nightscout/first_setup.md + +``` + +
+ +### Papertrail + +- Finally, you might want to modify the `PAPERTRAIL_API_TOKEN` line. Heroku offers a free, tiny amount of Papertrail service (this is like a logging service for how the site is running), but this generates a lot of confusion to most people later on, when they get a message that their "Free Papertrail Service has run out of room". Papertrail is not needed, edit the line and add `DISABLED` at the end, so that you can recover the function if you need it later. + + + +

+ +## Editing Config Vars in Heroku + +
+ +Once Nightscout deployed, you can access your variables from [Heroku](https://id.heroku.com/login) in order to change or customize your site. +Variables are described [here](/nightscout/setup_variables). + + + +- Select your app + + + +
+ +- Click `Settings` + + + +
+ +- Scroll down and click `Reveal Config Vars` + + + +
+ +- You can modify the values clicking on the pen icon + + + +
+ +- Change the contents of `Value` as needed then click `Save Changes` + + + +
+ +Changing a variable and saving a new value will restart your site, if the change is not actuated you might also want to [restart all dynos](/troubleshoot/heroku.md#restart-all-dynos). + +
+ +
+ +## Prevent your Nightscout app from falling asleep + +```{admonition} Use with caution +:class: warning +If an app fails and crashes at startup (database full), if you entered wrong credentials and the app stops for missing data activity, using this trick to keep it alive will not help. It might even make things worse in the case of wrong Dexcom credentials and lead to a locked account. +``` + +This is necessary if you don't have an uploader sending data to Nightscout, or a follower polling data from it. +For example using the bridge plugin. + +- You can use monitoring webapps like Uptime Robot, New Relic, ... + +
+ +------ + +You have completed a new Nightscout site creation. The following section provides more information for variables edition that you might not need to use now. + +------ + +
+ +## Renaming your Nightscout site + +```{warning} +Starting June 14th 2023, site names will include an [application name identifier](https://devcenter.heroku.com/articles/custom-domains) after your app name.
+Keep this in mind if you want to rename your site: the result might not be as simple as it was before. +``` + +You can rename your Nightscout site URL in your app `Settings`. + + + +Once done, make sure all apps (uploaders and downloaders) are updated accordingly. diff --git a/_sources/vendors/mongodb/atlas.md.txt b/_sources/vendors/mongodb/atlas.md.txt new file mode 100644 index 00000000..61d7e5a3 --- /dev/null +++ b/_sources/vendors/mongodb/atlas.md.txt @@ -0,0 +1,247 @@ +# MongoDB Atlas Database + +
+ +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +```{card} +## MongoDB Atlas Database +![MongoDB Atlas](/vendors/img/Atlas.png) +^^^ +MongoDB bought [mLab](https://twitter.com/chrisckchang/status/506959446753284096) in 2018 and shutdown its service in 2020. Most users migrated to MongoDB Atlas, using a free M0 database with a limited 512MB capacity. Leaving the database grow uncontrolled usually leads to a Nightscout crash. + +**Pros**: +* The M0 cluster is free +* Nightscout was adapted to MongoDB Atlas + +**Cons**: +* M0 clusters are designed for learning and testing, not production +* There is no warranty the M0 cluster will remain in the future +* A larger M2 cluster costs 9$ per month (consider hosted Nightscout) +* A full M0 database crashes Nightscout, this is a common issue for DIY closed loop system users +``` + +
+ +```{note} +MongoDB Atlas regularly changes the site aspect. If you encounter a page not matching this documentation search for keywords like `not now`, `skip` or `later` to continue. Report discrepancies [here](https://github.com/nightscout/nightscout.github.io/issues/new). +``` + +
+ +## Create an Atlas database + +a) Open a browser tab at: [https://www.mongodb.com/cloud/atlas/register](https://www.mongodb.com/cloud/atlas/register) + +b) Enter your information, click `Continue` then `Create account` + + + +
+ +MongoDB Atlas will send you an email, if you don't receive it check your Spam folder. + + + +
+ +In the email you received from **MongoDB Atlas** (mongodb-atlas @ mongodb.com), click on `Verify email` + + + +
+ +Another browser tab will open with your confirmed MongoDB account, `Continue`. + + + +
+ +Enter some information (like below) and click `Finish`. + + + +
+ +c) Select `Create a cluster in Shared Clusters (FREE)` + + + +```{admonition} If you ever see this, just STOP +:class: danger +We're building a free cluster: you don't need to provide any billing information. + +``` + +
+ +d) Check you selected `Shared`, leave all default values and click `Create Cluster` + + + +
+ +e) Select `Username and Password` and invent a database username (for example `nightscout`) and a database password (for example `soo5ecret` but please make one that's yours!). + +```{admonition} Database credentials +:class: warning +Do not use your Atlas **account** credentials. +Do not use special characters: only letters and numbers. No spaces. +``` + + + +Write down the password in the line below (yes, in this browser window you're reading now, unless you're reading a printed version). You’ll need it later. + + + +| Database password (write here ->) | +| ------------------------------------------------------------ | + +
+ +Then click `Create User`. + +f) Select `My Local Environment` and in the box `My IP address` write `0.0.0.0/0` (mind these are all zeroes, not the letter O) + +```{warning} +If you don't allow access from anywhere (IP 0.0.0.0/0) Nightscout will not be able to access your database." +``` + + + +Then click `Add Entry`. + +
+ +g) Click on `Finish and Close` + + + +
+ +h) Click on `Go to Databases` + + + +
+ +i) Atlas will create your default cluster, it can take more than 3 minutes + + + +
+ +j) Click on `CONNECT` + + + +
+ +k) If displayed, click on `Choose a connection method` (else skip) + + + +
+ +l) Select `Drivers` + + + +
+ +m) Scroll down (do not change any value) and copy the connection string: click `Copy` and paste it somewhere to edit it (like Notepad). + + + +
+ +n) Paste the string in the line below (yes, in this browser window you're reading now, unless you're reading a printed version). + +(paste here ->) + +
+ +```{hint} +It should be similar to this (`xxxxx` will be different): + +`mongodb+srv://nightscout:@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority` +``` + +
+ +o) (Optional) Invent a name for your database, this is not a critical information (for example `myCGMitc`). Only letters and numbers, no spaces. + +| Database Name (write here ->) | +| ------------------------------------------------------------ | + +
+ +p) Click on the button `Generate` (just here below this line: in this browser window you're reading): + + + +

The connection string will appear here

+ +
+ + +
+ +```{warning} +Keep this string safely aside, it is called your `MONGODB_URI` +``` + +
+ +p) If you want to do it manually: replace `` with your database password as noted previously (in the example below `soo5ecret`) and `` by any text you want, say `mycgmic` for example. The result will be like this: + +`mongodb+srv://nightscout:soo5ecret@cluster0.xxxxx.mongodb.net/myCGMitc?retryWrites=true&w=majority` + +```{hint} +**There should be NO `<` and NO `>` characters in the final string, neither for password nor for database name.** +``` + +
+ +You have completed a MongoDB Atlas database creation. +Now that you have **copied** the resulting `MONGODB_URI` string to a **safe place**, go back to the instructions page you were following. + +
diff --git a/_sources/vendors/nightscout4u/new_user.md.txt b/_sources/vendors/nightscout4u/new_user.md.txt new file mode 100644 index 00000000..980f1073 --- /dev/null +++ b/_sources/vendors/nightscout4u/new_user.md.txt @@ -0,0 +1,9 @@ +--- +orphan: true +--- + + + + + + diff --git a/_sources/vendors/northflank/database.md.txt b/_sources/vendors/northflank/database.md.txt new file mode 100644 index 00000000..19081333 --- /dev/null +++ b/_sources/vendors/northflank/database.md.txt @@ -0,0 +1,181 @@ +# Northflank Database + +
+ +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +```{card} +## Northflank Mongo Database +![Northflank](/vendors/img/Northflank.png) ![MongoDB](/vendors/img/MongoDB.png) +^^^ +Northflank offers a Mongo database. + +**Pros**: +* Simple to create +* Economic reliable database +* High quality Mongo database with a replica set +* You can deploy up to $20/mo worth of free resources on Northflank’s managed cloud + +**Cons**: +* Heroku Nightscout might crash with database timeouts +``` + +
+ +If you already have a Northflank account, [log in](https://app.northflank.com/login) and [continue (skip new account creation)](#create-your-database). + +**Else** + +## Create an account with Northflank + +a) Sign-up to [Northflank](https://app.northflank.com/signup) in a new browser tab. +Fill all required fields and `Sign up`. +You can also sign up with Google, GitHub, ... if you wish. + + + +
+ +Northflank will send you an email to complete the registration. + + + +
+ +b) Open your email and confirm with `Verify email`. + + + +
+ +c) Click `Choose theme`. + + + +
+ +d) Select `Skip for now`. + + + +
+ +e) Click `Create free project` + + + +
+ +f) Invent a project name (`nightscout` for example) and select a region (Europe or US) then click `Create project` + + + +
+ +
+ +## Create your database + +```{admonition} Costs +:class: warning +* The Mongo database is free, you only pay for the storage +* Minimum price is 0.3$/month, cost is then 0.3$/GiB/month +* A good database is important for your Nightscout site reliability +``` + +
+ +a) Open a new browser page [https://northflank.com/dbaas/mongodb-on-northflank](https://northflank.com/dbaas/mongodb-on-northflank) and click `Deploy MongoDB on Northflank for free` + + + +
+ +b) Select your account and your project name (see below if you don't have one yet). + + + +
+ +If you don't have a project in Northflank, create a new one with `Create project` and then select `Create free project` else skip to **c)**. + + + + + +Invent a project name (`nightscout` for example) and select a region (Europe or US) then click `Create project` + + + +
+ +c) Select `Deploy addons`. + + + +
+ +d) Select `MongoDB` and type a name for your addon (not important) in `Addon name`. + + + +
+ +e) Select a Mongo version if you want. + +All Mongo versions are supported by Nightscout: you can select the one you prefer. +Since recent versions don't add value, you can safely select an older version like 5.0.24. + + + +
+ +**Important:** If you will use this database with a Nightscout that is not in Northflank, you must enable `Publicly accessible`. +If you will deploy Nightscout in Northflank, you can leave it disabled. + + + +
+ +f) Select `Create addon` + + + +
+ +g) If you haven't yet, you need to add a payment method into Northflank. +You will be charged monthly for your database (0.3$ up to 1 GiB, then 0.3$/GiB). + + + +
+ +g) Enter your password and click `Confirm` to see your MongoDB information. + + + +
+ +h) Click the copy icon of the line `MONGO_SRV`. + + + +
+ +```{admonition} This is an important information +:class: warning +Now that you have **copied** the resulting `MONGODB_URI` string, keep it in a **safe place**, you will need it later. +``` + +
+ +i) Wait until your database is fully created. It might take some time. + + + +
\ No newline at end of file diff --git a/_sources/vendors/northflank/migrate.md.txt b/_sources/vendors/northflank/migrate.md.txt new file mode 100644 index 00000000..3e52770f --- /dev/null +++ b/_sources/vendors/northflank/migrate.md.txt @@ -0,0 +1,7 @@ +--- +orphan: true + +--- + +Now included in the main [Nightscout with Northflank](/vendors/northflank/new_user) page! + diff --git a/_sources/vendors/northflank/migrate_a.md.txt b/_sources/vendors/northflank/migrate_a.md.txt new file mode 100644 index 00000000..fc4215b9 --- /dev/null +++ b/_sources/vendors/northflank/migrate_a.md.txt @@ -0,0 +1,73 @@ +--- +orphan: true +--- + +```{warning} +**If you already have a Northflank database, you cannot use this wizard.** +[Create a new Northflank Nightscout site](/vendors/northflank/new_user.md#step-3-deploy-nightscout-in-northflank) with only `MONGODB_URI` and `API_SECRET` then [manually copy your Heroku variables](/vendors/northflank/new_usermd/#copy-all-variables-from-heroku). +``` + +a) Go to your `Account` `Dashboard` - `Settings` and scroll down to `Import`. +Select Heroku. + + + +```{note} +If you don't see this option, send a mail to Northflank support to request access to the feature. +``` + +

+ +b) Click `Link Heroku`. + + + +

+ +c) Login in Heroku. + + + +

+ +d) Click `Allow`. + + + +

+ +e) Select your Nightscout Heroku app then click `Continue`. + + + +

+ +f) Select your project (the one you created in **Step 1.g**) then click `Continue`. + + + +

+ +g) Verify the branch you want to migrate, usually it's `master` unless you know why you need another one. + + + +

+ +h) Select `heroku/builder-classic:22`. + + + +

+ +i) Modify your compute plan to the smallest **`nf-compute-10`** and click `Continue`. + + + +

+ +j) Wait until import completes then return to your Dashboard (top left). + + + +

diff --git a/_sources/vendors/northflank/new_user.md.txt b/_sources/vendors/northflank/new_user.md.txt new file mode 100644 index 00000000..020ad9fd --- /dev/null +++ b/_sources/vendors/northflank/new_user.md.txt @@ -0,0 +1,288 @@ +# Nightscout in Northflank + +
+ +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +```{card} +## Northflank +![](/vendors/img/Northflank.png) +^^^ +You can create your new Northflank Nightscout site with a [MongoDB Atlas](/vendors/mongodb/atlas) database or with its own [Northflank database](/vendors/northflank/database). + +**Pros**: +* Nightscout fits in the free tier +* Easy to deploy or migrate an existing site from Heroku +* Simple to use and troubleshoot +* Can use a native Northflank MongoDB database +* You can deploy up to $20/mo worth of free resources on Northflank’s managed cloud + +**Cons**: +* The Nightscout address generated for your site is virtually impossible to remember +``` + +
+ +## Set up a new Nightscout + +### Create your Northflank and GitHub accounts from a computer. + +```{note} +Do not change device/computer/browser during the setup process! +If you have unexpected issues when creating your site, restart with another browser. +``` + +
+ +### Step 0: Create a database + +```{note} +Make sure you [created one](/nightscout/database) before starting your Nightscout web app creation with Northflank. +Come back here when you have a MONGODB_URI connection string. +``` + + + +```{admonition} Migrating? +:class: tip +Copy the connection string from your previous platform: [edit the variables](/nightscout/setup_variables.md#nightscout-configuration) and look for `MONGODB_URI`. +If you don't see `MONGODB_URI` but see `MONGO_CONNECTION` (**NOT** `MONGO_COLLECTION`): use its value. +``` + +
+ +### Step 1: Create a GitHub account and fork the Nightscout project + +```{tab-set} + +:::{tab-item} This is not necessary anymore (with a Docker image) +Continue with Step 2. +::: + +:::{tab-item} I don't have a GitHub Account +### Create a GitHub account +::: {include} /vendors/github/create.md +::: + +:::{tab-item} I already have a GitHub Account +### Update your Nightscout fork +:::{include} /vendors/github/update_b.md +::: + +``` + +
+ +### Step 2: Create a Northflank account + +***If you already created your database in Northflank, skip to step 3.*** + +a) Sign-up to [Northflank](https://app.northflank.com/signup) in a new browser tab. Login with GitHub (click on the logo). + + + +
+ +b) Confirm your GitHub account if required. + + + +
+ +c) Select `Only select repositories`, in the drop-down list select `cgm-remote-monitor` then click `Install & Authorize`. + + + +
+ +c) Enter a user name, your email address and invent a password (type it twice to confirm). Accept the TOS and Privacy Policy then click `Continue `. + + + +
+ +d) Click `Choose theme`. + + + +
+ +e) Select `Skip for now`. + + + +
+ +f) Select `Create free project`. + + + +
+ +g) Enter a project name (for example nightscout) and select a region (you can make it geographically close to where you live) then click `Create project`. + + + +
+ +### Step 3: Deploy Nightscout in Northflank + +**What are you trying to do now?** + +```{tab-set} + +:::{tab-item} I want to create a brand new Nightscout from a Docker image (recommended) +:::{include} new_user_d.md +::: + + +:::{tab-item} I want to create a brand new Nightscout (old method) +:::{include} new_user_a.md +::: + +:::{tab-item} I want to migrate from Heroku +:::{include} migrate_a.md +::: + +``` + +To open your Nightscout site, navigate to your project `Services` and click the address link top right. + + + +
+ +**Good time to check you selected the right plan.** + +Make sure you selected the developer sandbox plan to avoid unexpected fees. + + + +
+ +```{include} /nightscout/first_setup.md + +``` + +
+ +
+ +## Change your Northflank Nightscout site name + +You [cannot](https://northflank.com/docs/v1/application/network/configure-ports#public-ports) override the default name if you don't have a DNS. +You can use [TinyURL](https://tinyurl.com/) to get a shorter name. + + + +You can also use a free [dynamic DNS](/nightscout/dns) service to do this in order to have something easier to remember. + +Keep the original Northflank URL in your [uploaders](/uploader/setup/) and [followers](/nightscout/downloaders/). + +
+ +------ + +You have completed a new Nightscout site creation. The following section provides more information for variables edition that you might not need to use now. + +------ + +
+ +## Editing Variables in Northflank + +
+ +a) Open [Northflank](https://app.northflank.com/login) and login with your username or with GitHub. + + + +
+ +b) Select `Services ` then your Nightscout project. + + + +
+ +c) Select `Environment` then `Edit`. + + + +
+ +e) You can perform various operations on your variables: + +1. Add a new variable with `+ Add Variable` +2. Edit variables values directly in the table +3. Delete a variable with the bin icon + +~~~{note} +Multiple lines values should be typed with `\n` separating each original line.
+Example:
+
+``` +----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGBygGSM49AwEHBHkwdwIBAQQg7c8w00t5ju7N980r\nerN8N+isnJoec+ohIEuD0teRbPmgCgYIKoZIzj0DAQehRANCAAREnRISLSiFgdn4\nLbf44yIKspXKr7GpPBVshv3ShOms2qHTdAFriXXRPmbq7eAJuFrxpYOduU1dl9vo\nouciW0je\n-----END PRIVATE KEY----- +``` +~~~ + +Don't forget to `Update & restart` when you're done editing. + +
+ +## Copy all variables from Heroku + +
+ +a) Export all your Heroku variables as explained [here](/troubleshoot/heroku.md/#method-2-export). In a file you can call `heroku.env`. + +If you're currently deploying a new Northflank Nightscout site, select `Env`. + + + +Continue to **c)** below. + +
+ +b) If you want to modify an existing Northflank site, + +Open [Northflank](https://app.northflank.com/login) and login with your username or with GitHub. + + + +
+ +Select `Services ` then your Nightscout project. + + + +
+ +Select `Environment` then `Env`. + + + +
+ +c) Select `Import from file` then the file (`heroku.env`) you saved in **a)**. + + + +Your variables should display like this: + + + +
+ +d) If you're creating a new site, return to the step you were following before importing all variables from Heroku. + +
+ +e) If you were importing all variables from a running Northflank Nightscout site, select `Update & restart`. + + \ No newline at end of file diff --git a/_sources/vendors/northflank/new_user_a.md.txt b/_sources/vendors/northflank/new_user_a.md.txt new file mode 100644 index 00000000..021a061a --- /dev/null +++ b/_sources/vendors/northflank/new_user_a.md.txt @@ -0,0 +1,189 @@ +--- +orphan: true +--- + +If you already created a Nightscout project (for example if you created your database in Northflank), select it now. + +
+ +
+ +a) Select `Add new service` or `New service`. + +
+ +
+ +b) Select `Build and deploy a Git repo`. Scroll down and put a name in `Service name` or click `Suggest random name`. + +
+ +
+ +c) Select your `cgm-remote-monitor` and the `master` branch. + +
+ +
+ +d) In `Buid options` select `Buildpack`. + +
+ +
+ +Open `Advanced build settings` and select `heroku/builder-classic:22`. + +
+ +
+ +e) Expand `Variables` and click `Add variable`. + +```{tip} +If you want to copy all variables from Heroku, follow [these instructions](#copy-all-variables-from-heroku) and then continue to **m)** below. +``` + +
+ +
+ +f) Setup your Nightscout core variables. + +`API_SECRET` will be your Nightscout site password, it needs to be at least 12 characters long and you should **NOT use spaces** if you use @ or ! symbols remember you will probably need to express them using [Percent encoding](https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_reserved_characters) in your uploader and downloader apps. If you're not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits. + + + +```{warning} +The API_SECRET is the **main password allowing full access to your Nightscout site**. Make sure it's reasonably secure (mix uppercase and lowercase letters, plus digits) and **do no not share it publicly**. If you think you exposed it by mistake, it is recommended that you **change it**. +``` + +
+ +Click `Add variable` each time to add another one. + +
+ +#### Dexcom Bridge + +g) If you use [Dexcom `bridge`](/troubleshoot/dexcom_bridge/) you need to configure these two variables with your Dexcom credentials: + +
+ +
+ +If you're using Dexcom Share in the US you should put **US**, in **any other case it must be EU**. +If you don't see it proposed at this point you'll need to **browse the list below to find it and modify it**. + +
+ +**Remember to add `bridge` at the end of the `enable` variable in the list below.** + +
+ +```{admonition} MOST COMMON ERRORS +:class: hint +The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom's Clarity page (check [here for USA accounts](https://clarity.dexcom.com) and [here for the others](https://clarity.dexcom.eu)) and try logging in to your Dexcom account. If your account info isn't valid, or you don't see any data in your Clarity account... you need to figure out your actual credentials before moving ahead. See [here](/troubleshoot/dexcom_bridge/) for troubleshooting tips and information on your Dexcom account. +``` + +```{admonition} Password +:class: note +*Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.* +``` + +```{hint} +You need to have at least one follower to use Dexcom Share. See [here](/uploader/setup.md#dexcom). +``` + +
+ +h) Select the units you’re using in `DISPLAY_UNITS` acceptable choices are `mg/dl` or `mmol/L` (or just `mmol`). + +
+ +
+ +i) You can add alarms values. See [here](/nightscout/setup_variables.md#alarms) for the meaning of each one. + +
+ +
+ +j) If you want to ensure that ONLY someone with permission to view your site (e.g., a token or the `API_SECRET`) is able to view the data, you should configure the [`AUTH_DEFAULT_ROLES`](auth_default_roles) variable in as `denied`. +If you want your site to be visible to anybody leave it as `readable`. + +
+ +
+ +k) In [`ENABLE`](enable), copy and paste the following words (separated by a space) so that won't have to think about which you want now: + +`careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors` + +**If you are using your Dexcom share account as a data source** also add `bridge` at the end, after a space like this: + +`careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge` + +
+ +
+ +l) You can modify the variables values, check the [documentation](/nightscout/setup_variables) for the meaning of each one. + +
+ +m) You can modify the 3 to 8 letter code to your URL. + +
+ +
+ +n) Scroll down and check you're using an `nf-compute-10` plan, then click: `Create Service` + +
+ +
+ +
+ +o) If not done before, you now need to add a payment method. + +
+ +
+ +p) Wait until your build completes. You will see a green cloud when done, it will take less than 15 minutes. + +
+ +
+ +
+ +### Step 4: Attach your database to your Nightscout site + +
+ +a) Browse back into your project `Service ` then `Environment`, click `Edit`. + +
+ +
+ +b) Select `Add variable ` at the end of the list. + +
+ +
+ +c) Name it `MONGODB_URI` and paste the string you obtained at **Step 0**. + +
+ +
+ +d) Click `Update and restart` bottom right. + +
+ +
\ No newline at end of file diff --git a/_sources/vendors/northflank/new_user_d.md.txt b/_sources/vendors/northflank/new_user_d.md.txt new file mode 100644 index 00000000..99bf4585 --- /dev/null +++ b/_sources/vendors/northflank/new_user_d.md.txt @@ -0,0 +1,177 @@ +--- +orphan: true +--- + +If you already created a Nightscout project (for example if you created your database in Northflank), select it now. + +
+ +
+ +a) Select `Add new service` or `New service`. + +
+ +
+ +b) Select `Deploy a Docker image`. Scroll down and put a name in `Service name` or click `Suggest random name`. + +
+ +
+ +c) In `Deployment`, select `External image` and type `nightscout/cgm-remote-monitor:latest` in `Image path`. + +
+ +
+ +d) Expand `Variables` and click `Add variable`. + +
+ +
+ +e) Setup your Nightscout core variables. + +```{tip} +If you want to copy all variables from Heroku, follow [these instructions](#copy-all-variables-from-heroku) and then continue to **l)** below. +``` + +`API_SECRET` will be your Nightscout site password, it needs to be at least 12 characters long and you should **NOT use spaces** if you use @ or ! symbols remember you will probably need to express them using [Percent encoding](https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_reserved_characters) in your uploader and downloader apps. If you're not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits. + + + +```{warning} +The API_SECRET is the **main password allowing full access to your Nightscout site**. Make sure it's reasonably secure (mix uppercase and lowercase letters, plus digits) and **do no not share it publicly**. If you think you exposed it by mistake, it is recommended that you **change it**. +``` + +
+ +Click `Add variable` each time to add another one. + +
+ +#### Dexcom Bridge + +f) If you use [Dexcom `bridge`](/troubleshoot/dexcom_bridge/) you need to configure these two variables with your Dexcom credentials: + +
+ +
+ +If you're using Dexcom Share in the US you should put **US**, in **any other case it must be EU**. +If you don't see it proposed at this point you'll need to **browse the list below to find it and modify it**. + +
+ +**Remember to add `bridge` at the end of the `enable` variable in the list below.** + +
+ +```{admonition} MOST COMMON ERRORS +:class: hint +The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom's Clarity page (check [here for USA accounts](https://clarity.dexcom.com) and [here for the others](https://clarity.dexcom.eu)) and try logging in to your Dexcom account. If your account info isn't valid, or you don't see any data in your Clarity account... you need to figure out your actual credentials before moving ahead. See [here](/troubleshoot/dexcom_bridge/) for troubleshooting tips and information on your Dexcom account. +``` + +```{admonition} Password +:class: note +*Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.* +``` + +```{hint} +You need to have at least one follower to use Dexcom Share. See [here](/uploader/setup.md#dexcom). +``` + +
+ +g) Select the units you’re using in `DISPLAY_UNITS` acceptable choices are `mg/dl` or `mmol/L` (or just `mmol`). + +
+ +
+ +h) You can add alarms values. See [here](/nightscout/setup_variables.md#alarms) for the meaning of each one. + +
+ +
+ +i) If you want to ensure that ONLY someone with permission to view your site (e.g., a token or the `API_SECRET`) is able to view the data, you should configure the [`AUTH_DEFAULT_ROLES`](auth_default_roles) variable in as `denied`. +If you want your site to be visible to anybody leave it as `readable`. + +
+ +
+ +j) In [`ENABLE`](enable), copy and paste the following words (separated by a space) so that won't have to think about which you want now: + +`careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors` + +**If you are using your Dexcom share account as a data source** also add `bridge` at the end, after a space like this: + +`careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge` + +
+ +
+ +k) You can modify the variables values, check the [documentation](/nightscout/setup_variables) for the meaning of each one. + +
+ +l) You can modify the 3 to 8 letter code to your URL. + +
+ +
+ +m) Scroll down and check you're using an `nf-compute-10` plan, then click: `Create Service` + +
+ +
+ +
+ +n) If not done before, you now need to add a payment method. + +
+ +
+ +o) Wait until your build completes. You will see a green cloud when done, it will take less than 15 minutes. + +
+ +
+ +
+ +### Step 4: Attach your database to your Nightscout site + +
+ +a) Browse back into your project `Service ` then `Environment`, click `Edit`. + +
+ +
+ +b) Select `Add variable ` at the end of the list. + +
+ +
+ +c) Name it `MONGODB_URI` and paste the string you obtained at **Step 0**. + +
+ +
+ +d) Click `Update and restart` bottom right. + +
+ +
\ No newline at end of file diff --git a/_sources/vendors/oracle/new_user.md.txt b/_sources/vendors/oracle/new_user.md.txt new file mode 100644 index 00000000..5fb981da --- /dev/null +++ b/_sources/vendors/oracle/new_user.md.txt @@ -0,0 +1,7 @@ +--- +orphan: true +--- + + + + \ No newline at end of file diff --git a/_sources/vendors/railway/NightscoutVariablesRailway.md.txt b/_sources/vendors/railway/NightscoutVariablesRailway.md.txt new file mode 100644 index 00000000..6809fcd4 --- /dev/null +++ b/_sources/vendors/railway/NightscoutVariablesRailway.md.txt @@ -0,0 +1,10 @@ +--- +orphan: true +--- + + + + + + + diff --git a/_sources/vendors/railway/database.md.txt b/_sources/vendors/railway/database.md.txt new file mode 100644 index 00000000..19c46026 --- /dev/null +++ b/_sources/vendors/railway/database.md.txt @@ -0,0 +1,154 @@ +# Railway Database + +
+ +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +```{danger} +The free plan has been removed Jul 3rd for new users and Aug 1st for existing users.
+Documentation will be updated to reflect the changes when visible. +``` + +
+ +```{card} +## Railway Mongo Database +![Railway](/vendors/img/Railway.png) ![MongoDB](/vendors/img/MongoDB.png) +^^^ +Railway offers a Mongo database. + +**Pros**: +* Simple to create +* Less overhead than Atlas (more space) +* Mongo database cost is $0.000231/GB/Minute + +**Cons**: +* You need to carefully monitor your database size and clean it up regularly to remain within the Hobby plan 5$/month limits +* Simple Mongo 4.4 database +``` + +
+ +## Create a Railway account + +If you already have a Railway account, make sure you have a developper plan: go to **step g)**. + +
+ +a) Open [Railway](https://railway.app) in a new browser tab and click `login`. Type your email and select `Email`. + + + + + +
+ +b) Leave the browser open on this screen + + + +
+ +c) Check your email (look also in the spam folder) and click on the `Authorize Railway App`. + + + +
+ +d) Type the code you had in **b)**. + + + +
+ +e) Close this tab and return to the one you left open in **b)**. + + + +
+ +f) Click on `Please agree to the new terms to keep on using Railway`. + + + +
+ +d) Scroll down and click `I agree with Railway's Terms of Service`. + + + +
+ +e) Scroll down and click `I will not deploy any of that`. + + + +
+ +f) You should now see this. You've created your Railway account. + + + +
+ +g) Upgrade your account to a Developer plan. Click on the `Unverified` and select `Remove Resource Limits`. + + + +
+ +```{danger} +The free plan will be removed Jul 3rd for new users and Aug 1st for existing users.
+Documentation will be updated to reflect the changes when visible. +``` + +Enter your credit card information and select `Subscribe to a Hobby Plan`. + + + +Your card will be billed 1$ that will be refund immediately. Bank fees won't be refund. + +
+ +## Create your database + +a) Click `New Project` from your Dashboard screen (top right). + + + +
+ +b) Click `Provision MongoDB` + + + +
+ +c) Select your new MongoDB project. + + + +
+ +d) Go to the `Connect` page. + + + +
+ +e) Scroll down to `Available Variables`, move the mouse to the end of the line showing the `MONGO_URL` and click the copy icon. + + + +
+ +```{admonition} This is an important information +:class: warning +Now that you have **copied** the resulting `MONGODB_URI` string, keep it in a **safe place**, you will need it later. +``` + diff --git a/_sources/vendors/railway/migrate.md.txt b/_sources/vendors/railway/migrate.md.txt new file mode 100644 index 00000000..15bf90a0 --- /dev/null +++ b/_sources/vendors/railway/migrate.md.txt @@ -0,0 +1,96 @@ +--- +orphan: true +--- + +- Log in Heroku [https://id.heroku.com/login](https://id.heroku.com/login) + +
+ +- Leave the Heroku page opened and return to the Railway page. +- If you cannot log into Heroku, select another deployment option (just above) and reuse your existing Atlas database connection string. + +
+ +a) Click on `Create a New project`. + +
+ +If you don't see that, top right, click `+ New Project`. + +
+ +
+ +b) Select `Deploy from GitHub repo`. + +
+ +
+ +Select `Configure GitHub App`. + +
+ +
+ +c) Choose `Only select repositories`, in the `Select repositories` drop-down select your own fork of `cgm-remote-monitor`. +Then, at the bottom, click `Install & Authorize`. + +
+ +
+ +You should be back to `Deploy from GitHub repo`, select it. + +
+ +
+ +d) Now you can select your own GitHub repository. + +
+ +
+ +e) Select `Add variables`. + +
+ +
+ +f) The Nightscout project will deploy in the background, just ignore it: now we need to import all variables from Heroku. +When you see this, press simultaneously the keys `Ctrl` and `K`. +**If you use a Mac `⌘` and `K`.** + +
+ +
+ +g) Select `Import variables from Heroku`. + +
+ +
+ +h) Click `Connect Heroku account`. + +
+ +
+ +Click `Allow`. + +
+ +
+ +i) Redo `Ctrl K` (or `⌘ K` and select `Import variables from Heroku`. Now you can select your Nightscout app. + +
+ +
+ +j) Wait until import completes. +Your site will redeploy, wait until redeploy completes. + +
diff --git a/_sources/vendors/railway/migration.md.txt b/_sources/vendors/railway/migration.md.txt new file mode 100644 index 00000000..1f240b84 --- /dev/null +++ b/_sources/vendors/railway/migration.md.txt @@ -0,0 +1,14 @@ +--- +orphan: true +--- + +
+ +```{danger} +The free plan has been removed Jul 3rd for new users and Aug 1st for existing users.
+Documentation will be updated to reflect the changes when visible. +``` + +
+ +Now included in the main [Nightscout with Railway](/vendors/railway/new_user) page! \ No newline at end of file diff --git a/_sources/vendors/railway/new_user.md.txt b/_sources/vendors/railway/new_user.md.txt new file mode 100644 index 00000000..16c42195 --- /dev/null +++ b/_sources/vendors/railway/new_user.md.txt @@ -0,0 +1,334 @@ +# Nightscout in Railway + +
+ +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +```{warning} +The free plan has been removed Jul 3rd for new users and Aug 1st for existing users. +``` + +
+ +```{card} +## Railway.app +![Railway](/vendors/img/Railway.png) +^^^ +You can easily create a new Railway Nightscout site with a [MongoDB Atlas](/vendors/mongodb/atlas) database or a [Railway MongoDB database](/vendors/railway/database). + +**Pros**: +* Nightscout fits in the 5$/month Hobby account +* Easy to deploy or migrate an existing site from Heroku +* Simple to use and troubleshoot +* You can host several Nightscout sites within a single Hobby account +* Can use a native Railway MongoDB database ($) + +**Cons**: +* The railway.app domain is blocked for safety by some companies +* Railway network model causes issues with some follower app and devices +``` + +
+ +## Set up a new Nightscout + +### Create your Railway and GitHub accounts from a computer. + +```{note} +Do not change device/computer/browser during the setup process! +If you have unexpected issues when creating your site, restart with another browser. +``` + +
+ +### Step 0: Create a database + +```{note} +Make sure you [created one](/nightscout/database) before starting your Nightscout web app creation with Railway. +Come back here when you have a MONGODB_URI connection string. +``` + + + +```{admonition} Migrating? +:class: tip +Copy the connection string from your previous platform: [edit the variables](/nightscout/setup_variables.md#nightscout-configuration) and look for `MONGODB_URI`. +If you don't see `MONGODB_URI` but see `MONGO_CONNECTION` (**NOT** `MONGO_COLLECTION`): use its value. +``` + +
+ +### Step 1: Fork `cgm-remote-monitor` + +**Do you have a GitHub account?** + +```{tab-set} + +:::{tab-item} This is not necessary anymore (with a Docker image) +Continue with Step 2. +::: + +:::{tab-item} I don't have a GitHub Account +::{admonition} Railway.app new security requirement +:class: warning +You cannot connect Railway to GitHub if you just created your account.
+Your GitHub account needs to have been created months ago.

+

+**Consider another platform.**
+::: + +:::{tab-item} I already have a GitHub Account +### Update your Nightscout fork +:::{include} /vendors/github/update_b.md +::: + +``` + +
+ +### Step 2: Create a Railway account + +If you already have a Railway account, make sure you have a Hobby plan: go to **step g)**. + +
+ +a) Open [Railway](https://railway.app) in a new browser tab and click `login`. Login with GitHub. + + + + + +
+ +b) If the following screen shows-up, select `Authorize Railway App`. + + + +
+ +c) Click on `Please agree to the new terms to keep on using Railway`. + + + +
+ +d) Scroll down and click `I agree with Railway's Terms of Service`. + + + +
+ +e) Scroll down and click `I will not deploy any of that`. + + + +
+ +```{warning} +The free plan has been removed Jul 3rd for new users and Aug 1st for existing users. +``` + +
+ +f) You should now see this. You've created your Railway account. +If it still shows 200 hours, refresh your browser page. + + + +
+ +g) Upgrade your account to a Hobby plan. Click on the `Starter Plan` information and select `Remove Resource Limits`. + + + +
+ +Enter your credit card information and select `Subscribe to a Hobby Plan`. + + + +Your card will be billed 1$ that will be refund immediately. Bank fees won't be refund. + +You will be billed 5$ per month. + +
+ +### Step 3 - Deploy Nightscout in Railway + +Select below how you want to do this: + +```{tab-set} + +:::{tab-item} Deploy with Docker (recommended) +:::{include} new_user_d.md +::: + +:::{tab-item} Using the Railway button +:::{include} new_user_b.md +::: + +:::{tab-item} Using the help page +:::{include} new_user_a.md +::: + +:::{tab-item} Migrate from Heroku +:::{include} migrate.md +::: + +``` + +
+ +Congratulations. You created your new Nightscout site with Railway. + +Click the site name to open Nightscout. + + + +
+ +```{include} /nightscout/first_setup.md + +``` + +
+ +
+ +## Change your Nightscout site name + +Railways automatically makes a name when creating your new site. It is rather difficult to remember. + +You can change the site name but need to keep the `.up.railway.app` domain. + +1. Select your Nightscout app + +2. Go in `Settings` + +3. In `Domains` (or `Networking` with Docker) go to the end of line and click the edit icon + +4. Write your new name and check it's available + + Click `Update` + + Your Nightscout URL will now be `https://`*yoursitename*`.up.railway.app` + + + +
+ +Change all your [uploaders](/uploader/setup/) and [follower](/nightscout/downloaders/) devices to reflect the new URL once verified correct functioning of your Nightscout site. + +
+ +------ + +You have completed a new Nightscout site creation. The following section provides more information for database migration and variables edition that you might not need to use now. + +------ + +
+ +## Editing Variables in Railway + +
+ +### Method 1 - Web interface + +This is recommended when you only need to edit or add few variables. + +a) Open [Railway](https://railway.app) and click `login`. Login with GitHub. + + + + + +
+ +b) Select your Nightscout project. + + + +
+ +c) Select your web app. + + + +
+ +d) Click on `Variables`. + + + +
+ +e) You can perform various operations on your variables: + +1. Add a new variable with `+ New Variable` +2. View the variable value with `Show Value` +3. Edit or delete the variable or its value with the line end menu + + + +
+ +Note that each variable modification will redeploy your project. + +
+ +### Method 2 - Raw Editor + +This is recommended when you must perform lots of changes to avoid multiple project redeploys. + +a) Open [Railway](https://railway.app) and click `login`. Login with GitHub. + + + + + +
+ +b) Select your Nightscout project. + + + +
+ +c) Select your web app. + + + +
+ +d) Click on `Variables`. + + + +
+ +e) Click on `RAW Editor` top right + + + +
+ +f) You can access all your variables in a text editor, each line contains the variable name, the sign `=` then its corresponding value. + +`VARIABLE=value` + +Perform all your changes taking care of uppercase and lowercase information and click `Update Variables` when finished. + + + +
+ +Once saved your project will redeploy. +If deploy fails, check your modifications... + +
diff --git a/_sources/vendors/railway/new_user2.md.txt b/_sources/vendors/railway/new_user2.md.txt new file mode 100644 index 00000000..3c725b98 --- /dev/null +++ b/_sources/vendors/railway/new_user2.md.txt @@ -0,0 +1,9 @@ +--- +orphan: true +--- +# **Update your link.** + +Merged with the main page [here](new_user.md). + +
+ diff --git a/_sources/vendors/railway/new_user_a.md.txt b/_sources/vendors/railway/new_user_a.md.txt new file mode 100644 index 00000000..18906658 --- /dev/null +++ b/_sources/vendors/railway/new_user_a.md.txt @@ -0,0 +1,412 @@ +--- +orphan: true +--- + +a) Click on `Create a New project`. + +
+ +If you don't see that, top right, click `+ New Project`. + +
+ +
+ +b) Select `Deploy from GitHub repo`. + +
+ +
+ +c) Select `Configure GitHub App`. + +
+ +
+ +d) Choose `Only select repositories`, in the `Select repositories` drop-down select your own fork of `cgm-remote-monitor`. +Then, at the bottom, click `Install & Authorize`. + +
+ +
+ +e) You should be back to `Deploy from GitHub repo`, select it. + +
+ +
+ +f) Now you can select your own GitHub repository. + +
+ +
+ +g) Select `Add variables`. + +
+ +
+ +h) The Nightscout project will deploy in the background, just ignore it: now we need to setup our Nightscout variables. +Click on `Raw Editor`. + +
+ +The raw editor will open, leave it like this for now. + +
+ +
+ +i) Compile the information below. + +File all necessary fields, click on the Validate button at the bottom of the form, if no error is seen you will have all variables displayed in the text box at the bottom, click on the Copy All button. + +
+ +#### Mandatory variables + +These three variables below must have a value. + +**MONGODB_URI** + +The MongoDB Connection String to connect to your MongoDB cluster. If you don't have this from your Mongo database, please re-read installation instructions at [Nightscout database](https://nightscout.github.io/nightscout/database) before continuing + +
+ +**API_SECRET** + +
+ +A passphrase that must be at least 12 characters long. Avoid special characters, which can cause problems in some cases + +**DISPLAY_UNITS** + +
+
Preferred BG units for the site: `mg/dl` or `mmol/l` (or just `mmol`) + +
+ +#### Customizations + +Leave default values if you don't want to change them + +**CUSTOM_TITLE** + +
+ +The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer + +**THEME** + +
+
Default setting for new browser views for the color theme of the CGM graph. (`default` `colors` or `colorblindfriendly`) + +**ENABLE** + +
+ +Plugins to enable for your site. Must be a space-delimited lower-case list. Include the word `bridge` here if you are receiving data from the Dexcom Share service + +**SHOW_PLUGINS** + +
+ +Default setting for whether or not these plugins are checked (active) by default not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case + +**TIME_FORMAT** + +
+
Default setting for new browser views for the time mode. (`12` or `24`) + +**NIGHT_MODE** + +
+
Default setting for new browser views for whether Night Mode should be enabled. (`on` or `off`) + +**BOLUS_RENDER_OVER** + +
+ +U value over which the bolus values are rendered on the chart if the `x U and Over` option is selected + +
+ +#### Dexcom Share + +If you want Nightscout to import directly from Dexcom Share + +**BRIDGE_USER_NAME** + +
+ +Your Dexcom account username to receive CGM data from the Dexcom Share service. Also make sure to include `bridge` in your ENABLE line. + +**BRIDGE_PASSWORD** + +
+ +Your Dexcom account password to receive CGM data from the Dexcom Share service. Also make sure to include `bridge` in your ENABLE line + +**BRIDGE_SERVER** + +
+
If you are bridging from the Dexcom Share service and are anywhere *outside* the US change this to EU. (`US` or `EU`) + +
+ +#### Alarms + +You can customize alarms or leave them to default values + +**ALARM_TYPES** + +
+
`simple` and/or `predict`v. Simple alarms trigger when BG crosses the various thresholds set below. Predict alarms use a formula that forecasts where the BG is going based on its trend. You will *not* get warnings when crossing the BG thresholds set below when using the predict type + +**ALARM_URGENT_HIGH** + +
+ +Urgent High BG threshold triggers the `ALARM_URGENT_HIGH` alarm. Set in mg/dL or mmol/L as set in `DISPLAY_UNITS` variable + +**ALARM_URGENT_LOW** + +
+ +Urgent Low BG threshold triggers the `ALARM_URGENT_LOW` alarm. Set in mg/dL or mmol/L as set in `DISPLAY_UNITS` variable + +**ALARM_HIGH** + +
+ +High BG threshold triggers the `ALARM_HIGH` alarm. Set in mg/dL or mmol/L as set in `DISPLAY_UNITS` variable + +**ALARM_LOW** + +
+ +Low BG threshold triggers the `ALARM_LOW` alarm. Set in mg/dL or mmol/L as set in `DISPLAY_UNITS` variable + +**ALARM_TIMEAGO_URGENT** + +
+ +Default setting for new browser views for the number of minutes since the last CGM reading to trigger an `ALARM_TIMEAGO_URGENT` alarm + +**ALARM_TIMEAGO_WARN** + +
+ +Default setting for new browser views for the number of minutes since the last CGM reading to trigger an `ALARM_TIMEAGO_WARN` alarm + + + +Now click on the Validate button below + + + +If errors show up below, please correct them and click Validate again. + +

Click the button above.

+

+

+ +

+ +

+ +
+ +
+ +j) Return to the Railway Raw editor. Paste the result. Click `Update Variables`. + +
+ +Your site will redeploy, wait until redeploy completes. + +
+ +```{admonition} Recommended +:class: hint +You should [change your Railway site name](#change-your-nightscout-site-name) now in order to make it easier to remember. +You can also do this later, **before setting your uploaders**. +``` + +
\ No newline at end of file diff --git a/_sources/vendors/railway/new_user_b.md.txt b/_sources/vendors/railway/new_user_b.md.txt new file mode 100644 index 00000000..c57a87b6 --- /dev/null +++ b/_sources/vendors/railway/new_user_b.md.txt @@ -0,0 +1,182 @@ +--- +orphan: true +--- + +#
+ +a) Click on the `Deploy on Railway` button below: + +[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template/6v8Ejj) + +***Note:*** *this is a private template as the community doesn't have a Railway account. +It doesn't include any referral code.* + +
+ +b) If you see this screen, select `Connect GitHub to Deploy`. + +
+ +Then select `Authorize Railway App`. + +
+ +
+ +c) Click `Configure` + +
+ +
+ +d) Click `Install & Authorize` + +
+ +
+ +e) You will then see this page, scroll down to define the [required variables](/nightscout/setup_variables.md#required-variables) for creating your Nightscout site. + +
+ +
+ +Mind if you see this you must [delete the`cgm-remote-monitor` fork in GitHub](/update/redeploy.md#delete-your-own-fork-of-cgm-remote-monitor) and retry `Deploy` from **a)** afterwards. + +
+ +
+ +f) Setup your Nightscout core variables. + +```{admonition} Migrating from Heroku +If you're migrating your project from Heroku, [display all variables in Heroku](/vendors/heroku/new_user.md#editing-config-vars-in-heroku) and copy all those with a value into Railway. +See below how to add variables in Railway but use your Heroku variables values. +``` + +`API_SECRET` will be your Nightscout site password, it needs to be at least 12 characters long and you should **NOT use spaces** if you use @ or ! symbols remember you will probably need to express them using [Percent encoding](https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_reserved_characters) in your uploader and downloader apps. If you're not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits. + +```{warning} +The API_SECRET is the **main password allowing full access to your Nightscout site**. Make sure it's reasonably secure (mix uppercase and lowercase letters, plus digits) and **do no not share it publicly**. If you think you exposed it by mistake, it is recommended that you **change it**. +``` + +
+ +g) At **Step 3** you created your database and came back with a MONGODB_URI string. Time has come to use it here. + +
+ +
+ +**Dexcom Bridge** + +h) If you use [Dexcom `bridge`](/troubleshoot/dexcom_bridge/) you need to configure these two variables with your Dexcom credentials: + +
+ +
+ +If you're using Dexcom Share in the US you should put **US**, in **any other case it must be EU**. +If you don't see it proposed at this point you'll need to **browse the list below to find it and modify it**. + +
+ +**Remember to add `bridge` at the end of the `enable` variable in the list below.** + +
+ +```{admonition} MOST COMMON ERRORS +:class: hint +The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom's Clarity page (check [here for USA accounts](https://clarity.dexcom.com) and [here for the others](https://clarity.dexcom.eu)) and try logging in to your Dexcom account. If your account info isn't valid, or you don't see any data in your Clarity account... you need to figure out your actual credentials before moving ahead. See [here](/troubleshoot/dexcom_bridge/) for troubleshooting tips and information on your Dexcom account. +``` + +```{admonition} Password +:class: note +*Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.* +``` + +```{hint} +You need to have at least one follower to use Dexcom Share. See [here](/uploader/setup.md#dexcom). +``` + +
+ +i) Many optional variables are already setup for you, open the caret to see them and eventually modify them (**recommended**). + +
+ +
+ +Select the units you’re using in `DISPLAY_UNITS` acceptable choices are `mg/dl` or `mmol/L` (or just `mmol`). + +
+ +
+ +You can update the alarms values. See [here](/nightscout/setup_variables.md#alarms) for the meaning of each one. + +
+ +
+ +If you want to ensure that ONLY someone with permission to view your site (e.g., a token or the `API_SECRET`) is able to view the data, you should configure the [`AUTH_DEFAULT_ROLES`](auth_default_roles) variable in as `denied`. +If you want your site to be visible to anybody leave it as `readable`. + +
+ +
+ +A common list of [`enable`](enable) variables is predefined, you can change them if you know why. +It's recommended that you leave them like this for now. + +Just remember to add `bridge` at the end if your get your BG values from Dexcom Share. + +
+ +
+ +You can modify the variables values, check the [documentation](/nightscout/setup_variables) for the meaning of each one. +Make sure you don't make typo errors, some will crash your site (like for example `LANGUAGE` value in upercase). + +
+ +j) You can now `Deploy`, and wait until it is complete. + +
+ +If you see this message, deploy didn't complete, let's fix this manually. + +
+ +j1) Select `Settings` and scroll down to `Service`. +Disconnect your `Source Repo` with the cross at the end of the line. + +
+ +j2) Confirm `Disconnect`. + +
+ +
+ +j3) Select `Connect Repo`. + +
+ +You should be able to select your GitHub `cgm-remote-monitor` repository. + +
+ +Your Railway app will now automatically deploy. + +
+ +
+ +```{admonition} Recommended +:class: hint +You should [change your Railway site name](#change-your-nightscout-site-name) now in order to make it easier to remember. +You can also do this later, **before setting your uploaders**. +``` + +
diff --git a/_sources/vendors/railway/new_user_d.md.txt b/_sources/vendors/railway/new_user_d.md.txt new file mode 100644 index 00000000..d92380c3 --- /dev/null +++ b/_sources/vendors/railway/new_user_d.md.txt @@ -0,0 +1,423 @@ +--- +orphan: true +--- + +a) Click on `Create a New project`. + +
+ +If you don't see that, top right, click `+ New Project`. + +
+ +
+ +b) Select `Empty project`. + +
+ +
+ +c) Select `Add a Service`. + +
+ +
+ +d) Select `Docker Image`. + +
+ +
+ +e) In the field `Name of the Image` type: + +`nightscout/cgm-remote-monitor:latest` + +and press \ + +
+ +
+ +f) Select your new service. + +
+ +
+ +g) Select `Add variables`. + +
+ +
+ +h) Now we need to setup our Nightscout variables. +Click on `Raw Editor`. + +
+ +The raw editor will open, leave it like this for now. + +
+ +
+ +i) Compile the information below. + +File all necessary fields, click on the Validate button at the bottom of the form, if no error is seen you will have all variables displayed in the text box at the bottom, click on the Copy All button. + +
+ +#### Mandatory variables + +These three variables below must have a value. + +**MONGODB_URI** + +The MongoDB Connection String to connect to your MongoDB cluster. If you don't have this from your Mongo database, please re-read installation instructions at [Nightscout database](https://nightscout.github.io/nightscout/database) before continuing + +
+ +**API_SECRET** + +
+ +A passphrase that must be at least 12 characters long. Avoid special characters, which can cause problems in some cases + +**DISPLAY_UNITS** + +
+
Preferred BG units for the site: `mg/dl` or `mmol/l` (or just `mmol`) + +
+ +#### Customizations + +Leave default values if you don't want to change them + +**CUSTOM_TITLE** + +
+ +The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer + +**THEME** + +
+
Default setting for new browser views for the color theme of the CGM graph. (`default` `colors` or `colorblindfriendly`) + +**ENABLE** + +
+ +Plugins to enable for your site. Must be a space-delimited lower-case list. Include the word `bridge` here if you are receiving data from the Dexcom Share service + +**SHOW_PLUGINS** + +
+ +Default setting for whether or not these plugins are checked (active) by default not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case + +**TIME_FORMAT** + +
+
Default setting for new browser views for the time mode. (`12` or `24`) + +**NIGHT_MODE** + +
+
Default setting for new browser views for whether Night Mode should be enabled. (`on` or `off`) + +**BOLUS_RENDER_OVER** + +
+ +U value over which the bolus values are rendered on the chart if the `x U and Over` option is selected + +
+ +#### Dexcom Share + +If you want Nightscout to import directly from Dexcom Share + +**BRIDGE_USER_NAME** + +
+ +Your Dexcom account username to receive CGM data from the Dexcom Share service. Also make sure to include `bridge` in your ENABLE line. + +**BRIDGE_PASSWORD** + +
+ +Your Dexcom account password to receive CGM data from the Dexcom Share service. Also make sure to include `bridge` in your ENABLE line + +**BRIDGE_SERVER** + +
+
If you are bridging from the Dexcom Share service and are anywhere *outside* the US change this to EU. (`US` or `EU`) + +
+ +#### Alarms + +You can customize alarms or leave them to default values + +**ALARM_TYPES** + +
+
`simple` and/or `predict`v. Simple alarms trigger when BG crosses the various thresholds set below. Predict alarms use a formula that forecasts where the BG is going based on its trend. You will *not* get warnings when crossing the BG thresholds set below when using the predict type + +**ALARM_URGENT_HIGH** + +
+ +Urgent High BG threshold triggers the `ALARM_URGENT_HIGH` alarm. Set in mg/dL or mmol/L as set in `DISPLAY_UNITS` variable + +**ALARM_URGENT_LOW** + +
+ +Urgent Low BG threshold triggers the `ALARM_URGENT_LOW` alarm. Set in mg/dL or mmol/L as set in `DISPLAY_UNITS` variable + +**ALARM_HIGH** + +
+ +High BG threshold triggers the `ALARM_HIGH` alarm. Set in mg/dL or mmol/L as set in `DISPLAY_UNITS` variable + +**ALARM_LOW** + +
+ +Low BG threshold triggers the `ALARM_LOW` alarm. Set in mg/dL or mmol/L as set in `DISPLAY_UNITS` variable + +**ALARM_TIMEAGO_URGENT** + +
+ +Default setting for new browser views for the number of minutes since the last CGM reading to trigger an `ALARM_TIMEAGO_URGENT` alarm + +**ALARM_TIMEAGO_WARN** + +
+ +Default setting for new browser views for the number of minutes since the last CGM reading to trigger an `ALARM_TIMEAGO_WARN` alarm + + + +Now click on the Validate button below + + + +If errors show up below, please correct them and click Validate again. + +

Click the button above.

+

+

+ +

+ +

+ +
+ +
+ +j) Return to the Railway Raw editor. Paste the result. Click `Update Variables`. + +
+ +
+ +k) On the top left of the screen `Deploy`. + +
+ +
+ +l) Select the `Settings` tab and click `Generate domain`. + +
+ +
+ +m) Edit your Nightscout site name and put yours (one that is not already used). + +
+ +
\ No newline at end of file diff --git a/_sources/vendors/raspberry-pi/new_user.md.txt b/_sources/vendors/raspberry-pi/new_user.md.txt new file mode 100644 index 00000000..7a6e3049 --- /dev/null +++ b/_sources/vendors/raspberry-pi/new_user.md.txt @@ -0,0 +1,8 @@ +--- +orphan: true +--- + + + + + diff --git a/_sources/vendors/render/new_user.md.txt b/_sources/vendors/render/new_user.md.txt new file mode 100644 index 00000000..63b098e0 --- /dev/null +++ b/_sources/vendors/render/new_user.md.txt @@ -0,0 +1,161 @@ +--- +orphan: true +--- + +# Nightscout in Render + +
+ +```{admonition} Too complicated? Not what you're looking for? +:class: seealso +Consider a hosted Nightscout service! Check for easier solutions [here](/index.md#nightscout-as-a-service). +``` + +
+ +```{card} +## Render +![Render Free](/vendors/img/Render.png) +^^^ +You can create your Nightscout site in Render. + +**Pros**: +* No credit card required + +**Cons**: +* The free plan doesn't guarantee any reliability +* App will sleep after 15 minutes +* Render URLs are considered unsafe by some internet providers +* Relying on the MongoDB Atlas database +``` + +
+ +------ + + +## Step 0: Create a database + +```{admonition} Render doesn't include a database +:class: note +Make sure you [created one](/nightscout/database) before starting your Nightscout web app creation with Render. +Come back here when you have a MONGODB_URI connection string. +``` + +```{admonition} Migrating? +:class: tip +Copy the connection string from your previous platform: [edit the variables](/nightscout/setup_variables.md#nightscout-configuration) and look for `MONGODB_URI`. +If you don't see `MONGODB_URI` but see `MONGO_CONNECTION` (**NOT** `MONGO_COLLECTION`): use its value. +``` + +
+ +## Step 1: Create a GitHub account and fork the Nightscout project + +```{tab-set} + +:::{tab-item} This is not necessary anymore (with a Docker image) +Continue with Step 2. +::: + +:::{tab-item} I don't have a GitHub Account +### Create a GitHub account +::: {include} /vendors/github/create.md +::: + +:::{tab-item} I already have a GitHub Account +### Update your Nightscout fork +:::{include} /vendors/github/update_b.md +::: + +``` + +
+ +## Step 2: Create a Render account + +a) Open a new browser page in [Render](https://render.com/) and select `GET STARTED FOR FREE` + +
+ +b) Sign up with GitHub + +
+ +c) `Authorize Render` + +
+ +d) `COMPLETE SIGN UP` with your GitHub account email + +
+ +e) Check your inbox and click the confirmation link + +
+ +
+ +## Step 3 - Deploy Nightscout in Render + +Select below how you want to do this: + +```{tab-set} + +:::{tab-item} Deploy with Docker (recommended) +:::{include} new_user_d.md +::: + +:::{tab-item} Using a blueprint +:::{include} new_user_a.md +::: + +``` + +
+ +* From the menu, `Dashboard`, then select your web service. + + + +
+ +* This is your new Nightscout site, click on the URL to open it + +
+ +
+ +```{include} /nightscout/first_setup.md + +``` + +
+ +## Editing Variables in Render + +
+ +* Sign in [Render](https://dashboard.render.com/) with GitHub + +
+ +* Select your web service + + + +* Go to `Environment`, your variables will display + + + +* You can modify variables by making the changes directly in the text boxes. + You can also add variables with `Add environment variable`. + When you're done, scroll down and `Save changes`. + + + +* Wait a few minutes for your site to redeploy. You can track the status in `Events`. + + + +
diff --git a/_sources/vendors/render/new_user_a.md.txt b/_sources/vendors/render/new_user_a.md.txt new file mode 100644 index 00000000..fab0a610 --- /dev/null +++ b/_sources/vendors/render/new_user_a.md.txt @@ -0,0 +1,132 @@ +--- +orphan: true +--- + +## Step 4: Add the `render.yaml` template + +- Sign in your GitHub account: [https://github.com/login](https://github.com/login). + +
+ +- Select your own `cgm-remote-monitor` project. + +
+ +1. Open the branches list +2. Type `render` +3. Select Create a branch: render from 'master' + +
+ +* Select Add File - Create new file + +
+ +* Type `render.yaml` for the name. Leave it open like that for now. + +
+ +* Open the `render.txt` template from [here](/_static/render.txt) and edit it with a notepad app, **select all**, copy and paste into the GitHub page you have open from above. + +
+ +* Scroll up the page in GitHub and select `Commit changes` top right. + +
+ +* Confirm with `Commit changes`. + +
+ +* Your cgm-remote-monitor project is ready for Render Blueprints deploy. + +
+ + + +## Step 5: First deploy in Render + +a) Select `Blueprints` + +
+ +b) Then `New blueprint instance` + +
+ +c) `Connect` your `cgm-remote-monitor` project + +
+ +d) Enter a name for your blueprint (anything simple, Nightscout is ok) + +
+ +e) Click the drop down menu of `Branch` (1) then select `render` (2) + +
+ +**You now need to setup core variables for your site:** + +
+ +f) In `MONGODB_URI` paste your database connection string from Step 0 above + +g) `API_SECRET` will be your Nightscout site password, it needs to be at least 12 characters long and you should **NOT use spaces** if you use @ or ! symbols remember you will probably need to express them using [Percent encoding](https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_reserved_characters) in your uploader and downloader apps. If you're not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits. + +```{warning} +The API_SECRET is the **main password allowing full access to your Nightscout site**. Make sure it's reasonably secure (mix uppercase and lowercase letters, plus digits) and **do no not share it publicly**. If you think you exposed it by mistake, it is recommended that you **change it**. +``` + +h) Define your `DISPLAY_UNITS` +Acceptable choices for the units used in Nightscout are `mg/dl` or `mmol/L` (or just `mmol`). + +
+ +i) Once all three variables have been set, `Apply` + +
+ +j) Your Nightscout site will be deployed. Wait until the operation completes after some minutes. + + + +
+ +Congratulations. You created your new Nightscout site with Render. + +The following step is important, don't skip it. + +
+ +## Step 6: Delete the `render` branch + +```{hint} +In order to deploy your site with a blueprint, you needed to modify your GitHub repository. +Now you want to remove this modification so that you'll be able to update it normally. +``` + +- Sign in your GitHub account: [https://github.com/login](https://github.com/login). + +
+ +- Select your own `cgm-remote-monitor` project. + +
+ +* Click on branches to display all. + +
+ +* Locate the `render` branch and click on the bin icon to delete it. + +
+ +You have successfully removed the temporary modification required to deploy a new Render site. + +
+ +* Your Render site will redeploy using the normal `master` branch of `cgm-remote-monitor`, wait a few minutes until the operation completes. + +
+ diff --git a/_sources/vendors/render/new_user_d.md.txt b/_sources/vendors/render/new_user_d.md.txt new file mode 100644 index 00000000..da6ecbd5 --- /dev/null +++ b/_sources/vendors/render/new_user_d.md.txt @@ -0,0 +1,75 @@ +--- +orphan: true +--- + +## Step 4: Create your Nightscout service + +- From the [dashboard](https://dashboard.render.com/), create a new Web Service. + +
+ +* Select `Deploy an existing image from a registry` then `Next`. + +
+ +* In the field `Image URL` type: + +``` +nightscout/cgm-remote-monitor:latest +``` + +Then `Next`. + +
+ +* In`Name` put the name of your Nightscout site (Render will add an extension if it's not unique). + +
+ +* Select the `Region` closer to where you live. + +
+ +* Select the `Free` instance type, knowing it will fall asleep (we'll fix that later on). + +
+ +* Clicking the button `+ Add Environment Variable` add the following two variables, and in the box on the right the matching value: + +``` +HOSTNAME 0.0.0.0 +PORT 1337 +``` + +
+ +**You now need to setup core variables for your site:** + +- Clicking the button `+ Add Environment Variable` add the following three variables: + +- `MONGODB_URI` paste your database connection string from Step 0 above + +- `API_SECRET` will be your Nightscout site password, it needs to be at least 12 characters long and you should **NOT use spaces** if you use @ or ! symbols remember you will probably need to express them using [Percent encoding](https://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_reserved_characters) in your uploader and downloader apps. If you're not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits. + +```{warning} +The API_SECRET is the **main password allowing full access to your Nightscout site**. Make sure it's reasonably secure (mix uppercase and lowercase letters, plus digits) and **do no not share it publicly**. If you think you exposed it by mistake, it is recommended that you **change it**. +``` + +- Define your `DISPLAY_UNITS` + +Acceptable choices for the units used in Nightscout are `mg/dl` or `mmol/L` (or just `mmol`). + +- Once all three variables have been set, `Create web Service` + +
+ +- Your Nightscout site will be deployed. Wait until the operation completes after some minutes. + + + + +
+ +Congratulations. You created your new Nightscout site with Render. + +
diff --git a/_sources/vendors/serendipity/index.md.txt b/_sources/vendors/serendipity/index.md.txt new file mode 100644 index 00000000..a084d829 --- /dev/null +++ b/_sources/vendors/serendipity/index.md.txt @@ -0,0 +1,8 @@ +--- +orphan: true +--- + + + + + diff --git a/_sources/vendors/synology/new_user.md.txt b/_sources/vendors/synology/new_user.md.txt new file mode 100644 index 00000000..acbd69e8 --- /dev/null +++ b/_sources/vendors/synology/new_user.md.txt @@ -0,0 +1,10 @@ +--- +orphan: true + +--- + + + + + + diff --git a/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000..eb19f698 --- /dev/null +++ b/_sphinx_design_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/_sphinx_design_static/design-tabs.js b/_sphinx_design_static/design-tabs.js new file mode 100644 index 00000000..36b38cf0 --- /dev/null +++ b/_sphinx_design_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/_static/NS-logo.png b/_static/NS-logo.png new file mode 100644 index 00000000..ee2139dd Binary files /dev/null and b/_static/NS-logo.png differ diff --git a/_static/NightscoutDataRecord.docx b/_static/NightscoutDataRecord.docx new file mode 100644 index 00000000..35a08484 Binary files /dev/null and b/_static/NightscoutDataRecord.docx differ diff --git a/_static/NightscoutDataRecord.pdf b/_static/NightscoutDataRecord.pdf new file mode 100644 index 00000000..19e8bae8 Binary files /dev/null and b/_static/NightscoutDataRecord.pdf differ diff --git a/_static/NightscoutDataRecord.xlsx b/_static/NightscoutDataRecord.xlsx new file mode 100644 index 00000000..dfe71ff2 Binary files /dev/null and b/_static/NightscoutDataRecord.xlsx differ diff --git a/_static/NightscoutVariablesRailway.html b/_static/NightscoutVariablesRailway.html new file mode 100644 index 00000000..e1218741 --- /dev/null +++ b/_static/NightscoutVariablesRailway.html @@ -0,0 +1,318 @@ + + + + +

Configure your Nightscout variables

+With this form you can easily decide which features to enable and customize your Nightscout. +

+

Mandatory variables

+

These three variables below must have a value.



+ + + + + + + + + + + + + + + + + + + + + + + +
MONGODB_URI
The MongoDB Connection String to connect to your MongoDB cluster. If you don't have this from your Mongo database, please re-read installation instructions at Nightscout database before continuing.

API_SECRET
A passphrase that must be at least 12 characters long. Avoid 'special' characters, which can cause problems in some cases.

DISPLAY_UNITS +
Preferred BG units for the site: 'mg/dl' or 'mmol/l' (or just 'mmol').

+

Customizations

+

Leave default values if you don't want to change them.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CUSTOM_TITLE
The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer.

THEME +
Default setting for new browser views for the color theme of the CGM graph. ('default' 'colors' or 'colorblindfriendly')

ENABLE
Plugins to enable for your site. Must be a space-delimited lower-case list. Include the word 'bridge' here if you are receiving data from the Dexcom Share service.

SHOW_PLUGINS
Default setting for whether or not these plugins are checked (active) by default not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case.

TIME_FORMAT +
Default setting for new browser views for the time mode. ('12' or '24')

NIGHT_MODE
Default setting for new browser views for whether Night Mode should be enabled. ('on' or 'off')

BOLUS_RENDER_OVER
U value over which the bolus values are rendered on the chart if the 'x U and Over' option is selected.

+

Dexcom Share

+

If you want Nightscout to import direcly from Dexcom Share

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
BRIDGE_USER_NAME
Your Dexcom account username to receive CGM data from the Dexcom Share service. Also make sure to include 'bridge' in your ENABLE line.

BRIDGE_PASSWORD
Your Dexcom account password to receive CGM data from the Dexcom Share service. Also make sure to include 'bridge' in your ENABLE line.

BRIDGE_SERVER +
If you are bridging from the Dexcom Share service and are anywhere *outside* the US change this to EU. ('US' or 'EU')

+

Alarms

+

You can customize alarms or leave them to default values

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
ALARM_TYPES +
simple' and/or 'predict'. Simple alarms trigger when BG crosses the various thresholds set below. Predict alarms use a formula that forecasts where the BG is going based on its trend. You will *not* get warnings when crossing the BG thresholds set below when using the predict type.

ALARM_URGENT_HIGH
Default setting for new browser views for the Urgent High alarm (triggered when BG crosses BG_HIGH). ('on' or 'off')

BG_HIGH
Urgent High BG threshold triggers the ALARM_URGENT_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable.

ALARM_URGENT_LOW
Default setting for new browser views for the Urgent Low alarm (triggered when BG crosses BG_LOW). ('on' or 'off')

BG_LOW
Urgent Low BG threshold triggers the ALARM_URGENT_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable.

ALARM_HIGH
Default setting for new browser views for the High alarm (triggered when BG crosses BG_TARGET_TOP). ('on' or 'off')

BG_TARGET_TOP
High BG threshold triggers the ALARM_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable.

ALARM_LOW
Default setting for new browser views for the Low alarm (triggered when BG crosses BG_TARGET_BOTTOM). ('on' or 'off')

BG_TARGET_BOTTOM
Low BG threshold triggers the ALARM_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable.

ALARM_TIMEAGO_URGENT
Default setting for new browser views for an urgent alarm when CGM data hasn't been received in the number of minutes set in ALARM_TIMEAGO_URGENT_MINS. ('on' or 'off')

ALARM_TIMEAGO_URGENT_MINS
Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_URGENT alarm.

ALARM_TIMEAGO_WARN
Default setting for new browser views for a warning alarm when CGM data hasn't been received in the number of minutes set in ALARM_TIMEAGO_WARN_MINS. ('on' or 'off')

ALARM_TIMEAGO_WARN_MINS
Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_WARN alarm.

+ +

+

Now click on the Validate button below

+ +

If errors show up, please correct them and click Validate again.

+

Click the button above.

+

+

+

+ +

+ + + diff --git a/_static/NightscoutVariablesUbuntu.html b/_static/NightscoutVariablesUbuntu.html new file mode 100644 index 00000000..afb772e8 --- /dev/null +++ b/_static/NightscoutVariablesUbuntu.html @@ -0,0 +1,385 @@ + + + + + +

Configure your Nightscout variables

+With this form you can easily decide which features to enable and customize your Nightscout. +

+

Mandatory variables

+

These three variables below must have a value.



+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BASE_URL
The BASE_URL consists of your Ubuntu computer/VPS IP and the Port 1337 on which the Nightscout app runs (replace 123.456.789.123 with your IP and leave :1337).

MONGO_CONNECTION
The MongoDB Connection String to connect to your MongoDB cluster. It will look like this: mongodb://MONGO_NS_USER:MONGO_NS_PASSWORD@127.0.0.1:27017/MONGO_NS_DB but you need to replace MONGO_NS_USER, MONGO_NS_PASSWORD and MONGO_NS_DB by your own database user and name.

API_SECRET
A passphrase that must be at least 12 characters long. Avoid 'special' characters, which can cause problems in some cases.

DISPLAY_UNITS +
Preferred BG units for the site: 'mg/dl' or 'mmol/l' (or just 'mmol').

+ +

Customizations

+

Leave default values if you don't want to change them.

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CUSTOM_TITLE
The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer.

THEME +
Default setting for new browser views for the color theme of the CGM graph. ('default' 'colors' or 'colorblindfriendly')

ENABLE
Plugins to enable for your site. Must be a space-delimited lower-case list. Include the word 'bridge' here if you are receiving data from the Dexcom Share service.

SHOW_PLUGINS
Default setting for whether or not these plugins are checked (active) by default not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case.

TIME_FORMAT +
Default setting for new browser views for the time mode. ('12' or '24')

NIGHT_MODE
Default setting for new browser views for whether Night Mode should be enabled. ('on' or 'off')

BOLUS_RENDER_OVER
U value over which the bolus values are rendered on the chart if the 'x U and Over' option is selected.

+ +

Dexcom Share

+

If you want Nightscout to import direcly from Dexcom Share

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
BRIDGE_USER_NAME
Your Dexcom account username to receive CGM data from the Dexcom Share service. Also make sure to include 'bridge' in your ENABLE line.

BRIDGE_PASSWORD
Your Dexcom account password to receive CGM data from the Dexcom Share service. Also make sure to include 'bridge' in your ENABLE line.

BRIDGE_SERVER +
If you are bridging from the Dexcom Share service and are anywhere *outside* the US change this to EU. ('US' or 'EU')

+ +

Alarms

+

You can customize alarms or leave them to default values

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ALARM_TYPES +
simple' and/or 'predict'. Simple alarms trigger when BG crosses the various thresholds set below. Predict alarms use a formula that forecasts where the BG is going based on its trend. You will *not* get warnings when crossing the BG thresholds set below when using the predict type.

ALARM_URGENT_HIGH
Default setting for new browser views for the Urgent High alarm (triggered when BG crosses BG_HIGH). ('on' or 'off')

BG_HIGH
Urgent High BG threshold triggers the ALARM_URGENT_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable.

ALARM_URGENT_LOW
Default setting for new browser views for the Urgent Low alarm (triggered when BG crosses BG_LOW). ('on' or 'off')

BG_LOW
Urgent Low BG threshold triggers the ALARM_URGENT_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable.

ALARM_HIGH
Default setting for new browser views for the High alarm (triggered when BG crosses BG_TARGET_TOP). ('on' or 'off')

BG_TARGET_TOP
High BG threshold triggers the ALARM_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable.

ALARM_LOW
Default setting for new browser views for the Low alarm (triggered when BG crosses BG_TARGET_BOTTOM). ('on' or 'off')

BG_TARGET_BOTTOM
Low BG threshold triggers the ALARM_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable.

ALARM_TIMEAGO_URGENT
Default setting for new browser views for an urgent alarm when CGM data hasn't been received in the number of minutes set in ALARM_TIMEAGO_URGENT_MINS. ('on' or 'off')

ALARM_TIMEAGO_URGENT_MINS
Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_URGENT alarm.

ALARM_TIMEAGO_WARN
Default setting for new browser views for a warning alarm when CGM data hasn't been received in the number of minutes set in ALARM_TIMEAGO_WARN_MINS. ('on' or 'off')

ALARM_TIMEAGO_WARN_MINS
Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_WARN alarm.

+ + +

+

Now click on the Validate button below

+ +

If errors show up, please correct them and click Validate again.

+

Click the button above.

+

+

+ +

+ +

+ + + + diff --git a/_static/_sphinx_javascript_frameworks_compat.js b/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 00000000..8549469d --- /dev/null +++ b/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,134 @@ +/* + * _sphinx_javascript_frameworks_compat.js + * ~~~~~~~~~~ + * + * Compatability shim for jQuery and underscores.js. + * + * WILL BE REMOVED IN Sphinx 6.0 + * xref RemovedInSphinx60Warning + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 00000000..4e9a9f1f --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,900 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/css/badge_only.css b/_static/css/badge_only.css new file mode 100644 index 00000000..c718cee4 --- /dev/null +++ b/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/_static/css/custom.css b/_static/css/custom.css new file mode 100644 index 00000000..25d3a3a6 --- /dev/null +++ b/_static/css/custom.css @@ -0,0 +1,9 @@ +code.literal { + color: #000000 !important; + background-color: #d3d3d3 !important; + font-size: 100%; +} + +code { + white-space : pre-wrap !important; +} \ No newline at end of file diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff b/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 00000000..6cb60000 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff2 b/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 00000000..7059e231 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff b/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 00000000..f815f63f Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff2 b/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 00000000..f2c76e5b Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/_static/css/fonts/fontawesome-webfont.eot b/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/_static/css/fonts/fontawesome-webfont.svg b/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_static/css/fonts/fontawesome-webfont.ttf b/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/_static/css/fonts/fontawesome-webfont.woff b/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/_static/css/fonts/fontawesome-webfont.woff2 b/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/_static/css/fonts/lato-bold-italic.woff b/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 00000000..88ad05b9 Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff differ diff --git a/_static/css/fonts/lato-bold-italic.woff2 b/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 00000000..c4e3d804 Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/_static/css/fonts/lato-bold.woff b/_static/css/fonts/lato-bold.woff new file mode 100644 index 00000000..c6dff51f Binary files /dev/null and b/_static/css/fonts/lato-bold.woff differ diff --git a/_static/css/fonts/lato-bold.woff2 b/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 00000000..bb195043 Binary files /dev/null and b/_static/css/fonts/lato-bold.woff2 differ diff --git a/_static/css/fonts/lato-normal-italic.woff b/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 00000000..76114bc0 Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff differ diff --git a/_static/css/fonts/lato-normal-italic.woff2 b/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 00000000..3404f37e Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/_static/css/fonts/lato-normal.woff b/_static/css/fonts/lato-normal.woff new file mode 100644 index 00000000..ae1307ff Binary files /dev/null and b/_static/css/fonts/lato-normal.woff differ diff --git a/_static/css/fonts/lato-normal.woff2 b/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 00000000..3bf98433 Binary files /dev/null and b/_static/css/fonts/lato-normal.woff2 differ diff --git a/_static/css/theme.css b/_static/css/theme.css new file mode 100644 index 00000000..c03c88f0 --- /dev/null +++ b/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css b/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css new file mode 100644 index 00000000..eb19f698 --- /dev/null +++ b/_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css @@ -0,0 +1 @@ +.sd-bg-primary{background-color:var(--sd-color-primary) !important}.sd-bg-text-primary{color:var(--sd-color-primary-text) !important}button.sd-bg-primary:focus,button.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}a.sd-bg-primary:focus,a.sd-bg-primary:hover{background-color:var(--sd-color-primary-highlight) !important}.sd-bg-secondary{background-color:var(--sd-color-secondary) !important}.sd-bg-text-secondary{color:var(--sd-color-secondary-text) !important}button.sd-bg-secondary:focus,button.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}a.sd-bg-secondary:focus,a.sd-bg-secondary:hover{background-color:var(--sd-color-secondary-highlight) !important}.sd-bg-success{background-color:var(--sd-color-success) !important}.sd-bg-text-success{color:var(--sd-color-success-text) !important}button.sd-bg-success:focus,button.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}a.sd-bg-success:focus,a.sd-bg-success:hover{background-color:var(--sd-color-success-highlight) !important}.sd-bg-info{background-color:var(--sd-color-info) !important}.sd-bg-text-info{color:var(--sd-color-info-text) !important}button.sd-bg-info:focus,button.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}a.sd-bg-info:focus,a.sd-bg-info:hover{background-color:var(--sd-color-info-highlight) !important}.sd-bg-warning{background-color:var(--sd-color-warning) !important}.sd-bg-text-warning{color:var(--sd-color-warning-text) !important}button.sd-bg-warning:focus,button.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}a.sd-bg-warning:focus,a.sd-bg-warning:hover{background-color:var(--sd-color-warning-highlight) !important}.sd-bg-danger{background-color:var(--sd-color-danger) !important}.sd-bg-text-danger{color:var(--sd-color-danger-text) !important}button.sd-bg-danger:focus,button.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}a.sd-bg-danger:focus,a.sd-bg-danger:hover{background-color:var(--sd-color-danger-highlight) !important}.sd-bg-light{background-color:var(--sd-color-light) !important}.sd-bg-text-light{color:var(--sd-color-light-text) !important}button.sd-bg-light:focus,button.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}a.sd-bg-light:focus,a.sd-bg-light:hover{background-color:var(--sd-color-light-highlight) !important}.sd-bg-muted{background-color:var(--sd-color-muted) !important}.sd-bg-text-muted{color:var(--sd-color-muted-text) !important}button.sd-bg-muted:focus,button.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}a.sd-bg-muted:focus,a.sd-bg-muted:hover{background-color:var(--sd-color-muted-highlight) !important}.sd-bg-dark{background-color:var(--sd-color-dark) !important}.sd-bg-text-dark{color:var(--sd-color-dark-text) !important}button.sd-bg-dark:focus,button.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}a.sd-bg-dark:focus,a.sd-bg-dark:hover{background-color:var(--sd-color-dark-highlight) !important}.sd-bg-black{background-color:var(--sd-color-black) !important}.sd-bg-text-black{color:var(--sd-color-black-text) !important}button.sd-bg-black:focus,button.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}a.sd-bg-black:focus,a.sd-bg-black:hover{background-color:var(--sd-color-black-highlight) !important}.sd-bg-white{background-color:var(--sd-color-white) !important}.sd-bg-text-white{color:var(--sd-color-white-text) !important}button.sd-bg-white:focus,button.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}a.sd-bg-white:focus,a.sd-bg-white:hover{background-color:var(--sd-color-white-highlight) !important}.sd-text-primary,.sd-text-primary>p{color:var(--sd-color-primary) !important}a.sd-text-primary:focus,a.sd-text-primary:hover{color:var(--sd-color-primary-highlight) !important}.sd-text-secondary,.sd-text-secondary>p{color:var(--sd-color-secondary) !important}a.sd-text-secondary:focus,a.sd-text-secondary:hover{color:var(--sd-color-secondary-highlight) !important}.sd-text-success,.sd-text-success>p{color:var(--sd-color-success) !important}a.sd-text-success:focus,a.sd-text-success:hover{color:var(--sd-color-success-highlight) !important}.sd-text-info,.sd-text-info>p{color:var(--sd-color-info) !important}a.sd-text-info:focus,a.sd-text-info:hover{color:var(--sd-color-info-highlight) !important}.sd-text-warning,.sd-text-warning>p{color:var(--sd-color-warning) !important}a.sd-text-warning:focus,a.sd-text-warning:hover{color:var(--sd-color-warning-highlight) !important}.sd-text-danger,.sd-text-danger>p{color:var(--sd-color-danger) !important}a.sd-text-danger:focus,a.sd-text-danger:hover{color:var(--sd-color-danger-highlight) !important}.sd-text-light,.sd-text-light>p{color:var(--sd-color-light) !important}a.sd-text-light:focus,a.sd-text-light:hover{color:var(--sd-color-light-highlight) !important}.sd-text-muted,.sd-text-muted>p{color:var(--sd-color-muted) !important}a.sd-text-muted:focus,a.sd-text-muted:hover{color:var(--sd-color-muted-highlight) !important}.sd-text-dark,.sd-text-dark>p{color:var(--sd-color-dark) !important}a.sd-text-dark:focus,a.sd-text-dark:hover{color:var(--sd-color-dark-highlight) !important}.sd-text-black,.sd-text-black>p{color:var(--sd-color-black) !important}a.sd-text-black:focus,a.sd-text-black:hover{color:var(--sd-color-black-highlight) !important}.sd-text-white,.sd-text-white>p{color:var(--sd-color-white) !important}a.sd-text-white:focus,a.sd-text-white:hover{color:var(--sd-color-white-highlight) !important}.sd-outline-primary{border-color:var(--sd-color-primary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-primary:focus,a.sd-outline-primary:hover{border-color:var(--sd-color-primary-highlight) !important}.sd-outline-secondary{border-color:var(--sd-color-secondary) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-secondary:focus,a.sd-outline-secondary:hover{border-color:var(--sd-color-secondary-highlight) !important}.sd-outline-success{border-color:var(--sd-color-success) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-success:focus,a.sd-outline-success:hover{border-color:var(--sd-color-success-highlight) !important}.sd-outline-info{border-color:var(--sd-color-info) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-info:focus,a.sd-outline-info:hover{border-color:var(--sd-color-info-highlight) !important}.sd-outline-warning{border-color:var(--sd-color-warning) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-warning:focus,a.sd-outline-warning:hover{border-color:var(--sd-color-warning-highlight) !important}.sd-outline-danger{border-color:var(--sd-color-danger) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-danger:focus,a.sd-outline-danger:hover{border-color:var(--sd-color-danger-highlight) !important}.sd-outline-light{border-color:var(--sd-color-light) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-light:focus,a.sd-outline-light:hover{border-color:var(--sd-color-light-highlight) !important}.sd-outline-muted{border-color:var(--sd-color-muted) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-muted:focus,a.sd-outline-muted:hover{border-color:var(--sd-color-muted-highlight) !important}.sd-outline-dark{border-color:var(--sd-color-dark) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-dark:focus,a.sd-outline-dark:hover{border-color:var(--sd-color-dark-highlight) !important}.sd-outline-black{border-color:var(--sd-color-black) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-black:focus,a.sd-outline-black:hover{border-color:var(--sd-color-black-highlight) !important}.sd-outline-white{border-color:var(--sd-color-white) !important;border-style:solid !important;border-width:1px !important}a.sd-outline-white:focus,a.sd-outline-white:hover{border-color:var(--sd-color-white-highlight) !important}.sd-bg-transparent{background-color:transparent !important}.sd-outline-transparent{border-color:transparent !important}.sd-text-transparent{color:transparent !important}.sd-p-0{padding:0 !important}.sd-pt-0,.sd-py-0{padding-top:0 !important}.sd-pr-0,.sd-px-0{padding-right:0 !important}.sd-pb-0,.sd-py-0{padding-bottom:0 !important}.sd-pl-0,.sd-px-0{padding-left:0 !important}.sd-p-1{padding:.25rem !important}.sd-pt-1,.sd-py-1{padding-top:.25rem !important}.sd-pr-1,.sd-px-1{padding-right:.25rem !important}.sd-pb-1,.sd-py-1{padding-bottom:.25rem !important}.sd-pl-1,.sd-px-1{padding-left:.25rem !important}.sd-p-2{padding:.5rem !important}.sd-pt-2,.sd-py-2{padding-top:.5rem !important}.sd-pr-2,.sd-px-2{padding-right:.5rem !important}.sd-pb-2,.sd-py-2{padding-bottom:.5rem !important}.sd-pl-2,.sd-px-2{padding-left:.5rem !important}.sd-p-3{padding:1rem !important}.sd-pt-3,.sd-py-3{padding-top:1rem !important}.sd-pr-3,.sd-px-3{padding-right:1rem !important}.sd-pb-3,.sd-py-3{padding-bottom:1rem !important}.sd-pl-3,.sd-px-3{padding-left:1rem !important}.sd-p-4{padding:1.5rem !important}.sd-pt-4,.sd-py-4{padding-top:1.5rem !important}.sd-pr-4,.sd-px-4{padding-right:1.5rem !important}.sd-pb-4,.sd-py-4{padding-bottom:1.5rem !important}.sd-pl-4,.sd-px-4{padding-left:1.5rem !important}.sd-p-5{padding:3rem !important}.sd-pt-5,.sd-py-5{padding-top:3rem !important}.sd-pr-5,.sd-px-5{padding-right:3rem !important}.sd-pb-5,.sd-py-5{padding-bottom:3rem !important}.sd-pl-5,.sd-px-5{padding-left:3rem !important}.sd-m-auto{margin:auto !important}.sd-mt-auto,.sd-my-auto{margin-top:auto !important}.sd-mr-auto,.sd-mx-auto{margin-right:auto !important}.sd-mb-auto,.sd-my-auto{margin-bottom:auto !important}.sd-ml-auto,.sd-mx-auto{margin-left:auto !important}.sd-m-0{margin:0 !important}.sd-mt-0,.sd-my-0{margin-top:0 !important}.sd-mr-0,.sd-mx-0{margin-right:0 !important}.sd-mb-0,.sd-my-0{margin-bottom:0 !important}.sd-ml-0,.sd-mx-0{margin-left:0 !important}.sd-m-1{margin:.25rem !important}.sd-mt-1,.sd-my-1{margin-top:.25rem !important}.sd-mr-1,.sd-mx-1{margin-right:.25rem !important}.sd-mb-1,.sd-my-1{margin-bottom:.25rem !important}.sd-ml-1,.sd-mx-1{margin-left:.25rem !important}.sd-m-2{margin:.5rem !important}.sd-mt-2,.sd-my-2{margin-top:.5rem !important}.sd-mr-2,.sd-mx-2{margin-right:.5rem !important}.sd-mb-2,.sd-my-2{margin-bottom:.5rem !important}.sd-ml-2,.sd-mx-2{margin-left:.5rem !important}.sd-m-3{margin:1rem !important}.sd-mt-3,.sd-my-3{margin-top:1rem !important}.sd-mr-3,.sd-mx-3{margin-right:1rem !important}.sd-mb-3,.sd-my-3{margin-bottom:1rem !important}.sd-ml-3,.sd-mx-3{margin-left:1rem !important}.sd-m-4{margin:1.5rem !important}.sd-mt-4,.sd-my-4{margin-top:1.5rem !important}.sd-mr-4,.sd-mx-4{margin-right:1.5rem !important}.sd-mb-4,.sd-my-4{margin-bottom:1.5rem !important}.sd-ml-4,.sd-mx-4{margin-left:1.5rem !important}.sd-m-5{margin:3rem !important}.sd-mt-5,.sd-my-5{margin-top:3rem !important}.sd-mr-5,.sd-mx-5{margin-right:3rem !important}.sd-mb-5,.sd-my-5{margin-bottom:3rem !important}.sd-ml-5,.sd-mx-5{margin-left:3rem !important}.sd-w-25{width:25% !important}.sd-w-50{width:50% !important}.sd-w-75{width:75% !important}.sd-w-100{width:100% !important}.sd-w-auto{width:auto !important}.sd-h-25{height:25% !important}.sd-h-50{height:50% !important}.sd-h-75{height:75% !important}.sd-h-100{height:100% !important}.sd-h-auto{height:auto !important}.sd-d-none{display:none !important}.sd-d-inline{display:inline !important}.sd-d-inline-block{display:inline-block !important}.sd-d-block{display:block !important}.sd-d-grid{display:grid !important}.sd-d-flex-row{display:-ms-flexbox !important;display:flex !important;flex-direction:row !important}.sd-d-flex-column{display:-ms-flexbox !important;display:flex !important;flex-direction:column !important}.sd-d-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}@media(min-width: 576px){.sd-d-sm-none{display:none !important}.sd-d-sm-inline{display:inline !important}.sd-d-sm-inline-block{display:inline-block !important}.sd-d-sm-block{display:block !important}.sd-d-sm-grid{display:grid !important}.sd-d-sm-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-sm-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 768px){.sd-d-md-none{display:none !important}.sd-d-md-inline{display:inline !important}.sd-d-md-inline-block{display:inline-block !important}.sd-d-md-block{display:block !important}.sd-d-md-grid{display:grid !important}.sd-d-md-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-md-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 992px){.sd-d-lg-none{display:none !important}.sd-d-lg-inline{display:inline !important}.sd-d-lg-inline-block{display:inline-block !important}.sd-d-lg-block{display:block !important}.sd-d-lg-grid{display:grid !important}.sd-d-lg-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-lg-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}@media(min-width: 1200px){.sd-d-xl-none{display:none !important}.sd-d-xl-inline{display:inline !important}.sd-d-xl-inline-block{display:inline-block !important}.sd-d-xl-block{display:block !important}.sd-d-xl-grid{display:grid !important}.sd-d-xl-flex{display:-ms-flexbox !important;display:flex !important}.sd-d-xl-inline-flex{display:-ms-inline-flexbox !important;display:inline-flex !important}}.sd-align-major-start{justify-content:flex-start !important}.sd-align-major-end{justify-content:flex-end !important}.sd-align-major-center{justify-content:center !important}.sd-align-major-justify{justify-content:space-between !important}.sd-align-major-spaced{justify-content:space-evenly !important}.sd-align-minor-start{align-items:flex-start !important}.sd-align-minor-end{align-items:flex-end !important}.sd-align-minor-center{align-items:center !important}.sd-align-minor-stretch{align-items:stretch !important}.sd-text-justify{text-align:justify !important}.sd-text-left{text-align:left !important}.sd-text-right{text-align:right !important}.sd-text-center{text-align:center !important}.sd-font-weight-light{font-weight:300 !important}.sd-font-weight-lighter{font-weight:lighter !important}.sd-font-weight-normal{font-weight:400 !important}.sd-font-weight-bold{font-weight:700 !important}.sd-font-weight-bolder{font-weight:bolder !important}.sd-font-italic{font-style:italic !important}.sd-text-decoration-none{text-decoration:none !important}.sd-text-lowercase{text-transform:lowercase !important}.sd-text-uppercase{text-transform:uppercase !important}.sd-text-capitalize{text-transform:capitalize !important}.sd-text-wrap{white-space:normal !important}.sd-text-nowrap{white-space:nowrap !important}.sd-text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-fs-1,.sd-fs-1>p{font-size:calc(1.375rem + 1.5vw) !important;line-height:unset !important}.sd-fs-2,.sd-fs-2>p{font-size:calc(1.325rem + 0.9vw) !important;line-height:unset !important}.sd-fs-3,.sd-fs-3>p{font-size:calc(1.3rem + 0.6vw) !important;line-height:unset !important}.sd-fs-4,.sd-fs-4>p{font-size:calc(1.275rem + 0.3vw) !important;line-height:unset !important}.sd-fs-5,.sd-fs-5>p{font-size:1.25rem !important;line-height:unset !important}.sd-fs-6,.sd-fs-6>p{font-size:1rem !important;line-height:unset !important}.sd-border-0{border:0 solid !important}.sd-border-top-0{border-top:0 solid !important}.sd-border-bottom-0{border-bottom:0 solid !important}.sd-border-right-0{border-right:0 solid !important}.sd-border-left-0{border-left:0 solid !important}.sd-border-1{border:1px solid !important}.sd-border-top-1{border-top:1px solid !important}.sd-border-bottom-1{border-bottom:1px solid !important}.sd-border-right-1{border-right:1px solid !important}.sd-border-left-1{border-left:1px solid !important}.sd-border-2{border:2px solid !important}.sd-border-top-2{border-top:2px solid !important}.sd-border-bottom-2{border-bottom:2px solid !important}.sd-border-right-2{border-right:2px solid !important}.sd-border-left-2{border-left:2px solid !important}.sd-border-3{border:3px solid !important}.sd-border-top-3{border-top:3px solid !important}.sd-border-bottom-3{border-bottom:3px solid !important}.sd-border-right-3{border-right:3px solid !important}.sd-border-left-3{border-left:3px solid !important}.sd-border-4{border:4px solid !important}.sd-border-top-4{border-top:4px solid !important}.sd-border-bottom-4{border-bottom:4px solid !important}.sd-border-right-4{border-right:4px solid !important}.sd-border-left-4{border-left:4px solid !important}.sd-border-5{border:5px solid !important}.sd-border-top-5{border-top:5px solid !important}.sd-border-bottom-5{border-bottom:5px solid !important}.sd-border-right-5{border-right:5px solid !important}.sd-border-left-5{border-left:5px solid !important}.sd-rounded-0{border-radius:0 !important}.sd-rounded-1{border-radius:.2rem !important}.sd-rounded-2{border-radius:.3rem !important}.sd-rounded-3{border-radius:.5rem !important}.sd-rounded-pill{border-radius:50rem !important}.sd-rounded-circle{border-radius:50% !important}.shadow-none{box-shadow:none !important}.sd-shadow-sm{box-shadow:0 .125rem .25rem var(--sd-color-shadow) !important}.sd-shadow-md{box-shadow:0 .5rem 1rem var(--sd-color-shadow) !important}.sd-shadow-lg{box-shadow:0 1rem 3rem var(--sd-color-shadow) !important}@keyframes sd-slide-from-left{0%{transform:translateX(-100%)}100%{transform:translateX(0)}}@keyframes sd-slide-from-right{0%{transform:translateX(200%)}100%{transform:translateX(0)}}@keyframes sd-grow100{0%{transform:scale(0);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50{0%{transform:scale(0.5);opacity:.5}100%{transform:scale(1);opacity:1}}@keyframes sd-grow50-rot20{0%{transform:scale(0.5) rotateZ(-20deg);opacity:.5}75%{transform:scale(1) rotateZ(5deg);opacity:1}95%{transform:scale(1) rotateZ(-1deg);opacity:1}100%{transform:scale(1) rotateZ(0);opacity:1}}.sd-animate-slide-from-left{animation:1s ease-out 0s 1 normal none running sd-slide-from-left}.sd-animate-slide-from-right{animation:1s ease-out 0s 1 normal none running sd-slide-from-right}.sd-animate-grow100{animation:1s ease-out 0s 1 normal none running sd-grow100}.sd-animate-grow50{animation:1s ease-out 0s 1 normal none running sd-grow50}.sd-animate-grow50-rot20{animation:1s ease-out 0s 1 normal none running sd-grow50-rot20}.sd-badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.sd-badge:empty{display:none}a.sd-badge{text-decoration:none}.sd-btn .sd-badge{position:relative;top:-1px}.sd-btn{background-color:transparent;border:1px solid transparent;border-radius:.25rem;cursor:pointer;display:inline-block;font-weight:400;font-size:1rem;line-height:1.5;padding:.375rem .75rem;text-align:center;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;vertical-align:middle;user-select:none;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none}.sd-btn:hover{text-decoration:none}@media(prefers-reduced-motion: reduce){.sd-btn{transition:none}}.sd-btn-primary,.sd-btn-outline-primary:hover,.sd-btn-outline-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-primary:hover,.sd-btn-primary:focus{color:var(--sd-color-primary-text) !important;background-color:var(--sd-color-primary-highlight) !important;border-color:var(--sd-color-primary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-primary{color:var(--sd-color-primary) !important;border-color:var(--sd-color-primary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary,.sd-btn-outline-secondary:hover,.sd-btn-outline-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-secondary:hover,.sd-btn-secondary:focus{color:var(--sd-color-secondary-text) !important;background-color:var(--sd-color-secondary-highlight) !important;border-color:var(--sd-color-secondary-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-secondary{color:var(--sd-color-secondary) !important;border-color:var(--sd-color-secondary) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success,.sd-btn-outline-success:hover,.sd-btn-outline-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-success:hover,.sd-btn-success:focus{color:var(--sd-color-success-text) !important;background-color:var(--sd-color-success-highlight) !important;border-color:var(--sd-color-success-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-success{color:var(--sd-color-success) !important;border-color:var(--sd-color-success) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info,.sd-btn-outline-info:hover,.sd-btn-outline-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-info:hover,.sd-btn-info:focus{color:var(--sd-color-info-text) !important;background-color:var(--sd-color-info-highlight) !important;border-color:var(--sd-color-info-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-info{color:var(--sd-color-info) !important;border-color:var(--sd-color-info) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning,.sd-btn-outline-warning:hover,.sd-btn-outline-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-warning:hover,.sd-btn-warning:focus{color:var(--sd-color-warning-text) !important;background-color:var(--sd-color-warning-highlight) !important;border-color:var(--sd-color-warning-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-warning{color:var(--sd-color-warning) !important;border-color:var(--sd-color-warning) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger,.sd-btn-outline-danger:hover,.sd-btn-outline-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-danger:hover,.sd-btn-danger:focus{color:var(--sd-color-danger-text) !important;background-color:var(--sd-color-danger-highlight) !important;border-color:var(--sd-color-danger-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-danger{color:var(--sd-color-danger) !important;border-color:var(--sd-color-danger) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light,.sd-btn-outline-light:hover,.sd-btn-outline-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-light:hover,.sd-btn-light:focus{color:var(--sd-color-light-text) !important;background-color:var(--sd-color-light-highlight) !important;border-color:var(--sd-color-light-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-light{color:var(--sd-color-light) !important;border-color:var(--sd-color-light) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted,.sd-btn-outline-muted:hover,.sd-btn-outline-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-muted:hover,.sd-btn-muted:focus{color:var(--sd-color-muted-text) !important;background-color:var(--sd-color-muted-highlight) !important;border-color:var(--sd-color-muted-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-muted{color:var(--sd-color-muted) !important;border-color:var(--sd-color-muted) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark,.sd-btn-outline-dark:hover,.sd-btn-outline-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-dark:hover,.sd-btn-dark:focus{color:var(--sd-color-dark-text) !important;background-color:var(--sd-color-dark-highlight) !important;border-color:var(--sd-color-dark-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-dark{color:var(--sd-color-dark) !important;border-color:var(--sd-color-dark) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black,.sd-btn-outline-black:hover,.sd-btn-outline-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-black:hover,.sd-btn-black:focus{color:var(--sd-color-black-text) !important;background-color:var(--sd-color-black-highlight) !important;border-color:var(--sd-color-black-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-black{color:var(--sd-color-black) !important;border-color:var(--sd-color-black) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white,.sd-btn-outline-white:hover,.sd-btn-outline-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-btn-white:hover,.sd-btn-white:focus{color:var(--sd-color-white-text) !important;background-color:var(--sd-color-white-highlight) !important;border-color:var(--sd-color-white-highlight) !important;border-width:1px !important;border-style:solid !important}.sd-btn-outline-white{color:var(--sd-color-white) !important;border-color:var(--sd-color-white) !important;border-width:1px !important;border-style:solid !important}.sd-stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.sd-hide-link-text{font-size:0}.sd-octicon,.sd-material-icon{display:inline-block;fill:currentColor;vertical-align:middle}.sd-avatar-xs{border-radius:50%;object-fit:cover;object-position:center;width:1rem;height:1rem}.sd-avatar-sm{border-radius:50%;object-fit:cover;object-position:center;width:3rem;height:3rem}.sd-avatar-md{border-radius:50%;object-fit:cover;object-position:center;width:5rem;height:5rem}.sd-avatar-lg{border-radius:50%;object-fit:cover;object-position:center;width:7rem;height:7rem}.sd-avatar-xl{border-radius:50%;object-fit:cover;object-position:center;width:10rem;height:10rem}.sd-avatar-inherit{border-radius:50%;object-fit:cover;object-position:center;width:inherit;height:inherit}.sd-avatar-initial{border-radius:50%;object-fit:cover;object-position:center;width:initial;height:initial}.sd-card{background-clip:border-box;background-color:var(--sd-color-card-background);border:1px solid var(--sd-color-card-border);border-radius:.25rem;color:var(--sd-color-card-text);display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;position:relative;word-wrap:break-word}.sd-card>hr{margin-left:0;margin-right:0}.sd-card-hover:hover{border-color:var(--sd-color-card-border-hover);transform:scale(1.01)}.sd-card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem 1rem}.sd-card-title{margin-bottom:.5rem}.sd-card-subtitle{margin-top:-0.25rem;margin-bottom:0}.sd-card-text:last-child{margin-bottom:0}.sd-card-link:hover{text-decoration:none}.sd-card-link+.card-link{margin-left:1rem}.sd-card-header{padding:.5rem 1rem;margin-bottom:0;background-color:var(--sd-color-card-header);border-bottom:1px solid var(--sd-color-card-border)}.sd-card-header:first-child{border-radius:calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0}.sd-card-footer{padding:.5rem 1rem;background-color:var(--sd-color-card-footer);border-top:1px solid var(--sd-color-card-border)}.sd-card-footer:last-child{border-radius:0 0 calc(0.25rem - 1px) calc(0.25rem - 1px)}.sd-card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.sd-card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.sd-card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom,.sd-card-img-top{width:100%}.sd-card-img,.sd-card-img-top{border-top-left-radius:calc(0.25rem - 1px);border-top-right-radius:calc(0.25rem - 1px)}.sd-card-img,.sd-card-img-bottom{border-bottom-left-radius:calc(0.25rem - 1px);border-bottom-right-radius:calc(0.25rem - 1px)}.sd-cards-carousel{width:100%;display:flex;flex-wrap:nowrap;-ms-flex-direction:row;flex-direction:row;overflow-x:hidden;scroll-snap-type:x mandatory}.sd-cards-carousel.sd-show-scrollbar{overflow-x:auto}.sd-cards-carousel:hover,.sd-cards-carousel:focus{overflow-x:auto}.sd-cards-carousel>.sd-card{flex-shrink:0;scroll-snap-align:start}.sd-cards-carousel>.sd-card:not(:last-child){margin-right:3px}.sd-card-cols-1>.sd-card{width:90%}.sd-card-cols-2>.sd-card{width:45%}.sd-card-cols-3>.sd-card{width:30%}.sd-card-cols-4>.sd-card{width:22.5%}.sd-card-cols-5>.sd-card{width:18%}.sd-card-cols-6>.sd-card{width:15%}.sd-card-cols-7>.sd-card{width:12.8571428571%}.sd-card-cols-8>.sd-card{width:11.25%}.sd-card-cols-9>.sd-card{width:10%}.sd-card-cols-10>.sd-card{width:9%}.sd-card-cols-11>.sd-card{width:8.1818181818%}.sd-card-cols-12>.sd-card{width:7.5%}.sd-container,.sd-container-fluid,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container-xl{margin-left:auto;margin-right:auto;padding-left:var(--sd-gutter-x, 0.75rem);padding-right:var(--sd-gutter-x, 0.75rem);width:100%}@media(min-width: 576px){.sd-container-sm,.sd-container{max-width:540px}}@media(min-width: 768px){.sd-container-md,.sd-container-sm,.sd-container{max-width:720px}}@media(min-width: 992px){.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:960px}}@media(min-width: 1200px){.sd-container-xl,.sd-container-lg,.sd-container-md,.sd-container-sm,.sd-container{max-width:1140px}}.sd-row{--sd-gutter-x: 1.5rem;--sd-gutter-y: 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-top:calc(var(--sd-gutter-y) * -1);margin-right:calc(var(--sd-gutter-x) * -0.5);margin-left:calc(var(--sd-gutter-x) * -0.5)}.sd-row>*{box-sizing:border-box;flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--sd-gutter-x) * 0.5);padding-left:calc(var(--sd-gutter-x) * 0.5);margin-top:var(--sd-gutter-y)}.sd-col{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-auto>*{flex:0 0 auto;width:auto}.sd-row-cols-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}@media(min-width: 576px){.sd-col-sm{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-sm-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-sm-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-sm-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-sm-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-sm-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-sm-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-sm-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-sm-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-sm-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-sm-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-sm-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-sm-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-sm-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 768px){.sd-col-md{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-md-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-md-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-md-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-md-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-md-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-md-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-md-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-md-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-md-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-md-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-md-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-md-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-md-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 992px){.sd-col-lg{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-lg-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-lg-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-lg-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-lg-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-lg-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-lg-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-lg-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-lg-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-lg-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-lg-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-lg-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-lg-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-lg-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}@media(min-width: 1200px){.sd-col-xl{flex:1 0 0%;-ms-flex:1 0 0%}.sd-row-cols-xl-auto{flex:1 0 auto;-ms-flex:1 0 auto;width:100%}.sd-row-cols-xl-1>*{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-row-cols-xl-2>*{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-row-cols-xl-3>*{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-row-cols-xl-4>*{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-row-cols-xl-5>*{flex:0 0 auto;-ms-flex:0 0 auto;width:20%}.sd-row-cols-xl-6>*{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-row-cols-xl-7>*{flex:0 0 auto;-ms-flex:0 0 auto;width:14.2857142857%}.sd-row-cols-xl-8>*{flex:0 0 auto;-ms-flex:0 0 auto;width:12.5%}.sd-row-cols-xl-9>*{flex:0 0 auto;-ms-flex:0 0 auto;width:11.1111111111%}.sd-row-cols-xl-10>*{flex:0 0 auto;-ms-flex:0 0 auto;width:10%}.sd-row-cols-xl-11>*{flex:0 0 auto;-ms-flex:0 0 auto;width:9.0909090909%}.sd-row-cols-xl-12>*{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}}.sd-col-auto{flex:0 0 auto;-ms-flex:0 0 auto;width:auto}.sd-col-1{flex:0 0 auto;-ms-flex:0 0 auto;width:8.3333333333%}.sd-col-2{flex:0 0 auto;-ms-flex:0 0 auto;width:16.6666666667%}.sd-col-3{flex:0 0 auto;-ms-flex:0 0 auto;width:25%}.sd-col-4{flex:0 0 auto;-ms-flex:0 0 auto;width:33.3333333333%}.sd-col-5{flex:0 0 auto;-ms-flex:0 0 auto;width:41.6666666667%}.sd-col-6{flex:0 0 auto;-ms-flex:0 0 auto;width:50%}.sd-col-7{flex:0 0 auto;-ms-flex:0 0 auto;width:58.3333333333%}.sd-col-8{flex:0 0 auto;-ms-flex:0 0 auto;width:66.6666666667%}.sd-col-9{flex:0 0 auto;-ms-flex:0 0 auto;width:75%}.sd-col-10{flex:0 0 auto;-ms-flex:0 0 auto;width:83.3333333333%}.sd-col-11{flex:0 0 auto;-ms-flex:0 0 auto;width:91.6666666667%}.sd-col-12{flex:0 0 auto;-ms-flex:0 0 auto;width:100%}.sd-g-0,.sd-gy-0{--sd-gutter-y: 0}.sd-g-0,.sd-gx-0{--sd-gutter-x: 0}.sd-g-1,.sd-gy-1{--sd-gutter-y: 0.25rem}.sd-g-1,.sd-gx-1{--sd-gutter-x: 0.25rem}.sd-g-2,.sd-gy-2{--sd-gutter-y: 0.5rem}.sd-g-2,.sd-gx-2{--sd-gutter-x: 0.5rem}.sd-g-3,.sd-gy-3{--sd-gutter-y: 1rem}.sd-g-3,.sd-gx-3{--sd-gutter-x: 1rem}.sd-g-4,.sd-gy-4{--sd-gutter-y: 1.5rem}.sd-g-4,.sd-gx-4{--sd-gutter-x: 1.5rem}.sd-g-5,.sd-gy-5{--sd-gutter-y: 3rem}.sd-g-5,.sd-gx-5{--sd-gutter-x: 3rem}@media(min-width: 576px){.sd-col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-sm-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-sm-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-sm-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-sm-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-sm-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-sm-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-sm-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-sm-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-sm-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-sm-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-sm-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-sm-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-sm-0,.sd-gy-sm-0{--sd-gutter-y: 0}.sd-g-sm-0,.sd-gx-sm-0{--sd-gutter-x: 0}.sd-g-sm-1,.sd-gy-sm-1{--sd-gutter-y: 0.25rem}.sd-g-sm-1,.sd-gx-sm-1{--sd-gutter-x: 0.25rem}.sd-g-sm-2,.sd-gy-sm-2{--sd-gutter-y: 0.5rem}.sd-g-sm-2,.sd-gx-sm-2{--sd-gutter-x: 0.5rem}.sd-g-sm-3,.sd-gy-sm-3{--sd-gutter-y: 1rem}.sd-g-sm-3,.sd-gx-sm-3{--sd-gutter-x: 1rem}.sd-g-sm-4,.sd-gy-sm-4{--sd-gutter-y: 1.5rem}.sd-g-sm-4,.sd-gx-sm-4{--sd-gutter-x: 1.5rem}.sd-g-sm-5,.sd-gy-sm-5{--sd-gutter-y: 3rem}.sd-g-sm-5,.sd-gx-sm-5{--sd-gutter-x: 3rem}}@media(min-width: 768px){.sd-col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-md-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-md-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-md-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-md-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-md-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-md-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-md-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-md-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-md-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-md-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-md-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-md-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-md-0,.sd-gy-md-0{--sd-gutter-y: 0}.sd-g-md-0,.sd-gx-md-0{--sd-gutter-x: 0}.sd-g-md-1,.sd-gy-md-1{--sd-gutter-y: 0.25rem}.sd-g-md-1,.sd-gx-md-1{--sd-gutter-x: 0.25rem}.sd-g-md-2,.sd-gy-md-2{--sd-gutter-y: 0.5rem}.sd-g-md-2,.sd-gx-md-2{--sd-gutter-x: 0.5rem}.sd-g-md-3,.sd-gy-md-3{--sd-gutter-y: 1rem}.sd-g-md-3,.sd-gx-md-3{--sd-gutter-x: 1rem}.sd-g-md-4,.sd-gy-md-4{--sd-gutter-y: 1.5rem}.sd-g-md-4,.sd-gx-md-4{--sd-gutter-x: 1.5rem}.sd-g-md-5,.sd-gy-md-5{--sd-gutter-y: 3rem}.sd-g-md-5,.sd-gx-md-5{--sd-gutter-x: 3rem}}@media(min-width: 992px){.sd-col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-lg-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-lg-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-lg-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-lg-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-lg-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-lg-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-lg-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-lg-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-lg-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-lg-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-lg-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-lg-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-lg-0,.sd-gy-lg-0{--sd-gutter-y: 0}.sd-g-lg-0,.sd-gx-lg-0{--sd-gutter-x: 0}.sd-g-lg-1,.sd-gy-lg-1{--sd-gutter-y: 0.25rem}.sd-g-lg-1,.sd-gx-lg-1{--sd-gutter-x: 0.25rem}.sd-g-lg-2,.sd-gy-lg-2{--sd-gutter-y: 0.5rem}.sd-g-lg-2,.sd-gx-lg-2{--sd-gutter-x: 0.5rem}.sd-g-lg-3,.sd-gy-lg-3{--sd-gutter-y: 1rem}.sd-g-lg-3,.sd-gx-lg-3{--sd-gutter-x: 1rem}.sd-g-lg-4,.sd-gy-lg-4{--sd-gutter-y: 1.5rem}.sd-g-lg-4,.sd-gx-lg-4{--sd-gutter-x: 1.5rem}.sd-g-lg-5,.sd-gy-lg-5{--sd-gutter-y: 3rem}.sd-g-lg-5,.sd-gx-lg-5{--sd-gutter-x: 3rem}}@media(min-width: 1200px){.sd-col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.sd-col-xl-1{-ms-flex:0 0 auto;flex:0 0 auto;width:8.3333333333%}.sd-col-xl-2{-ms-flex:0 0 auto;flex:0 0 auto;width:16.6666666667%}.sd-col-xl-3{-ms-flex:0 0 auto;flex:0 0 auto;width:25%}.sd-col-xl-4{-ms-flex:0 0 auto;flex:0 0 auto;width:33.3333333333%}.sd-col-xl-5{-ms-flex:0 0 auto;flex:0 0 auto;width:41.6666666667%}.sd-col-xl-6{-ms-flex:0 0 auto;flex:0 0 auto;width:50%}.sd-col-xl-7{-ms-flex:0 0 auto;flex:0 0 auto;width:58.3333333333%}.sd-col-xl-8{-ms-flex:0 0 auto;flex:0 0 auto;width:66.6666666667%}.sd-col-xl-9{-ms-flex:0 0 auto;flex:0 0 auto;width:75%}.sd-col-xl-10{-ms-flex:0 0 auto;flex:0 0 auto;width:83.3333333333%}.sd-col-xl-11{-ms-flex:0 0 auto;flex:0 0 auto;width:91.6666666667%}.sd-col-xl-12{-ms-flex:0 0 auto;flex:0 0 auto;width:100%}.sd-g-xl-0,.sd-gy-xl-0{--sd-gutter-y: 0}.sd-g-xl-0,.sd-gx-xl-0{--sd-gutter-x: 0}.sd-g-xl-1,.sd-gy-xl-1{--sd-gutter-y: 0.25rem}.sd-g-xl-1,.sd-gx-xl-1{--sd-gutter-x: 0.25rem}.sd-g-xl-2,.sd-gy-xl-2{--sd-gutter-y: 0.5rem}.sd-g-xl-2,.sd-gx-xl-2{--sd-gutter-x: 0.5rem}.sd-g-xl-3,.sd-gy-xl-3{--sd-gutter-y: 1rem}.sd-g-xl-3,.sd-gx-xl-3{--sd-gutter-x: 1rem}.sd-g-xl-4,.sd-gy-xl-4{--sd-gutter-y: 1.5rem}.sd-g-xl-4,.sd-gx-xl-4{--sd-gutter-x: 1.5rem}.sd-g-xl-5,.sd-gy-xl-5{--sd-gutter-y: 3rem}.sd-g-xl-5,.sd-gx-xl-5{--sd-gutter-x: 3rem}}.sd-flex-row-reverse{flex-direction:row-reverse !important}details.sd-dropdown{position:relative}details.sd-dropdown .sd-summary-title{font-weight:700;padding-right:3em !important;-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;user-select:none}details.sd-dropdown:hover{cursor:pointer}details.sd-dropdown .sd-summary-content{cursor:default}details.sd-dropdown summary{list-style:none;padding:1em}details.sd-dropdown summary .sd-octicon.no-title{vertical-align:middle}details.sd-dropdown[open] summary .sd-octicon.no-title{visibility:hidden}details.sd-dropdown summary::-webkit-details-marker{display:none}details.sd-dropdown summary:focus{outline:none}details.sd-dropdown .sd-summary-icon{margin-right:.5em}details.sd-dropdown .sd-summary-icon svg{opacity:.8}details.sd-dropdown summary:hover .sd-summary-up svg,details.sd-dropdown summary:hover .sd-summary-down svg{opacity:1;transform:scale(1.1)}details.sd-dropdown .sd-summary-up svg,details.sd-dropdown .sd-summary-down svg{display:block;opacity:.6}details.sd-dropdown .sd-summary-up,details.sd-dropdown .sd-summary-down{pointer-events:none;position:absolute;right:1em;top:1em}details.sd-dropdown[open]>.sd-summary-title .sd-summary-down{visibility:hidden}details.sd-dropdown:not([open])>.sd-summary-title .sd-summary-up{visibility:hidden}details.sd-dropdown:not([open]).sd-card{border:none}details.sd-dropdown:not([open])>.sd-card-header{border:1px solid var(--sd-color-card-border);border-radius:.25rem}details.sd-dropdown.sd-fade-in[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out;animation:sd-fade-in .5s ease-in-out}details.sd-dropdown.sd-fade-in-slide-down[open] summary~*{-moz-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;-webkit-animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out;animation:sd-fade-in .5s ease-in-out,sd-slide-down .5s ease-in-out}.sd-col>.sd-dropdown{width:100%}.sd-summary-content>.sd-tab-set:first-child{margin-top:0}@keyframes sd-fade-in{0%{opacity:0}100%{opacity:1}}@keyframes sd-slide-down{0%{transform:translate(0, -10px)}100%{transform:translate(0, 0)}}.sd-tab-set{border-radius:.125rem;display:flex;flex-wrap:wrap;margin:1em 0;position:relative}.sd-tab-set>input{opacity:0;position:absolute}.sd-tab-set>input:checked+label{border-color:var(--sd-color-tabs-underline-active);color:var(--sd-color-tabs-label-active)}.sd-tab-set>input:checked+label+.sd-tab-content{display:block}.sd-tab-set>input:not(:checked)+label:hover{color:var(--sd-color-tabs-label-hover);border-color:var(--sd-color-tabs-underline-hover)}.sd-tab-set>input:focus+label{outline-style:auto}.sd-tab-set>input:not(.focus-visible)+label{outline:none;-webkit-tap-highlight-color:transparent}.sd-tab-set>label{border-bottom:.125rem solid transparent;margin-bottom:0;color:var(--sd-color-tabs-label-inactive);border-color:var(--sd-color-tabs-underline-inactive);cursor:pointer;font-size:var(--sd-fontsize-tabs-label);font-weight:700;padding:1em 1.25em .5em;transition:color 250ms;width:auto;z-index:1}html .sd-tab-set>label:hover{color:var(--sd-color-tabs-label-active)}.sd-col>.sd-tab-set{width:100%}.sd-tab-content{box-shadow:0 -0.0625rem var(--sd-color-tabs-overline),0 .0625rem var(--sd-color-tabs-underline);display:none;order:99;padding-bottom:.75rem;padding-top:.75rem;width:100%}.sd-tab-content>:first-child{margin-top:0 !important}.sd-tab-content>:last-child{margin-bottom:0 !important}.sd-tab-content>.sd-tab-set{margin:0}.sd-sphinx-override,.sd-sphinx-override *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sd-sphinx-override p{margin-top:0}:root{--sd-color-primary: #0071bc;--sd-color-secondary: #6c757d;--sd-color-success: #28a745;--sd-color-info: #17a2b8;--sd-color-warning: #f0b37e;--sd-color-danger: #dc3545;--sd-color-light: #f8f9fa;--sd-color-muted: #6c757d;--sd-color-dark: #212529;--sd-color-black: black;--sd-color-white: white;--sd-color-primary-highlight: #0060a0;--sd-color-secondary-highlight: #5c636a;--sd-color-success-highlight: #228e3b;--sd-color-info-highlight: #148a9c;--sd-color-warning-highlight: #cc986b;--sd-color-danger-highlight: #bb2d3b;--sd-color-light-highlight: #d3d4d5;--sd-color-muted-highlight: #5c636a;--sd-color-dark-highlight: #1c1f23;--sd-color-black-highlight: black;--sd-color-white-highlight: #d9d9d9;--sd-color-primary-text: #fff;--sd-color-secondary-text: #fff;--sd-color-success-text: #fff;--sd-color-info-text: #fff;--sd-color-warning-text: #212529;--sd-color-danger-text: #fff;--sd-color-light-text: #212529;--sd-color-muted-text: #fff;--sd-color-dark-text: #fff;--sd-color-black-text: #fff;--sd-color-white-text: #212529;--sd-color-shadow: rgba(0, 0, 0, 0.15);--sd-color-card-border: rgba(0, 0, 0, 0.125);--sd-color-card-border-hover: hsla(231, 99%, 66%, 1);--sd-color-card-background: transparent;--sd-color-card-text: inherit;--sd-color-card-header: transparent;--sd-color-card-footer: transparent;--sd-color-tabs-label-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-hover: hsla(231, 99%, 66%, 1);--sd-color-tabs-label-inactive: hsl(0, 0%, 66%);--sd-color-tabs-underline-active: hsla(231, 99%, 66%, 1);--sd-color-tabs-underline-hover: rgba(178, 206, 245, 0.62);--sd-color-tabs-underline-inactive: transparent;--sd-color-tabs-overline: rgb(222, 222, 222);--sd-color-tabs-underline: rgb(222, 222, 222);--sd-fontsize-tabs-label: 1rem} diff --git a/_static/design-tabs.js b/_static/design-tabs.js new file mode 100644 index 00000000..36b38cf0 --- /dev/null +++ b/_static/design-tabs.js @@ -0,0 +1,27 @@ +var sd_labels_by_text = {}; + +function ready() { + const li = document.getElementsByClassName("sd-tab-label"); + for (const label of li) { + syncId = label.getAttribute("data-sync-id"); + if (syncId) { + label.onclick = onLabelClick; + if (!sd_labels_by_text[syncId]) { + sd_labels_by_text[syncId] = []; + } + sd_labels_by_text[syncId].push(label); + } + } +} + +function onLabelClick() { + // Activate other inputs with the same sync id. + syncId = this.getAttribute("data-sync-id"); + for (label of sd_labels_by_text[syncId]) { + if (label === this) continue; + label.previousElementSibling.checked = true; + } + window.localStorage.setItem("sphinx-design-last-tab", syncId); +} + +document.addEventListener("DOMContentLoaded", ready, false); diff --git a/_static/docker-compose.yml b/_static/docker-compose.yml new file mode 100644 index 00000000..341f6712 --- /dev/null +++ b/_static/docker-compose.yml @@ -0,0 +1,127 @@ +version: '3.9' + +x-logging: + &default-logging + options: + max-size: '10m' + max-file: '5' + driver: json-file + +services: + nightscout: + image: nightscout/cgm-remote-monitor:latest + environment: +# ----------------------------------------------------------------------------------------------- +# Here are your Nightscout variables: +# Respect the format VARIABLE: value (with a space after :) +# +# Mandatory information + TZ: YOUR_TIMEZONE + API_SECRET: YOUR_API_SECRET + ENABLE: careportal sage iage cage iob cob basal upbat devicestatus dbsize cors + SHOW_PLUGINS: careportal sage iob cob dbsize cors ar2 + DISPLAY_UNITS: mg/dl + + #BRIDGE_USER_NAME: username + #BRIDGE_PASSWORD: password + #BRIDGE_SERVER: EU + + AUTH_DEFAULT_ROLES: readable + NIGHT_MODE: off + THEME: colors + TIME_FORMAT: 24 + SCALE_Y: linear + AR2_CONE_FACTOR: 0 + SHOW_RAWBG: always + DBSIZE_MAX: DISK_SIZE + #BASAL_RENDER: default + BOLUS_RENDER_FORMAT_SMALL: minimal + BOLUS_RENDER_OVER: 1 + + BG_LOW: 60 + BG_TARGET_BOTTOM: 70 + BG_TARGET_TOP: 180 + BG_HIGH: 200 + ALARM_TYPES: simple + ALARM_HIGH: on + ALARM_LOW: on + ALARM_URGENT_HIGH: on + ALARM_URGENT_LOW: on + ALARM_TIMEAGO_URGENT: on + ALARM_TIMEAGO_URGENT_MINS: 30 + ALARM_TIMEAGO_WARN: on + ALARM_TIMEAGO_WARN_MINS: 15 + + DEVICESTATUS_ADVANCED: true + SAGE_INFO: 336 + SAGE_URGENT: 348 + SAGE_WARN: 342 + #SHOW_FORECAST: + #PUMP_FIELDS: reservoir battery clock status + #PUMP_RETRO_FIELDS: battery reservoir clock status + #PUMP_URGENT_BATT: 26 + #PUMP_WARN_BATT: 51 + #IAGE_INFO: 68 + #IAGE_URGENT: 79 + #IAGE_WARN: 72 + #PUMP_ENABLE_ALERTS: true + #PUMP_URGENT_BATT_U: 30 + #PUMP_URGENT_BATT_V: 1.25 + #PUMP_URGENT_RES: 10 + #PUMP_URGENT_CLOCK: 30 + #LOOP_ENABLE_ALERTS: true + #LOOP_WARN: 20 + #LOOP_URGENT: 60 +# ----------------------------------------------------------------------------------------------- +# Do not change anything below unless you know what you are doing +# ----------------------------------------------------------------------------------------------- + INSECURE_USE_HTTP: 'true' + MONGO_CONNECTION: mongodb://mongo:27017/Nightscout + ports: + - "1337:1337" + depends_on: + - mongo + labels: + - 'traefik.enable=true' + # Change the below Host from `localhost` to be the web address where Nightscout is running. + # Also change the email address in the `traefik` service below. + - 'traefik.http.routers.nightscout.rule=Host(`YOUR_PUBLIC_HOST_URL`)' + - 'traefik.http.routers.nightscout.entrypoints=websecure' + - 'traefik.http.routers.nightscout.tls.certresolver=le' + volumes: + - /nightscout/docker:/var/opt/ssl/:ro + restart: unless-stopped + + mongo: +# Note you can also use mongo:5 + image: mongo:4.4 + container_name: mongo + volumes: + - ./data:/data/db +# Enable only of you want external access, but then you should modify mongo login and passord + #ports: + #- "27017:27017" + logging: *default-logging + restart: unless-stopped + + traefik: + image: traefik:latest + container_name: 'traefik' + command: + - '--providers.docker=true' + - '--providers.docker.exposedbydefault=false' + - '--entrypoints.web.address=:80' + - '--entrypoints.web.http.redirections.entrypoint.to=websecure' + - '--entrypoints.websecure.address=:443' + - "--certificatesresolvers.le.acme.httpchallenge=true" + - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web" + - '--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json' + # Change the below to match your email address + - '--certificatesresolvers.le.acme.email=YOUR_EMAIL' + ports: + - '443:443' + - '80:80' + volumes: + - './letsencrypt:/letsencrypt' + - '/var/run/docker.sock:/var/run/docker.sock:ro' + restart: unless-stopped \ No newline at end of file diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 00000000..527b876c --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,156 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 00000000..c066c69a --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,14 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'dirhtml', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 00000000..a858a410 Binary files /dev/null and b/_static/file.png differ diff --git a/_static/fly.toml b/_static/fly.toml new file mode 100644 index 00000000..eb2a82cc --- /dev/null +++ b/_static/fly.toml @@ -0,0 +1,139 @@ +# +# fly.toml file generated for Nightscout see https://nightscout.github.io/ +# + +#--------------------------------------------------------------------------------- +# Change the app value to your site name. (i.e. sitename to have sitename.fly.io +#--------------------------------------------------------------------------------- +app = "CHANGE ME TO YOUR SITE NAME!" +primary_region = "ams" +kill_signal = "SIGINT" +kill_timeout = 5 +processes = [] + +#---------------------------------------------------------------------------------- +# +# Review and modify the variables below and adapt them to your needs +# The first three API_SECRET, DISPLAY_UNITS and MONGODB_URI are MANDATORY +# + +[env] +# A passphrase that must be at least 12 characters long. Avoid 'special' characters, which can cause problems in some cases. +API_SECRET="CHANGE ME!" + +# Preferred BG units for the site: 'mg/dl' or 'mmol/l' (or just 'mmol'). +DISPLAY_UNITS="mg/dl" + +# The MongoDB Connection String to connect to your MongoDB cluster. If you don't have this from MongoDB Atlas, please re-read installation instructions at https://nightscout.github.io/vendors/mongodb/atlas/ before continuing. +MONGODB_URI="mongodb+srv:// CHANGE ME!" + +# +# If you want Nightscout to get BG readings from Dexcom Share you must enter your account credentials +# + +# Your Dexcom account username to receive CGM data from the Dexcom Share service. Also make sure to include 'bridge' in your ENABLE line. +BRIDGE_USER_NAME="CHANGE ME!" + +# Your Dexcom account password to receive CGM data from the Dexcom Share service. Also make sure to include 'bridge' in your ENABLE line. +BRIDGE_PASSWORD="CHANGE ME!" + +# If you are bridging from the Dexcom Share service and are anywhere *outside* the US change this to EU. ('US' or 'EU') +BRIDGE_SERVER="US" + +# +# The following variables are optional, only make sure to add bridge in ENABLE if you use Dexcom Share as a data source +# + +# Plugins to enable for your site. Must be a space-delimited lower-case list. Include the word 'bridge' here if you are receiving data from the Dexcom Share service. +ENABLE="careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors" + +# The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer. +CUSTOM_TITLE="Nightscout" + +# Default setting for whether or not these plugins are checked (active) by default not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case. +SHOW_PLUGINS="careportal dbsize" + +# simple' and/or 'predict'. Simple alarms trigger when BG crosses the various thresholds set below. Predict alarms use a formula that forecasts where the BG is going based on its trend. You will *not* get warnings when crossing the BG thresholds set below when using the predict type. +ALARM_TYPES="simple" + +# Urgent High BG threshold triggers the ALARM_URGENT_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable. +BG_HIGH=260 + +# Urgent Low BG threshold triggers the ALARM_URGENT_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable. +BG_LOW=55 + +# Low BG threshold triggers the ALARM_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable. +BG_TARGET_BOTTOM=70 + +# High BG threshold triggers the ALARM_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable. +BG_TARGET_TOP=180 + +# Default setting for new browser views for the Urgent High alarm (triggered when BG crosses BG_HIGH). ('on' or 'off') +ALARM_URGENT_HIGH="on" + +# Default setting for new browser views for the Urgent Low alarm (triggered when BG crosses BG_LOW). ('on' or 'off') +ALARM_URGENT_LOW="on" + +# Default setting for new browser views for the High alarm (triggered when BG crosses BG_TARGET_TOP). ('on' or 'off') +ALARM_HIGH="on" + +# Default setting for new browser views for the Low alarm (triggered when BG crosses BG_TARGET_BOTTOM). ('on' or 'off') +ALARM_LOW="on" + +# Default setting for new browser views for an urgent alarm when CGM data hasn't been received in the number of minutes set in ALARM_TIMEAGO_URGENT_MINS. ('on' or 'off') +ALARM_TIMEAGO_URGENT="on" + +# Default setting for new browser views for a warning alarm when CGM data hasn't been received in the number of minutes set in ALARM_TIMEAGO_WARN_MINS. ('on' or 'off') +ALARM_TIMEAGO_WARN="on" + +# Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_URGENT alarm. +ALARM_TIMEAGO_URGENT_MINS=30 + +# Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_WARN alarm. +ALARM_TIMEAGO_WARN_MINS=15 + +# Default setting for new browser views for whether Night Mode should be enabled. ('on' or 'off') +NIGHT_MODE="off" + +# Default setting for new browser views for the color theme of the CGM graph. ('default' 'colors' or 'colorblindfriendly') +THEME="colors" + +# Default setting for new browser views for the time mode. ('12' or '24') +TIME_FORMAT=12 + +# U value over which the bolus values are rendered on the chart if the 'x U and Over' option is selected. +BOLUS_RENDER_OVER=1 + +# DO NOT MODIFY ANYTHING BELOW +# ////////////////////////////////////////////////////////////////////////////////////////////// +PORT = "3000" + +[experimental] + allowed_public_ports = [] + auto_rollback = true + +[[services]] + http_checks = [] + internal_port = 3000 + processes = ["app"] + protocol = "tcp" + script_checks = [] + [services.concurrency] + hard_limit = 25 + soft_limit = 20 + type = "connections" + + [[services.ports]] + force_https = true + handlers = ["http"] + port = 80 + + [[services.ports]] + handlers = ["tls", "http"] + port = 443 + + [[services.tcp_checks]] + grace_period = "1s" + interval = "15s" + restart_limit = 0 + timeout = "2s" diff --git a/_static/flydb/fly.toml b/_static/flydb/fly.toml new file mode 100644 index 00000000..84bbf1d9 --- /dev/null +++ b/_static/flydb/fly.toml @@ -0,0 +1,28 @@ +# fly.toml app configuration file generated for nightscout-ferretdb on 2024-04-13T22:55:43+02:00 +# +# See https://fly.io/docs/reference/configuration/ for information about how to use this file. +# + +app = 'nsferretdb' +primary_region = 'ams' + +[build] + image = 'ghcr.io/ferretdb/ferretdb' + +[http_service] + internal_port = 27017 + force_https = true + auto_stop_machines = true + auto_start_machines = true + min_machines_running = 0 + processes = ['app'] + +[[services]] + protocol = 'tcp' + internal_port = 27017 + +[[services.ports]] + port = 27017 + +[[vm]] + size = 'shared-cpu-1x' diff --git a/_static/jquery-3.6.0.js b/_static/jquery-3.6.0.js new file mode 100644 index 00000000..fc6c299b --- /dev/null +++ b/_static/jquery-3.6.0.js @@ -0,0 +1,10881 @@ +/*! + * jQuery JavaScript Library v3.6.0 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright OpenJS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2021-03-02T17:08Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 + // Plus for old WebKit, typeof returns "function" for HTML collections + // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) + return typeof obj === "function" && typeof obj.nodeType !== "number" && + typeof obj.item !== "function"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.6.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), + function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); + } ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.6 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2021-02-16 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem && elem.namespaceURI, + docElem = elem && ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +} +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the primary Deferred + primary = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + primary.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( primary.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return primary.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); + } + + return primary.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + + // Support: Chrome 86+ + // In Chrome, if an element having a focusout handler is blurred by + // clicking outside of it, it invokes the handler synchronously. If + // that handler calls `.remove()` on the element, the data is cleared, + // leaving `result` undefined. We need to guard against this. + return result && result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + which: true +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + // Suppress native focus or blur as it's already being fired + // in leverageNative. + _default: function() { + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + // + // Support: Firefox 70+ + // Only Firefox includes border widths + // in computed dimensions. (gh-4529) + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; + tr.style.cssText = "border:1px solid"; + + // Support: Chrome 86+ + // Height set through cssText does not get applied. + // Computed height then comes back as 0. + tr.style.height = "1px"; + trChild.style.height = "9px"; + + // Support: Android 8 Chrome 86+ + // In our bodyBackground.html iframe, + // display for all div elements is set to "inline", + // which causes a problem only in Android 8 Chrome 86. + // Ensuring the div is display: block + // gets around this issue. + trChild.style.display = "block"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + + parseInt( trStyle.borderTopWidth, 10 ) + + parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml, parserErrorElem; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) {} + + parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; + if ( !xml || parserErrorElem ) { + jQuery.error( "Invalid XML: " + ( + parserErrorElem ? + jQuery.map( parserErrorElem.childNodes, function( el ) { + return el.textContent; + } ).join( "\n" ) : + data + ) ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ).filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ).map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + +originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script but not if jsonp + if ( !isSuccess && + jQuery.inArray( "script", s.dataTypes ) > -1 && + jQuery.inArray( "json", s.dataTypes ) < 0 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + diff --git a/_static/underscore-1.13.1.js b/_static/underscore-1.13.1.js new file mode 100644 index 00000000..ffd77af9 --- /dev/null +++ b/_static/underscore-1.13.1.js @@ -0,0 +1,2042 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define('underscore', factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, (function () { + var current = global._; + var exports = global._ = factory(); + exports.noConflict = function () { global._ = current; return exports; }; + }())); +}(this, (function () { + // Underscore.js 1.13.1 + // https://underscorejs.org + // (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors + // Underscore may be freely distributed under the MIT license. + + // Current version. + var VERSION = '1.13.1'; + + // Establish the root object, `window` (`self`) in the browser, `global` + // on the server, or `this` in some virtual machines. We use `self` + // instead of `window` for `WebWorker` support. + var root = typeof self == 'object' && self.self === self && self || + typeof global == 'object' && global.global === global && global || + Function('return this')() || + {}; + + // Save bytes in the minified (but not gzipped) version: + var ArrayProto = Array.prototype, ObjProto = Object.prototype; + var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null; + + // Create quick reference variables for speed access to core prototypes. + var push = ArrayProto.push, + slice = ArrayProto.slice, + toString = ObjProto.toString, + hasOwnProperty = ObjProto.hasOwnProperty; + + // Modern feature detection. + var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined', + supportsDataView = typeof DataView !== 'undefined'; + + // All **ECMAScript 5+** native function implementations that we hope to use + // are declared here. + var nativeIsArray = Array.isArray, + nativeKeys = Object.keys, + nativeCreate = Object.create, + nativeIsView = supportsArrayBuffer && ArrayBuffer.isView; + + // Create references to these builtin functions because we override them. + var _isNaN = isNaN, + _isFinite = isFinite; + + // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. + var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); + var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', + 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; + + // The largest integer that can be represented exactly. + var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; + + // Some functions take a variable number of arguments, or a few expected + // arguments at the beginning and then a variable number of values to operate + // on. This helper accumulates all remaining arguments past the function’s + // argument length (or an explicit `startIndex`), into an array that becomes + // the last argument. Similar to ES6’s "rest parameter". + function restArguments(func, startIndex) { + startIndex = startIndex == null ? func.length - 1 : +startIndex; + return function() { + var length = Math.max(arguments.length - startIndex, 0), + rest = Array(length), + index = 0; + for (; index < length; index++) { + rest[index] = arguments[index + startIndex]; + } + switch (startIndex) { + case 0: return func.call(this, rest); + case 1: return func.call(this, arguments[0], rest); + case 2: return func.call(this, arguments[0], arguments[1], rest); + } + var args = Array(startIndex + 1); + for (index = 0; index < startIndex; index++) { + args[index] = arguments[index]; + } + args[startIndex] = rest; + return func.apply(this, args); + }; + } + + // Is a given variable an object? + function isObject(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + } + + // Is a given value equal to null? + function isNull(obj) { + return obj === null; + } + + // Is a given variable undefined? + function isUndefined(obj) { + return obj === void 0; + } + + // Is a given value a boolean? + function isBoolean(obj) { + return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; + } + + // Is a given value a DOM element? + function isElement(obj) { + return !!(obj && obj.nodeType === 1); + } + + // Internal function for creating a `toString`-based type tester. + function tagTester(name) { + var tag = '[object ' + name + ']'; + return function(obj) { + return toString.call(obj) === tag; + }; + } + + var isString = tagTester('String'); + + var isNumber = tagTester('Number'); + + var isDate = tagTester('Date'); + + var isRegExp = tagTester('RegExp'); + + var isError = tagTester('Error'); + + var isSymbol = tagTester('Symbol'); + + var isArrayBuffer = tagTester('ArrayBuffer'); + + var isFunction = tagTester('Function'); + + // Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old + // v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236). + var nodelist = root.document && root.document.childNodes; + if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') { + isFunction = function(obj) { + return typeof obj == 'function' || false; + }; + } + + var isFunction$1 = isFunction; + + var hasObjectTag = tagTester('Object'); + + // In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`. + // In IE 11, the most common among them, this problem also applies to + // `Map`, `WeakMap` and `Set`. + var hasStringTagBug = ( + supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8))) + ), + isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map)); + + var isDataView = tagTester('DataView'); + + // In IE 10 - Edge 13, we need a different heuristic + // to determine whether an object is a `DataView`. + function ie10IsDataView(obj) { + return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer); + } + + var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView); + + // Is a given value an array? + // Delegates to ECMA5's native `Array.isArray`. + var isArray = nativeIsArray || tagTester('Array'); + + // Internal function to check whether `key` is an own property name of `obj`. + function has$1(obj, key) { + return obj != null && hasOwnProperty.call(obj, key); + } + + var isArguments = tagTester('Arguments'); + + // Define a fallback version of the method in browsers (ahem, IE < 9), where + // there isn't any inspectable "Arguments" type. + (function() { + if (!isArguments(arguments)) { + isArguments = function(obj) { + return has$1(obj, 'callee'); + }; + } + }()); + + var isArguments$1 = isArguments; + + // Is a given object a finite number? + function isFinite$1(obj) { + return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj)); + } + + // Is the given value `NaN`? + function isNaN$1(obj) { + return isNumber(obj) && _isNaN(obj); + } + + // Predicate-generating function. Often useful outside of Underscore. + function constant(value) { + return function() { + return value; + }; + } + + // Common internal logic for `isArrayLike` and `isBufferLike`. + function createSizePropertyCheck(getSizeProperty) { + return function(collection) { + var sizeProperty = getSizeProperty(collection); + return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX; + } + } + + // Internal helper to generate a function to obtain property `key` from `obj`. + function shallowProperty(key) { + return function(obj) { + return obj == null ? void 0 : obj[key]; + }; + } + + // Internal helper to obtain the `byteLength` property of an object. + var getByteLength = shallowProperty('byteLength'); + + // Internal helper to determine whether we should spend extensive checks against + // `ArrayBuffer` et al. + var isBufferLike = createSizePropertyCheck(getByteLength); + + // Is a given value a typed array? + var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/; + function isTypedArray(obj) { + // `ArrayBuffer.isView` is the most future-proof, so use it when available. + // Otherwise, fall back on the above regular expression. + return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) : + isBufferLike(obj) && typedArrayPattern.test(toString.call(obj)); + } + + var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false); + + // Internal helper to obtain the `length` property of an object. + var getLength = shallowProperty('length'); + + // Internal helper to create a simple lookup structure. + // `collectNonEnumProps` used to depend on `_.contains`, but this led to + // circular imports. `emulatedSet` is a one-off solution that only works for + // arrays of strings. + function emulatedSet(keys) { + var hash = {}; + for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true; + return { + contains: function(key) { return hash[key]; }, + push: function(key) { + hash[key] = true; + return keys.push(key); + } + }; + } + + // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't + // be iterated by `for key in ...` and thus missed. Extends `keys` in place if + // needed. + function collectNonEnumProps(obj, keys) { + keys = emulatedSet(keys); + var nonEnumIdx = nonEnumerableProps.length; + var constructor = obj.constructor; + var proto = isFunction$1(constructor) && constructor.prototype || ObjProto; + + // Constructor is a special case. + var prop = 'constructor'; + if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop); + + while (nonEnumIdx--) { + prop = nonEnumerableProps[nonEnumIdx]; + if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) { + keys.push(prop); + } + } + } + + // Retrieve the names of an object's own properties. + // Delegates to **ECMAScript 5**'s native `Object.keys`. + function keys(obj) { + if (!isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); + var keys = []; + for (var key in obj) if (has$1(obj, key)) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + } + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + function isEmpty(obj) { + if (obj == null) return true; + // Skip the more expensive `toString`-based type checks if `obj` has no + // `.length`. + var length = getLength(obj); + if (typeof length == 'number' && ( + isArray(obj) || isString(obj) || isArguments$1(obj) + )) return length === 0; + return getLength(keys(obj)) === 0; + } + + // Returns whether an object has a given set of `key:value` pairs. + function isMatch(object, attrs) { + var _keys = keys(attrs), length = _keys.length; + if (object == null) return !length; + var obj = Object(object); + for (var i = 0; i < length; i++) { + var key = _keys[i]; + if (attrs[key] !== obj[key] || !(key in obj)) return false; + } + return true; + } + + // If Underscore is called as a function, it returns a wrapped object that can + // be used OO-style. This wrapper holds altered versions of all functions added + // through `_.mixin`. Wrapped objects may be chained. + function _$1(obj) { + if (obj instanceof _$1) return obj; + if (!(this instanceof _$1)) return new _$1(obj); + this._wrapped = obj; + } + + _$1.VERSION = VERSION; + + // Extracts the result from a wrapped and chained object. + _$1.prototype.value = function() { + return this._wrapped; + }; + + // Provide unwrapping proxies for some methods used in engine operations + // such as arithmetic and JSON stringification. + _$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value; + + _$1.prototype.toString = function() { + return String(this._wrapped); + }; + + // Internal function to wrap or shallow-copy an ArrayBuffer, + // typed array or DataView to a new view, reusing the buffer. + function toBufferView(bufferSource) { + return new Uint8Array( + bufferSource.buffer || bufferSource, + bufferSource.byteOffset || 0, + getByteLength(bufferSource) + ); + } + + // We use this string twice, so give it a name for minification. + var tagDataView = '[object DataView]'; + + // Internal recursive comparison function for `_.isEqual`. + function eq(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // `null` or `undefined` only equal to itself (strict comparison). + if (a == null || b == null) return false; + // `NaN`s are equivalent, but non-reflexive. + if (a !== a) return b !== b; + // Exhaust primitive checks + var type = typeof a; + if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; + return deepEq(a, b, aStack, bStack); + } + + // Internal recursive comparison function for `_.isEqual`. + function deepEq(a, b, aStack, bStack) { + // Unwrap any wrapped objects. + if (a instanceof _$1) a = a._wrapped; + if (b instanceof _$1) b = b._wrapped; + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + // Work around a bug in IE 10 - Edge 13. + if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) { + if (!isDataView$1(b)) return false; + className = tagDataView; + } + switch (className) { + // These types are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN. + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + case '[object Symbol]': + return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); + case '[object ArrayBuffer]': + case tagDataView: + // Coerce to typed array so we can fall through. + return deepEq(toBufferView(a), toBufferView(b), aStack, bStack); + } + + var areArrays = className === '[object Array]'; + if (!areArrays && isTypedArray$1(a)) { + var byteLength = getByteLength(a); + if (byteLength !== getByteLength(b)) return false; + if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true; + areArrays = true; + } + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, bCtor = b.constructor; + if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor && + isFunction$1(bCtor) && bCtor instanceof bCtor) + && ('constructor' in a && 'constructor' in b)) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var _keys = keys(a), key; + length = _keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = _keys[length]; + if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; + } + + // Perform a deep comparison to check if two objects are equal. + function isEqual(a, b) { + return eq(a, b); + } + + // Retrieve all the enumerable property names of an object. + function allKeys(obj) { + if (!isObject(obj)) return []; + var keys = []; + for (var key in obj) keys.push(key); + // Ahem, IE < 9. + if (hasEnumBug) collectNonEnumProps(obj, keys); + return keys; + } + + // Since the regular `Object.prototype.toString` type tests don't work for + // some types in IE 11, we use a fingerprinting heuristic instead, based + // on the methods. It's not great, but it's the best we got. + // The fingerprint method lists are defined below. + function ie11fingerprint(methods) { + var length = getLength(methods); + return function(obj) { + if (obj == null) return false; + // `Map`, `WeakMap` and `Set` have no enumerable keys. + var keys = allKeys(obj); + if (getLength(keys)) return false; + for (var i = 0; i < length; i++) { + if (!isFunction$1(obj[methods[i]])) return false; + } + // If we are testing against `WeakMap`, we need to ensure that + // `obj` doesn't have a `forEach` method in order to distinguish + // it from a regular `Map`. + return methods !== weakMapMethods || !isFunction$1(obj[forEachName]); + }; + } + + // In the interest of compact minification, we write + // each string in the fingerprints only once. + var forEachName = 'forEach', + hasName = 'has', + commonInit = ['clear', 'delete'], + mapTail = ['get', hasName, 'set']; + + // `Map`, `WeakMap` and `Set` each have slightly different + // combinations of the above sublists. + var mapMethods = commonInit.concat(forEachName, mapTail), + weakMapMethods = commonInit.concat(mapTail), + setMethods = ['add'].concat(commonInit, forEachName, hasName); + + var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map'); + + var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap'); + + var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set'); + + var isWeakSet = tagTester('WeakSet'); + + // Retrieve the values of an object's properties. + function values(obj) { + var _keys = keys(obj); + var length = _keys.length; + var values = Array(length); + for (var i = 0; i < length; i++) { + values[i] = obj[_keys[i]]; + } + return values; + } + + // Convert an object into a list of `[key, value]` pairs. + // The opposite of `_.object` with one argument. + function pairs(obj) { + var _keys = keys(obj); + var length = _keys.length; + var pairs = Array(length); + for (var i = 0; i < length; i++) { + pairs[i] = [_keys[i], obj[_keys[i]]]; + } + return pairs; + } + + // Invert the keys and values of an object. The values must be serializable. + function invert(obj) { + var result = {}; + var _keys = keys(obj); + for (var i = 0, length = _keys.length; i < length; i++) { + result[obj[_keys[i]]] = _keys[i]; + } + return result; + } + + // Return a sorted list of the function names available on the object. + function functions(obj) { + var names = []; + for (var key in obj) { + if (isFunction$1(obj[key])) names.push(key); + } + return names.sort(); + } + + // An internal function for creating assigner functions. + function createAssigner(keysFunc, defaults) { + return function(obj) { + var length = arguments.length; + if (defaults) obj = Object(obj); + if (length < 2 || obj == null) return obj; + for (var index = 1; index < length; index++) { + var source = arguments[index], + keys = keysFunc(source), + l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (!defaults || obj[key] === void 0) obj[key] = source[key]; + } + } + return obj; + }; + } + + // Extend a given object with all the properties in passed-in object(s). + var extend = createAssigner(allKeys); + + // Assigns a given object with all the own properties in the passed-in + // object(s). + // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) + var extendOwn = createAssigner(keys); + + // Fill in a given object with default properties. + var defaults = createAssigner(allKeys, true); + + // Create a naked function reference for surrogate-prototype-swapping. + function ctor() { + return function(){}; + } + + // An internal function for creating a new object that inherits from another. + function baseCreate(prototype) { + if (!isObject(prototype)) return {}; + if (nativeCreate) return nativeCreate(prototype); + var Ctor = ctor(); + Ctor.prototype = prototype; + var result = new Ctor; + Ctor.prototype = null; + return result; + } + + // Creates an object that inherits from the given prototype object. + // If additional properties are provided then they will be added to the + // created object. + function create(prototype, props) { + var result = baseCreate(prototype); + if (props) extendOwn(result, props); + return result; + } + + // Create a (shallow-cloned) duplicate of an object. + function clone(obj) { + if (!isObject(obj)) return obj; + return isArray(obj) ? obj.slice() : extend({}, obj); + } + + // Invokes `interceptor` with the `obj` and then returns `obj`. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + function tap(obj, interceptor) { + interceptor(obj); + return obj; + } + + // Normalize a (deep) property `path` to array. + // Like `_.iteratee`, this function can be customized. + function toPath$1(path) { + return isArray(path) ? path : [path]; + } + _$1.toPath = toPath$1; + + // Internal wrapper for `_.toPath` to enable minification. + // Similar to `cb` for `_.iteratee`. + function toPath(path) { + return _$1.toPath(path); + } + + // Internal function to obtain a nested property in `obj` along `path`. + function deepGet(obj, path) { + var length = path.length; + for (var i = 0; i < length; i++) { + if (obj == null) return void 0; + obj = obj[path[i]]; + } + return length ? obj : void 0; + } + + // Get the value of the (deep) property on `path` from `object`. + // If any property in `path` does not exist or if the value is + // `undefined`, return `defaultValue` instead. + // The `path` is normalized through `_.toPath`. + function get(object, path, defaultValue) { + var value = deepGet(object, toPath(path)); + return isUndefined(value) ? defaultValue : value; + } + + // Shortcut function for checking if an object has a given property directly on + // itself (in other words, not on a prototype). Unlike the internal `has` + // function, this public version can also traverse nested properties. + function has(obj, path) { + path = toPath(path); + var length = path.length; + for (var i = 0; i < length; i++) { + var key = path[i]; + if (!has$1(obj, key)) return false; + obj = obj[key]; + } + return !!length; + } + + // Keep the identity function around for default iteratees. + function identity(value) { + return value; + } + + // Returns a predicate for checking whether an object has a given set of + // `key:value` pairs. + function matcher(attrs) { + attrs = extendOwn({}, attrs); + return function(obj) { + return isMatch(obj, attrs); + }; + } + + // Creates a function that, when passed an object, will traverse that object’s + // properties down the given `path`, specified as an array of keys or indices. + function property(path) { + path = toPath(path); + return function(obj) { + return deepGet(obj, path); + }; + } + + // Internal function that returns an efficient (for current engines) version + // of the passed-in callback, to be repeatedly applied in other Underscore + // functions. + function optimizeCb(func, context, argCount) { + if (context === void 0) return func; + switch (argCount == null ? 3 : argCount) { + case 1: return function(value) { + return func.call(context, value); + }; + // The 2-argument case is omitted because we’re not using it. + case 3: return function(value, index, collection) { + return func.call(context, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(context, accumulator, value, index, collection); + }; + } + return function() { + return func.apply(context, arguments); + }; + } + + // An internal function to generate callbacks that can be applied to each + // element in a collection, returning the desired result — either `_.identity`, + // an arbitrary callback, a property matcher, or a property accessor. + function baseIteratee(value, context, argCount) { + if (value == null) return identity; + if (isFunction$1(value)) return optimizeCb(value, context, argCount); + if (isObject(value) && !isArray(value)) return matcher(value); + return property(value); + } + + // External wrapper for our callback generator. Users may customize + // `_.iteratee` if they want additional predicate/iteratee shorthand styles. + // This abstraction hides the internal-only `argCount` argument. + function iteratee(value, context) { + return baseIteratee(value, context, Infinity); + } + _$1.iteratee = iteratee; + + // The function we call internally to generate a callback. It invokes + // `_.iteratee` if overridden, otherwise `baseIteratee`. + function cb(value, context, argCount) { + if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context); + return baseIteratee(value, context, argCount); + } + + // Returns the results of applying the `iteratee` to each element of `obj`. + // In contrast to `_.map` it returns an object. + function mapObject(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var _keys = keys(obj), + length = _keys.length, + results = {}; + for (var index = 0; index < length; index++) { + var currentKey = _keys[index]; + results[currentKey] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + } + + // Predicate-generating function. Often useful outside of Underscore. + function noop(){} + + // Generates a function for a given object that returns a given property. + function propertyOf(obj) { + if (obj == null) return noop; + return function(path) { + return get(obj, path); + }; + } + + // Run a function **n** times. + function times(n, iteratee, context) { + var accum = Array(Math.max(0, n)); + iteratee = optimizeCb(iteratee, context, 1); + for (var i = 0; i < n; i++) accum[i] = iteratee(i); + return accum; + } + + // Return a random integer between `min` and `max` (inclusive). + function random(min, max) { + if (max == null) { + max = min; + min = 0; + } + return min + Math.floor(Math.random() * (max - min + 1)); + } + + // A (possibly faster) way to get the current timestamp as an integer. + var now = Date.now || function() { + return new Date().getTime(); + }; + + // Internal helper to generate functions for escaping and unescaping strings + // to/from HTML interpolation. + function createEscaper(map) { + var escaper = function(match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped. + var source = '(?:' + keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function(string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + } + + // Internal list of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + + // Function for escaping strings to HTML interpolation. + var _escape = createEscaper(escapeMap); + + // Internal list of HTML entities for unescaping. + var unescapeMap = invert(escapeMap); + + // Function for unescaping strings from HTML interpolation. + var _unescape = createEscaper(unescapeMap); + + // By default, Underscore uses ERB-style template delimiters. Change the + // following template settings to use alternative delimiters. + var templateSettings = _$1.templateSettings = { + evaluate: /<%([\s\S]+?)%>/g, + interpolate: /<%=([\s\S]+?)%>/g, + escape: /<%-([\s\S]+?)%>/g + }; + + // When customizing `_.templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /(.)^/; + + // Certain characters need to be escaped so that they can be put into a + // string literal. + var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; + + function escapeChar(match) { + return '\\' + escapes[match]; + } + + // In order to prevent third-party code injection through + // `_.templateSettings.variable`, we test it against the following regular + // expression. It is intentionally a bit more liberal than just matching valid + // identifiers, but still prevents possible loopholes through defaults or + // destructuring assignment. + var bareIdentifier = /^\s*(\w|\$)+\s*$/; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + // NB: `oldSettings` only exists for backwards compatibility. + function template(text, settings, oldSettings) { + if (!settings && oldSettings) settings = oldSettings; + settings = defaults({}, settings, _$1.templateSettings); + + // Combine delimiters into one regular expression via alternation. + var matcher = RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + // Compile the template source, escaping string literals appropriately. + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + source += text.slice(index, offset).replace(escapeRegExp, escapeChar); + index = offset + match.length; + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } else if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + // Adobe VMs need the match returned to produce the correct offset. + return match; + }); + source += "';\n"; + + var argument = settings.variable; + if (argument) { + // Insure against third-party code injection. (CVE-2021-23358) + if (!bareIdentifier.test(argument)) throw new Error( + 'variable is not a bare identifier: ' + argument + ); + } else { + // If a variable is not specified, place data values in local scope. + source = 'with(obj||{}){\n' + source + '}\n'; + argument = 'obj'; + } + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + 'return __p;\n'; + + var render; + try { + render = new Function(argument, '_', source); + } catch (e) { + e.source = source; + throw e; + } + + var template = function(data) { + return render.call(this, data, _$1); + }; + + // Provide the compiled source as a convenience for precompilation. + template.source = 'function(' + argument + '){\n' + source + '}'; + + return template; + } + + // Traverses the children of `obj` along `path`. If a child is a function, it + // is invoked with its parent as context. Returns the value of the final + // child, or `fallback` if any child is undefined. + function result(obj, path, fallback) { + path = toPath(path); + var length = path.length; + if (!length) { + return isFunction$1(fallback) ? fallback.call(obj) : fallback; + } + for (var i = 0; i < length; i++) { + var prop = obj == null ? void 0 : obj[path[i]]; + if (prop === void 0) { + prop = fallback; + i = length; // Ensure we don't continue iterating. + } + obj = isFunction$1(prop) ? prop.call(obj) : prop; + } + return obj; + } + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + function uniqueId(prefix) { + var id = ++idCounter + ''; + return prefix ? prefix + id : id; + } + + // Start chaining a wrapped Underscore object. + function chain(obj) { + var instance = _$1(obj); + instance._chain = true; + return instance; + } + + // Internal function to execute `sourceFunc` bound to `context` with optional + // `args`. Determines whether to execute a function as a constructor or as a + // normal function. + function executeBound(sourceFunc, boundFunc, context, callingContext, args) { + if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); + var self = baseCreate(sourceFunc.prototype); + var result = sourceFunc.apply(self, args); + if (isObject(result)) return result; + return self; + } + + // Partially apply a function by creating a version that has had some of its + // arguments pre-filled, without changing its dynamic `this` context. `_` acts + // as a placeholder by default, allowing any combination of arguments to be + // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument. + var partial = restArguments(function(func, boundArgs) { + var placeholder = partial.placeholder; + var bound = function() { + var position = 0, length = boundArgs.length; + var args = Array(length); + for (var i = 0; i < length; i++) { + args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i]; + } + while (position < arguments.length) args.push(arguments[position++]); + return executeBound(func, bound, this, this, args); + }; + return bound; + }); + + partial.placeholder = _$1; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). + var bind = restArguments(function(func, context, args) { + if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function'); + var bound = restArguments(function(callArgs) { + return executeBound(func, bound, context, this, args.concat(callArgs)); + }); + return bound; + }); + + // Internal helper for collection methods to determine whether a collection + // should be iterated as an array or as an object. + // Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength + // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 + var isArrayLike = createSizePropertyCheck(getLength); + + // Internal implementation of a recursive `flatten` function. + function flatten$1(input, depth, strict, output) { + output = output || []; + if (!depth && depth !== 0) { + depth = Infinity; + } else if (depth <= 0) { + return output.concat(input); + } + var idx = output.length; + for (var i = 0, length = getLength(input); i < length; i++) { + var value = input[i]; + if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) { + // Flatten current level of array or arguments object. + if (depth > 1) { + flatten$1(value, depth - 1, strict, output); + idx = output.length; + } else { + var j = 0, len = value.length; + while (j < len) output[idx++] = value[j++]; + } + } else if (!strict) { + output[idx++] = value; + } + } + return output; + } + + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. + var bindAll = restArguments(function(obj, keys) { + keys = flatten$1(keys, false, false); + var index = keys.length; + if (index < 1) throw new Error('bindAll must be passed function names'); + while (index--) { + var key = keys[index]; + obj[key] = bind(obj[key], obj); + } + return obj; + }); + + // Memoize an expensive function by storing its results. + function memoize(func, hasher) { + var memoize = function(key) { + var cache = memoize.cache; + var address = '' + (hasher ? hasher.apply(this, arguments) : key); + if (!has$1(cache, address)) cache[address] = func.apply(this, arguments); + return cache[address]; + }; + memoize.cache = {}; + return memoize; + } + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + var delay = restArguments(function(func, wait, args) { + return setTimeout(function() { + return func.apply(null, args); + }, wait); + }); + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + var defer = partial(delay, _$1, 1); + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. Normally, the throttled function will run + // as much as it can, without ever going more than once per `wait` duration; + // but if you'd like to disable the execution on the leading edge, pass + // `{leading: false}`. To disable execution on the trailing edge, ditto. + function throttle(func, wait, options) { + var timeout, context, args, result; + var previous = 0; + if (!options) options = {}; + + var later = function() { + previous = options.leading === false ? 0 : now(); + timeout = null; + result = func.apply(context, args); + if (!timeout) context = args = null; + }; + + var throttled = function() { + var _now = now(); + if (!previous && options.leading === false) previous = _now; + var remaining = wait - (_now - previous); + context = this; + args = arguments; + if (remaining <= 0 || remaining > wait) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + previous = _now; + result = func.apply(context, args); + if (!timeout) context = args = null; + } else if (!timeout && options.trailing !== false) { + timeout = setTimeout(later, remaining); + } + return result; + }; + + throttled.cancel = function() { + clearTimeout(timeout); + previous = 0; + timeout = context = args = null; + }; + + return throttled; + } + + // When a sequence of calls of the returned function ends, the argument + // function is triggered. The end of a sequence is defined by the `wait` + // parameter. If `immediate` is passed, the argument function will be + // triggered at the beginning of the sequence instead of at the end. + function debounce(func, wait, immediate) { + var timeout, previous, args, result, context; + + var later = function() { + var passed = now() - previous; + if (wait > passed) { + timeout = setTimeout(later, wait - passed); + } else { + timeout = null; + if (!immediate) result = func.apply(context, args); + // This check is needed because `func` can recursively invoke `debounced`. + if (!timeout) args = context = null; + } + }; + + var debounced = restArguments(function(_args) { + context = this; + args = _args; + previous = now(); + if (!timeout) { + timeout = setTimeout(later, wait); + if (immediate) result = func.apply(context, args); + } + return result; + }); + + debounced.cancel = function() { + clearTimeout(timeout); + timeout = args = context = null; + }; + + return debounced; + } + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + function wrap(func, wrapper) { + return partial(wrapper, func); + } + + // Returns a negated version of the passed-in predicate. + function negate(predicate) { + return function() { + return !predicate.apply(this, arguments); + }; + } + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + function compose() { + var args = arguments; + var start = args.length - 1; + return function() { + var i = start; + var result = args[start].apply(this, arguments); + while (i--) result = args[i].call(this, result); + return result; + }; + } + + // Returns a function that will only be executed on and after the Nth call. + function after(times, func) { + return function() { + if (--times < 1) { + return func.apply(this, arguments); + } + }; + } + + // Returns a function that will only be executed up to (but not including) the + // Nth call. + function before(times, func) { + var memo; + return function() { + if (--times > 0) { + memo = func.apply(this, arguments); + } + if (times <= 1) func = null; + return memo; + }; + } + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + var once = partial(before, 2); + + // Returns the first key on an object that passes a truth test. + function findKey(obj, predicate, context) { + predicate = cb(predicate, context); + var _keys = keys(obj), key; + for (var i = 0, length = _keys.length; i < length; i++) { + key = _keys[i]; + if (predicate(obj[key], key, obj)) return key; + } + } + + // Internal function to generate `_.findIndex` and `_.findLastIndex`. + function createPredicateIndexFinder(dir) { + return function(array, predicate, context) { + predicate = cb(predicate, context); + var length = getLength(array); + var index = dir > 0 ? 0 : length - 1; + for (; index >= 0 && index < length; index += dir) { + if (predicate(array[index], index, array)) return index; + } + return -1; + }; + } + + // Returns the first index on an array-like that passes a truth test. + var findIndex = createPredicateIndexFinder(1); + + // Returns the last index on an array-like that passes a truth test. + var findLastIndex = createPredicateIndexFinder(-1); + + // Use a comparator function to figure out the smallest index at which + // an object should be inserted so as to maintain order. Uses binary search. + function sortedIndex(array, obj, iteratee, context) { + iteratee = cb(iteratee, context, 1); + var value = iteratee(obj); + var low = 0, high = getLength(array); + while (low < high) { + var mid = Math.floor((low + high) / 2); + if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; + } + return low; + } + + // Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions. + function createIndexFinder(dir, predicateFind, sortedIndex) { + return function(array, item, idx) { + var i = 0, length = getLength(array); + if (typeof idx == 'number') { + if (dir > 0) { + i = idx >= 0 ? idx : Math.max(idx + length, i); + } else { + length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; + } + } else if (sortedIndex && idx && length) { + idx = sortedIndex(array, item); + return array[idx] === item ? idx : -1; + } + if (item !== item) { + idx = predicateFind(slice.call(array, i, length), isNaN$1); + return idx >= 0 ? idx + i : -1; + } + for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { + if (array[idx] === item) return idx; + } + return -1; + }; + } + + // Return the position of the first occurrence of an item in an array, + // or -1 if the item is not included in the array. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + var indexOf = createIndexFinder(1, findIndex, sortedIndex); + + // Return the position of the last occurrence of an item in an array, + // or -1 if the item is not included in the array. + var lastIndexOf = createIndexFinder(-1, findLastIndex); + + // Return the first value which passes a truth test. + function find(obj, predicate, context) { + var keyFinder = isArrayLike(obj) ? findIndex : findKey; + var key = keyFinder(obj, predicate, context); + if (key !== void 0 && key !== -1) return obj[key]; + } + + // Convenience version of a common use case of `_.find`: getting the first + // object containing specific `key:value` pairs. + function findWhere(obj, attrs) { + return find(obj, matcher(attrs)); + } + + // The cornerstone for collection functions, an `each` + // implementation, aka `forEach`. + // Handles raw objects in addition to array-likes. Treats all + // sparse array-likes as if they were dense. + function each(obj, iteratee, context) { + iteratee = optimizeCb(iteratee, context); + var i, length; + if (isArrayLike(obj)) { + for (i = 0, length = obj.length; i < length; i++) { + iteratee(obj[i], i, obj); + } + } else { + var _keys = keys(obj); + for (i = 0, length = _keys.length; i < length; i++) { + iteratee(obj[_keys[i]], _keys[i], obj); + } + } + return obj; + } + + // Return the results of applying the iteratee to each element. + function map(obj, iteratee, context) { + iteratee = cb(iteratee, context); + var _keys = !isArrayLike(obj) && keys(obj), + length = (_keys || obj).length, + results = Array(length); + for (var index = 0; index < length; index++) { + var currentKey = _keys ? _keys[index] : index; + results[index] = iteratee(obj[currentKey], currentKey, obj); + } + return results; + } + + // Internal helper to create a reducing function, iterating left or right. + function createReduce(dir) { + // Wrap code that reassigns argument variables in a separate function than + // the one that accesses `arguments.length` to avoid a perf hit. (#1991) + var reducer = function(obj, iteratee, memo, initial) { + var _keys = !isArrayLike(obj) && keys(obj), + length = (_keys || obj).length, + index = dir > 0 ? 0 : length - 1; + if (!initial) { + memo = obj[_keys ? _keys[index] : index]; + index += dir; + } + for (; index >= 0 && index < length; index += dir) { + var currentKey = _keys ? _keys[index] : index; + memo = iteratee(memo, obj[currentKey], currentKey, obj); + } + return memo; + }; + + return function(obj, iteratee, memo, context) { + var initial = arguments.length >= 3; + return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial); + }; + } + + // **Reduce** builds up a single result from a list of values, aka `inject`, + // or `foldl`. + var reduce = createReduce(1); + + // The right-associative version of reduce, also known as `foldr`. + var reduceRight = createReduce(-1); + + // Return all the elements that pass a truth test. + function filter(obj, predicate, context) { + var results = []; + predicate = cb(predicate, context); + each(obj, function(value, index, list) { + if (predicate(value, index, list)) results.push(value); + }); + return results; + } + + // Return all the elements for which a truth test fails. + function reject(obj, predicate, context) { + return filter(obj, negate(cb(predicate)), context); + } + + // Determine whether all of the elements pass a truth test. + function every(obj, predicate, context) { + predicate = cb(predicate, context); + var _keys = !isArrayLike(obj) && keys(obj), + length = (_keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = _keys ? _keys[index] : index; + if (!predicate(obj[currentKey], currentKey, obj)) return false; + } + return true; + } + + // Determine if at least one element in the object passes a truth test. + function some(obj, predicate, context) { + predicate = cb(predicate, context); + var _keys = !isArrayLike(obj) && keys(obj), + length = (_keys || obj).length; + for (var index = 0; index < length; index++) { + var currentKey = _keys ? _keys[index] : index; + if (predicate(obj[currentKey], currentKey, obj)) return true; + } + return false; + } + + // Determine if the array or object contains a given item (using `===`). + function contains(obj, item, fromIndex, guard) { + if (!isArrayLike(obj)) obj = values(obj); + if (typeof fromIndex != 'number' || guard) fromIndex = 0; + return indexOf(obj, item, fromIndex) >= 0; + } + + // Invoke a method (with arguments) on every item in a collection. + var invoke = restArguments(function(obj, path, args) { + var contextPath, func; + if (isFunction$1(path)) { + func = path; + } else { + path = toPath(path); + contextPath = path.slice(0, -1); + path = path[path.length - 1]; + } + return map(obj, function(context) { + var method = func; + if (!method) { + if (contextPath && contextPath.length) { + context = deepGet(context, contextPath); + } + if (context == null) return void 0; + method = context[path]; + } + return method == null ? method : method.apply(context, args); + }); + }); + + // Convenience version of a common use case of `_.map`: fetching a property. + function pluck(obj, key) { + return map(obj, property(key)); + } + + // Convenience version of a common use case of `_.filter`: selecting only + // objects containing specific `key:value` pairs. + function where(obj, attrs) { + return filter(obj, matcher(attrs)); + } + + // Return the maximum element (or element-based computation). + function max(obj, iteratee, context) { + var result = -Infinity, lastComputed = -Infinity, + value, computed; + if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) { + obj = isArrayLike(obj) ? obj : values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value != null && value > result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + each(obj, function(v, index, list) { + computed = iteratee(v, index, list); + if (computed > lastComputed || computed === -Infinity && result === -Infinity) { + result = v; + lastComputed = computed; + } + }); + } + return result; + } + + // Return the minimum element (or element-based computation). + function min(obj, iteratee, context) { + var result = Infinity, lastComputed = Infinity, + value, computed; + if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) { + obj = isArrayLike(obj) ? obj : values(obj); + for (var i = 0, length = obj.length; i < length; i++) { + value = obj[i]; + if (value != null && value < result) { + result = value; + } + } + } else { + iteratee = cb(iteratee, context); + each(obj, function(v, index, list) { + computed = iteratee(v, index, list); + if (computed < lastComputed || computed === Infinity && result === Infinity) { + result = v; + lastComputed = computed; + } + }); + } + return result; + } + + // Sample **n** random values from a collection using the modern version of the + // [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle). + // If **n** is not specified, returns a single random element. + // The internal `guard` argument allows it to work with `_.map`. + function sample(obj, n, guard) { + if (n == null || guard) { + if (!isArrayLike(obj)) obj = values(obj); + return obj[random(obj.length - 1)]; + } + var sample = isArrayLike(obj) ? clone(obj) : values(obj); + var length = getLength(sample); + n = Math.max(Math.min(n, length), 0); + var last = length - 1; + for (var index = 0; index < n; index++) { + var rand = random(index, last); + var temp = sample[index]; + sample[index] = sample[rand]; + sample[rand] = temp; + } + return sample.slice(0, n); + } + + // Shuffle a collection. + function shuffle(obj) { + return sample(obj, Infinity); + } + + // Sort the object's values by a criterion produced by an iteratee. + function sortBy(obj, iteratee, context) { + var index = 0; + iteratee = cb(iteratee, context); + return pluck(map(obj, function(value, key, list) { + return { + value: value, + index: index++, + criteria: iteratee(value, key, list) + }; + }).sort(function(left, right) { + var a = left.criteria; + var b = right.criteria; + if (a !== b) { + if (a > b || a === void 0) return 1; + if (a < b || b === void 0) return -1; + } + return left.index - right.index; + }), 'value'); + } + + // An internal function used for aggregate "group by" operations. + function group(behavior, partition) { + return function(obj, iteratee, context) { + var result = partition ? [[], []] : {}; + iteratee = cb(iteratee, context); + each(obj, function(value, index) { + var key = iteratee(value, index, obj); + behavior(result, value, key); + }); + return result; + }; + } + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + var groupBy = group(function(result, value, key) { + if (has$1(result, key)) result[key].push(value); else result[key] = [value]; + }); + + // Indexes the object's values by a criterion, similar to `_.groupBy`, but for + // when you know that your index values will be unique. + var indexBy = group(function(result, value, key) { + result[key] = value; + }); + + // Counts instances of an object that group by a certain criterion. Pass + // either a string attribute to count by, or a function that returns the + // criterion. + var countBy = group(function(result, value, key) { + if (has$1(result, key)) result[key]++; else result[key] = 1; + }); + + // Split a collection into two arrays: one whose elements all pass the given + // truth test, and one whose elements all do not pass the truth test. + var partition = group(function(result, value, pass) { + result[pass ? 0 : 1].push(value); + }, true); + + // Safely create a real, live array from anything iterable. + var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; + function toArray(obj) { + if (!obj) return []; + if (isArray(obj)) return slice.call(obj); + if (isString(obj)) { + // Keep surrogate pair characters together. + return obj.match(reStrSymbol); + } + if (isArrayLike(obj)) return map(obj, identity); + return values(obj); + } + + // Return the number of elements in a collection. + function size(obj) { + if (obj == null) return 0; + return isArrayLike(obj) ? obj.length : keys(obj).length; + } + + // Internal `_.pick` helper function to determine whether `key` is an enumerable + // property name of `obj`. + function keyInObj(value, key, obj) { + return key in obj; + } + + // Return a copy of the object only containing the allowed properties. + var pick = restArguments(function(obj, keys) { + var result = {}, iteratee = keys[0]; + if (obj == null) return result; + if (isFunction$1(iteratee)) { + if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]); + keys = allKeys(obj); + } else { + iteratee = keyInObj; + keys = flatten$1(keys, false, false); + obj = Object(obj); + } + for (var i = 0, length = keys.length; i < length; i++) { + var key = keys[i]; + var value = obj[key]; + if (iteratee(value, key, obj)) result[key] = value; + } + return result; + }); + + // Return a copy of the object without the disallowed properties. + var omit = restArguments(function(obj, keys) { + var iteratee = keys[0], context; + if (isFunction$1(iteratee)) { + iteratee = negate(iteratee); + if (keys.length > 1) context = keys[1]; + } else { + keys = map(flatten$1(keys, false, false), String); + iteratee = function(value, key) { + return !contains(keys, key); + }; + } + return pick(obj, iteratee, context); + }); + + // Returns everything but the last entry of the array. Especially useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. + function initial(array, n, guard) { + return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); + } + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. The **guard** check allows it to work with `_.map`. + function first(array, n, guard) { + if (array == null || array.length < 1) return n == null || guard ? void 0 : []; + if (n == null || guard) return array[0]; + return initial(array, array.length - n); + } + + // Returns everything but the first entry of the `array`. Especially useful on + // the `arguments` object. Passing an **n** will return the rest N values in the + // `array`. + function rest(array, n, guard) { + return slice.call(array, n == null || guard ? 1 : n); + } + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. + function last(array, n, guard) { + if (array == null || array.length < 1) return n == null || guard ? void 0 : []; + if (n == null || guard) return array[array.length - 1]; + return rest(array, Math.max(0, array.length - n)); + } + + // Trim out all falsy values from an array. + function compact(array) { + return filter(array, Boolean); + } + + // Flatten out an array, either recursively (by default), or up to `depth`. + // Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively. + function flatten(array, depth) { + return flatten$1(array, depth, false); + } + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + var difference = restArguments(function(array, rest) { + rest = flatten$1(rest, true, true); + return filter(array, function(value){ + return !contains(rest, value); + }); + }); + + // Return a version of the array that does not contain the specified value(s). + var without = restArguments(function(array, otherArrays) { + return difference(array, otherArrays); + }); + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // The faster algorithm will not work with an iteratee if the iteratee + // is not a one-to-one function, so providing an iteratee will disable + // the faster algorithm. + function uniq(array, isSorted, iteratee, context) { + if (!isBoolean(isSorted)) { + context = iteratee; + iteratee = isSorted; + isSorted = false; + } + if (iteratee != null) iteratee = cb(iteratee, context); + var result = []; + var seen = []; + for (var i = 0, length = getLength(array); i < length; i++) { + var value = array[i], + computed = iteratee ? iteratee(value, i, array) : value; + if (isSorted && !iteratee) { + if (!i || seen !== computed) result.push(value); + seen = computed; + } else if (iteratee) { + if (!contains(seen, computed)) { + seen.push(computed); + result.push(value); + } + } else if (!contains(result, value)) { + result.push(value); + } + } + return result; + } + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + var union = restArguments(function(arrays) { + return uniq(flatten$1(arrays, true, true)); + }); + + // Produce an array that contains every item shared between all the + // passed-in arrays. + function intersection(array) { + var result = []; + var argsLength = arguments.length; + for (var i = 0, length = getLength(array); i < length; i++) { + var item = array[i]; + if (contains(result, item)) continue; + var j; + for (j = 1; j < argsLength; j++) { + if (!contains(arguments[j], item)) break; + } + if (j === argsLength) result.push(item); + } + return result; + } + + // Complement of zip. Unzip accepts an array of arrays and groups + // each array's elements on shared indices. + function unzip(array) { + var length = array && max(array, getLength).length || 0; + var result = Array(length); + + for (var index = 0; index < length; index++) { + result[index] = pluck(array, index); + } + return result; + } + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + var zip = restArguments(unzip); + + // Converts lists into objects. Pass either a single array of `[key, value]` + // pairs, or two parallel arrays of the same length -- one of keys, and one of + // the corresponding values. Passing by pairs is the reverse of `_.pairs`. + function object(list, values) { + var result = {}; + for (var i = 0, length = getLength(list); i < length; i++) { + if (values) { + result[list[i]] = values[i]; + } else { + result[list[i][0]] = list[i][1]; + } + } + return result; + } + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](https://docs.python.org/library/functions.html#range). + function range(start, stop, step) { + if (stop == null) { + stop = start || 0; + start = 0; + } + if (!step) { + step = stop < start ? -1 : 1; + } + + var length = Math.max(Math.ceil((stop - start) / step), 0); + var range = Array(length); + + for (var idx = 0; idx < length; idx++, start += step) { + range[idx] = start; + } + + return range; + } + + // Chunk a single array into multiple arrays, each containing `count` or fewer + // items. + function chunk(array, count) { + if (count == null || count < 1) return []; + var result = []; + var i = 0, length = array.length; + while (i < length) { + result.push(slice.call(array, i, i += count)); + } + return result; + } + + // Helper function to continue chaining intermediate results. + function chainResult(instance, obj) { + return instance._chain ? _$1(obj).chain() : obj; + } + + // Add your own custom functions to the Underscore object. + function mixin(obj) { + each(functions(obj), function(name) { + var func = _$1[name] = obj[name]; + _$1.prototype[name] = function() { + var args = [this._wrapped]; + push.apply(args, arguments); + return chainResult(this, func.apply(_$1, args)); + }; + }); + return _$1; + } + + // Add all mutator `Array` functions to the wrapper. + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + _$1.prototype[name] = function() { + var obj = this._wrapped; + if (obj != null) { + method.apply(obj, arguments); + if ((name === 'shift' || name === 'splice') && obj.length === 0) { + delete obj[0]; + } + } + return chainResult(this, obj); + }; + }); + + // Add all accessor `Array` functions to the wrapper. + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + _$1.prototype[name] = function() { + var obj = this._wrapped; + if (obj != null) obj = method.apply(obj, arguments); + return chainResult(this, obj); + }; + }); + + // Named Exports + + var allExports = { + __proto__: null, + VERSION: VERSION, + restArguments: restArguments, + isObject: isObject, + isNull: isNull, + isUndefined: isUndefined, + isBoolean: isBoolean, + isElement: isElement, + isString: isString, + isNumber: isNumber, + isDate: isDate, + isRegExp: isRegExp, + isError: isError, + isSymbol: isSymbol, + isArrayBuffer: isArrayBuffer, + isDataView: isDataView$1, + isArray: isArray, + isFunction: isFunction$1, + isArguments: isArguments$1, + isFinite: isFinite$1, + isNaN: isNaN$1, + isTypedArray: isTypedArray$1, + isEmpty: isEmpty, + isMatch: isMatch, + isEqual: isEqual, + isMap: isMap, + isWeakMap: isWeakMap, + isSet: isSet, + isWeakSet: isWeakSet, + keys: keys, + allKeys: allKeys, + values: values, + pairs: pairs, + invert: invert, + functions: functions, + methods: functions, + extend: extend, + extendOwn: extendOwn, + assign: extendOwn, + defaults: defaults, + create: create, + clone: clone, + tap: tap, + get: get, + has: has, + mapObject: mapObject, + identity: identity, + constant: constant, + noop: noop, + toPath: toPath$1, + property: property, + propertyOf: propertyOf, + matcher: matcher, + matches: matcher, + times: times, + random: random, + now: now, + escape: _escape, + unescape: _unescape, + templateSettings: templateSettings, + template: template, + result: result, + uniqueId: uniqueId, + chain: chain, + iteratee: iteratee, + partial: partial, + bind: bind, + bindAll: bindAll, + memoize: memoize, + delay: delay, + defer: defer, + throttle: throttle, + debounce: debounce, + wrap: wrap, + negate: negate, + compose: compose, + after: after, + before: before, + once: once, + findKey: findKey, + findIndex: findIndex, + findLastIndex: findLastIndex, + sortedIndex: sortedIndex, + indexOf: indexOf, + lastIndexOf: lastIndexOf, + find: find, + detect: find, + findWhere: findWhere, + each: each, + forEach: each, + map: map, + collect: map, + reduce: reduce, + foldl: reduce, + inject: reduce, + reduceRight: reduceRight, + foldr: reduceRight, + filter: filter, + select: filter, + reject: reject, + every: every, + all: every, + some: some, + any: some, + contains: contains, + includes: contains, + include: contains, + invoke: invoke, + pluck: pluck, + where: where, + max: max, + min: min, + shuffle: shuffle, + sample: sample, + sortBy: sortBy, + groupBy: groupBy, + indexBy: indexBy, + countBy: countBy, + partition: partition, + toArray: toArray, + size: size, + pick: pick, + omit: omit, + first: first, + head: first, + take: first, + initial: initial, + last: last, + rest: rest, + tail: rest, + drop: rest, + compact: compact, + flatten: flatten, + without: without, + uniq: uniq, + unique: uniq, + union: union, + intersection: intersection, + difference: difference, + unzip: unzip, + transpose: unzip, + zip: zip, + object: object, + range: range, + chunk: chunk, + mixin: mixin, + 'default': _$1 + }; + + // Default Export + + // Add all of the Underscore functions to the wrapper object. + var _ = mixin(allExports); + // Legacy Node.js API. + _._ = _; + + return _; + +}))); +//# sourceMappingURL=underscore-umd.js.map diff --git a/_static/underscore.js b/_static/underscore.js new file mode 100644 index 00000000..cf177d42 --- /dev/null +++ b/_static/underscore.js @@ -0,0 +1,6 @@ +!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define("underscore",r):(n="undefined"!=typeof globalThis?globalThis:n||self,function(){var t=n._,e=n._=r();e.noConflict=function(){return n._=t,e}}())}(this,(function(){ +// Underscore.js 1.13.1 +// https://underscorejs.org +// (c) 2009-2021 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. +var n="1.13.1",r="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||Function("return this")()||{},t=Array.prototype,e=Object.prototype,u="undefined"!=typeof Symbol?Symbol.prototype:null,o=t.push,i=t.slice,a=e.toString,f=e.hasOwnProperty,c="undefined"!=typeof ArrayBuffer,l="undefined"!=typeof DataView,s=Array.isArray,p=Object.keys,v=Object.create,h=c&&ArrayBuffer.isView,y=isNaN,d=isFinite,g=!{toString:null}.propertyIsEnumerable("toString"),b=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],m=Math.pow(2,53)-1;function j(n,r){return r=null==r?n.length-1:+r,function(){for(var t=Math.max(arguments.length-r,0),e=Array(t),u=0;u=0&&t<=m}}function J(n){return function(r){return null==r?void 0:r[n]}}var G=J("byteLength"),H=K(G),Q=/\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;var X=c?function(n){return h?h(n)&&!q(n):H(n)&&Q.test(a.call(n))}:C(!1),Y=J("length");function Z(n,r){r=function(n){for(var r={},t=n.length,e=0;e":">",'"':""","'":"'","`":"`"},Cn=Ln($n),Kn=Ln(_n($n)),Jn=tn.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},Gn=/(.)^/,Hn={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},Qn=/\\|'|\r|\n|\u2028|\u2029/g;function Xn(n){return"\\"+Hn[n]}var Yn=/^\s*(\w|\$)+\s*$/;var Zn=0;function nr(n,r,t,e,u){if(!(e instanceof r))return n.apply(t,u);var o=Mn(n.prototype),i=n.apply(o,u);return _(i)?i:o}var rr=j((function(n,r){var t=rr.placeholder,e=function(){for(var u=0,o=r.length,i=Array(o),a=0;a1)ur(a,r-1,t,e),u=e.length;else for(var f=0,c=a.length;f0&&(t=r.apply(this,arguments)),n<=1&&(r=null),t}}var lr=rr(cr,2);function sr(n,r,t){r=qn(r,t);for(var e,u=nn(n),o=0,i=u.length;o0?0:u-1;o>=0&&o0?a=o>=0?o:Math.max(o+f,a):f=o>=0?Math.min(o+1,f):o+f+1;else if(t&&o&&f)return e[o=t(e,u)]===u?o:-1;if(u!=u)return(o=r(i.call(e,a,f),$))>=0?o+a:-1;for(o=n>0?a:f-1;o>=0&&o0?0:i-1;for(u||(e=r[o?o[a]:a],a+=n);a>=0&&a=3;return r(n,Fn(t,u,4),e,o)}}var Ar=wr(1),xr=wr(-1);function Sr(n,r,t){var e=[];return r=qn(r,t),jr(n,(function(n,t,u){r(n,t,u)&&e.push(n)})),e}function Or(n,r,t){r=qn(r,t);for(var e=!er(n)&&nn(n),u=(e||n).length,o=0;o=0}var Br=j((function(n,r,t){var e,u;return D(r)?u=r:(r=Nn(r),e=r.slice(0,-1),r=r[r.length-1]),_r(n,(function(n){var o=u;if(!o){if(e&&e.length&&(n=In(n,e)),null==n)return;o=n[r]}return null==o?o:o.apply(n,t)}))}));function Nr(n,r){return _r(n,Rn(r))}function Ir(n,r,t){var e,u,o=-1/0,i=-1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;ao&&(o=e);else r=qn(r,t),jr(n,(function(n,t,e){((u=r(n,t,e))>i||u===-1/0&&o===-1/0)&&(o=n,i=u)}));return o}function Tr(n,r,t){if(null==r||t)return er(n)||(n=jn(n)),n[Wn(n.length-1)];var e=er(n)?En(n):jn(n),u=Y(e);r=Math.max(Math.min(r,u),0);for(var o=u-1,i=0;i1&&(e=Fn(e,r[1])),r=an(n)):(e=qr,r=ur(r,!1,!1),n=Object(n));for(var u=0,o=r.length;u1&&(t=r[1])):(r=_r(ur(r,!1,!1),String),e=function(n,t){return!Er(r,t)}),Ur(n,e,t)}));function zr(n,r,t){return i.call(n,0,Math.max(0,n.length-(null==r||t?1:r)))}function Lr(n,r,t){return null==n||n.length<1?null==r||t?void 0:[]:null==r||t?n[0]:zr(n,n.length-r)}function $r(n,r,t){return i.call(n,null==r||t?1:r)}var Cr=j((function(n,r){return r=ur(r,!0,!0),Sr(n,(function(n){return!Er(r,n)}))})),Kr=j((function(n,r){return Cr(n,r)}));function Jr(n,r,t,e){A(r)||(e=t,t=r,r=!1),null!=t&&(t=qn(t,e));for(var u=[],o=[],i=0,a=Y(n);ir?(e&&(clearTimeout(e),e=null),a=c,i=n.apply(u,o),e||(u=o=null)):e||!1===t.trailing||(e=setTimeout(f,l)),i};return c.cancel=function(){clearTimeout(e),a=0,e=u=o=null},c},debounce:function(n,r,t){var e,u,o,i,a,f=function(){var c=zn()-u;r>c?e=setTimeout(f,r-c):(e=null,t||(i=n.apply(a,o)),e||(o=a=null))},c=j((function(c){return a=this,o=c,u=zn(),e||(e=setTimeout(f,r),t&&(i=n.apply(a,o))),i}));return c.cancel=function(){clearTimeout(e),e=o=a=null},c},wrap:function(n,r){return rr(r,n)},negate:fr,compose:function(){var n=arguments,r=n.length-1;return function(){for(var t=r,e=n[r].apply(this,arguments);t--;)e=n[t].call(this,e);return e}},after:function(n,r){return function(){if(--n<1)return r.apply(this,arguments)}},before:cr,once:lr,findKey:sr,findIndex:vr,findLastIndex:hr,sortedIndex:yr,indexOf:gr,lastIndexOf:br,find:mr,detect:mr,findWhere:function(n,r){return mr(n,Dn(r))},each:jr,forEach:jr,map:_r,collect:_r,reduce:Ar,foldl:Ar,inject:Ar,reduceRight:xr,foldr:xr,filter:Sr,select:Sr,reject:function(n,r,t){return Sr(n,fr(qn(r)),t)},every:Or,all:Or,some:Mr,any:Mr,contains:Er,includes:Er,include:Er,invoke:Br,pluck:Nr,where:function(n,r){return Sr(n,Dn(r))},max:Ir,min:function(n,r,t){var e,u,o=1/0,i=1/0;if(null==r||"number"==typeof r&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=er(n)?n:jn(n)).length;ae||void 0===t)return 1;if(t + + + + + + Nightscout for clinicians — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout for clinicians

+
+
+

Tip

+

Unless specified, links within the text are for advanced explanation of the underlying mechanisms but don’t necessarily add value for clinicians use of Nightscout.

+
+
+

What is Nightscout?

+

Nightscout is an open-source cloud application used to visualize, store and share in real-time:

+
    +
  • data from continuous glucose monitoring sensors

  • +
  • manually or automatically logged treatments

  • +
  • basal rates from pumps (optional)

  • +
+
+
+
+

How can I access patient data?

+

Your patient should share a unique web URL with you, it will look like https://name.domain.ext.

+

Since the URL is open for viewing to anybody having internet access to it, patients or caregivers can decide to make the access secure and will share a tokened read-only access URL looking like https://name.domain.ext?token=clinic-48aed625abb0ec86.
+You need to use the full URL provided to access your patient Nightscout site.

+

Any device connected to the internet can be used to visualize patient data.

+
+

Cannot access patient URL

+

Should you experience issues to access the Nightscout site, check with your IT team if the domain used by your patient is not blocked by a local internet safety rule. Many patients or caregivers who build their own Nightscout site rely on platforms as a service or free DNS providers that can get classified as unsafe by cybersecurity systems.
+Ask your IT and cybersecurity teams to perform all necessary verifications to allow access to your patient site: Nightscout itself is safe for infrastructures, it doesn’t contain any sort of cyberthread or malware.

+
+

Since Nightscout can be hosted in a large variety of platforms, you can expect the site domain to be (but not only) in the following list:

+

heroku.com, azurewebsites.net, railway.app, fly.dev, onrender.com, t1pal.com, ns10be.de, nightscout.pro, mooo.com, chickenkiller.com, crabdance.com, strangled.net, code.run, nightscout4u.com

+
+

Read only access

+

Writing data into Nightscout is protected with a password called API_SECRET that should not be shared with you by the patient.

+
+
+
+
+

What should I see when I open a Nightscout site?

+

What will display should be similar to this:

+

Nightscout

+

If you see this, it means your patient forgot to send you the link with a read-only token:

+../../_images/Admin02.png +
+
+
+

Next steps:

+

Follow the links below.

+ +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/clinicians/reports/index.html b/clinicians/reports/index.html new file mode 100644 index 00000000..65d4e517 --- /dev/null +++ b/clinicians/reports/index.html @@ -0,0 +1,321 @@ + + + + + + + Nightscout reports — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout reports

+

Access reports from the drawer menu,

+../../_images/Clinic14.png +
+
+

View profiles

+

Profiles view gives important information on the patient therapy parameters.

+

Select profiles then SHOW (no additional setup is necessary).

+../../_images/Clinic20.png +

Patients profile(s) will display.

+../../_images/Clinic19.png +

DIA is the duration of the insulin action.

+

Carbs absorption rate is complex to calculate for patients and can be undefined (or zero) if the DIY system doesn’t update the value (when existing).

+

Insulin to Carbs ratio (IC) and Insulin Sensitivity Factor (ISF) can be defined by time periods. Only one visible value means whole day.

+

Basal rates should match the pump settings.

+
+
+
+

Select a report

+

Select the report type:

+../../_images/Clinic15.png +
    +
  • Day to day

  • +
  • Week to week

  • +
  • Daily Stats

  • +
  • Distribution

  • +
  • Hourly stats

  • +
  • Percentile Chart

  • +
  • Weekly Distribution

  • +
+
+
+
+

Setup the report

+

Select the period used to analyze data.

+

Enable the check box and either select From: and To: dates to define the interval

+../../_images/Clinic16.png +

or:

+../../_images/Clinic17.png +
    +
  • Today

  • +
  • Last 2 days

  • +
  • Last 3 days,

  • +
  • Last week

  • +
  • Last 2 weeks

  • +
  • Last Month

  • +
  • Last 3 months

  • +
+

Avoid selecting too long periods of time for daily reports.

+
+

Unless looking for specific Notes or Event type leave the checkboxes disabled.

+../../_images/Clinic18.png +
+

You can select which week days to use.

+../../_images/Reports03.png +
+

Confirm Target BT range bottom and top for TIR (or TITR) and graph range lines.

+

You can sort the report from older to newer or newer first.

+../../_images/Clinic24.png +
+

Click SHOW and wait for data to load and rendering to complete. This might take some time if the period is long (this will also depend on the Nightscout host engine).

+../../_images/Reports05.png +
+
+
+

Day To day

+

This report will show BG, day by day, including selected treatments.

+../../_images/Clinic21.png +../../_images/Clinic22.png +

Enable insulin, carbs and basal rate to have consistent insulin distribution information.

+../../_images/Clinic23.png +
+

When changing selections, click again SHOW to update the view.

+
+
+
+

Week to Week

+

This report will give a week by week spaghetti view, with color code for week days selected.

+../../_images/Reports10.png +
+
+
+

Daily stats

+

This report will give a daily distribution view.

+../../_images/Reports11.png +
+
+
+

Distribution

+

This report will give a complete distribution view.

+

You also can filter by hours (scroll to the bottom of the page).

+../../_images/Reports18.png +../../_images/Reports12.png +

You can quickly find %TIR, %TUR, %TAR and the rough estimated HbA1c values.

+../../_images/Clinic25.png +

Range must be modified to see %TITR.

+
+
+
+

Percentile Chart

+

This report will give a percentile distribution view.

+../../_images/Reports16.png +../../_images/Clinic26.png +
+
+
+

Hourly stats

+

This report will give an hourly distribution view with a box plot showing 25% and 75% percentile plus mean and standard deviation, then additional hour by hour statistics in a table.

+../../_images/Reports13.png +
+
+
+

Weekly Distribution

+

This report will give a weekly view.

+../../_images/Reports14.png +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/clinicians/setup/index.html b/clinicians/setup/index.html new file mode 100644 index 00000000..1dd58e8c --- /dev/null +++ b/clinicians/setup/index.html @@ -0,0 +1,254 @@ + + + + + + + Setup the main view — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Setup the main view

+

Before checking reports, you should verify your patient has setup correctly data upload.
+The steps below might not be necessary but will probably give you more insights on the patient system.

+

If you’re only looking for reports, skip this step and continue to reports.

+
+
+

Customize your view

+

Open the main menu, located at the top right of the window, select the drawer icon:

+../../_images/Clinic01.png +

Select the units for blood glucose values.

+../../_images/Clinic02.png +

Select the language used for Nightscout display.

+../../_images/Clinic03.png +

If the patient uses a pump that can send its basal rates, or has setup programmed basal rates, enable basal default display.

+../../_images/Clinic04.png +

Enable all available plugins and save.
+This will only modify the way you visualize Nightscout on the device you’re using. It will not interfere with the patient settings.

+../../_images/Clinic05.png +
+
+
+

Identify displayed items

+

A typical DIY closed loop user display will look like this.

+../../_images/Clinic06.png +

Last 48 hours are visible, you can select the upper graph time scale clicking on the corresponding length (2 to 24 hours). You can slide the lower graph selection to visualize the corresponding time period on the top graph.

+

The rounded rectangle indicators are called “pills” and contain immediately visible indications, or more insights if you hover on them with the mouse.

+

They can be automatically or manually updated by the patient or its closed loop/uploader device, else they will be empty or meaningless. As setting warning and urgent limit values for these pills is not always adjusted by the user in Nightscout variables, they might appear in yellow or red for values that are within normal usage.

+../../_images/Clinic07.png +

Current blood glucose is displayed top left, the arrow only indicates the difference between the current measurement and the previous one (you’ll see the measurement age on the left of the view).

+../../_images/Clinic08.png +
    +
  • IOB: Insulin on board, is calculated using the insulin duration parameter in the current profile if no external closed loop system is used, or by this external algorithm if any (OpenAPS/Loop).

  • +
  • COB: Carbs on board are calculated by the absorption rate set in the profile.

  • +
  • CAGE, SAGE, BAGE, IAGE are timers counting the time since last Cannula (infusion site), Sensor, Battery and Insulin cartridge change.

  • +
  • BASAL displays the current basal rate.

  • +
+

Uploading device battery level and Nightscout storage used space are not of clinical interest.

+../../_images/Clinic09.png +

Connected pumps will show available insulin units, battery status and last registered activity.

+../../_images/Clinic10.png +

DIY closed loop systems can be identified with the Loop (Loop) or OpenAPS (OpenAPS, AndoidAPS, FreeAPS, iAPS) pill. Only one will be enabled, if the other one appears it will normally show an exclamation mark. If a DIY closed loop system Nightscout doesn’t show any active pill, configuration needs to be fixed so that Nightscout receives all necessary data (patient responsibility).

+../../_images/Clinic11.png +

Basal display shows the programmed basal in dotted lines and the actual basal modulation. This is an example for the default basal display.

+../../_images/Clinic12.png +

Loop adds rich details to Nightscout real time display, like food types and visual information.

+

Hovering on the DIY closed loop system pill (Loop/OpenAPS) will show insights of the algorithm decisions.

+../../_images/Clinic13.png +
+
+
+

Next step:

+

Follow the link below.

+ +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/genindex/index.html b/genindex/index.html new file mode 100644 index 00000000..4401bf97 --- /dev/null +++ b/genindex/index.html @@ -0,0 +1,193 @@ + + + + + + Index — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000..ace811d8 --- /dev/null +++ b/index.html @@ -0,0 +1,436 @@ + + + + + + + Welcome to Nightscout — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Welcome to Nightscout

+
+

Nightscout

+
+

Health professional? You might not want to build a Nightscout site and just need to find out how to get data from it, jump to the dedicated pages here.

+
+
+

Introduction

+

Nightscout (also known as CGM in the Cloud) is an open-source cloud application used by people with diabetes and parents of kids with diabetes to visualize, store and share the data from their Continuous Glucose Monitoring sensors in real-time. Once setup, Nightscout acts as a central repository of blood glucose and insulin dosing/treatment data for a single person, allowing you to view the CGM graph and treatment data anywhere using just a web browser connected to the internet.

+

There are several parts to this system. You need somewhere online to store, process and visualize this data (a Nightscout Site), something to upload CGM data to your Nightscout (an Uploader), and then optionally you can use other devices to access or view this data (one - or more - Follower).

+
+

Nightscout Site

+
    +
  • The Nightscout cloud application can be installed by yourself (Do It Yourself, in short: DIY) using hosting services from various cloud service providers.

  • +
  • You can also pay to use a fully-managed Nightscout hosting service and avoid having to personally build and maintain your site.

  • +
+
+
+

Uploader

+

The CGM data is usually sent to Nightscout by an uploader device such as a mobile cellphone running an app like xDrip+, Spike, xDrip4iOS, Medtronic Uploader and others. Alternatively, the CGM data can be pulled directly from your online Dexcom account. The application you’ll need for uploading the data depends on which CGM device you’re using and what type of mobile device you have.

+
+
+

Followers

+

In addition to viewing the data using a web browser, there are also applications available for mobile devices, smartwatches, electronic devices and other cloud-based services which allow you alternative ways to view and interact with the information stored within your Nightscout site (often known as “Followers”).

+

Nightscout Environment

+
+
+
+

Development History

+

Nightscout was developed by people with Type 1 Diabetes and parents of kids with T1D and has continued to be developed, maintained, and supported by volunteers, clinical use, and commercial sponsorship. The web portal known as Nightscout is made by the CGM Remote Monitor Contributors and the Nightscout community over years.

+

When first implemented, Nightscout was a solution specifically for remote monitoring of Dexcom G4 CGM data. Today, there are Nightscout solutions available for nearly all commercial CGM sensors. The goal of the project is to allow the remote monitoring, sharing and analysis of any T1D’s glucose levels using existing monitoring devices.

+
+
+

What are the values of Nightscout

+

We are compelled in the pursuit of humane and equitable application of technology to liberating people from the burden of diabetes. We are not waiting to deliver the benefits we’ve found in sharing all diabetes experiences. Nightscout is free to contribute, free to access, free to criticize, free to try, free to depend on, free to modify, and free to distribute. The Nightscout community demands respect and dignity for all community members. The reputation of the Nightscout community is affected by the quality of the source code, the quality of our relationships, the quality of our discussions, what we are known for doing: the way we treat each other. +Users of Nightscout are impacted by reliability, security and confidentiality of Nightscout. Therefore, the developers and contributors of Nightscout strive to improve the quality of Nightscout while making these opportunities accessible to all.

+

Nightscout’s longevity, the application, the ecosystem, and the culture demand we use all tools at our disposable to achieve the values in a sustainable way. We are not waiting to do whatever it takes to meet the needs of people affected by the inhumane demands of diabetes. Our active collaboration against the burden of diabetes creates the results we desire.

+
+
+

What Do I Need?

+

You will need:

+
    +
  • A CGM sensor

  • +
  • A way to upload your data, to be stored in Nightscout (this is generally an internet-connected mobile phone with a matching uploader app)

  • +
  • Internet access

  • +
  • Basic computer skills and the ability to carefully follow the installation guides shown on this site

    +

    *”Carefully” means that you will thoroughly read, follow and complete each step without skipping any and without giving up thinking that it is too difficult - it isn’t, you just need to be patient.*

    +
  • +
+
+

IMPORTANT

+

Before using Nightscout, it is important to understand that this project:

+
    +
  • is an open-source, community-based project and is not supported by any company

  • +
  • is not officially approved or regulated for diabetes therapy and/or treatment in any way

  • +
+

If you will be using DIY: You must understand that you take full responsibility for building and running this system and you agree to do so at your own risk.

+
+
+

SAFETY

+
    +
  • This project requires a working internet connection and availability of third-party cloud services

  • +
  • Do not rely only on Nightscout as the only way you have of knowing your blood glucose values and trends

  • +
  • Make sure you’re ready to cope with an unexpected failure and always have alternative ways to check your blood glucose levels

  • +
+
+
+
+

How Much Does It Cost?

+

There’s no simple answer to this. You basically have two options:

+
    +
  1. DIY: Use instructions on this website to create your own installation. You will need to maintain this installation yourself. There are cloud providers that offer the needed hosting services for free, so your monthly hosting cost can be free - $0 with this option. Historically vast majority of Nightscout users have opted for this choice. Of note, with this option you are the person responsible for ensuring the service is up when you need it. The community aims to support people who choose this option, but this is entirely driven by a voluteer effort and support might not be available when you need it.

  2. +
  3. Use a service: You can use a hosting provider that does all of this work for you in exchange for a monthly fee. There are currently three options available for this (NS10BE, T1Pal, Nightscout.Pro, Serendipity Bio, and Nightscout4u), all of which are from active Nightscout community members. If you’re a non-technical person, this is a great choice.

  4. +
+

The Nightscout development community actively supports both of these choices.

+
+
+

Build your own Nightscout DIY site

+
+

Tip

+


Interested in building a Nightscout DIY site? You’ll find instructions ⇒ HERE ⇐.

+
+

Note: DIY users of Nightscout have been historically using platforms like Digital Ocean, Microsoft Azure and then Salesforce Heroku to host their sites. With time, more platforms were added.

+

If you have the time to author instructions for this purpose, new documentation pull requests are extremely welcome as well as comments.

+
+
+

Nightscout as a Service

+

If you want to save time and avoid the need to maintain a DIY solution, you have three service providers of choice.

+
+

T1Pal

+
+
+

+
+ +
+
+
+

NS10BE

+
+
+https://ns.10be.de/templates/images/ns.10be.de-logo_halb_klein.jpg +
+ +
+
+
+

Nightscout Pro

+
+
+https://nightscout.pro/wp-content/uploads/2022/12/nightscoutsocial.jpg +
+ +
+
+
+

Serendipity Bio

+
+
+

+
+ +
+
+
+

Nightscout4u

+
+
+https://www.nightscout4u.com/images/LogoNightscout4u0002.png +
+ +
+
+
+
+

Who Can Help Me?

+

You will find many willing and open-hearted people in the Facebook groups.

+

The main group for all Nightscout support is the “CGM in the Cloud” Facebook group.

+

There are also many local Nightscout communities and you’ll probably be able to find one in your own country and language if this helps.

+
+

Technical Support

+

Unless you’re paying for a hosted Nightscout including support, this project is “Do It Yourself” (DIY) and supported by volunteers. Whilst you will almost certainly always will find someone ready to help you for free, building your own Nightscout site doesn’t entitle you to any form of support from anybody.

+

The open-source diabetes movement is founded on the idea of paying it forward and helping others to learn things that others took their time to help teach you about.

+

Ask nicely, and nice people will always do nice things and help you.

+

Nightscout developers are busy people and we’d like them to concentrate on maintaining and improving Nightscout, not only supporting users. (This means do not send them private messages or friend requests just to help fix something that is already clearly documented or for help that can be easily requested in the CGM in the Cloud group)

+
+
+

Facebook Privacy

+

You’ll find a lot of useful and friendly diabetes-oriented groups on Facebook and it’s probably the best place to find online support. Some people express concerns about using Facebook: if you’re worried about your privacy just remember Facebook will only share the information that you allow it to share.

+
+
+
+

How to Use These Docs

+
    +
  • Use the navigation menu at the top on the left of the screen to find the section that you are looking for.

  • +
  • A Table of Contents for the current page is always displayed on the left side of the screen.

  • +
  • You can search the Nightscout Docs site by entering your search string (only English) below the Nightscout main logo top left.

  • +
+
+
+

How Can I Help?

+

You’ll find the source repository for this documentation here. Please don’t hesitate to improve or correct anything you see and create a pull request!

+

You’re also welcome to contribute or report any error, unclear explanation, typo, broken link etc. by going to GitHub and opening an issue.

+

Finally, to help on the development of Nightscout itself, feel free to join in at our Discord Channel.

+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/admin_tools/index.html b/nightscout/admin_tools/index.html new file mode 100644 index 00000000..9edb2b56 --- /dev/null +++ b/nightscout/admin_tools/index.html @@ -0,0 +1,319 @@ + + + + + + + Admin Tools — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Admin Tools

+
+
+

Subjects and Roles

+

Note: authentication tokens are also called access tokens

+
+

Changing API_SECRET

+

If you change your API_SECRET all your tokens will change. Make sure you update your devices and send the new token link to those you allowed to access your Nightscout

+
+

To access the Authentication options, click the settings panel (three horizontal bars in the top right) in your website and select Admin Tools. The Authentication options are at the top of the Admin page. (Note: you must be logged in with your API SECRET to access these tools.)

+../../_images/Admin04.png +
+

You will see several predefined roles:

+../../_images/Admin01.png +
+
+

Roles

+
    +
  • admin: full access

  • +
  • careportal: can view the site and make CarePortal/treatment entries

  • +
  • readable: read-only access; no ability to make CarePortal/treatment entries. This user CAN see reports and profile information.

  • +
  • denied: no access (this role only works if the AUTH_DEFAULT_ROLES setting is also denied. You can’t have a site that is readable to everyone and create a “denied” token for a specific user.)

  • +
  • devicestatus-upload: used by devices

  • +
+
+

Hint

+

There is currently no way to limit a user so that he cannot view the Reports section if he has access to the site. Time/date-based roles are not currently possible.

+
+
+
+
+

Create a Token

+
    +
  • Click the “Add New Subject” button.

  • +
+../../_images/Admin00.png +
+
    +
  • Fill in the name of the subject and the “role” you are giving this subject (from the list of roles shown above). Note you should only grant the readable role for users who do not need to save or edit data in Nightscout. For example, you might want to share the site to a school nurse, but not have him able edit the data.

  • +
+../../_images/Admin05.png +
    +
  • An admin token is necessary for AAPS to upload using the API V3.

  • +
+../../_images/Admin05b.png +
+
    +
  • Click save.

  • +
  • The token will be shown. You can use it in two different ways:

    +
      +
    • Copy the token URL (right-click on it in the browser and select the option to copy the link address) and provide it to the user (e.g., paste it into an email). If the user enters the entire URL (with token), the token will be in effect.

    • +
    • Copy the token string (in the example below school-a595d5f0aeff64c0) and use it for authentication at site opening, instead of the API secret (Nightscout minimum version 14.1.0 required).

    • +
    +
  • +
+../../_images/Admin06.png +
+

You can also add the token to the site URL to authenticate using a token. Your site link with token will look like this:

+

https://yoursitename.yourplatform.com/?token=school-a595d5f0aeff64c0

+

Anybody with this link can use your Nightscout with the role defined for this token.

+
+

Hint

+

If the user copies only your core URL into a browser, and your site is readable by default, the token will be bypassed. (Possible strategies to ensure the user puts the role-based URL into a browser include using a tinyurl or bit.ly.)

+
+
    +
  • You can edit a subject by clicking the edit icon, making changes, and saving.

  • +
  • You can delete a subject by clicking the red X icon to remove the subject from the list.

  • +
+

See how to setup your downloaders (followers) with a secured site.

+
+
+
+
+
+

Database Maintenance

+

If you use a small or a free database (like MongoDB Atlas), it will require maintenance as nothing in Nightscout is setup to perform cleanup and unless you planned for a larger size database, it will eventually fill-up.

+
+

Warning

+

Make sure you leave dbsize visible on your page to keep it under control.

+
+
+

This panel will give access to basic maintenance actions on various database collections.

+
+
+

Mongo status Database

+
+

Your status database contains battery, pump, … extra information as those defined in devicestatus that you can safely delete when necessary.

+../../_images/Admin07.png +
+

When it comes to treatments and entries, deleting data is something you need to carefully evaluate if you like Nightscout to be the main repository for your history.

+
+
+

Mongo treatments Database

+
+../../_images/Admin08.png +
+
+
+

Mongo entries Database

+
+../../_images/Admin09.png +
+
+
+

Remove future items from Database

+
+

Future treatments and entries generated by an incorrect time zone, daylight saving time change, or any other mistake can completely block your site. Using this feature will purge the database of these unwanted values automatically. Detected issues will appear in Database contains x future records and should be fixed.

+
+../../_images/Admin10.png +
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/advanced/index.html b/nightscout/advanced/index.html new file mode 100644 index 00000000..67725478 --- /dev/null +++ b/nightscout/advanced/index.html @@ -0,0 +1,245 @@ + + + + + + + Advanced Nightscout deployments — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Advanced Nightscout deployments

+
+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+
+

Building Nightscout DIY in a cloud platform

+

You can run your Nightscout site in several vendors platforms, using free or paid accounts.

+

We documented Heroku, Azure, Railway, Northflank and Fly.io. There are probably others, don’t hesitate to open an issue in the documentation with the easiest deployment method if you want to see them named here.

+
+
+
+

Building Nightscout DIY in a virtual server

+

You can run your Nightscout site in physical or virtual private servers, using free or paid accounts.
+The original Nightscout project was also developed to run in Digital Ocean.

+

You can use step by step Linux commands or deploy with a simple scripted install.

+

Below is a list of some VPS. There are probably others, don’t hesitate to open an issue in the documentation with the easiest deployment method if you want to see them named here.

+

Google Cloud with a Scripted deployment (one command).
+Oracle and extensive documentation (npm and Docker).
+Amazon Web Service

+

Some common deployment methods:

+

Ubuntu commands.
+Docker container.

+
+
+
+

Building Nightscout inside your NAS

+

Don’t buy a NAS device just for this, but if you already have one that’s worth a try!

+

You can host your Nightscout site in your Synology NAS.
+You can also try with your QNAP NAS.

+
+
+
+

Building Nightscout with a Raspberry PI 4

+

If you own one, you can use it to host your Nightscout, see here.

+
+
+
+

Home Assistant Add-On for Nightscout

+

This add-on is a wrapper around nightscout/cgm-remote-monitor. It includes a Mongo Database which is used to store the uploaded values.

+

See here.

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/close_loop/index.html b/nightscout/close_loop/index.html new file mode 100644 index 00000000..af49eec5 --- /dev/null +++ b/nightscout/close_loop/index.html @@ -0,0 +1,235 @@ + + + + + + + Closed loop systems — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Closed loop systems

+
+

Nightscout is integrated with DIY closed loop systems.

+

Look into the specific app documentation to know more about optimal Nightscout settings.

+

The heading for each section is a link to the Nightscout overview page for that closed-loop system.

+

You will also find general support in Loop and Learn.

+ +
+
+

Loop

+

Loop is an iOS app that assists in the many insulin dosing decisions people with diabetes face every day. You enter your own settings for desired correction range, basal schedule, insulin sensitivity factor (ISF), carbohydrate ratio (CR) and the type of insulin you are using. The glucose predictions, using your settings and meal entries, provide Loop with the information needed to modify insulin delivery to attain a targeted glucose range in the future.

+

See here how to configure Loop to upload to Nightscout.

+

Facebook group: Looped

+
+
+
+

AAPS

+

AndroidAPS is an open source app for people living with insulin-dependent diabetes that acts as an artificial pancreas system (APS) on Google Android smartphones. AAPS uses an openAPS software algorithm.

+

See here how to configure AAPS NSClient to upload to Nightscout.

+

Facebook group: Android APS Users

+
+
+
+

iAPS

+

iAPS is a open source artificial pancreas system based on the OpenAPS algorithm.

+

Facebook group: iAPS

+
+
+
+

OpenAPS

+

Mind the documentation is not up to date for Nightscout DIY options.

+

The Open Source Artificial Pancreas System (OpenAPS) is a safe but powerful, advanced but easily understandable, Artificial Pancreas System (APS) designed to automatically adjust an insulin pump’s insulin delivery to keep blood glucose (BG) in a safe range at all times. It does this by communicating with an insulin pump to obtain details of all recent insulin dosing (basal and boluses), by communicating with a Continuous Glucose Monitor (CGM) to obtain current and recent BG estimates, and by issuing commands to the insulin pump to adjust insulin dosing as needed.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/database/index.html b/nightscout/database/index.html new file mode 100644 index 00000000..b8511969 --- /dev/null +++ b/nightscout/database/index.html @@ -0,0 +1,321 @@ + + + + + + + Choose your database — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Choose your database

+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+

You must create a database unless it’s already included in the platform you selected, check below.

+
+ +
+
+
+ +
+

You need to create a database.

+
+ +
+

You don’t need to create a database: continue here

+
+ +
+

You don’t need to create a database: go directly to the hosting site.

+
+
+
+

Find a list of commonly used database hosting services below, decide which one you’ll want to use and create your database.

+
+
+

Warning

+

Using a free, limited size database (like M0 Atlas) means you will have to maintain it.
+Since it will regularly grow with the data you send to Nightscout, take a note to perform regular cleanup to avoid your site crashing.

+
+
+
+

MongoDB Atlas Database

+

MongoDB Atlas

+
+
+

MongoDB bought mLab in 2018 and shutdown its service in 2020. Most users migrated to MongoDB Atlas, using a free M0 database with a limited 512MB capacity.

+

Pros:

+
    +
  • The M0 cluster is free

  • +
  • Nightscout was adapted to MongoDB Atlas

  • +
+

Cons:

+
    +
  • M0 clusters are designed for learning and testing, not production: performance and availability are not guaranteed

  • +
  • There is no warranty the M0 cluster will remain in the future

  • +
  • A larger M2 cluster costs 9$ per month (not competitive against hosted solutions)

  • +
  • A full M0 database crashes Nightscout, this is a common issue for DIY closed loop system users

  • +
+
+ +
+
+
+

Railway Mongo Database

+

Railway MongoDB

+
+
+

Railway offers a Mongo database.

+

Pros:

+
    +
  • Simple to create

  • +
  • Less overhead than Atlas (more space)

  • +
+

Cons:

+
    +
  • Requires a 5$/month hobby plan as billing starting amount

  • +
  • Running a database together with a Railway Nightscout site will increase billing above ~200MiB used

  • +
  • Simple Mongo 4.4 database

  • +
+
+ +
+
+
+

Northflank Mongo Database

+

Northflank MongoDB

+
+
+

Northflank offers a Mongo database.

+

Pros:

+
    +
  • Simple to create

  • +
  • Economic reliable database

  • +
  • High quality Mongo database with a replica set

  • +
+

Cons:

+
    +
  • Billing will occur but the cost is really limited: 0.3$ per GiB (it usually takes years to reach 1GB for Nightscout)

  • +
  • There is no warranty this offer will be maintained in the future

  • +
+
+ +
+
+
+

VPS Mongo Database

+

MongoDB

+
+
+

You can create a Mongo Database in a Virtual Private Server, either using a free plan (Oracle, Google) or a paid account (Digital Ocean and so many others …).

+

Pros:

+
    +
  • Lot of space

  • +
  • Standard community method largely supported by IT specialists

  • +
+

Cons:

+
    +
  • Requires commands to be typed and some IT knowledge

  • +
+
+ +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/discover/index.html b/nightscout/discover/index.html new file mode 100644 index 00000000..bb649cd2 --- /dev/null +++ b/nightscout/discover/index.html @@ -0,0 +1,488 @@ + + + + + + + Discover your Nightscout site — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Discover your Nightscout site

+
+
+

Privacy

+

Having the URL of your Nightscout site, anybody can view your BG and run reports of your data. It it strongly recommended that you secure your site.

+
+
+

It should look very similar to this when your uploader has added some data.

+../../_images/UseNS00.png +
+

The central part will show your recent BG, you can select how many hours you want to be displayed with Hours: 2 3 4 6 12 24. The pale blue dots are the AR2 prevision as explained here. The lower part will display the last 48 hours and you can use the lower right selection to browse your old data.

+../../_images/UseNS01.png +
+

In the upper part you’ll see the current time of your site, your current BG (and how long ago it was measured) plus the delta with the previous measurement and a trend arrow. More explanations here.

+

Optionally you will see other indications (pills) that can be personalized in your variables and plugins like detailed here.

+../../_images/UseNS03.png +
+
+

Authenticate yourself

+

By default you site opens read only, you need to authenticate using your API secret in order to modify settings and add treatments. Click on the lock icon, enter your API secret and click Update.

+../../_images/UseNS04.png +

This will unlock your careportal (if enabled) and edit (if enabled).

+../../_images/UseNS05.png +
+
+
+

Add a treatment (careportal)

+

Some uploaders will send treatments to Nightscout but others won’t. If you whish to do this manually, careportal is here for that.

+

+ will open an interface to manually enter treatments.

+../../_images/UseNS06.png +
+

In the Event Type drop down menu, you can select the treatment type you want to add. Additional available entries will depend on the plugins you enabled like Loop and OpenAPS/AAPS.

+
+

BG Check

+

BG check allows you to enter a blood glucose reading value from your Meter. With a CGM using Sensor reading doesn’t add much value.

+

Keep in mind the value will be inserted now (unless you modify the event time) and might not match your CGM value for non stable BG due to capillary time lag.

+../../_images/UseNS07.png +
+
+
+

Correction Bolus

+

Correction Bolus allows you to enter the amount of insulin units injected for a correction.

+

It will show as a circle with the lower half blue, with its size depending on the amount of units, UI indicated below (depending on bolus rendering setting).

+../../_images/UseNS08.png +
+
+
+

Meal Bolus

+
+
+

Carb Correction

+
+
+

Snack Bolus

+

These treatments allow you to enter the amount of food you eat (and eventually the matching insulin treatment).

+

It will show as a circle with the higher half white (if including carbs), with its size depending on the amount of food. Without carbs the upper half will not be filled with the white color. If you add proteins and fat, the amount will display in this order: carbs/proteins/fat. With insulin the lower half of the circle will fill in blue and units will be indicated below.

+

You can select the timing of carbs absorption in Carb Time (i.e. when did you or will you actually eat these carbs)

+../../_images/UseNS09.png +
+
+
+

Combo Bolus

+

Combo bolus allows you to insert the corresponding bolus if you use a pump. Insert the total amount of insulin in Insulin Given then break down in Split with the percentage administered now and the extended amount. Enter theDuration of the extended bolus below.

+

It will display as a classic bolus at treatment time and basal will reflect the extended amount for the selected duration.

+../../_images/UseNS10.png +
+
+
+

Announcement

+

Announcements are used to change your page title in order to alert viewers.

+

Entering another treatment will acknowledge the announcement and return your page title to default.

+../../_images/UseNS11.png +
+
+
+

Note

+
+
+

Question

+

Notes and questions are a way to add comments and interact with others using your Nightscout page.

+../../_images/UseNS12.png +
+
+
+

Exercise

+

You can log physical activities and specify the duration.

+../../_images/UseNS13.png +
+
+
+

Pump Site Change cage

+
+
+

CGM Sensor Start sage

+
+
+

CGM Sensor Insert

+
+
+

CGM Sensor Stop

+
+
+

Pump Battery Change bage

+
+
+

Insulin Cartridge Change iage

+

Logging these events will help you remember various expirations dates and will update the corresponding pills if enabled.

+../../_images/UseNS14.png +
+
+
+

Temp Basal Start

+
+
+

Temp Basal Stop

+

You can indicate temporary basal rate changes using either a percentage change in Percent or the absolute rate in Basal value. You need basal to be enabled to visualize it.

+../../_images/UseNS15.png +
+
+
+

Profile Switch

+

If you have more than one profile stored, you can switch profile to keep your profile parameters synchronized.

+

For a temporary switch (like for physical activities) you can select the duration.

+../../_images/UseNS16.png +
+
+
+

D.A.D. Alert

+

Log a Diabetic Alert Dog event.

+../../_images/UseNS20.png +
+
+
+
+

Edit Mode (edit)

+

For values still present on your display (last 48 hours), you can use Edit to move or delete bolus and correction treatments.

+

../../_images/UseNS17.png will change color to red in edit mode ../../_images/UseNS18.png.

+
    +
  1. Drag the treatment in the past or future in the black area to move both food and insulin.

  2. +
  3. If you want to move only insulin drop in the blue area.

  4. +
  5. For carbs only, in the white area.

  6. +
  7. To delete a complete treatment drop it in the red delete area.

  8. +
+

Once done, exit the edit mode by de-selecting it (white on black background). ../../_images/UseNS17.png

+../../_images/UseNS19.png +
+
+
+

Drawer Menu

+

Once authenticated (click the lock icon up right) you’ll find many features in the drawer menu like access to advanced plugins and customizations of your web page (local view only, in order to modify the default view look into your Heroku variables here).

+../../_images/UseNS21.png +

Reports will drive you to a powerful reporting toolset detailed here.

+

Profile Editor will allow you to modify and add profiles, see here.

+

Food Editor handles your customized food database.

+

Admin Tools gives you access control and database tools, see here.

+
+
+

Simple views:

+../../_images/UseNS22.png +
+
    +
  • Clock - Shows current BG, trend arrow, and time of day. Grey text on a black background.

  • +
+../../_images/SetupNS32.png +
    +
  • Color - Shows current BG and trend arrow. White text on a color background.

  • +
+../../_images/SetupNS33.png +
    +
  • Simple - Shows current BG. Grey text on a black background.

  • +
  • [+] - Create custom, simplified views using a predefined set of elements.

  • +
+../../_images/SetupNS34.png +
+

List of available items:

+
    +
  • SGV - Sensor Glucose Value

  • +
  • SGV age - time since the last SGV read

  • +
  • SGV delta - change of SGV in the last 5 minutes

  • +
  • Trend arrow - icon of the SG trend

  • +
  • Time - current time

  • +
  • Line break - invisible item that will move following items to the next line (by default all are showing on the same level)

  • +
+

All visible items have Size property which allows to customize the view even more. Also, all items may appear multiple times on the view.

+

Apart from adding items, it is possible to customize other aspects of the views, like selecting Color or Black background. The first one will indicate current BG threshold (green = in range; blue = below range; yellow = above range; red = urgent below/above). Show SGV age option will make SGV age item appear Always or only if the predefined threshold is reached: Only after threshold. Breaching SGV age threshold will also make Color background turn grey and strike through SGV. Clock view configurator will generate an URL (available under Open my clock view! link) that could be bookmarked.

+

If you launch one of these views in a fullscreen view in iOS, you can use a left-to-right swipe gesture to exit the view.

+
+
+
+

Settings:

+../../_images/UseNS23.png +
+

You can customize your view using Settings. Changes will only be applied to your current browser view, if you want to make these settings default for any browser you need to change directly the corresponding system variables indicated below and add the corresponding plugins in SHOW_PLUGINS.

+

You need to authenticate to save your settings.

+
+

Units DISPLAY_UNITS

+
+
+

Date Format TIME_FORMAT

+
+
+

Language LANGUAGE

+
+
+

Scale SCALE_Y

+
+
+

Render Basal BASAL_RENDER

+
+
+

Render Bolus Amount BOLUS_RENDER

+
+
+

Alarms ALARM

+
+../../_images/UseNS24.png +
+
+
+

Edit Mode EDIT

+
+
+

Show Raw BG Data rawbg

+
+
+

Custom Title CUSTOM_TITLE

+
+
+

Theme THEME

+
+
+

Show Plugins SHOW_PLUGINS

+
+../../_images/UseNS25.png +
+

In order to Save your changes you need to Authenticate, click Authenticate and enter your API Secret.

+

Reset, and use defaults will reverse your changes to defaults from your config variables.

+

In About you’ll see your current Nightscout version.

+
+
+
+
+

API

+

You can find information about your site API at:

+

https://{url}/api-docs[?token=TOKEN]

+

https://{url}/api/v2/properties.json[?token=TOKEN]

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/dns/index.html b/nightscout/dns/index.html new file mode 100644 index 00000000..fbeefbe9 --- /dev/null +++ b/nightscout/dns/index.html @@ -0,0 +1,293 @@ + + + + + + + Use a Dynamic DNS — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Warning

+

Nightscout developers advice: not a good idea.

+
+
+

Use a Dynamic DNS

+
+

Either because running a VPS, Northflank or simply because you’d like an alternate name to your Nightscout page, you can use either you own DNS name or free services like those below.

+
+

Warning

+

Adding a free DNS service to your Nightscout setup increases the possibility of unexpected outage.
+Paid DNS services are available at 1$ per month.

+
+
+
+

No-IP

+

No-IP provides one free dynamic DNS hostname.

+
+

Warning

+

Using No-IP for free requires you to confirm your hostname every month.

+
+
    +
  1. Sign up to No-IP. Do not create a Hostname yet.

    +
    +
  2. +
  3. From the dashboard, in Dynamic DNS, No-IP hostnames click Create Hostname.
    +../../_images/DNS01.png

    +
    +
  4. +
  5. Invent your Hostname and select a Domain in the Free Domain list. This will be the URL you will be able to browse from any computer to your Nightscout site.
    +../../_images/DNS02.png

    +
    +
  6. +
  7. If you’re using a VPS or you know the IP address of your current Nightscout, select DNS Host (A) and enter it in IPv4 Address.
    +../../_images/DNS03.png

    +
    +
  8. +
  9. Else, if you only know your current Nightscout site name, select DNS Alias (CNAME) and enter it in Target.
    +../../_images/DNS04.png

    +
    +
  10. +
  11. Click Create Hostname bottom right.

    +
    +
  12. +
+

You now can use this URL when accessing your Nightscout site, in any browser and also for your uploaders and followers.

+
+
+
+

Dynu

+
    +
  1. Sign up to Dynu.

    +
    +
  2. +
  3. From the Control Panel, select DDNS Services.
    +../../_images/DNS05.png

    +
    +
  4. +
  5. Invent your Host name and select a Top Level domain in the list. This will be the URL you will be able to browse from any computer to your Nightscout site.
    +../../_images/DNS06.png

    +
    +
  6. +
  7. Click Add.

    +
    +
  8. +
  9. Replace the proposed IP address in IPv4 Address by your own Nightscout IP, (you can disable IPv6 features) and click Save.
    +../../_images/DNS07.png

    +
    +
  10. +
+

You now can use this URL when accessing your Nightscout site, in any browser and also for your uploaders and followers.

+
+
+
+

FreeDNS

+

FreeDNS proposes thousands of free DNS names, with the issue that many are flagged as dangerous when you’ll want to browse them from your cellular or within public/private networks. You’ll find one that fits your needs but you might need several attempts.

+
+

Warning

+

Using FreeDNS for free requires you to login to confirm your account every six months.

+
+
    +
  1. Sign up to FreeDNS. Enter all required information and click Send activation email.
    +../../_images/DNS08.png

    +
    +
  2. +
  3. Check your inbox (search Spam if you don’t receive the email) and click on the activation link.
    +../../_images/DNS09.png

    +
    +
  4. +
  5. Select Subdomains in the menu, then Add a subdomain.
    +../../_images/DNS10.png

    +
    +
  6. +
  7. Invent your host name in Subdomain, select a domain name in the list (there are more than you can see) and put your Nightscout IP in the Destination field. Write the text in the image and click Save.
    +../../_images/DNS11.png

    +

    Note: you might want to select a less popular name than those proposed by selecting Registry in the left menu (example below for us.to).
    +../../_images/DNS12.png

    +
    +
  8. +
  9. You now can use this URL when accessing your Nightscout site, in any browser and also for your uploaders and followers.
    +../../_images/DNS13.png

  10. +
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/docker/index.html b/nightscout/docker/index.html new file mode 100644 index 00000000..9275a921 --- /dev/null +++ b/nightscout/docker/index.html @@ -0,0 +1,192 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/downloaders/index.html b/nightscout/downloaders/index.html new file mode 100644 index 00000000..42f2078b --- /dev/null +++ b/nightscout/downloaders/index.html @@ -0,0 +1,428 @@ + + + + + + + Setup Downloaders - Followers — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Setup Downloaders - Followers

+
+
+

Smartwatches

+

See the dedicated page here. +../../_images/IconSW.png

+
+
+

Note: ../../_images/LockOK.png indicates applications compliant to Nightscout access tokens.

+
+
+

Android

+
+

xDrip+

+

../../_images/IconSW.png../../_images/IconPhone.png../../_images/IconTablet.png ../../_images/LockOK.png

+https://xdrip-plus.firebaseapp.com/cdn/xdrip-plus-slides/img/xdrip-plus-high-low-alarms.png +

Select the Nightscout Follower data source and type your Nightscout URL:

+

Example: https://name.domain.tld

+

For a secured site add the token and @ before:

+

Example: https://token@name.domain.tld

+../../_images/Follower00.png +

Facebook group xDrip

+
+
+
+

AndroidAPS NSClient

+

../../_images/IconSW.png../../_images/IconPhone.png../../_images/IconTablet.png ../../_images/LockOK.png

+

Facebook group AndroidAPS Users

+
+
+
+

Nightwatch (Google Play Store)

+

../../_images/IconPhone.png../../_images/IconTablet.png ../../_images/LockOK.png

+

Monitor your Nightscout glucose levels on your Android phone or tablet. Dark UI, large readings and buttons, designed for usage at night.

+../../_images/Follower10.png +
+
+
+

Nightwatch (legacy)

+

../../_images/IconSW.png../../_images/IconPhone.png../../_images/IconTablet.png

+

CGM data on your Android Phone and Android Wear Watch!

+

Nightwatch is not maintained anymore and might not work with recent Android versions. Switching to xDrip+ is recommended.

+
+
+
+

Glimp

+

../../_images/IconSW.png../../_images/IconPhone.png../../_images/IconTablet.png ../../_images/LockOK.png

+

In Settings, Cloud, Nightscout, select Download only and type your Nightscout URL. Use a token or API_SECRET for a secure site.

+../../_images/Follower06.png +
+
+
+

Diabox

+

../../_images/IconSW.png../../_images/IconPhone.png../../_images/IconTablet.png ../../_images/LockNO.png

+

In Settings, set Data Collection to Follower, select Nightscout and type your Nightscout URL.

+../../_images/Follower07.png +
+
+
+
+

iOS

+
+

Nightscout X

+

../../_images/IconPhone.png../../_images/IconTablet.png ../../_images/LockOK.png

+../../_images/Follower04.png +
+
+
+

Nightguard

+

../../_images/IconSW.png../../_images/IconPhone.png../../_images/IconTablet.png ../../_images/LockNO.png

+

GitHub

+https://raw.githubusercontent.com/nightscout/nightguard/master/images/nightguard24.jpg +
+
+
+

Nightscouter

+

../../_images/IconSW.png../../_images/IconPhone.png../../_images/IconTablet.png ../../_images/LockNO.png

+

GitHub

+
+
+
+

Loop Follow

+

../../_images/IconSW.png../../_images/IconPhone.png../../_images/IconTablet.png ../../_images/LockOK.png

+
+
+
+

Spike

+

../../_images/IconSW.png../../_images/IconPhone.png../../_images/IconTablet.png ../../_images/LockOK.png

+https://spike-app.com/wp-content/uploads/2019/03/iPhoneXSpikeHome2019.png +

Look here.

+
+
+
+

xDrip4iOS

+

../../_images/IconSW.png../../_images/IconPhone.png../../_images/IconTablet.png ../../_images/LockOK.png

+

Set xDrip4iOS to follower mode and enable Nightscout, type your Nightscout URL.
+If you’re using a secured Nightscout site, enter your token in the matching field.

+../../_images/Follower01.png +

Facebook group xDrip4iOS

+
+
+
+

sugarmate

+
+

Important limitation

+

Sugarmate doesn’t allow Nightscout as a data source if you included bridge in ENABLE. +If you need this data source: enable obscuration variables.

+
+

../../_images/IconSW.png../../_images/IconPhone.png../../_images/IconTablet.png ../../_images/LockOK.png

+../../_images/Follower05.png +

Add Nightscout as a data source, type your Nightscout URL.

+../../_images/Follower02.png +
+
+
+

Diabetes Cockpit

+

../../_images/IconSW.png../../_images/IconTablet.png ../../_images/LockOK.png

+../../_images/Follower08.png +
+
+
+

Gluco-Tracker

+

../../_images/IconSW.png../../_images/IconPhone.png../../_images/IconTablet.png ../../_images/LockOK.png

+../../_images/Follower09.png +
+
+
+

NightscoutMenuBar

+
+
+

BitBar Nightscout

+
+
+
+
+

Mac

+
+

Nightscout MacOS Menu Bar

+

Show your current BG in the system bar at the top of your screen on Mac (including Loop details). Available directly through the Apple Store.

+../../_images/Follower11.png +
+
+
+
+

Windows

+
+

FloatingGlucose (archived)

+../../_images/LockOK.png +https://raw.githubusercontent.com/dabear/FloatingGlucose/master/floatingglucose.png +
+
+
+

Owlet

+../../_images/LockOK.png +https://raw.githubusercontent.com/kashamalasha/nightscout-widget-electron/main/docs/screenshot-widget.png +
+
+
+

NS2Win

+../../_images/LockOK.png +https://user-images.githubusercontent.com/60714349/230734030-d6ae822f-1a48-48d2-8df0-cb168146176b.png +
+
+
+
+

Displays

+
+

M5Stack NightscoutMon

+

../../_images/LockOK.png Facebook group M5STACK NIGHTSCOUT

+https://raw.githubusercontent.com/mlukasek/M5_NightscoutMon/master/images/M5NS_mon_2019-06-20_page1.jpg +
+
+

M5Stick NightscoutMon

+https://raw.githubusercontent.com/mlukasek/M5StickC_NightscoutMon/master/images/M5StickC_Nightscout_w-speaker.jpg +

../../_images/LockOK.png

+
+
+
+

BGBuddy

+https://user-images.githubusercontent.com/11561147/208538830-5ceb35ea-0ee1-4cdb-b980-db8bcfabd936.jpg +
+
+
+

SugarPiDisplay

+https://raw.githubusercontent.com/bassettb/SugarPiDisplay/master/docs/image2.jpg +
+
+
+
+

Other

+

Home assistant

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/first_setup/index.html b/nightscout/first_setup/index.html new file mode 100644 index 00000000..a700bbc5 --- /dev/null +++ b/nightscout/first_setup/index.html @@ -0,0 +1,227 @@ + + + + + + + New Nightscout Setup — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

New Nightscout Setup

+
+

a) Your Nightscout site should open and direct you to a new profile creation.

+../../_images/NewNS50.png +
+

b) Setup your Time zone and eventually all other fields. Do not leave any fields empty. If you don’t know which value to use, just use the default value. You can change these values later at any time.

+../../_images/NewNS44.png +
+

c) Browse down to Authentication status and click Authenticate. Enter your API secret. Click Update.

+../../_images/NewNS45.png +
+

d) Click Save.

+../../_images/NewNS46.png +
+

e) If the following pop-up shows up click OK, and check status (upper right of the window).

+../../_images/NewNS47.png +
+

f) If you need to modify your profile after this, authenticate with the lock icon (top right of the page): enter your API secret. Then click on the hamburger menu and select Profile Editor.

+../../_images/NewNS43.png +
+
+

Privacy warning

+

Anyone with access to the URL of your Nightscout site, can view your BG and run reports of your data. It it strongly recommended that you enable security to your site once you’re done with the setup

+
+
+

g) Dexcom Share users should see data flowing in after some minutes. +xDrip+ users (including Medtronic CareLink followers) should setup the uploader as shown here. +xDrip4iOS users here. +AAPS and Loop: consult the relative documentation.

+../../_images/NewNS48.png +
+
+

You have completed a new Nightscout site creation. You can continue here now.

+

The following section provides more information that you might not need to use now.

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/github/index.html b/nightscout/github/index.html new file mode 100644 index 00000000..cdc71344 --- /dev/null +++ b/nightscout/github/index.html @@ -0,0 +1,258 @@ + + + + + + + GitHub — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

GitHub

+

You will need your own GitHub account if you want to deploy Nightscout in some platforms (check below).

+
+ +
+
+
+ +
+

You need your own GitHub account and cgm-remote-monitor fork (copy).

+
+ +
+

A GitHub account and cgm-remote-monitor fork (copy) is not mandatory but it is recommended.

+
+ +
+

You don’t need a GitHub account.

+
+
+
+
+

Create a GitHub account

+

a) Click this link to create a GitHub account: https://github.com/

+

Enter your email and click Sign up for GitHub

+

../../_images/NewNS00a.png

+

b) Enter a password and a username (anything you want and that is accepted, not very important).
+Type n to decline advertisement emails.

+

../../_images/NewNS00.png

+

c) Play and solve the puzzle then click Create account

+

../../_images/NewNS01.png

+

d) GitHub will send you a verification code. Open your mail and check your inbox (check your spam-folder if not received after a couple of minutes).

+

../../_images/NewNS02.png

+

e) If a personalization sequence starts, click Skip personalization at the bottom.

+

../../_images/NewNS03.png

+

f) Leave the page that opened as it is. Don’t close it.

+

../../_images/NewNS04.png

+

You have created your GitHub account. Now fork the Nightscout project.

+
+
+

Fork the Nightscout project

+

a) Click here to log in at GitHub: https://github.com/login.
+Enter your username or email and your password. Click Sign in

+

../../_images/UpdateNS00.png

+
+

If you already have a fork of cgm-remote-monitor in GitHub

+

Delete or update your current cgm-remote-monitor fork before continuing.

+
+

b) Open this link https://github.com/nightscout/cgm-remote-monitor. Click on Fork

+

../../_images/NewNS29.png

+

Confirm with Create fork

+
+

Warning

+

Make sure you deselect Copy the master branch only.

+
+

../../_images/NewNS51.png

+

c) Wait for a moment

+

../../_images/NewNS30.png

+

d) You now have a copy (fork) of the Nightscout project repository in your own GitHub.

+

../../_images/UpdateNS30.png

+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/ifttt/index.html b/nightscout/ifttt/index.html new file mode 100644 index 00000000..f8f8ec79 --- /dev/null +++ b/nightscout/ifttt/index.html @@ -0,0 +1,356 @@ + + + + + + + IFTTT Integration — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

IFTTT Integration

+

If This, Then That (IFTTT) is a useful Nightscout integration. By using IFTTT, you can have single button presses on your iPhone that will set an override, log a cannula change, log a sensor change and much more.

+
+

Step 1: Get your API Secret Hash

+

First we need to gather one thing called your “hashed API Secret”. In your internet browser, open a “console” window while viewing your Nightscout site. Make sure you have “authenticated” your site by using your API secret in the Nightscout settings area (hint: if you see a little padlock in the upper left corner of the site, you haven’t authenticated it). Refresh the site and your hashed secret key will be shown as “apisecrethash: “xxxxxxxxxx…””

+

For Safari users on Mac, you can open the console window by selecting “Develop” from the Safari top menu, and then “Show Page Source” (if you do not see “Develop” in the top menu, activate it by going to Safari > Preferences… > Advanced, and checking the “Show Develop menu in menu bar” option). If you’re having problems seeing the apisecrethash, click the little grey triangle next to the “status isAuthenticated” line and the objects below it will display (see screenshot). Your hashed API secret can be copied and pasted from that line, as shown below. Save that somewhere easy to get to again, because you will be using it later.

+../../_images/hashed_API.png +

For Chrome users, the console window is found through the View >> Developer >> View Source. Click on the Console tab and scroll to find the “status isAuthenticated” row to find your apisecrethash. Copy your API hash to somewhere you can retreive it again, we will be copy/pasting it in Step 2.

+../../_images/hashed_API2.png +
+
+

Step 2: Create your “Applets”

+

IFTTT calls their little actions that you’ll create an “applet”. I have no idea why. But, I will go along and use their terminology so we are all consistent. We are basically interested in creating applets that will be buttons on your phone to do cool things in Nightscout. So, you’ll have a button that will log when you changed your sensor last…letting you see in Nightscout easily just how old a sensor is at any given time. Or you can create a button that will turn on an “exercise” override that you already programmed into your kid’s Loop app. So, let’s make our first applet (aka button).

+ +../../_images/IFTTT_signup.png +
    +
  • Login to your IFTTT.com account and select click this link to get to the page for creating your first “New Applet”. (You can also get to this Applet creation page by selecting your Account icon in the upper right of the IFTTT website, then clicking on “Create”.)

  • +
  • In the screen that appears, click on the black “+this” part of the screen

  • +
+../../_images/IFTTT_this.png +
    +
  • In the next screen, type “button” in the search field and then click on the red box labelled “ButtonWidget”

  • +
+../../_images/IFTTT_button.png +
    +
  • Connect the button widget by clicking on the large black”connect” button twice, once on the main screen and then second on the pop-up window that will appear immediately after that. (You will only have to “connect” the widgets for the first applet you make. After that the widgets will already connected to your IFTTT account.)

  • +
+../../_images/IFTTT_connect1.png +
    +
  • Click on the large red “button press” box

  • +
+../../_images/IFTTT_buttonpress.png +
    +
  • Click on the black “+that” text

  • +
+../../_images/IFTTT_that.png +
    +
  • Enter “Webhooks” in the search field and click on the Webhooks app

  • +
+../../_images/webhooks1.png +
    +
  • Connect the Webhooks app

  • +
+../../_images/webhooks2.png +
    +
  • Select the blue “Make a Web Request” box

  • +
+../../_images/webhooks24.png +
    +
  • Now you will have a blank web request template to complete. Screenshot below is an example of a completed recipe for eating soon IFTTT action. There are four parts you will need to fill in, and they are described below the screenshot.

  • +
+../../_images/webhooks25.png +
+

Danger

+

URL +https://yoursite.platform.fqd/api/v1/treatments.json
(for all IFTTT recipes that are NOT remote overrides…so things like cannula changes, sensor changes, pump battery changes, etc.)

+Change the your URL to your actual site’s info.

+
+
+

Warning

+

Method +The method will be POST

+
+
+

Hint

+

Content Type +The content type will be application/json.

+
+
+

Danger

+

Body +The content of the body will depend on the action that you would like this particular button press to perform. While many recipes are available, any recipe that log carbs to NS will only display the carbs in Nightscout…Loop will not “use” those carbs in treatment or prediction math. The display of carbs in NS though may still be helpful for remote care givers to leave an indication that a low is being noticed and treated. Some sample content for actions that may be useful in Loop:

+Pump Site Change
+{“enteredBy”: “IFTTT-button”, “eventType”: “Site Change”, “duration”: 0, “secret”: “your_hashed_api_goes_here!!!”}

+CGM Sensor Start
+{“enteredBy”: “IFTTT-button”, “eventType”: “Sensor Start”, “duration”: 0, “secret”: “your_hashed_api_goes_here!!!”}

+Note
+{“enteredBy”: “IFTTT-button”, “eventType”: “Note”, “notes”: “Hi mom, please don’t text me for a bit. I’m taking a test.”, “secret”: “your_hashed_api_goes_here!!!”}

+
+
+

Warning

+

Special note for IFTTT to set a Remote Override with dev branch +Triggering a remote override with IFTTT takes a couple considerations;

+
    +
  1. You have followed the directions for setting up remote overrides in Nightscout already.

  2. +
  3. Remote overrides will use https://yoursite.herokuapp.com/api/v2/notifications/loop for the URL line of the applet. Notice that is different from the other type of applets’ URL.

  4. +
  5. The Body message of the applet needs to match the override already programmed in Loop app; the reason, reasonDisplay, and duration all need to match what is preset in your Loop app. The “duration” is giving in minutes in the body message (vs hours in Loop), and if the override is one that is “enabled indefinitely” then the duration is “infinite”. The “reason” is the name of the override but NO EMOJI, and the “reasonDisplay” is the override name with the emoji. Check out the samples Body messages for overrides below. You will have to edit your body messages to match your reason and reasonDisplay. The target range and duration of the override does not need to be specified.

    +Body message for override named “hormones”
    +{“eventType”: “Temporary Override”, “reason”: “hormones”, “reasonDisplay”: “🧟‍♀️ hormones”, “secret”: “your_hashed_api_goes_here!!!”}

    +Body message for override named “running”
    +{“eventType”: “Temporary Override”, “reason”: “running”, “reasonDisplay”: “🏃‍♀️ running”, “secret”: “your_hashed_api_goes_here!!!”}

    +Body message for override named “Low Treatment”
    +{“eventType”: “Temporary Override”, “reason”: “Low Treatment”, “reasonDisplay”: “🍬 Low Treatment”, “secret”: “your_hashed_api_goes_here!!!”}

    +Body message to cancel any override
    +{“eventType”: “Temporary Override Cancel”, “secret”: “your_hashed_api_goes_here!!!”}

  6. +
+
+
    +
  • Click the Create Action button on the bottom of the screen when you finish.

  • +
  • Now is your chance to change the title of your applet now to something meaningful. You can turn on notifications, too, using the slider shown. If you turn on the notifications, you will get an alert on your phone and pebble watch when the button press has been successfully deployed. Finish the IFTTT button by clicking on the Finish button that appears.

  • +
+../../_images/webhooks26.png +
    +
  • Repeat the setup for new applets for as many automated actions/overrides as you would like to setup.

  • +
+../../_images/webhooks27.png +
+
+

Step 3: Enable IFTTT in your Nightscout site

+

Now that we have cool applets made, we need to give Nightscout some information so that it will accept commands from our applets. It’s pretty simple to do…just a couple additions to your Heroku settings.

+
    +
  • Find your Maker Key by going to your IFTTT account icon in upper right corner, choose “My services” and then click on the Webhooks service, settings.

  • +
+
+../../_images/webhooks10.png +
    +
  • You will see your Maker Key as the last part of the URL after the use/; copy and paste that last part (the red circled part as shown)

  • +
+../../_images/webhooks11.png +
    +
  • Login to your Nightscout site host (azure or heroku) and (1) add your Maker Key to the MAKER_KEY line and (2) add “maker” to your ENABLE line.

  • +
+../../_images/IFTTT_NSkey.png +../../_images/IFTTT_enable.png +
+
+

Step 4: Install IFTTT app on your iPhone/Android

+

Now that all the hard work is done, we can take easy street and just add that work to the phone via the IFTTT app. By accessing the IFTTT widget on your iPhone, you’ll be able to easily and quickly access the useful buttons you’ve just created.

+
    +
  • Download the IFTTT app on your phone and log in using your IFTTT account.

  • +
  • For iPhone users, if you swipe right from your iPhone’s home screen, you will have the Today view showing. Scroll to the bottom, click “edit”. This should show a list of existing widgets, followed by a list of “more widgets” with green + signs. Click on the IFTTT’s green circle and the widget will be moved to the top, active widgets area. You can hold your finger on the three left lines of the IFTTT widget row to drag it to the top of your widget panel, if you prefer to have it as the top-most widget.

  • +
+../../_images/IFTTT_today.PNG +

If you end up with more than four IFTTT applets, they will appear in reverse-order of when they were created…which may not be the same as you’d prefer them to appear on your widget bar. If you’d like to reorder them:

+
    +
  • go into your iPhone’s IFTTT app

  • +
  • click on My Applets

  • +
  • click on the gear icon in upper left of screen

  • +
  • click on Widgets

  • +
  • click on the pencil icon in upper right of screen

  • +
  • click and hold the three lines that appear on the right side of the widget that you want to move. Drag the widget to the order in the list that you’d like it to appear in your widget quickscreen.

  • +
+../../_images/IFTTT_reorder.png +
+
+

Extra Credit: Alexa integration

+
    +
  • Since you have IFTTT/Maker requests working, you can get it to work with anything that supports IFTTT, including Alexa. You will need to add “alexa” to your ENABLE line in your Heroku settings. And then repeat the steps above, but instead of using “ButtonWidget” service we started with earlier (the “+if” part of the setup)…you will use the “AmazonAlexa” service.

  • +
+../../_images/alexa_maker.png +
    +
  • Alexa requests do not need underscores, FYI.

  • +
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/multiadmin/index.html b/nightscout/multiadmin/index.html new file mode 100644 index 00000000..111883a1 --- /dev/null +++ b/nightscout/multiadmin/index.html @@ -0,0 +1,415 @@ + + + + + + + Multiple sites and support — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Multiple sites and support

+
+

You might need to have access to multiple accounts without having to juggle between logins and passwords. Below are described some centralizing methods reducing the administrative burden.

+
+
+

Remote support and security

+

Giving username and passwords to someone in order to obtain help to fix Nightscout raises serious security issues. Malicious code can be added to your Nightscout project by ill-intentioned people. Always make sure the version deployed is a fork of the official project. After receiving help, good practice is to change your passwords (if shared) and your API secret.

+

When possible prefer inviting collaborators (see below) and remove them once the issue is fixed.

+
+
+
+

Github

+

You need only one Github account since you can connect multiple web apps to the same GitHub account.

+

Using this strategy you only need to update one GitHub account when a new Nightscout version is released and you will be able to deploy it in all your web apps.

+
+

Hint

+

If you have several web apps connected to the same GitHub repository you must use the standard update method. +Not redeploy (else you’ll break all the links to the repository).

+
+
+
+

Enable automatic deploys in Heroku

+

Automatic deploys will allow you to update automatically your Heroku apps when you update the GitHub repository: you will not need to login into Heroku and perform Manual Deploy, as soon as a new version will be merged into GitHub an automated deploy will trigger in all enabled Heroku apps.

+
    +
  • To enable automatic deploy, log in Heroku and select your app, then Deploy. Verify GitHub and your cgm-remote-monitor app are connected.

  • +
+../../_images/MultiNS06.png +
+
    +
  • Verify the master branch is selected and click Enable Automatic Deploys.

  • +
+../../_images/MultiNS04.png +
+
    +
  • Your Heroku site will update automatically every time you update the GitHub repository.

  • +
+../../_images/MultiNS05.png +
+
+
+

Automatic deploys in Railway and Northflank

+

You don’t need to do anything as all your web apps will upgrade automatically when you upgrade GitHub.

+
+
+
+
+

Heroku

+

You can setup multiple Nightscout sites per Heroku account. You be charged the Eco/Basic plan fee for each app.

+

You can setup collaborators in Heroku. This is very useful for remote support.

+
+
+

Invite someone as a collaborator

+
    +
  • Log into your Heroku account and select your app.

  • +
+../../_images/MultiNS00.png +
+
    +
  • Select Access.

  • +
+../../_images/MultiNS01.png +
+
    +
  • Click Add collaborator and enter the email address of the person supporting you (that is the email address he used to setup his own Heroku account).

  • +
+../../_images/MultiNS02.png +
+
    +
  • You will now see it as a collaborator. Using the pen icon you can modify it or delete it (useful when asking for support, once everything is working).

  • +
+../../_images/MultiNS03.png +
+
+
+

Being a collaborator

+

Note: you will receive an email with the invitation.

+
    +
  • Log in your Heroku account. You will see the apps you are collaborating to in the same list than your primary app. You can now perform most tasks directly in that one Heroku account (deploys, change variables, …).

  • +
+../../_images/MultiNS07.png +
+
+
+
+

Atlas

+

You can invite another user in your organization in order to manage several organizations from the same Atlas account. This is very useful for remote support.

+
+

Invite another user

+

Log into your Atlas account.

+
+
    +
  • Top menu, click Access Manager and select Organization Access from the drop down menu

  • +
+../../_images/MultiNS08.png +
+
    +
  • Click Invite Users

  • +
+../../_images/MultiNS09.png +
+
    +
  • Enter the email address of the person supporting you (that is the email address he used to setup his own Atlas account).

  • +
+../../_images/MultiNS10.png +
+
    +
  • Select Organization Owner then click Invite to Organization.

  • +
+
+

Warning

+

Make sure you enable Organization Owner for the invited user!

+
+../../_images/MultiNS11.png +
+
+
+

Being invited

+

Note: you will receive an email with the invitation.

+
    +
  • Log in your own Atlas account.

  • +
  • Top left, from the drop down menu click the caret and select View all Organizations

  • +
+../../_images/MultiNS12.png +
+
    +
  • In the left menu, click Invitations then click ACCEPT the invitation.

  • +
+../../_images/MultiNS13.png +
+
    +
  • Going back to all your organizations you can now see and administer both of them from this account. In the example below Nightscout is your own organization and My Org 2020-09-20 is a guest organization.

  • +
+../../_images/MultiNS14.png +
+
+

Hint

+

You can rename your organizations from the top left cog (Settings) then clicking the pen icon.

+
+../../_images/MultiNS15.png +
+
+
+
+

Northflank

+

You can setup two Nightscout sites per Northflank account. The 20$ per month credit applies.

+

You can setup teammates in Northflank.

+
+
+

Invite a teammate

+
    +
  • Log into your Northflank account and select Overview, in Members click + to add a teammate.

  • +
+../../_images/NorthflankS1.png +
+
    +
  • Enter the email address of the person supporting you (that is the email address he used to setup his own Northflank account). Add Admin privileges if you want him to interact with your data, leave Default for an observer.

  • +
+../../_images/NorthflankS2.png +
+
    +
  • You can manage teammates in Members: change privileges and delete them, or revoke invitations.

  • +
+
+
+
+

Being invited

+

You will receive an email with the invitation.

+

You will see the invitee project with yours.

+
+
+
+
+

Railway

+
    +
  • Open your Railway dashboard and select your project.

  • +
+../../_images/RailwayM15.png +
+
    +
  • Top right select Settings and Members.

  • +
  • Enter the email address of the person supporting you (that is the email address he used to setup his own Railway account). Select Can Edit privileges if you want him to interact with your data, leave Can View for an observer.

  • +
+../../_images/RailwayS1.png +
    +
  • Confirm the invite with Invite to project.

  • +
+../../_images/RailwayS2.png +
+
+

Being invited

+

You will receive an email with the invitation.

+

You will see the invitee project with yours.

+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/new_user/index.html b/nightscout/new_user/index.html new file mode 100644 index 00000000..44b02354 --- /dev/null +++ b/nightscout/new_user/index.html @@ -0,0 +1,281 @@ + + + + + + + New Nightscout Users — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

New Nightscout Users

+

”What is great is there will be multiple options for those interested in setting up the system! #wearenotwaiting” J.A.

+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+ +
+

Basic concepts

+

Even if knowing how it works is not mandatory, it is very useful to understand a few background concepts before starting DIY Nightscout.

+
    +
  1. The code available open source in GitHub or packaged for you in Docker is the set of instruction that will be used to make your Nightscout. You don’t need to understand it or be a programmer to use it.

  2. +
  3. Your Nightscout will usually be running a web application in the internet cloud, meaning that somewhere on the planet, a computer or another will spend some of its time to keep your Nightscout active. This is the engine of Nightscout: it will make sure to be ready to accept the data you will send to it (BG, treatments, …) or to answer to data requests when you ask them (BG, reports, …) and even send alarms when instructed to do so. You will not see the engine work but you will see its frontpage: the web URL of your Nightscout site, which will be available on any device connected to the internet.

  4. +
  5. Since you will need to store a lot of data, Nightscout must have a database. This database will also be in the cloud, meaning data will be stored on one or more computers, somewhere. The Nightscout engine mentioned above will store and read data from this database whenever required.

  6. +
+../../_images/nselements.png +

From this you understand there are three main pieces necessary to build your Nightscout:

+
    +
  1. The Nightscout code also known as cgm-remote-monitor

  2. +
  3. A cloud platform running the Nightscout web app

  4. +
  5. A cloud database storing Nightscout data

  6. +
+

Some platforms offer both engine and database like Azure, Railway, Northflank and all VPS servers. But you can use an external database if you want. Some others like Heroku or Fly.io don’t propose a database and require you to use an external one. Traditionally the database holding Nightscout data is hosted by another provider (mLab, now MongoDB Atlas) but it might not be the most reliable solution.

+
+
+
+

Building Nightscout DIY in a cloud platform

+

You can run your Nightscout site in several vendors platforms, using free or paid accounts. Try the wizard to see which options can match your needs.

+

Below is a list of most used platforms. There are probably others, don’t hesitate to open an issue in the documentation with the easiest deployment method if you want to see them named here.

+
+
+
+

Vendors comparison table

+
+

Note

+

Hosted services include everything: platform, database and support.

+
+

T1Pal, NS10BE, Nightscout Pro, Serendipity Bio, Nightscout4u

+../../_images/Comparison.png +
+
+
+

Free DIY

+

These are the current solutions not involving, or limiting to a strict minimum, costs.

+
+

Note

+

Most vendors will require a credit card to authenticate users and avoid abuse.

+
+

Azure, Northflank, Fly.io, Render, Atlas, Google Cloud, Oracle

+../../_images/Comparison2.png +
+
+ +
+

Security and safekeeping

+
    +
  • Do not use the same password for all your accounts, and choose passwords that are not easy to guess.

  • +
  • Do not use the API_SECRET for the Atlas database password.

  • +
  • Do not use your Dexcom or CareLink user name or password for Nightscout components.

  • +
  • Do not share the API_SECRET or other passwords of your accounts to others.

  • +
  • Do not use Nightscout or any related applications on rooted and/or otherwise compromised devices, and ensure you always have the latest operating system and virus protection updates installed.

  • +
+

If you want to read more about Nightscout security, including about additional configuration options to make your installation more secure, please check our security guide.

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/platform/index.html b/nightscout/platform/index.html new file mode 100644 index 00000000..bd08bc1b --- /dev/null +++ b/nightscout/platform/index.html @@ -0,0 +1,374 @@ + + + + + + + Choose your platform — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Choose your platform

+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+

Various platforms are available to host your Nightscout site in the cloud.

+
+

Warning

+

Creating a database is mandatory if you want to use: Heroku, Railway, Northflank, Fly.io or Azure. +Make sure you have one before creating a Nightscout web app in these platforms.

+
+

Find a list of commonly used hosting services below, decide which one you’ll want to use.

+
+
+
+

Heroku

+

Heroku Eco

+
+
+

Since the beginning Heroku has been a very popular platform for Nightscout. Most of the documentation was based on a Heroku Nightscout.
+On August 25th 2022, Salesforce decided to drop the free plan. +You can create your new Nightscout site with Heroku using an Eco plan (5$/month).

+

Pros:

+
    +
  • Large platform with a reliable history

  • +
  • Well documented, well known by the community

  • +
+

Cons:

+
    +
  • The Eco plan has the same limitations than the previous Free plan, for 5$ per month

  • +
  • For a Nightscout site a 7$ per month Basic plan is not really worth it (compared to hosted solutions)

  • +
  • Doesn’t include a database

  • +
+
+ +
+
+
+

Azure

+

Azure

+
+
+

Nightscout DIY was originally created with Azure but most users dropped it after costs increased.
+A new deployment method fitting in the free tier has been created using a Docker container.

+

Pros:

+
    +
  • Large platform with a reliable history

  • +
  • Well known by the community IT specialists

  • +
  • Using a basic plan and free services keep it free

  • +
+

Cons:

+
    +
  • Trial account lasts maximum 12 months

  • +
  • Basic plan and pay as you go is free if you stay within quotas

  • +
  • The F1 free app service plan is designed for testing, not production

  • +
  • The Cosmos database doesn’t integrate correctly with Nightscout

  • +
+
+ +
+
+
+

Railway.app

+

Railway

+
+
+

You can easily create a new Railway Nightscout site with a MongoDB Atlas or a Railway MongoDB database. The Hobby plan (5$ per month) allows one Nightscout site and a small database.

+

Pros:

+
    +
  • Easy to deploy or migrate an existing site from Heroku (but not worth it without free tier)

  • +
  • Simple to use and troubleshoot

  • +
  • Can use a reliable native Railway MongoDB database, the cost will add-up within the subscription ($)

  • +
+

Cons:

+
    +
  • The free tier has been removed, only active developers can have 5$ credit per month

  • +
  • The railway.app domain is blocked for safety by some companies

  • +
  • Railway network model causes issues with some follower app and devices

  • +
+
+ +
+
+
+

Northflank

+

+
+
+

You can create your new free Northflank Nightscout site, with its own Northflank database or with a MongoDB Atlas database.

+

Pros:

+
    +
  • Nightscout fits in the free tier

  • +
  • Easy to deploy or migrate an existing site from Heroku

  • +
  • Simple to use and troubleshoot

  • +
  • Can use a professional native Northflank MongoDB database ($)

  • +
+

Cons:

+
    +
  • The Nightscout address generated for your site is impossible to remember

  • +
+
+ +
+
+
+

Fly.io

+

Fly.io

+
+
+

Fly.io proposed a simple migration wizard from Heroku and you can create your new Nightscout site in Fly.io. Using a computer is mandatory with Fly.io as managing your site will require the use of a command line utility. Not recommended for beginners.

+

Pros:

+
    +
  • Nightscout fits in the free tier

  • +
  • Easy to migrate an existing site from Heroku

  • +
+

Cons:

+
    +
  • Maintaining your site requires the use of command line instructions, not very intuitive

  • +
  • Doesn’t include a database

  • +
+
+ +
+
+
+

Google Cloud

+

xDrip+

+
+
+

A scripted Nightscout installation in Google Cloud is a new complete solution proposed by the xDrip+ developers team. Whilst deploying Nightscout manually in Ubuntu can be complex, their approach makes is rather simple for non-technical people.

+

Pros:

+
    +
  • Complete solution offering a large free database

  • +
  • A web interface to edit your variables

  • +
  • Tools provided to migrate the database from another platform

  • +
  • Virtually free (<5c/month)

  • +
+

Cons:

+
    +
  • Not available for free for Australia and Cina users

  • +
  • Relying on a free DNS provider

  • +
+
+ +
+
+
+

Render

+

xDrip+

+
+
+

A free solution with little experience.

+

Pros:

+
    +
  • No credit card required

  • +
+

Cons:

+
    +
  • The free plan doesn’t guarantee any reliability

  • +
  • App will sleep after 15 minutes

  • +
  • Render URLs are considered unsafe by some internet providers

  • +
  • Doesn’t include a database

  • +
+
+ +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/plugins-old/index.html b/nightscout/plugins-old/index.html new file mode 100644 index 00000000..730cb2a9 --- /dev/null +++ b/nightscout/plugins-old/index.html @@ -0,0 +1,189 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/plugins-v15/index.html b/nightscout/plugins-v15/index.html new file mode 100644 index 00000000..4856ca16 --- /dev/null +++ b/nightscout/plugins-v15/index.html @@ -0,0 +1,231 @@ + + + + + + + Nightscout-connect — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout-connect

+

As the dependencies of the historical plugins (bridge and mmconnect) have been deprecated, a new plugin has being created to allow long term sustaining and increase the number of supported cloud providers.

+

This plugin is under test and is currently only available in the dev branch of Nightscout (version 15.0).

+
+

Prerequisites

+

You need to use the development branch of Nightscout.

+
+

AAPS users

+

Do not upgrade Nightscout to V15 unless you use the dev version of AAPS.

+
+

Follow these guidelines to update your Nightscout app to dev.

+
+

In order to enable the nightscout-connect plugin you need to add connect in your ENABLE variable.

+

Edit your variables following these instructions, search the ENABLE variable, modify its contents to add the word connect, separated by a space, at the end of the line.

+
+
+
+

dexcomshare

+

dexcomshare is the replacement of bridge.

+

In order to use it you need to add the following variables in your Nightscout configuration:

+

Remove the word bridge from the ENABLE variable list.

+

CONNECT_SOURCE=dexcomshare

+

CONNECT_SHARE_SERVER=ous Add this variable only if you’re not in the US. Else don’t add it (us).

+

CONNECT_SHARE_ACCOUNT_NAME= The username on your master device (the one connected to the sensor)

+

CONNECT_SHARE_PASSWORD= The password matching the username above.

+
+
+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/profile_editor/index.html b/nightscout/profile_editor/index.html new file mode 100644 index 00000000..9cbbdb4f --- /dev/null +++ b/nightscout/profile_editor/index.html @@ -0,0 +1,234 @@ + + + + + + + Setup your Profile — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Setup your Profile

+../../_images/SetupNS13a.png +

The top part will show your site settings: Title, Units and Date Format.

+../../_images/Profile00.png +
+
+

Profile view

+

Profile Editor will display your active profile. If you created more than one profile you can select the one you want with the drop down menu Stored Profiles.

+

You can add a profile with +, delete it with X and duplicate (clone) it to create a new one starting with the values in the current one.

+

Note: changing profile selection keeps the modifications you’ve made in other profiles.

+../../_images/Profile02.png +
+

Each profile has a Name, a Timezone and a DIA that you can modify. If you don’t know which DIA to use, ask you endocrinologist since this is a complex subject. See also here.

+../../_images/Profile03.png +
+

For each profile you can define Insulin to carb ratio (I:C), Insulin sensitivity factor (ISF) and Carbs absorption rate. Both I:C and ISF can be defined for specific times of the day by slices of 30 minutes, click the + sign to add another interval.

+

These values are key to diabetes management. Ask your endocrinologist about them if you don’t know where to start.

+

Look here for calculating the carbs absorption rate.

+../../_images/Profile04.png +
+

If your uploader doesn’t send pump basal values to Nightscout, you can duplicate the information in Basal rates in order to match your current basal profile (and Nightscout is also a nice place to save this information). Basal rates can be defined by 30 minutes intervals, click + to add another one .

+../../_images/Profile05.png +
+

You can also define your Target BG range Low and High for various moments of the day.

+../../_images/Profile06.png +
+

After you defined your profile you need to Authenticate with your API Secret in order to be able to save it.

+

For modifications, read the next paragraph and make sure you understand the Database records mechanism.

+../../_images/Profile07.png +
+
+
+

Modifying a profile and Database records

+

When you modify a profile and save it, the whole database record will be updated to reflect the profile change. This means all periods of time using this specific profile since the database record Valid time and date will be updated to your profile modification. If you don’t want this to happen, you should create a new database record and recreate your profiles in this new record.

+

You can add a record with +, delete one with X (it will delete the corresponding profiles information in the time frame of the record) and duplicate (clone) it.

+../../_images/Profile01.png +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/pushover/index.html b/nightscout/pushover/index.html new file mode 100644 index 00000000..c7e8fc5b --- /dev/null +++ b/nightscout/pushover/index.html @@ -0,0 +1,476 @@ + + + + + + + Remote notifications — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Remote notifications

+

While Loop app currently sends notifications locally on Loop user’s iPhone, parents and caregivers likely want those messages on their phones, too. We can achieve this functionality through a combination of Nightscout, IFTTT, Google, and Pushover.

+

Traditionally, most people may already know of Pushover alerts through their NS site. The old Loop docs had set up for how to add your PUSHOVER_ANNOUNCEMENT_KEY , PUSHOVER_API_TOKEN, and PUSHOVER_USER_KEY in your Heroku settings to get notifications on the non-looping phones of parents and caregivers. The drawback for that method is that you could not necessarily fine-tune the alerts (maybe you wanted battery alarms on your NS website, but not get pushovers for them…a bit hard to separate out the environments that way) and Pushover had a demanding acknowledgment requirement. If you failed to acknowledge an alert, you may end up getting alarm fatigue fairly quickly as the alarm repeated itself.

+

Using Pushover THROUGH IFTTT however, we can improve the possible notifications and who receives which ones. For example, a teenage Looper may want notifications when his/her pump site needs changing and when his/her Dexcom is about to expire in the next day. S/he already gets local notifications on his/her phone via Loop for low reservoir volumes, low pump battery, and Loop failures. Dexcom app provides high/low BG notifications locally, too. If s/he were to get those same alarms via Pushover, s/he would inevitably get alarm fatigue. A remotely-monitoring parent may want additional information, like a pushover alert when the school nurse boluses for lunch, as well as Loop failures, low iPhone battery level for the child, low pump battery, and other such information that might be useful. Perhaps there’s also an emergency contact person that you only want to get high/low BG alerts…you can set that up as well quite easily.

+

The basic concept is that NS puts out an event that triggers the IFTTT service called Webhooks (old name was “Maker Webhooks” hence you may see references to “maker” in NS docs). Actually, there are several types of events that NS has programmed in all ready to use in IFTTT.

+../../_images/ns-core-events.png +

For this setup, we are going to use the most general logging event called ns-event. You’ll get all the alarms and notifications logged, and then you can decide in subsequent steps which ones you’d actually like to send to your phone for pushover notification.

+

As a brief roadmap for what we are going to do:

+
    +
  1. Get necessary accounts setup

  2. +
  3. Add a folder to your Google Drive

  4. +
  5. Make an IFTTT applet to log NS events to your Google Spreadsheets

  6. +
  7. Enable NS to work with that new IFTTT applet

  8. +
  9. Make an IFTTT applet to send Pushover alert when the Google Spreadsheet is updated

  10. +
+
+

Get Prepped

+

If you don’t already have these steps done, you will need them. Skip any that you already have done.

+
    +
  • Setup a Nightscout site

  • +
  • Get an IFTTT account

  • +
  • Get a Pushover Account

  • +
  • Get a Google Account

  • +
  • Download the Pushover app onto your phone, and any other phone you’d like to receive Pushover alerts

  • +
  • Download the IFTTT app onto your phone, and any other phone you’d like to use IFTTT applets on

  • +
  • Login to the Pushover and IFTTT apps with your login information

  • +
+
+
+

Add a Google Drive folder

+
    +
  • Login to your Google account and select Google Drive

  • +
+../../_images/google1.png +
    +
  • Click on the blue “New” button and create a new folder named IFTTT.

  • +
+../../_images/google2.png +
    +
  • Double click on the newly created IFTTT folder, select the blue “New” button again, and create a new subfolder called “Nightscout-Alarms”

  • +
+../../_images/google3.png +

This IFTTT/Nightscout-Alarms folder will eventually contain numerous Google Spreadsheets, one for each NS alarm or information that is logged. As new alarms are triggered, the IFTTT applet we are about to write will add a row to the appropriate spreadsheet logging the time of the alarm and any other reported details that go with the entry. For now though, your drive will be blank…screenshot below just to give you an idea of where we are going.

+../../_images/google4.png +
+
+

Make 1st IFTTT Applet to Log NS Alarms

+
    +
  • Login to your IFTTT.com account and select the “New Applet” button.

  • +
+../../_images/IFTTT_newapplet.png +
    +
  • In the screen that appears, click on the blue “+this” part of the screen

  • +
+../../_images/IFTTT_this.png +
    +
  • In the next screen, type “webhooks” in the search field and then click on the blue connect button

  • +
+../../_images/webhooks1.png +
    +
  • If this is the first time you are using IFTTT Webhooks service, you will have a “Connect” button to select. If you already have IFTTT applets using Webhooks, you won’t see this screen…just move to the next bullet.

  • +
+../../_images/webhooks2.png +
    +
  • Click on the “receive a web request” blue box, and then fill in the Event Name as ns-event and then press the “Create trigger” button. (Side note: the event name used here corresponds to the triggers discussed above for core events that NS already has integrated for IFTTT users. If you want to, instead, use the other triggers such as ns-warn or ns-urgent, you can. This example is using the most general trigger so that the options are wider for most users.)

  • +
+../../_images/webhooks3.png +
    +
  • Click on the blue “+that” text

  • +
+../../_images/IFTTT_that2.png +
    +
  • Enter google in the search field and click on the Google Sheets icon

  • +
+../../_images/webhooks4.png +
    +
  • Select the green “Add row to spreadsheet” box

  • +
+../../_images/webhooks5.png +
    +
  • Delete the contents of the “Spreadsheet Name” and “Drive folder path”. For the “Spreadsheet Name”, click the “Add Ingredient” button and select the “Value1”. For the “Drive folder path”, enter IFTTT/Nightscout-Alarms. You do not have to modify the “Formatted row” box’s contents. Click the “Create action” button at the bottom.

  • +
+../../_images/webhooks6.png +
    +
  • Turn off the toggle for receiving notifications when the applet runs, and then click the Finish button

  • +
+../../_images/webhooks7.png +
    +
  • You’ll now have the finished IFTTT applet that will cause a row to be added to a Google spreadsheet…tracking all your NS notifications and alarms. If it is the first time that alarm has been logged, the applet will also create the spreadsheet itself. After a while, your IFTTT/Nightscout-Alarms folder will start to look like the screenshot posted above with numerous spreadsheets for each alarm type.

  • +
+../../_images/webhooks8.png +
+
+

Enable IFTTT Webhooks in your Nightscout site

+
+

Note

+

If you already have created IFTTT buttons previously to work with your NS site, you can skip this section. If those buttons are working, then you’ve already added your MAKER_KEY and “maker” to your ENABLE line in Heroku.

+
+
    +
  • To actually make that first applet work, we need to enter a “Maker Key” to get NS and IFTTT talking to each other. Find your Maker Key by going to your IFTTT account, Services and then clicking on Webhooks. (Your screen may not have as many services showing; the example account below just happens to already use several services.)

  • +
+../../_images/webhooks9.png +
+../../_images/webhooks10.png +
    +
  • You will see your Maker Key as the last part of the URL; copy that last part (the red circled part)

  • +
+../../_images/webhooks11.png +
    +
  • Navigate to your Heroku account’s settings tab, “reveal config vars” and (1) add your Maker Key to the MAKER_KEY line and (2) add “maker” to your ENABLE line.

  • +
+../../_images/IFTTT_NSkey.png +../../_images/IFTTT_enable.png +
+
+

Make 2nd IFTTT Applet to send Pushover notifications

+
    +
  • In your IFTTT account, select the “New Applet” button.

  • +
+../../_images/webhooks12.png +
    +
  • In the screen that appears, click on the blue “+this” part of the screen

  • +
+../../_images/IFTTT_this.png +
    +
  • In the next screen, type “google” in the search field and then click on the “Google Sheets” logo.

  • +
+../../_images/webhooks4.png +
    +
  • Click on the “New row added to spreadsheet” as the trigger.

  • +
+../../_images/webhooks13.png +
    +
  • Enter the following information: Folder path is IFTTT/Nightscout-Alarms and for the filename you are going to enter the name of the particular NS alarm or information that you would like to get pushover alerts for. Click on the “Create trigger” button to save the trigger.

  • +
+../../_images/webhooks14.png +
+

Note

+

This applet can’t be created unless your filename (alarm spreadsheet) already exists. If your 1st applet we created above hasn’t run for a long time, the spreadsheets may not exist yet because the alarms haven’t triggered. You have two options…(1) manually create the file in your Google Drive so that you can finish the applet now or (2) wait several days/weeks for the alarms to happen and that will automatically create the files in your Google drive.

+If you choose option 1, here’s a partial list of some of the filenames you could create in advance:

+
+
* Loop isn't looping
+* Cannula age 48 hours
+* Cannula age 72 hours
+* Meal Bolus
+* Warning, Pump Reservoir Low
+* Warning Uploader Battery is Low
+* Temporary Override
+
+Depending on your alert levels you specified in NS, some of the hours in the titles may vary to match your settings
+
+
+
    +
  • Click on the blue “+that” text

  • +
+../../_images/IFTTT_that2.png +
    +
  • Enter pushover in the search field and click on the Pushover icon. If this is your first time linking your IFTTT to Pushover, you will be prompted to enter your Pushover account login and allow IFTTT access. This only needs to be done once.

  • +
+../../_images/webhooks15.png +
    +
  • Select the “Send a Pushover notification” box

  • +
+../../_images/webhooks16.png +
    +
  • Delete the contents of the “Title” and “Message” and “URL” boxes. For the Title, click the “Add Ingredient” button and add ColumnC. For the “Message”, click the “Add Ingredient” button and add the values of various columns from your spreadsheet for the information you would like to include. For the alerts: ColumnC contains the alarm name, ColumnA is the date/time of the alarm, and ColumnD has more detailed information about the info/alarm. This is a pretty decent recipe to follow to get the useful information in your notification.

  • +
+../../_images/webhooks17.png +
    +
  • Select the “Message Priority” that you would like for this particular alarm type.

  • +
+../../_images/webhooks18.png +
    +
  • Select the “Device” that you would like to receive this particular alarm type. The devices listed will be all your devices that have Pushover app installed and logged into. Click “Create Action” when you are finished.

  • +
+../../_images/webhooks19.png +
    +
  • You’ll now have made the IFTTT applet that will cause a Pushover notification to a particular device for a particular NS alarm, once the first applet records the alarm in the google spreadsheet. Keep the “receive notification when this Applet runs” toggled off and click the Finish button.

  • +
+../../_images/webhooks20.png +
+
+

Revisit Nightscout Alert Levels

+

Putting all these notifications together may cause you to want to revisit the alert levels you have set in your Heroku settings. Here’s a short summary of NS for the looping-related alerts (Note: the last row, Upbat, is the Looping iPhone battery level for Loop users; or the rig’s battery level for OpenAPS users.) If you’d like some of these alarms for your site and don’t currently have them activated (they are all off by default unless specifically turned on), the lines you’d need to add are in the last column. If you like the default values of the WARN and/or URGENT, you don’t have to add those extra lines…just the line to enable the alerts will be sufficient.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SETTINGDEFAULT
WARN
DEFAULT
URGENT
HEROKU
SETTINGS
CAGE4872CAGE_ENABLE_ALERTS = true
CAGE_WARN=XX
CAGE_URGENT=XX
SAGE164168SAGE_ENABLE_ALERTS = true
SAGE_WARN=XX
SAGE_URGENT=XX
IAGE4872IAGE_ENABLE_ALERTS = true
IAGE_WARN=XX
IAGE_URGENT=XX
LOOP3060LOOP_ENABLE_ALERTS = true
LOOP_WARN=XX
LOOP_URGENT=XX
OPENAPS3060OPENAPS_ENABLE_ALERTS = true
OPENAPS_WARN=XX
OPENAPS_URGENT=XX
PUMP_CLOCK3060PUMP_ENABLE_ALERTS = true
PUMP_WARN_CLOCK=XX
PUMP_URGENT_CLOCK=XX
PUMP_RES105PUMP_ENABLE_ALERTS = true
PUMP_WARN_RES=XX
PUMP_URGENT_RES=XX
PUMP_BATT_P3020PUMP_ENABLE_ALERTS = true
PUMP_WARN_BATT_P=XX
PUMP_URGENT_BATT_P=XX
PUMP_BATT_V1.351.30PUMP_ENABLE_ALERTS = true
PUMP_WARN_BATT_V=XX
PUMP_URGENT_BATT_V=XX
UPBAT3020UPBAT_ENABLE_ALERTS = true
UPBAT_WARN=XX
UPBAT_URGENT=XX
+
+
+

Final notes

+
    +
  • You can use other notification services than Pushover in the last part of the second applet. For example, you could use the SMS service to send text notifications to your iPhone instead of Pushover. The downside for that is that the SMS service is limited to 100 message each month…some users may exceed that pretty easily. Another alternative notification would be IFTTT’s own Notification service. This would work well, but does not have the ability to distinguish between devices the way Pushover allows. If you use IFTTT’s Notifications service, every phone using your IFTTT account will get the notices.

  • +
  • To be clear, you do NOT need to have pushover on your ENABLE line nor have PUSHOVER_USER_KEY, PUSHOVER_API_TOKEN, or PUSHOVER_ANNOUNCEMENT_KEY entered into your Heroku settings in order for any of the above to work. This is not the same Pushover as NS has integrated into its code. This is actually through IFTTT services, you just need a Pushover account to link to during the 2nd applet setup.

  • +
  • To create more notifications, simply repeat the steps for the 2nd applet you created, only this time use a new filename that corresponds to the spreadsheet tracking the alert you’d like notifications for. You’ll end up with multiple applets of the dark blue type (the pushover notifiers) and only a single light blue (NS alarm general collector).

  • +
+../../_images/webhooks23.png +
    +
  • Here are examples of the Meal Bolus and Temp Basal ns-event logging spreadsheets

  • +
+../../_images/webhooks21.png +../../_images/webhooks22.png +
    +
  • The 1st applet can only create up to 2000 active rows in a given spreadsheet. After that, the applet will automatically create a new spreadsheet. For most alarms, it may take quite some time to reach 2000 rows of info. For other alerts, such as temp basals being set, that may fill up rather fast for the average looper. You can either clean out the data rows periodically to make room, or update your filename in the 2nd applet periodically when a new spreadsheet is made.

  • +
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/reports/index.html b/nightscout/reports/index.html new file mode 100644 index 00000000..0937f663 --- /dev/null +++ b/nightscout/reports/index.html @@ -0,0 +1,345 @@ + + + + + + + Create Reports — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Create Reports

+

Nightscout offers some fantastic data-crunching report tools in the drawer menu,

+../../_images/UseNS21.png +
+

An interesting video on how to use them with Gary Scheiner.

+
+

Select Reports to open the reports page.

+../../_images/Reports00.png +
+

First select the report type you’d like to see (see below for an overview).

+

Day to day, Week to week, Daily Stats, Distribution, Hourly stats, Percentile Chart, Weekly Distribution, Calibrations, Treatments, Profiles or Loopalyzer

+

Then select the period for which you want your data analyzed.

+

Enable the check box and either select From: and To: dates or Today, Last 2 days, Last 3 days, Last week, Last 2 weeks, Last Month, Last 3 months.

+../../_images/Reports01.png +
+

You can filter your data using key Notes or Event type (select one in the drop down list).

+../../_images/Reports02.png +
+

You can select which week days to use in order to better analyze patterns.

+../../_images/Reports03.png +
+

Confirm your Target BT range bottom and top for your TIR and graph range lines.

+

You can also sort the report from older to newer or newer first.

+../../_images/Reports04.png +
+

Click SHOW and wait for data to load and rendering to complete. This might take some time if the period is long.

+../../_images/Reports05.png +
+
+

Day To day

+

This report will show your BG, day by day, including the treatments you select.

+../../_images/Reports06.png +
+

If you want to change selections, you need to click again SHOW to update the view.

+../../_images/Reports07.png +
+

If you select Insulin distribution you will get a short report.

+

Note: You need Basal rate enabled to see bolus vs basal information.

+../../_images/Reports08.png +
+

You can change the vertical scale to Logarithmic or Linear.

+

You can change the graph Size.

+../../_images/Reports09.png +
+
+
+

Week to Week

+

This report will give you a week by week view, with color code for week days selected.

+../../_images/Reports10.png +
+
+
+

Daily stats

+

This report will give you a daily distribution view.

+../../_images/Reports11.png +
+
+
+

Distribution

+

This report will give you a complete distribution view with a lot of information on the dates range you selected.

+

You also can filter by hours (scroll to the bottom of the page).

+../../_images/Reports18.png +../../_images/Reports12.png +

A1c is only a rough estimation that can be very inaccurate and does not replace actual blood testing. The formula used is taken from:Nathan, David M., et al. “Translating the A1C assay into estimated average glucose values.” Diabetes care 31.8 (2008): 1473-1478.

+

Time in fluctuation and Time in rapid fluctuation measure the % of time during the examined period, during which the blood glucose has been changing relatively fast or rapidly. Lower values are better.

+

Mean Total Daily Change is a sum of the absolute value of all glucose excursions for the examined period, divided by the number of days. Lower is better.

+

Mean Hourly Change is a sum of the absolute value of all glucose excursions for the examined period, divided by the number of hours in the period. Lower is better.

+

Out of Range RMS is calculated by squaring the distance out of range for all glucose readings for the examined period, summing them, dividing by the count and taking the square root. This metric is similar to in-range percentage but weights readings far out of range higher. Lower values are better.

+

GVI (Glycemic Variability Index) and PGS (Patient Glycemic Status) are measures developed by Dexcom, details can be found here.

+
+
+
+

Hourly stats

+

This report will give you an hourly distribution view with a box plot and additional hour by hour statistics.

+../../_images/Reports13.png +
+
+
+

Percentile Chart

+

This report will give you a percentile distribution view of the range you selected.

+../../_images/Reports16.png +
+
+
+

Weekly Distribution

+

This report will give you a weekly view of your statistics.

+../../_images/Reports14.png +
+
+
+

Calibrations

+

This will give you a table of your calibrations, if your uploader sends the correct event and data.

+../../_images/Reports22.png +
+
+
+

Treatments

+

This will give you a table of your treatments, day by day.

+../../_images/Reports15.png +
+
+
+

Profiles

+

This report will display profiles used in the time range.

+../../_images/Reports17.png +
+
+
+

Loopalyzer

+

Loopalyzer is an utility made to help analyze and tune closed loop systems. It may work with other setups as well, both closed and open loop, and non loop.

+

Select the period on which you want to run the report then click Show. A set of graphs will display top to bottom your basal profile, blood glucose, loop deviation from basal (that should be minimized for an optimized closed loop system), insulin on board and carbs on board. On the last two graphs, treatments are represented by vertical black bars.

+../../_images/Reports19.png +
+

Using the dedicated menu you can display your profiles below the graph and use Timeshift. Click Show to update the display when changing the options.

+

You can navigate day to day with < Previous day and Next day > or by period length with << Previous and Next >> (i.e. if you selected a week it will go backwards and forward week by week).

+../../_images/Reports20.png +

Timeshift will allow you to synchronize meals within a time range in order to better analyze your data. Obviously the rest of the day will not make sense since the shift only highlights the time range you are analyzing now. For example below: dinner analysis.

+../../_images/Reports21.png +
+

You might also be interested by AutoTune.

+
+

Warning

+

Make sure to temporarily disable authentication before running AutoTune.

+
+
+
+
+

Nightscout Reporter

+

https://nightrep.zreptil.de/ can be used to generate PDF documents with the data stored at Nightscout.

+

You need to add cors to your ENABLE variables

+

Facebook group Nightscout Reporter

+
+
+
+

Power BI

+

Facebook group Nightscout Power BI Reporting

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/security/index.html b/nightscout/security/index.html new file mode 100644 index 00000000..c354df24 --- /dev/null +++ b/nightscout/security/index.html @@ -0,0 +1,380 @@ + + + + + + + Nightscout Security and Privacy — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout Security and Privacy

+

Nightscout security model is based on the following assumptions:

+
    +
  • The users of Nightscout only use it to process information about themselves or someone they’re legally responsible for and thus own all of the data being stored in Nightscout.

  • +
  • Given the user / operator of Nightscout is assumed to have full ownership of the data stored in Nightscout, it is assumed the user has full responsibility around the use and sharing of the data.

  • +
  • Nightscout provides a set of APIs for reading and writing data into the Nightscout database. Nightscout itself does not directly interface with any devices. Nightscout users should verify any applications using the APIs to process the data in Nightscout have been implemented in a secure fashion and have data validation processes in place in case an unauthorized user gains access to Nightscout and alters the data.

  • +
  • If unauthorized users gain access to the server being used to host Nightscout, the database used with Nightscout or any device used to access the Nightscout APIs, the entire system’s security has to be considered compromised and the user must assume any data stored in the system might be altered and thus should not be trusted.

  • +
+
+

Personal use only

+

The system has not been designed for scenarios where a third party operates a Nightscout installation on behalf of others and if such installations are made, both the users and operators of such installations need to understand there is a large body of legislation across the world that covers use cases and data storage enabled by Nightscout and the liability issues around such installations are extremely complicated.

+
+
+
+

Security and safekeeping

+
    +
  • Use the same email address for all accounts so you’ll have access to all your accounts after installation. Do not use a disposable email address - use something you know you can access later.

  • +
  • Use a safe password for all accounts related to Nightscout, including the password for the email account for the accounts. We highly recommend using a password manager such as 1Password and allowing it to generate the passwords for you.

  • +
  • Do not reuse the same password for all your accounts.

  • +
  • Do not use your Dexcom or CareLink user name or password for Nightscout components.

  • +
  • Do not use the API_SECRET for the Atlas database password.

  • +
  • Do not share the API_SECRET or access tokens with administration privileges to anyone, ever. If you need to grant access to Nightscout, see below for instructions how to create access tokens for this purpose.

  • +
  • Do not use Nightscout or any related applications on rooted and/or otherwise compromised devices, and ensure you always have the latest operating system and virus protection updates installed.

  • +
+
+
+
+

HTTPS and certificate errors

+

One of the core security mechanisms on web is the SSL encryption applied to HTTP connections. When installed to Heroku, Nightscout by default forces connections to use HTTPS, thus ensuring the connection is encrypted. For secure Nightscout use, it’s crucial that you assume something is wrong if you ever see your browser complain the SSL certificate of your Nightscout site does not match or work as expected by the browser. This can be a sign of a so called Man In The Middle (MITM) attack and proceeding with the problematic certificate will subsequently compromise your Nightscout site. If you see an error related to SSL, you should immediately rename the site (see below for instructions).

+
+
+
+

Administration messages

+

Nightscout 14.2 introduced a new feature called Admin Notifies, which can warn you about issues with Nightscout installation and security issues.

+

If you see the red megaphone in your navigation bar, it means you have messages in the queue.

+../../_images/Security02.png +

You have to be authenticated to Nightscout using the API_SECRET or an authentication token that has administration access to read the messages.

+../../_images/Security03.png +

There are multiple types of messages that might be shown:

+
+
+

I’m seeing a message about the API_SECRET being weak

+../../_images/Security04.png +

This message is shown when cryptographic analysis if the API_SECRET shows the secret is easily guessable by a computer and should be changed. Things you can do to have this message go away:

+
    +
  • The API_SECRET must be at least 12 characters long, but making it even longer makes it more secure

  • +
  • Use a mix of small and CAPITAL letters, numbers and non-alphanumeric characters such as !#%&/()= in the API_SECRET +Note: make sure your uploader and downloaders can handle special characters, you might need to express them using Percent encoding for example an API_SECRET like D0n't*H4ck@M3% would be expressed as: D0n%27t%2AH4ck%40M3%25

  • +
  • Consider generating the API_SECRET using a password manager

  • +
+
+
+
+

I’m seeing a message about authentication failures

+../../_images/Security06.png +

This is highly likely caused by you having installed an app on some device with the wrong API_SECRET or access token, and the app trying to authenticate to your Nightscout, or you or one of the family members have just tried to sign into Nightscout with wrong credentials.

+

If you have apps running that use the Nightscout REST API, check you have the correct API_SECRET and/or access token configured to each.

+

If the message keeps appearing unexpectedly or is reported against multiple IP numbers, it’s possible someone is trying to brute force attack your installation and guess your API_SECRET to be able to modify data in your Nightscout. In this situation, we highly recommend you rename the Nightscout site to change it’s address and pick a name that’s hard to guess.

+
+
+
+

I’m seeing a message Nightscout is readable by the world

+../../_images/Security05.png +

This means the site shows the CGM data to users who can guess the site address without authentication. Note Nightscout never allows data to be saved or edited without authentication, so this is not necessarily a problem depending on how hard your site address is to guess and how you want the information to be shared.

+

If you want to have the site require authentication, read the “How to Turn Off Unauthorized Access” section below.

+
+
+
+
+

Renaming the Nightscout site

+

See the instructions in the specific platform section for a new Nightscout creation.

+

Once done, make sure all apps (uploaders and downloaders) are updated accordingly.

+
+
+
+

How to Turn Off Unauthorized Access

+
+

Privacy warning

+

In a default setup, anyone with your Nightscout URL can view your site.

+
+
+

Hint

+

Make sure the app you use to see your data can handle a secured Nightscout site.

+
+

To Take Advantage of Roles, Turn Off Unauthorized Access to Your Site:

+

If you want to ensure that ONLY someone with permission to view your site (e.g., a token) is able to view the data, you should configure the AUTH_DEFAULT_ROLES variable. Set the value as: denied.

+

Edit (or add) this variable and set it to denied (see here how to edit variables).

+../../_images/Admin03.png +

This creates a scenario in which a token will be required for all access (even only view).

+../../_images/Admin02.png +

In order to make your site visible to anybody, set AUTH_DEFAULT_ROLES variable to readable.

+
+
+
+

Create Authentication Tokens for Users

+

Note: authentication tokens are also called access tokens

+
+

Changing API_SECRET

+

If you change your API_SECRET all your tokens will change. Make sure you update your devices and send the new token link to those you allowed to access your Nightscout

+
+

To access the Authentication options, click the settings panel (three horizontal bars in the top right) in your website and select Admin Tools. The Authentication options are at the top of the Admin page. (Note: you must be logged in with your API SECRET to access these tools.)

+../../_images/Admin04.png +
+

You will see several predefined roles:

+../../_images/Admin01.png +
+
+

Roles

+
    +
  • admin: full access

  • +
  • careportal: can view the site and make CarePortal/treatment entries

  • +
  • readable: read-only access; no ability to make CarePortal/treatment entries. This user CAN see reports and profile information.

  • +
  • denied: no access (this role only works if the AUTH_DEFAULT_ROLES setting is also denied. You can’t have a site that is readable to everyone and create a “denied” token for a specific user.)

  • +
  • devicestatus-upload: used by devices

  • +
+
+

Hint

+

There is currently no way to limit a user so that he cannot view the Reports section if he has access to the site. Time/date-based roles are not currently possible.

+
+
+
+
+

Create a Token

+
    +
  • Click the “Add New Subject” button.

  • +
+../../_images/Admin00.png +
+
    +
  • Fill in the name of the subject and the “role” you are giving this subject (from the list of roles shown above). Note you should only grant the readable role for users who do not need to save or edit data in Nightscout. For example, you might want to share the site to a school nurse, but not have him able edit the data.

  • +
+../../_images/Admin05.png +
    +
  • An admin token is necessary for AAPS to upload using the API V3.

  • +
+../../_images/Admin05b.png +
+
    +
  • Click save.

  • +
  • The token will be shown. You can use it in two different ways:

    +
      +
    • Copy the token URL (right-click on it in the browser and select the option to copy the link address) and provide it to the user (e.g., paste it into an email). If the user enters the entire URL (with token), the token will be in effect.

    • +
    • Copy the token string (in the example below school-a595d5f0aeff64c0) and use it for authentication at site opening, instead of the API secret (Nightscout minimum version 14.1.0 required).

    • +
    +
  • +
+../../_images/Admin06.png +
+

You can also add the token to the site URL to authenticate using a token. Your site link with token will look like this:

+

https://yoursitename.yourplatform.com/?token=school-a595d5f0aeff64c0

+

Anybody with this link can use your Nightscout with the role defined for this token.

+
+

Hint

+

If the user copies only your core URL into a browser, and your site is readable by default, the token will be bypassed. (Possible strategies to ensure the user puts the role-based URL into a browser include using a tinyurl or bit.ly.)

+
+
    +
  • You can edit a subject by clicking the edit icon, making changes, and saving.

  • +
  • You can delete a subject by clicking the red X icon to remove the subject from the list.

  • +
+

See how to setup your downloaders (followers) with a secured site.

+
+
+
+
+

Developers: API authorization

+

See this page for how to authenticate your app in the API V1 calls.

+

The API documentation is visible on your Nightscout site using this extension to your site address:

+

https://YOUR-SITE.com/api-docs/ and https://YOUR-SITE.com/api3-docs/.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/setup_variables/index.html b/nightscout/setup_variables/index.html new file mode 100644 index 00000000..f181df32 --- /dev/null +++ b/nightscout/setup_variables/index.html @@ -0,0 +1,1175 @@ + + + + + + + Nightscout Configuration — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout Configuration

+

Nightscout configuration is held in variables , their content can be modified to change and customize the behavior (data source, security, alarms, …) and appearance (language, colors, visible items, …). When deploying your Nightscout, most are left with default values and with time you might want to tune your site.

+

Variables location will depend on the platform you use:

+
+ +
+
+
+ + + + + + + + + + + + + + + +
+

If you use a hosted service, open the vendor web interface to access your Nightcsout site variables configuration or contact support.

+
+
+
+
+
+

Hint

+

Only most used variables are explained below.
+For the full list consult the main repository ReadMe.

+
+
+
+

Nightscout Config Vars

+
+
+

Required variables

+
+

MONGODB_URI (Database connection string)

+

The connection string required to access your Mongo database (where all your data is stored in the cloud).

+
+

Warning

+

MONGODB_URI is handled automatically if you use a hosted service or Google Cloud xDrip+ method. In these cases you don’t need to worry about it and can’t or shouldn’t change it.
+This string is vital to your Nightscout functioning. A wrong connection string will prevent your site from opening and your data uploading in Nightscout.

+
+

An Atlas database string will look like this:

+

mongodb+svr://sally:sallypass@cluster0.abcdef.mongodb.net/nightscout?retryWrites=true&w=majority

+

A traditional MongoDB string will look like this:

+

mongodb://sally:sallypass@myhosteddb.fqd/nightscout

+
+

Hint

+

If you migrated from mLab, this variable might be MONGO_CONNECTION. +Only one of these two variables must be present: MONGODB_URI or MONGO_CONNECTION.

+
+
+
+
+

API_SECRET (Nightscout password)

+
+

This is an important password

+

Knowing your site’s API Secret gives anybody full access to your Nightscout data, allows uploading to your site and uncontrolled access. Make sure you keep this password secret and avoid exposing it publicly.

+
+

A passphrase that must be at least 12 characters long, for example:

+
MyV3ry53cr37
+
+
+
+

Hint

+

Don’t make it too long and do not put special characters in it (better stick to letters and numbers).
It is case-sensitive.
+If you need to share Nightscout access but control the access, use an admin token.

+
+
+
+
+

DISPLAY_UNITS (Units to use)

+

Preferred BG units for the site: mg/dl or mmol/L (or just mmol). Setting to mmol/L puts the entire server into mmol/L mode by default, no further settings needed. Make sure it matches you uploader and followers.

+
+
+
+
+
+

Features

+
+

ENABLE (Enable Plugins)

+
+

Hint

+

Select the right plugins! Better too many than not enough.

+
+

Select which Plugins to enable for your site, this is the current list:

+
    +
  • careportal (Careportal)

  • +
  • boluscalc (Bolus Wizard)

  • +
  • food (Custom Foods)

  • +
  • rawbg (Raw BG)

  • +
  • iob (Insulin-on-Board)

  • +
  • cob (Carbs-on-Board)

  • +
  • bwp (Bolus Wizard Preview)

  • +
  • cage (Cannula Age)

  • +
  • sage (Sensor Age)

  • +
  • iage (Insulin Age)

  • +
  • bage (Battery Age)

  • +
  • treatmentnotify (Treatment Notifications)

  • +
  • basal (Basal Profile)

  • +
  • bolus (Bolus Rendering)

  • +
  • connect (Nightscout Connect) - Beta

  • +
  • bridge (Share2Nightscout bridge) - Deprecated

  • +
  • mmconnect (MiniMed Connect bridge) - Deprecated: not functional

  • +
  • pump (Pump Monitoring)

  • +
  • openaps (OpenAPS)

  • +
  • loop (Loop)

  • +
  • override (Override Mode)

  • +
  • xdripjs (xDrip-js)

  • +
  • alexa (Amazon Alexa)

  • +
  • googlehome (Google Home/DialogFLow)

  • +
  • speech (Speech)

  • +
  • cors (CORS)

  • +
+

Must be a space-delimited, lower-case list.

+

careportal basal dbsize

+

Include the word bridge here if you are receiving data from the Dexcom Share service.

+

careportal basal dbsize bridge

+

If you don’t want to decide now, add all the followings, you can disable them if you don’t need them:

+

careportal basal dbsize rawbg iob maker bridge cob bwp cage iage sage boluscalc pushover treatmentnotify mmconnect loop pump profile food openaps bage alexa override cors

+

Note: mmconnect is not functional with Heroku (if you wanted to bridge from the MiniMed CareLink service you will need another device to send data to Nightscout). If you are sending data to CareLink do NOT enable mmconnect.

+
+
+
+

DISABLE (Disable Plugins)

+

Used to disable default features, expects a space delimited list.

+

For example this will disable the direction arrow and uploader battery information:

+

direction upbat

+
+
+
+

AUTH_DEFAULT_ROLES (Authentication)

+

Possible values readable, denied, or any valid role name. When readable, anyone can view Nightscout without a token. Setting it to denied will require a token from every visit, using status-only will enable api-secret based login.

+

More information on how to setup tokens here.

+
+
+
+
+

Alarms

+

These alarm setting affect all delivery methods (browser, Pushover, IFTTT, etc.). Values and settings entered here will be the defaults for new browser views, but will be overridden if different choices are made in the settings UI.

+
+

ALARM_TYPES

+
+

TYPES

+

Keep the simple type if you want BG_ parameters (setup below) to be used.

+
+

simple and/or predict.

+

Simple alarms trigger when BG crosses the various thresholds set below.

+

Predict alarms uses highly tuned formula that forecasts where the BG is going based on its trend. You will not get warnings when crossing any of the BG_ thresholds set below when using only the predict type.

+
+

BG Thresholds

+

These values are the ones that will trigger simple alarms. They are expressed in the unit you selected with DISPLAY_UNITS.

+
+
+
+

BG_HIGH

+

Urgent High BG threshold, triggers the ALARM_URGENT_HIGH alarm.

+
+
+

BG_LOW

+

Urgent Low BG threshold, triggers the ALARM_URGENT_LOW alarm.

+
+
+

BG_TARGET_BOTTOM

+

Low BG threshold, triggers the ALARM_LOW alarm.

+
+
+

BG_TARGET_TOP

+

High BG threshold, triggers the ALARM_HIGH alarm.

+
+
+

ALARM_* and ALARM_URGENT_*

+

You can setup alarms, so that when your Nightscout page is open and the alarm enabled, above (HIGH) or below (LOW) a certain threshold, a sound might play.

+
+
+
+

ALARM_URGENT_HIGH

+

Default setting for new browser views, for the Urgent High alarm (triggered when BG crosses BG_HIGH). (on or off)

+
+
+

ALARM_HIGH

+

Default setting for new browser views, for the High alarm (triggered when BG crosses BG_TARGET_TOP). (on or off)

+
+
+

ALARM_LOW

+

Default setting for new browser views, for the Low alarm (triggered when BG crosses BG_TARGET_BOTTOM). (on or off)

+
+
+

ALARM_URGENT_LOW

+

Default setting for new browser views, for the Urgent Low alarm (triggered when BG crosses BG_LOW). (on or off)

+
+
+

Other Alarms on by Default

+

These other two alarms are on by default, so set them to ‘off’ if you prefer no alarms.

+
    +
  • ALARM_TIMEAGO_WARN

  • +
  • ALARM_TIMEAGO_URGENT

  • +
+
+
+

Pushover

+

ALARM_*_MINS: Only the first value of the space separated list, for options in browser, will be used for pushover.

+
+
+
+

ALARM_URGENT_HIGH_MINS

+

Number of minutes to snooze urgent high alarms.

+
+
+

ALARM_HIGH_MINS

+

Number of minutes to snooze high alarms.

+
+
+

ALARM_LOW_MINS

+

Number of minutes to snooze low alarms.

+
+
+

ALARM_URGENT_LOW_MINS

+

Number of minutes to snooze urgent low alarms.

+
+
+

ALARM_URGENT_MINS

+

Number of minutes to snooze urgent alarms (that aren’t tagged as high or low).

+
+
+

ALARM_WARN_MINS

+

Number of minutes to snooze warning alarms (that aren’t tagged as high or low).

+
+
+

TIMEAGO

+

Missing data alarms can also be setup, so that when your Nightscout page is open and the alarm enabled, after a certain time without receiving BG, a sound might play.

+
+
+
+

ALARM_TIMEAGO_URGENT

+

Default setting for new browser views, for an urgent alarm when CGM data hasn’t been received in the number of minutes set in ALARM_TIMEAGO_URGENT_MINS. (on or off)

+
+
+

ALARM_TIMEAGO_URGENT_MINS

+

Default setting for new browser views, for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_URGENT alarm.

+
+
+

ALARM_TIMEAGO_WARN

+

Default setting for new browser views, for a warning alarm when CGM data hasn’t been received in the number of minutes set in ALARM_TIMEAGO_WARN_MINS. (on or off)

+
+
+

ALARM_TIMEAGO_WARN_MINS

+

Default setting for new browser views, for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_WARN alarm.

+
+
+
+
+
+

Predefined values for your browser settings (default)

+
+

TIME_FORMAT (12)

+

Possible values 12 or 24. This defines the horizontal timeline expressed as AM/PM or 0-24.

+
+
+
+

NIGHT_MODE (off)

+

Possible values on or off. Night mode has a lower brightness and contrast.

+
+
+
+

SHOW_RAWBG (never)

+

Display of raw CGM data (this is a legacy feature). (always, never, or noise)

+../../_images/SetupNS35.png +
+
+
+

CUSTOM_TITLE (Nightscout)

+

The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer.

+../../_images/SetupNS05.png +
+
+

THEME (colors)

+

Color theme of the CGM graph.

+

default

+../../_images/SetupNS06.png +

colors

+../../_images/SetupNS07.png +

colorblindfriendly

+../../_images/SetupNS08.png +
+
+
+

SHOW_PLUGINS

+

Default setting for whether or not these plugins are checked (active) by default, not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case.

+

When you ENABLE a plugin, it will be used by Nightscout but might not be visible unless you select it in the drawer menu. If you want a plugin to display by default you need to add it to the SHOW_PLUGINS list.

+

More details below.

+
+
+
+

SHOW_FORECAST (ar2)

+

Plugin forecasts that should be shown by default, supports space delimited values such as: +ar2 openaps loop false

+

Note the ar2 forecast is selected by default so if no value is set, it will be AR2. AR2 is an early attempt at forecasting BG and you should not base any medical decisions on it’s predictions.

+

If you are looping, you can chose instead to use either loop or openaps which will use the appropriate algorithm.

+

You should also add the parameter to the SHOW_PLUGINS and ENABLE variables.

+

For example, if you are using the Loop app for iPhone, you should have the following settings (In addition to any others outlined in the docs):

+
ENABLE=loop
+SHOW_PLUGINS=loop
+SHOW_FORECAST=loop
+
+
+
+
+
+

LANGUAGE (en)

+

Language of Nightscout. If not available English is used.

+

Currently supported language codes are: bg (Български), cs (Čeština), de (Deutsch), dk (Dansk), el (Ελληνικά), en (English), es (Español), fi (Suomi), fr (Français), he (עברית), hr (Hrvatski), it (Italiano), ko (한국어), nb (Norsk (Bokmål)), nl (Nederlands), pl (Polski), pt (Português (Brasil)), ro (Română), ru (Русский), sk (Slovenčina), sv (Svenska), tr (Turkish), zh_cn (中文(简体)), zh_tw (中文(繁體))

+
+
+
+

SCALE_Y (log)

+

The type of scaling used for the Y axis of the charts system wide.

+

The default log (logarithmic) option will let you see more detail towards the lower range, while still showing the full CGM range.

+../../_images/SetupNS40.png +

The linear option has equidistant tick marks; the range used is dynamic so that space at the top of chart isn’t wasted.

+../../_images/SetupNS39.png +

The log-dynamic is similar to the default log options, but uses the same dynamic range and the linear scale.

+../../_images/SetupNS41.png +
+
+
+

EDIT_MODE (on)

+

Possible values on or off. Enables the icon allowing for editing of treatments in the main view. More about edit here.

+../../_images/SetupNS42.png +
+
+
+

BOLUS_RENDER

+

Settings to configure Bolus rendering

+

BOLUS_RENDER_OVER (0) - U value over which the bolus labels use the format defined in BOLUS_RENDER_FORMAT. This value can be an integer or a float, e.g. 0.3, 1.5, 2, etc.

+

BOLUS_RENDER_FORMAT (default) - Possible values are hidden, default (with leading zero and U), concise (with U, without leading zero), and minimal (without leading zero and U).

+

BOLUS_RENDER_FORMAT_SMALL (default) - Possible values are hidden, default (with leading zero and U), concise (with U, without leading zero), and minimal (without leading zero and U).

+../../_images/SetupNS43.png +
+
+
+
+
+

Split View

+

Some users will need easy access to multiple Nightscout views at the same time. We have a special view for this case, accessed on /split path on your Nightscout URL. The view supports any number of sites between 1 to 8 way split, where the content for the screen can be loaded from multiple Nightscout instances. Note you still need to host separate instances for each Nightscout being monitored including the one that hosts the split view page - these variables only add the ability to load multiple views into one browser page. To set the URLs from which the content is loaded, set:

+

FRAME_URL_1 - URL where content is loaded, for the first view (increment the number up to 8 to get more views)

+

FRAME_NAME_1 - Name for the first split view portion of the screen (increment the number to name more views)

+
+

For example:

+

FRAME_URL_1 https://janecgm.myurl.fqd

+

FRAME_NAME_1 Jane

+

FRAME_URL_2 https://joecgm.myurl.fqd

+

FRAME_NAME_2 Joe

+
+

To display the split view browse to:

+

https://myAppName.myurl.fqd/split

+
+

8 split view example:

+../../_images/SetupNS30.png +
+
+
+
+
+

Plugins

+

Plugins are used to extend the way information is displayed, how notifications are sent, alarms are triggered, and more.

+

If you want the ENABLE’d plugins to show by default on any browser, you should put them in the SHOW_PLUGINS variable.

+

If you want to specifically disable a plugin (mainly a default plugin) you should place it in the DISABLE variable.

+

You also can decide to visualize them or not on your Nightscout view with the drawer menu. Authenticate and Save the settings on your browser. Your site variables will not be modified and only default view will be seen on a new browser window.

+../../_images/SetupNS09.png +
+
+

Default Plugins

+

Below some default plugins: timeago, upbat, direction and delta.

+../../_images/SetupNS11.png +
+

Hovering the mouse on (computer) or touching (touch screen) some plugins will give you additional information.

+
+

delta (BG Delta)

+

Calculates and displays the change between the last 2 BG values. Delta shows a * if time difference is more than 5 minutes.

+
+
+

direction (BG Direction)

+

Displays the trend direction, the arrow change is only based on the difference from the current to the latest measurement.

+
+
+

upbat (Uploader Battery)

+

Displays the most recent battery status from the uploader phone(s) and bridge. Use these extended setting to adjust behavior:

+

UPBAT_ENABLE_ALERTS (false) - Set to true to enable uploader battery alarms via Pushover and IFTTT.

+

UPBAT_WARN (30) - Minimum battery percent to trigger warning.

+

UPBAT_URGENT (20) - Minimum battery percent to trigger urgent alarm.

+
+
+
+

timeago (Time Ago)

+

Displays the time since last CGM entry. Use these extended setting to adjust behavior:

+

TIMEAGO_ENABLE_ALERTS (false) - Set to true to enable stale data alarms via Pushover and IFTTT.

+

ALARM_TIMEAGO_WARN (on) - possible values on or off

+

ALARM_TIMEAGO_WARN_MINS (15) - minutes since the last reading to trigger a warning

+

ALARM_TIMEAGO_URGENT (on) - possible values on or off

+

ALARM_TIMEAGO_URGENT_MINS (30) - minutes since the last reading to trigger a urgent alarm

+
+
+
+

devicestatus (Device Status)

+

Used by upbat and other plugins to display device status info. Supports the DEVICESTATUS_ADVANCED="true" extended setting to send all device statuses to the client for retrospective use and to support other plugins.

+

Example: upbat information using devicestatus.

+../../_images/SetupNS20.png +
+
+
+

errorcodes (CGM Error Codes)

+

Generates alarms for CGM codes 9 (hourglass) and 10 (???).

+

Use extended settings to adjust what errorcodes trigger notifications and alarms:

+
    +
  • ERRORCODES_INFO (1 2 3 4 5 6 7 8) - By default the needs calibration (blood drop) and other codes below 9 generate an info level notification, set to a space separate list of number or off to disable

  • +
  • ERRORCODES_WARN (off) - By default there are no warning configured, set to a space separate list of numbers or off to disable

  • +
  • ERRORCODES_URGENT (9 10) - By default the hourglass and ??? generate an urgent alarm, set to a space separate list of numbers or off to disable

    +
    +
  • +
+
+
+

ar2 (AR2 Forecasting)

+

Generates alarms based on forecasted values.

+
    +
  • Enabled by default if no thresholds are set OR ALARM_TYPES includes predict.

    +
      +
    • You can permanently disable AR2 setting the SHOW_FORECAST variable to false (or removing ar2 if you use it for openaps or loop).

    • +
    +
  • +
  • AR2 forecasting display can be enabled/disabled from ...

  • +
  • Use extended settings to adjust AR2 behavior:

    +
      +
    • AR2_CONE_FACTOR (2) - to adjust size of cone, use 0 for a single line.

    • +
    +
  • +
+../../_images/SetupNS10.png +
+
+
+

simplealarms (Simple BG Alarms)

+
    +
  • Uses BG_HIGH, BG_TARGET_TOP, BG_TARGET_BOTTOM, BG_LOW thresholds to generate alarms.

    +

    Simple alarms are enabled by default if one of the BG_HIGH, BG_TARGET_TOP, BG_TARGET_BOTTOM, BG_LOW thresholds is set or ALARM_TYPES includes simple.

    +

    You’ll find the plugin in the drawer menu. You can change thresholds in Profile editor.

    +

    You can click the loudspeaker icon to test the alarms volume or to snooze an active alarm. If you want to use sound alarms, you should click the icon to enable playback at least once after opening your Nightscout page in order to allow the browser to play it.

    +
  • +
+../../_images/SetupNS12.png +
+
+
+

profile (Treatment Profile)

+

Add a link in the drawer menu to Profile Editor and allows to enter treatment profile settings. Also uses the extended setting:

+
    +
  • PROFILE_HISTORY (off) - possible values on or off. Enable/disable NS ability to keep history of your profiles (still experimental)

  • +
  • PROFILE_MULTIPLE (off) - possible values on or off. Enable/disable NS ability to handle and switch between multiple treatment profiles

  • +
+

More variables of your profile will be used by Nightscout plugins like treatments, see below or here.

+../../_images/SetupNS13.png +
+
+
+

dbsize (Database Size)

+

Show size of Nightscout Database, as a percentage of declared available space or in MiB.

+../../_images/SetupNS15.png +
+

Many deployments of Nightscout use free tier of MongoDB Atlas on Heroku, which is limited in size to 512MiB. After some time, as volume of stored data grows, it may happen that this limit is reached and system is unable to store new data. This plugin provides pill that indicates size of Database and shows (when configured) alarms regarding reaching space limit.

+
+

IMPORTANT

+

This plugin can only check how much space database already takes, but cannot infer max size available on server for it. To have correct alarms and realistic percentage, DBSIZE_MAX need to be properly set - according to your own mongoDB hosting configuration.

+
+

NOTE: This plugin rely on db.stats() for reporting logical size of database, which may be different than physical size of database on server. It may work for free tier of MongoDB on Atlas, since it calculate quota according to logical size too, but may fail for other hostings or self-hosted database with quota based on physical size.

+

NOTE: MongoDB Atlas quota is for all databases in cluster, while each instance will get only size of its own database only. It is ok when you only have one database in cluster (most common scenario) but will not work for multiple parallel databases. In such case, spliting known quota equally beetween databases and setting DBSIZE_MAX to that fraction may help, but wont be precise.

+

All sizes are expressed as integers, in Mebibytes 1 MiB == 1024 KiB == 1024*1024 B

+

Extended settings available:

+
    +
  • DBSIZE_MAX (496) - Maximal allowed size of database on your mongoDB server, in MiB. You need to adjust that value to match your database hosting limits - default value is for standard Heroku mongoDB free tier.

  • +
  • DBSIZE_WARN_PERCENTAGE (60) - Threshold to show first warning about database size. When database reach this percentage of DBSIZE_MAX size - pill will show size in yellow.

  • +
  • DBSIZE_URGENT_PERCENTAGE (75) - Threshold to show urgent warning about database size. When database reach this percentage of DBSIZE_MAX size, it is urgent to do backup and clean up old data. At this percentage info pill turns red.

  • +
  • DBSIZE_ENABLE_ALERTS (false) - Set to true to enable notifications about database size.

  • +
  • DBSIZE_IN_MIB (false) - Set to true to display size of database in MiB-s instead of default percentage.

  • +
+
+
+
+
+
+

Advanced Plugins:

+
+

careportal (Careportal)

+

An optional form to enter treatments.

+

Care Portal is an important plugin that gives access to the Log a treatment interface. Unlock it entering your API secret with the lock icon top right, then use the + icon to log a treatment. More information here.

+../../_images/SetupNS14.png +
+
+
+

boluscalc (Bolus Wizard)

+

Bolus Wizard plugin gives access to the Bolus Wizard interface. You can access it with the calculator icon top right.

+../../_images/SetupNS16.png +
+
+
+

food (Custom Foods)

+

Custom Foods enabled by the variable food allows to to customize your food database and adds a Food Editor entry in the menu.

+../../_images/SetupNS17.png +
+
+
+

rawbg (Raw BG)

+

Calculates BG using sensor and calibration records from and displays an alternate BG values and noise levels. Defaults that can be adjusted with extended setting. Raw BG will only display if your sensor provides this data, your bridge device transfers it and your uploader sends it to Nightscout.

+
    +
  • DISPLAY(unsmoothed) - Allows the user to control which algorithm is used to calculate the displayed raw BG values using the most recent calibration record.

    +
      +
    • unfiltered - Raw BG is calculated by applying the calibration to the glucose record’s unfiltered value.

    • +
    • filtered - Raw BG is calculated by applying the calibration to the glucose record’s filtered value. The glucose record’s filtered values are generally produced by the CGM by a running average of the unfiltered values to produce a smoothed value when the sensor noise is high.

    • +
    • unsmoothed - Raw BG is calculated by first finding the ratio of the calculated filtered value (the same value calculated by the filtered setting) to the reported glucose value. The displayed raw BG value is calculated by dividing the calculated unfiltered value (the same value calculated by the unfiltered setting) by the ratio. The effect is to exaggerate changes in trend direction so the trend changes are more noticeable to the user. This is the legacy raw BG calculation algorithm.

    • +
    +
  • +
+../../_images/SetupNS21.png +
+
+
+

iob (Insulin-on-Board) - cob (Carbs-on-Board)

+../../_images/SetupNS18.png +
+
+
+

iob (Insulin-on-Board)

+

Adds the IOB pill visualization in the client and calculates values that used by other plugins. Uses treatments with insulin doses and the dia and sens fields from the treatment profile.

+
+
+

cob (Carbs-on-Board)

+

Adds the COB pill visualization in the client and calculates values that used by other plugins. Uses treatments with carb doses and the carbs_hr, carbratio, and sens fields from the treatment profile.

+

When you enter the information with the Care Portal or Nightscout receives if from the uploader, you can see remaining insulin on board and carbs.

+
+
+
+

bwp (Bolus Wizard Preview)

+

This plugin in intended for the purpose of automatically snoozing alarms when the CGM indicates high blood sugar but there is also insulin on board (IOB) and secondly, alerting to user that it might be beneficial to measure the blood sugar using a glucometer and dosing insulin as calculated by the pump or instructed by trained medicare professionals. The values provided by the plugin are provided as a reference based on CGM data and insulin sensitivity you have configured, and are not intended to be used as a reference for bolus calculation. The plugin calculates the bolus amount when above your target, generates alarms when you should consider checking and bolusing, and snoozes alarms when there is enough IOB to cover a high BG. Uses the results of the iob plugin and sens, target_high, and target_low fields from the treatment profile. Defaults that can be adjusted with extended settings

+
    +
  • BWP_WARN (0.50) - If BWP is > BWP_WARN a warning alarm will be triggered.

  • +
  • BWP_URGENT (1.00) - If BWP is > BWP_URGENT an urgent alarm will be triggered.

  • +
  • BWP_SNOOZE_MINS (10) - minutes to snooze when there is enough IOB to cover a high BG.

  • +
  • BWP_SNOOZE - (0.10) If BG is higher then the target_high and BWP < BWP_SNOOZE alarms will be snoozed for BWP_SNOOZE_MINS.

  • +
+../../_images/SetupNS19.png +
+
+
+

Age pills

+../../_images/SetupNS23.png +
+
+
+

cage (Cannula Age)

+

Calculates the number of hours since the last Site Change treatment that was recorded.

+
    +
  • CAGE_ENABLE_ALERTS (false) - Set to true to enable notifications to remind you of upcoming cannula change.

  • +
  • CAGE_INFO (44) - If time since last Site Change matches CAGE_INFO, user will be warned of upcoming cannula change

  • +
  • CAGE_WARN (48) - If time since last Site Change matches CAGE_WARN, user will be alarmed to to change the cannula

  • +
  • CAGE_URGENT (72) - If time since last Site Change matches CAGE_URGENT, user will be issued a persistent warning of overdue change.

  • +
  • CAGE_DISPLAY (hours) - Possible values are hours or days. If days is selected and age of canula is greater than 24h number is displayed in days and hours

  • +
+
+
+

sage (Sensor Age)

+

Calculates the number of days and hours since the last Sensor Start and Sensor Change treatment that was recorded.

+
    +
  • SAGE_ENABLE_ALERTS (false) - Set to true to enable notifications to remind you of upcoming sensor change.

  • +
  • SAGE_INFO (144) - If time since last sensor event matches SAGE_INFO, user will be warned of upcoming sensor change

  • +
  • SAGE_WARN (164) - If time since last sensor event matches SAGE_WARN, user will be alarmed to to change/restart the sensor

  • +
  • SAGE_URGENT (166) - If time since last sensor event matches SAGE_URGENT, user will be issued a persistent warning of overdue change.

  • +
+
+
+

iage (Insulin Age)

+

Calculates the number of days and hours since the last Insulin Change treatment that was recorded.

+
    +
  • IAGE_ENABLE_ALERTS (false) - Set to true to enable notifications to remind you of upcoming insulin reservoir change.

  • +
  • IAGE_INFO (44) - If time since last Insulin Change matches IAGE_INFO, user will be warned of upcoming insulin reservoir change

  • +
  • IAGE_WARN (48) - If time since last Insulin Change matches IAGE_WARN, user will be alarmed to to change the insulin reservoir

  • +
  • IAGE_URGENT (72) - If time since last Insulin Change matches IAGE_URGENT, user will be issued a persistent warning of overdue change.

  • +
+
+
+

bage (Battery Age)

+

Calculates the number of days and hours since the last Pump Battery Change treatment that was recorded.

+
    +
  • BAGE_ENABLE_ALERTS (false) - Set to true to enable notifications to remind you of upcoming pump battery change.

  • +
  • BAGE_DISPLAY (days) - Set to hours to display time since last Pump Battery Change in hours only.

  • +
  • BAGE_INFO (312) - If time since last Pump Battery Change matches BAGE_INFO hours, user will be warned of upcoming pump battery change (default of 312 hours is 13 days).

  • +
  • BAGE_WARN (336) - If time since last Pump Battery Change matches BAGE_WARN hours, user will be alarmed to to change the pump battery (default of 336 hours is 14 days).

  • +
  • BAGE_URGENT (360) - If time since last Pump Battery Change matches BAGE_URGENT hours, user will be issued a persistent warning of overdue change (default of 360 hours is 15 days).

    +
    +
  • +
+
+
+

treatmentnotify (Treatment Notifications)

+

Generates notifications when a treatment has been entered and snoozes alarms minutes after a treatment. Default snooze is 10 minutes, and can be set using the TREATMENTNOTIFY_SNOOZE_MINS extended setting.

+
+
+
+

basal (Basal Profile)

+../../_images/SetupNS26.png +
+

Adds the Basal pill visualization to display the basal rate for the current time. Also enables the bwp plugin to calculate correction temp basal suggestions. Uses the basal field from the treatment profile. Also uses the extended settings:

+
    +
  • BASAL_RENDER (none)

  • +
+

Possible values are none,

+

default,

+../../_images/SetupNS29.png +

or icicle (inverted)

+../../_images/SetupNS28.png +
+
+
+

bridge (Share2Nightscout bridge)

+

Glucose reading directly from the Dexcom Share service, uses these extended settings (***** mandatory):

+
    +
  • BRIDGE_USER_NAME - Your username for the Share service. *****

  • +
  • BRIDGE_PASSWORD - Your password for the Share service. *****

  • +
  • BRIDGE_INTERVAL (150000 2.5 minutes) - The time (in milliseconds) to wait between each update.

  • +
  • BRIDGE_MAX_COUNT (1) - The number of records to attempt to fetch per update.

  • +
  • BRIDGE_FIRST_FETCH_COUNT (3) - Changes max count during the very first update only.

  • +
  • BRIDGE_MAX_FAILURES (3) - How many failures before giving up.

  • +
  • BRIDGE_MINUTES (1400) - The time window to search for new data per update (the default value is one day in minutes).

  • +
  • BRIDGE_SERVER (US) - Set to US to fetch data from Dexcom servers in the US. Set to (EU) to fetch from non US servers instead. *****

  • +
  • OBSCURED (bridge) - Obscure data source when using bridge uploader.

  • +
  • OBSCURE_DEVICE_PROVENANCE (dexcom-dont-own-my-body-data) - Self explanatory.

  • +
+
+
+
+

mmconnect (MiniMed Connect bridge)

+
+

Warning

+

This plugin is NOT functional with 7xx pumps do not enable it.

+
+

Transfer real-time MiniMed Connect data from the Medtronic CareLink server into Nightscout (read more) (***** mandatory) with the following extended settings:

+
    +
  • MMCONNECT_USER_NAME - Your user name for CareLink Connect. *****

  • +
  • MMCONNECT_PASSWORD - Your password for CareLink Connect. *****

  • +
  • MMCONNECT_INTERVAL (60000 1 minute) - Number of milliseconds to wait between requests to the CareLink server.

  • +
  • MMCONNECT_MAX_RETRY_DURATION (32) - Maximum number of total seconds to spend retrying failed requests before giving up.

  • +
  • MMCONNECT_SGV_LIMIT (24) - Maximum number of recent sensor glucose values to send to Nightscout on each request.

  • +
  • MMCONNECT_VERBOSE - Set this to “true” to log CareLink request information to the console.

  • +
  • MMCONNECT_STORE_RAW_DATA - Set this to “true” to store raw data returned from CareLink as type: "carelink_raw" database entries (useful for development).

  • +
  • MMCONNECT_SERVER - Set this to EU if you’re using the European Medtronic services *****

  • +
+
+
+
+

pump (Pump Monitoring)

+../../_images/SetupNS24.png +
+

Generic Pump Monitoring for OpenAPS, MiniMed Connect, RileyLink, t:slim, …

+
    +
  • Requires DEVICESTATUS_ADVANCED="true" to be set

  • +
  • PUMP_ENABLE_ALERTS (false) - Set to true to enable notifications for Pump battery and reservoir.

  • +
  • PUMP_WARN_ON_SUSPEND (false) - Set to true to get an alarm when the pump is suspended.

  • +
  • PUMP_FIELDS (reservoir battery) - The fields to display by default. Any of the following fields: reservoir, battery, clock, status, and device

  • +
  • PUMP_RETRO_FIELDS (reservoir battery clock) - The fields to display in retro mode. Any of the above fields.

  • +
  • PUMP_WARN_CLOCK (30) - The number of minutes ago that needs to be exceed before an alert is triggered.

  • +
  • PUMP_URGENT_CLOCK (60) - The number of minutes ago that needs to be exceed before an urgent alarm is triggered.

  • +
  • PUMP_WARN_RES (10) - The number of units remaining, a warning will be triggered when dropping below this threshold.

  • +
  • PUMP_URGENT_RES (5) - The number of units remaining, an urgent alarm will be triggered when dropping below this threshold.

  • +
  • PUMP_WARN_BATT_P (30) - The % of the pump battery remaining, a warning will be triggered when dropping below this threshold.

  • +
  • PUMP_URGENT_BATT_P (20) - The % of the pump battery remaining, an urgent alarm will be triggered when dropping below this threshold.

  • +
  • PUMP_WARN_BATT_V (1.35) - The voltage (if percent isn’t available) of the pump battery, a warning will be triggered when dropping below this threshold.

  • +
  • PUMP_URGENT_BATT_V (1.30) - The voltage (if percent isn’t available) of the pump battery, an urgent alarm will be triggered when dropping below this threshold.

  • +
+
+
+
+
+

openaps (OpenAPS)

+../../_images/SetupNS36.png +
+

Integrated OpenAPS loop monitoring, uses these extended setting:

+
    +
  • Requires DEVICESTATUS_ADVANCED="true" to be set

  • +
  • OPENAPS_ENABLE_ALERTS (false) - Set to true to enable notifications when OpenAPS isn’t looping. If OpenAPS is going to offline for a period of time, you can add an OpenAPS Offline event for the expected duration from Careportal to avoid getting alerts.

  • +
  • OPENAPS_WARN (30) - The number of minutes since the last loop that needs to be exceed before an alert is triggered

  • +
  • OPENAPS_URGENT (60) - The number of minutes since the last loop that needs to be exceed before an urgent alarm is triggered

  • +
  • OPENAPS_FIELDS (status-symbol status-label iob meal-assist rssi) - The fields to display by default. Any of the following fields: status-symbol, status-label, iob, meal-assist, freq, and rssi

  • +
  • OPENAPS_RETRO_FIELDS (status-symbol status-label iob meal-assist rssi) - The fields to display in retro mode. Any of the above fields.

  • +
  • OPENAPS_PRED_IOB_COLOR (#1e88e5) - The color to use for IOB prediction lines. Colors can be in #RRGGBB format, but other CSS color units may be used as well.

  • +
  • OPENAPS_PRED_COB_COLOR (#FB8C00) - The color to use for COB prediction lines. Same format as above.

  • +
  • OPENAPS_PRED_ACOB_COLOR (#FB8C00) - The color to use for ACOB prediction lines. Same format as above.

  • +
  • OPENAPS_PRED_ZT_COLOR (#00d2d2) - The color to use for ZT prediction lines. Same format as above.

  • +
  • OPENAPS_PRED_UAM_COLOR (#c9bd60) - The color to use for UAM prediction lines. Same format as above.

  • +
  • OPENAPS_COLOR_PREDICTION_LINES (true) - Enables / disables the colored lines vs the classic purple color.

  • +
+

Also see Pushover and IFTTT Maker.

+
+
+
+
+

loop (Loop)

+../../_images/SetupNS25.png +
+

iOS Loop app monitoring, uses these extended settings:

+
    +
  • Requires DEVICESTATUS_ADVANCED="true" to be set

  • +
  • LOOP_ENABLE_ALERTS (false) - Set to true to enable notifications when Loop isn’t looping.

  • +
  • LOOP_WARN (30) - The number of minutes since the last loop that needs to be exceeded before an alert is triggered

  • +
  • LOOP_URGENT (60) - The number of minutes since the last loop that needs to be exceeded before an urgent alarm is triggered

  • +
  • Add loop to SHOW_FORECAST to show forecasted BG.

  • +
+

For remote overrides, the following extended settings must be configured:

+
    +
  • LOOP_APNS_KEY - Apple Push Notifications service (APNs) Key, created in the Apple Developer website.

  • +
  • LOOP_APNS_KEY_ID - The Key ID for the above key.

  • +
  • LOOP_DEVELOPER_TEAM_ID - Your Apple developer team ID.

  • +
  • LOOP_PUSH_SERVER_ENVIRONMENT - (optional) Set this to production if you are using a provisioning profile that specifies production aps-environment, such as when distributing builds via TestFlight.

  • +
+
+
+
+

override (Override Mode)

+

Additional monitoring for DIY automated insulin delivery systems to display real-time overrides such as Eating Soon or Exercise Mode:

+
    +
  • Requires DEVICESTATUS_ADVANCED="true" to be set

  • +
+
+
+
+

xdripjs (xDrip-js)

+

Integrated xDrip-js monitoring, uses these extended settings:

+
    +
  • Requires DEVICESTATUS_ADVANCED="true" to be set

  • +
  • XDRIPJS_ENABLE_ALERTS (false) - Set to true to enable notifications when CGM state is not OK or battery voltages fall below threshold.

  • +
  • XDRIPJS_STATE_NOTIFY_INTRVL (0.5) - Set to number of hours between CGM state notifications

  • +
  • XDRIPJS_WARN_BAT_V (300) - The voltage of either transmitter battery, a warning will be triggered when dropping below this threshold.

    +
    +
  • +
+
+
+

alexa (Amazon Alexa)

+

Integration with Amazon Alexa, detailed setup instructions

+
+
+
+

googlehome (Google Home/DialogFlow)

+

Integration with Google Home (via DialogFlow), detailed setup instructions

+
+
+
+

speech (Speech)

+

Speech synthesis plugin. When enabled, speaks out the blood glucose values, IOB and alarms. Note you have to set the LANGUAGE setting on the server to get all translated alarms.

+
+
+
+

cors (CORS)

+

Enabled CORS so other websites can make request to your Nightscout site, uses these extended settings:

+
    +
  • CORS_ALLOW_ORIGIN (*) - The list of sites that are allow to make requests

  • +
+
+
+
+
+
+
+

Extended Settings

+

Some plugins support additional configuration using extra environment variables. These are prefixed with the name of the plugin and a _. For example setting MYPLUGIN_EXAMPLE_VALUE=1234 would make extendedSettings.exampleValue available to the MYPLUGIN plugin.

+

Plugins only have access to their own extended settings, all the extended settings of client plugins will be sent to the browser.

+
    +
  • DEVICESTATUS_ADVANCED (true) - Defaults to true. Users who only have a single device uploading data to Nightscout can set this to false to reduce the data use of the site.

  • +
  • DEVICESTATUS_DAYS (1) - Defaults to 1, can optionally be set to 2. Users can use this to show 48 hours of device status data for in retro mode, rather than the default 24 hours. Setting this value to 2 will roughly double the bandwidth usage of nightscout, so users with a data cap may not want to update this setting.

  • +
+
+
+

Pushover

+

In addition to the normal web based alarms, there is also support for Pushover based alarms and notifications.

+

To get started install the Pushover application on your iOS or Android device and create an account.

+

Using that account login to Pushover, in the top left you’ll see your User Key, you’ll need this plus an application API Token/Key to complete this setup.

+

You’ll need to Create a Pushover Application. You only need to set the Application name, you can ignore all the other settings, but setting an Icon is a nice touch. Maybe you’d like to use this one?

+

Pushover is configured using the following Environment Variables:

+
* `ENABLE` - `pushover` should be added to the list of plugin, for example: `ENABLE="pushover"`.
+* `PUSHOVER_API_TOKEN` - Used to enable pushover notifications, this token is specific to the application you create from in [Pushover](https://pushover.net/), ***[additional pushover information](#pushover)*** below.
+* `PUSHOVER_USER_KEY` - Your Pushover user key, can be found in the top left of the [Pushover](https://pushover.net/) site, this can also be a pushover delivery group key to send to a group rather than just a single user.  This also supports a space delimited list of keys.  To disable `INFO` level pushes set this to `off`.
+* `PUSHOVER_ALARM_KEY` - An optional Pushover user/group key, will be used for system wide alarms (level > `WARN`).  If not defined this will fallback to `PUSHOVER_USER_KEY`.  A possible use for this is sending important messages and alarms to a CWD that you don't want to send all notification too.  This also support a space delimited list of keys.  To disable Alarm pushes set this to `off`.
+* `PUSHOVER_ANNOUNCEMENT_KEY` - An optional Pushover user/group key, will be used for system wide user generated announcements.  If not defined this will fallback to `PUSHOVER_USER_KEY` or `PUSHOVER_ALARM_KEY`.  This also support a space delimited list of keys. To disable Announcement pushes set this to `off`.
+* `BASE_URL` - Used for pushover callbacks, usually the URL of your Nightscout site, use https when possible.
+* `API_SECRET` - Used for signing the pushover callback request for acknowledgments.
+
+If you never want to get info level notifications (treatments) use `PUSHOVER_USER_KEY="off"`
+If you never want to get an alarm via pushover use `PUSHOVER_ALARM_KEY="off"`
+If you never want to get an announcement via pushover use `PUSHOVER_ANNOUNCEMENT_KEY="off"`
+
+If only `PUSHOVER_USER_KEY` is set it will be used for all info notifications, alarms, and announcements
+
+For testing/development try [localtunnel](http://localtunnel.me/).
+
+
+
+
+
+

IFTTT Maker

+

In addition to the normal web based alarms, and pushover, there is also integration for IFTTT Webhooks.

+

With Maker you are able to integrate with all the other IFTTT Services. For example you can send a tweet when there is an alarm, change the color of hue light, send an email, send and sms, and so much more.

+
    +
  1. Setup IFTTT account: login or create an account

  2. +
  3. Follow the Detailed IFTTT setup Instructions

  4. +
  5. Configure Nightscout by setting these webpage environment variables:

  6. +
+
    +
  • ENABLE - maker should be added to the list of plugins, for example: ENABLE="maker".

  • +
  • MAKER_KEY - Set this to your secret key (see [Detailed Instructions ) MAKER_KEY="abcMyExampleabc123defjt1DeNSiftttmak-XQb69p" This also supports a space delimited list of keys.

  • +
  • MAKER_ANNOUNCEMENT_KEY - An optional Maker key, will be used for system wide user generated announcements. If not defined this will fallback to MAKER_KEY. A possible use for this is sending important messages and alarms to another device that you don’t want to send all notification too. This also support a space delimited list of keys.

  • +
+

Plugins can create custom events, but all events sent to IFTTT webhooks will be prefixed with ns-. The core events are:

+
    +
  • ns-event - This event is sent to the maker service for all alarms and notifications. This is good catch all event for general logging.

  • +
  • ns-allclear - This event is sent to the maker service when an alarm has been acknowledged or when the server starts up without triggering any alarms. For example, you could use this event to turn a light to green.

  • +
  • ns-info - Plugins that generate notifications at the info level will cause this event to also be triggered. It will be sent in addition to ns-event.

  • +
  • ns-warning - Alarms at the warning level with cause this event to also be triggered. It will be sent in addition to ns-event.

  • +
  • ns-urgent - Alarms at the urgent level with cause this event to also be triggered. It will be sent in addition to ns-event.

  • +
  • see the full list of events

  • +
+
+
+
+

Treatment Profile

+

Some of the plugins make use of a treatment profile that can be edited using the Profile Editor.

+

Treatment Profile Fields:

+
    +
  • timezone (Time Zone) - time zone local to the patient. Should be set.

  • +
  • units (Profile Units) - blood glucose units used in the profile, either “mg/dl” or “mmol”

  • +
  • dia (Insulin duration) - value should be the duration of insulin action to use in calculating how much insulin is left active. Defaults to 3 hours.

  • +
  • carbs_hr (Carbs per Hour) - The number of carbs that are processed per hour, for more information see #DIYPS.

  • +
  • carbratio (Carb Ratio) - grams per unit of insulin.

  • +
  • sens (Insulin sensitivity) How much one unit of insulin will normally lower blood glucose.

  • +
  • basal The basal rate set on the pump.

  • +
  • target_high - Upper target for correction boluses.

  • +
  • target_low - Lower target for correction boluses.

  • +
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/stringhelp/index.html b/nightscout/stringhelp/index.html new file mode 100644 index 00000000..3a09fb1d --- /dev/null +++ b/nightscout/stringhelp/index.html @@ -0,0 +1,192 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/tokens/index.html b/nightscout/tokens/index.html new file mode 100644 index 00000000..4f5d9979 --- /dev/null +++ b/nightscout/tokens/index.html @@ -0,0 +1,255 @@ + + + + + + + Roles — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Note: authentication tokens are also called access tokens

+
+

Changing API_SECRET

+

If you change your API_SECRET all your tokens will change. Make sure you update your devices and send the new token link to those you allowed to access your Nightscout

+
+

To access the Authentication options, click the settings panel (three horizontal bars in the top right) in your website and select Admin Tools. The Authentication options are at the top of the Admin page. (Note: you must be logged in with your API SECRET to access these tools.)

+../../_images/Admin04.png +
+

You will see several predefined roles:

+../../_images/Admin01.png +
+
+

Roles

+
    +
  • admin: full access

  • +
  • careportal: can view the site and make CarePortal/treatment entries

  • +
  • readable: read-only access; no ability to make CarePortal/treatment entries. This user CAN see reports and profile information.

  • +
  • denied: no access (this role only works if the AUTH_DEFAULT_ROLES setting is also denied. You can’t have a site that is readable to everyone and create a “denied” token for a specific user.)

  • +
  • devicestatus-upload: used by devices

  • +
+
+

Hint

+

There is currently no way to limit a user so that he cannot view the Reports section if he has access to the site. Time/date-based roles are not currently possible.

+
+
+
+
+

Create a Token

+
    +
  • Click the “Add New Subject” button.

  • +
+../../_images/Admin00.png +
+
    +
  • Fill in the name of the subject and the “role” you are giving this subject (from the list of roles shown above). Note you should only grant the readable role for users who do not need to save or edit data in Nightscout. For example, you might want to share the site to a school nurse, but not have him able edit the data.

  • +
+../../_images/Admin05.png +
    +
  • An admin token is necessary for AAPS to upload using the API V3.

  • +
+../../_images/Admin05b.png +
+
    +
  • Click save.

  • +
  • The token will be shown. You can use it in two different ways:

    +
      +
    • Copy the token URL (right-click on it in the browser and select the option to copy the link address) and provide it to the user (e.g., paste it into an email). If the user enters the entire URL (with token), the token will be in effect.

    • +
    • Copy the token string (in the example below school-a595d5f0aeff64c0) and use it for authentication at site opening, instead of the API secret (Nightscout minimum version 14.1.0 required).

    • +
    +
  • +
+../../_images/Admin06.png +
+

You can also add the token to the site URL to authenticate using a token. Your site link with token will look like this:

+

https://yoursitename.yourplatform.com/?token=school-a595d5f0aeff64c0

+

Anybody with this link can use your Nightscout with the role defined for this token.

+
+

Hint

+

If the user copies only your core URL into a browser, and your site is readable by default, the token will be bypassed. (Possible strategies to ensure the user puts the role-based URL into a browser include using a tinyurl or bit.ly.)

+
+
    +
  • You can edit a subject by clicking the edit icon, making changes, and saving.

  • +
  • You can delete a subject by clicking the red X icon to remove the subject from the list.

  • +
+

See how to setup your downloaders (followers) with a secured site.

+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/ubuntu/index.html b/nightscout/ubuntu/index.html new file mode 100644 index 00000000..726c94c8 --- /dev/null +++ b/nightscout/ubuntu/index.html @@ -0,0 +1,192 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/wearable/index.html b/nightscout/wearable/index.html new file mode 100644 index 00000000..3178f7fd --- /dev/null +++ b/nightscout/wearable/index.html @@ -0,0 +1,459 @@ + + + + + + + Nightscout on your Watch — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout on your Watch

+
+
+

Pebble Smartwatches

+../../_images/PebbleNSFoundation.jpeg +

Pebble smartwatch use is a historic milestone of CGM in the Cloud. Pebble has been bought by Fitbit in 2016 and necessary resources have moved to archives and rebble.io. Pebble support is still maintained in Loop, AndroidAPS, FreeAPS and xDrip+.

+

You still can find the Pebble app for iOS in the Apple Store. For Android you need to download it from APKMirror or APKPure.

+

For authentication and getting the watchfaces, the original server closed so you’ll need to register with Rebble.

+

You’ll find Nightscout watchfaces here. Search for Nightscout, CGM, …

+

Configure the watchface with your Nightscout site URL.

+
+
+

urchin

+

A Pebble watchface to view data from a continuous glucose monitor in graph format.

+
+

If you want to use your Pebble with Loop look here, for AndroidAPS here and FreeAPS here.

+
+
+
+

xDrip+

+

Enable Pebble Integration in Smartwatch features.

+../../_images/Watch02.png +
+

You can answer no to default watchface install so that you will be able to select another one. You can then decide to install or not the snooze control.

+../../_images/Watch03.png +
+
+
+
+

Android Wear OS smartwatches

+

With an Android smartphone.

+
+ +
+
    +
  • Recommended: Install an old version of Android Wear on your phone (search APKMirror for example: Android Wear 2.9.0.185084575.gms) and pair your watch. Make sure to allow GPS and Wear OS access to position on the watch. Allow Wear OS to run in background on your phone.

  • +
+

Note:If you installed Wear OS, you will need to manually update the watch Google Play Services see here.

+
    +
  • Once your smartwatch Google Play Service has been updated to a version above 9.x you can safely update Android Wear to Wear OS.

  • +
  • Change the watchface to match your app (in Wear OS or on your watch).

  • +
+
+ +
+
    +
  • Install Wear OS on your phone and pair your watch. Make sure to allow GPS and Wear OS access to position on the watch. Allow Wear OS to run in background on your phone.

  • +
  • Install your app wear extension from the smartwatch Google Play store, selecting the apps installed on your phone.Note: Newer versions of Wear OS do not support this feature anymore, use Wear Installer or Use GeminiMan Wear OS Manager or Easy Fire Tools.

  • +
  • Change the watchface to match your app (in Wear OS or on your watch).

  • +
+
+ +
+
    +
  • Install Wear OS on your phone and pair your watch. Make sure to allow GPS and Wear OS access to position on the watch. Allow Wear OS to run in background on your phone.

  • +
  • Use Wear Installer or Use GeminiMan Wear OS Manager or Easy Fire Tools.

  • +
  • Change the watchface to match your app (in Wear OS or on your watch).

  • +
+
+
+
+
+

xDrip+

+

Enable Android Wear Integration to send xDrip+ BG to the smartwatch. Do not enable neither Collection nor Force Collection.

+../../_images/Watch00.png +

Full xDrip+ wear documentation here.

+

NB: you can also use Tasker.

+
+
+

AndroidAPS

+

For AndroidAPS here.

+
+
+

Glimp

+

Select your Wearable device and enable the Glimp watchface.

+../../_images/Watch01.png +
+
+

NightWear

+

NightWear is a minimal Wear OS watch face and complication available in the Google Play Store directly from your watch.

+

It uses Wear’s standalone app support, so requires no companion app installed on the phone, or no phone at all as long as the watch has an internet connection. This also means it’s possible to display Nightscout data on a Google Wear OS watch paired with an Apple iPhone.

+
+
+
+
+

Amazfit Pace & Stratos

+
+

xDrip+

+
    +
  • Install the Amazfit watch app on your phone.

  • +
  • Install the Amazfit tool on a Windows PC.

  • +
  • Download the widget from the project author (Klaus3d3) GitHub repository.

  • +
  • OEM unlock and enable USB debug on the watch, run TOOL ALL IN ONE and click the APK Installer button, select the widget apk file and INSTALL it. Close the install window and click Reboot System.

  • +
  • In xDrip+, enable the Amazfit service and select the options you want to enable.

  • +
+../../_images/Watch04.png +

Original instructions here.

+
+
+
+
+

Xiaomi MiBand 2, 3, 4, 5 and 6

+
+
+

Amazfit Band 5, Bip, Bip Lite, Bip S and Bip S lite, T-Rex Pro

+
+
+

Amazfit GTR2, GTR2e, GTS2, GTS 2 mini, GTS2e, GTR42 and 47

+
+

xDrip+

+

Follow Artem’s instructions here.

+
+
+
+
+

Apple Watch

+
+

Nightguard

+

Apple Watch series 3 and above.

+

GitHub

+
+
+
+

sugarmate

+
+

Important limitation

+

Sugarmate doesn’t allow Nightscout as a data source if you included bridge in ENABLE. +If you need this data source: enable obscuration variables.

+
+

You can setup sugarmate as a calendar complication to display Nightscout on your Apple watch.

+
+
+
+

Gluco-Tracker

+
+
+
+

Loop Follow

+

You can setup Loop Follow as a calendar complication to display Nightscout on your Apple watch.

+
+
+
+
+

Fitbit

+
+

Nightscout Monitor

+

Ionic/Sense/Versa/Versa 2/Versa 3/Versa Lite

+

Repository

+
+
+
+

Glance

+

Ionic/Sense/Versa/Versa 2/Versa 3/Versa 4/Versa Lite

+

Web site

+
+
+
+

Sentinel

+

Ionic/Sense/Versa/Versa 2/Versa Lite

+

Facebook group: Sentinel

+
+
+
+

Marclock

+

Ionic/Sense/Versa/Versa 2/Versa Lite

+

Instructions

+
+
+
+

Analog watchfaces

+
+

Analog CGM

+
+
+

Orbits NS

+
+
+

Radial CGM

+

Ionic/Versa/Versa 2/Versa Lite/Versa 3/Sense

+
+
+
+
+
+

Samsung Gear Smartwatches

+
+

xDrip+ with Tasker

+

Note: also available for Android Wear devices

+

Instructions

+
+
+
+

G-Watch app

+

Facebook group: G-Watch App

+
+
+
+
+

Garmin Smartwatches and Computers

+

By Phimby

+

By Horsetooth

+

By andreas-may

+

By Fredrik_S

+

By John_

+

By floheigl

+
+
+
+

Karoo/Karoo 2

+

By Henry Haspden

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/wizard/index.html b/nightscout/wizard/index.html new file mode 100644 index 00000000..bdcea09e --- /dev/null +++ b/nightscout/wizard/index.html @@ -0,0 +1,345 @@ + + + + + + + Help me choose — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Help me choose

+../../_images/wizard.png +
+

Welcome to the Nightscout new user wizard.

+

This set of questions will hopefully help choose the best solution for you, or at least give you hints on where to start.

+
+

Hint

+

This wizard is thought for one Nightscout site (one patient with diabetes). If you need more Nightscout sites you might need more accounts. Some hosted providers provide discounts, T1Pal support up to 5 patients per subscription.

+
+
+ + + + + + + + + + + + + +

I want to contribute to Nightscout research and development.

What is the maximum acceptable cost per month per site?

How much of an issue is it when Nightscout is down?

How much time are you ready to spend on creating and maintaining it?

+ +
+

Now click SHOW below to validate your choices.
+If you change any option above, validate again to update.

+

+
+
+

Database options

+
+
+

-

+
+
+
+
+

Nightscout options

+
+
+

-

+
+
+

Made you mind? Have a look at your options:

+
+
+

Hosted

+

T1Pal
+NS10BE
+Nightscout Pro
+Serendipity Bio
+Nightscout4u

+
+
+

Database

+

MongoDB Atlas
+Railway Mongo Database
+Northflank Mongo Database
+VPS Mongo Database

+
+
+

Provider

+

Heroku Eco plan
+Railway
+Northflank
+Fly.io
+Azure
+Render

+
+
+

VPS

+

Google Cloud
+Oracle Cloud
+Advanced DIY

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/nightscout/xdripteam/index.html b/nightscout/xdripteam/index.html new file mode 100644 index 00000000..5bbda2b8 --- /dev/null +++ b/nightscout/xdripteam/index.html @@ -0,0 +1,191 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/objects.inv b/objects.inv new file mode 100644 index 00000000..9264370c Binary files /dev/null and b/objects.inv differ diff --git a/pages/configure/index.html b/pages/configure/index.html new file mode 100644 index 00000000..73ff73d8 --- /dev/null +++ b/pages/configure/index.html @@ -0,0 +1,642 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Warning

+

Historical pages

+
+ + Auto Configure Nightscout? + + + + + + + + +
+
+

How do we configure Nightscout?

+
+ +
+
+
+ +

Step 1: Sign up for an account at CloudMQTT

+

Click here to sign up and create your MQTT server

+

Step 2: Enter your MQTT server information below +

+
+
+ + +
+
+ +
+
+
+ +
+
+ +
+
+
+
+
+
+ REST API + + +

Enter your API_SECRET and REST API URL below.

+

Your API_SECRET must be 12 characters or more

+

Your REST API URL format should be https://foobar.azurewebsites.net/api/v1

+

Change foobar to your personal site name, and don't forget to add /api/v1 to the end of the URL.

+
+
+ + +
+
+
+ + +
+
+
+
+
+
+ +

Step 1: Sign up for a Mongolab account and create a database

+

+ Detailed instructions are available at nightscout.info. If you already have a Mongo database for Nightscout, skip this step. +

+

Step 2: Enter your Mongo server, port and database name

+

For example: ds012345.mongolab.com:12345/databasename

+
+ + +
+
+
+

Step 3: Enter the db username and password for your database

+ +
+ +
+
+ +
+
+
+

+

+ + + : + + @ + + / + + + +
+
+
+ + + + + + + + + + + + + + + + + +
+

Required

+
+ MONGO_CONNECTION + + + Custom +
+

Required for REST API

+
+ API_SECRET + + + Custom +
+
+
+
+
+
+
+
+

+ +

+
+

+      
+
+
+ + + +
+
+ + +
+ + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pages/mongostring/index.html b/pages/mongostring/index.html new file mode 100644 index 00000000..b95b5b05 --- /dev/null +++ b/pages/mongostring/index.html @@ -0,0 +1,394 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Warning

+

Historical pages

+
+ + What's my mongodb URI? + + + + + + + +
+
+

What is my MONGODB URI?

+
+ Create database +

Step 1: Sign up for an account to manage your database

+

+ Mongolab has a free sign up. +

+

Step 2: Create a database

+
+ + +
+
+
+

Step 3: Create a user for your new database

+ Create a user for the database +
+ +
+
+ +
+
+
+

+

+ + + : + + @ + + / + + + +
+
+
+

+ +

+
+
+
+
+ + + +
+
+ + +
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/pages/update-fork/index.html b/pages/update-fork/index.html new file mode 100644 index 00000000..e52f05bf --- /dev/null +++ b/pages/update-fork/index.html @@ -0,0 +1,239 @@ + + + + + + + Update your Nightscout — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Update your Nightscout

+
+
+

The latest release is 15.0.2.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Platform

Link

../../_images/T1Pal.png

Contact T1Pal

../../_images/10BE.png

Change branch in your server

Nightscout.pro

Contact Nightscout.pro

../../_images/Heroku.png

Update

../../_images/Railway.png

Update

../../_images/Northflank.png

Update

../../_images/GoogleCloud.png

Google Cloud xDrip+
Continue here

../../_images/Azure.png

Update

../../_images/Fly.io.png

Update

../../_images/Render.png

Update

../../_images/Nightscout4u.png

Contact Nightscout4u

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/search/index.html b/search/index.html new file mode 100644 index 00000000..70775a37 --- /dev/null +++ b/search/index.html @@ -0,0 +1,208 @@ + + + + + + Search — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 00000000..6b065e8c --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["404", "clinicians/home", "clinicians/reports", "clinicians/setup", "index", "nightscout/admin_tools", "nightscout/advanced", "nightscout/close_loop", "nightscout/database", "nightscout/discover", "nightscout/dns", "nightscout/docker", "nightscout/downloaders", "nightscout/first_setup", "nightscout/github", "nightscout/ifttt", "nightscout/multiadmin", "nightscout/new_user", "nightscout/platform", "nightscout/plugins-old", "nightscout/plugins-v15", "nightscout/profile_editor", "nightscout/pushover", "nightscout/reports", "nightscout/security", "nightscout/setup_variables", "nightscout/stringhelp", "nightscout/tokens", "nightscout/ubuntu", "nightscout/wearable", "nightscout/wizard", "nightscout/xdripteam", "pages/configure/index", "pages/mongostring/index", "pages/update-fork/index", "translate", "troubleshoot/atlas", "troubleshoot/azure", "troubleshoot/cleanup", "troubleshoot/connection_string", "troubleshoot/dexcom_bridge", "troubleshoot/fly.io", "troubleshoot/github", "troubleshoot/heroku", "troubleshoot/northflank", "troubleshoot/railway", "troubleshoot/render", "troubleshoot/troublehoot", "troubleshoot/troubleshoot", "update/dev_branch", "update/downgrade", "update/redeploy", "update/upd_stack", "update/update", "uploader/setup", "uploader/uploaders", "uploader/xdripcarelink", "vendors/10BE", "vendors/NAS/synology", "vendors/T1Pal/new_user", "vendors/VPS/docker", "vendors/VPS/ubuntu", "vendors/azure/migrate", "vendors/azure/new_user", "vendors/azure/new_user_a", "vendors/azure/new_user_b", "vendors/digitalocean/new_user", "vendors/fly.io/new_user", "vendors/github/create", "vendors/github/delete", "vendors/github/update", "vendors/github/update_b", "vendors/google/new_user", "vendors/heroku", "vendors/heroku/ecoplan", "vendors/heroku/hobbyplan", "vendors/heroku/mfa", "vendors/heroku/migrate", "vendors/heroku/new_user", "vendors/mongodb/atlas", "vendors/nightscout4u/new_user", "vendors/northflank/database", "vendors/northflank/migrate", "vendors/northflank/migrate_a", "vendors/northflank/new_user", "vendors/northflank/new_user_a", "vendors/northflank/new_user_d", "vendors/oracle/new_user", "vendors/railway/NightscoutVariablesRailway", "vendors/railway/database", "vendors/railway/migrate", "vendors/railway/migration", "vendors/railway/new_user", "vendors/railway/new_user2", "vendors/railway/new_user_a", "vendors/railway/new_user_b", "vendors/railway/new_user_d", "vendors/raspberry-pi/new_user", "vendors/render/new_user", "vendors/render/new_user_a", "vendors/render/new_user_d", "vendors/serendipity/index", "vendors/synology/new_user"], "filenames": ["404.md", "clinicians/home.md", "clinicians/reports.md", "clinicians/setup.md", "index.md", "nightscout/admin_tools.md", "nightscout/advanced.md", "nightscout/close_loop.md", "nightscout/database.md", "nightscout/discover.md", "nightscout/dns.md", "nightscout/docker.md", "nightscout/downloaders.md", "nightscout/first_setup.md", "nightscout/github.md", "nightscout/ifttt.md", "nightscout/multiadmin.md", "nightscout/new_user.md", "nightscout/platform.md", "nightscout/plugins-old.md", "nightscout/plugins-v15.md", "nightscout/profile_editor.md", "nightscout/pushover.md", "nightscout/reports.md", "nightscout/security.md", "nightscout/setup_variables.md", "nightscout/stringhelp.md", "nightscout/tokens.md", "nightscout/ubuntu.md", "nightscout/wearable.md", "nightscout/wizard.md", "nightscout/xdripteam.md", "pages/configure/index.md", "pages/mongostring/index.md", "pages/update-fork/index.md", "translate.md", "troubleshoot/atlas.md", "troubleshoot/azure.md", "troubleshoot/cleanup.md", "troubleshoot/connection_string.md", "troubleshoot/dexcom_bridge.md", "troubleshoot/fly.io.md", "troubleshoot/github.md", "troubleshoot/heroku.md", "troubleshoot/northflank.md", "troubleshoot/railway.md", "troubleshoot/render.md", "troubleshoot/troublehoot.md", "troubleshoot/troubleshoot.md", "update/dev_branch.md", "update/downgrade.md", "update/redeploy.md", "update/upd_stack.md", "update/update.md", "uploader/setup.md", "uploader/uploaders.md", "uploader/xdripcarelink.md", "vendors/10BE.md", "vendors/NAS/synology.md", "vendors/T1Pal/new_user.md", "vendors/VPS/docker.md", "vendors/VPS/ubuntu.md", "vendors/azure/migrate.md", "vendors/azure/new_user.md", "vendors/azure/new_user_a.md", "vendors/azure/new_user_b.md", "vendors/digitalocean/new_user.md", "vendors/fly.io/new_user.md", "vendors/github/create.md", "vendors/github/delete.md", "vendors/github/update.md", "vendors/github/update_b.md", "vendors/google/new_user.md", "vendors/heroku.md", "vendors/heroku/ecoplan.md", "vendors/heroku/hobbyplan.md", "vendors/heroku/mfa.md", "vendors/heroku/migrate.md", "vendors/heroku/new_user.md", "vendors/mongodb/atlas.md", "vendors/nightscout4u/new_user.md", "vendors/northflank/database.md", "vendors/northflank/migrate.md", "vendors/northflank/migrate_a.md", "vendors/northflank/new_user.md", "vendors/northflank/new_user_a.md", "vendors/northflank/new_user_d.md", "vendors/oracle/new_user.md", "vendors/railway/NightscoutVariablesRailway.md", "vendors/railway/database.md", "vendors/railway/migrate.md", "vendors/railway/migration.md", "vendors/railway/new_user.md", "vendors/railway/new_user2.md", "vendors/railway/new_user_a.md", "vendors/railway/new_user_b.md", "vendors/railway/new_user_d.md", "vendors/raspberry-pi/new_user.md", "vendors/render/new_user.md", "vendors/render/new_user_a.md", "vendors/render/new_user_d.md", "vendors/serendipity/index.md", "vendors/synology/new_user.md"], "titles": ["", "Nightscout for clinicians", "Nightscout reports", "Setup the main view", "Welcome to Nightscout", "Admin Tools", "Advanced Nightscout deployments", "Closed loop systems", "Choose your database", "Discover your Nightscout site", "Use a Dynamic DNS", "<no title>", "Setup Downloaders - Followers", "New Nightscout Setup", "GitHub", "IFTTT Integration", "Multiple sites and support", "New Nightscout Users", "Choose your platform", "<no title>", "Nightscout-connect", "Setup your Profile", "Remote notifications", "Create Reports", "Nightscout Security and Privacy", "Nightscout Configuration", "<no title>", "Roles", "<no title>", "Nightscout on your Watch", "Help me choose", "<no title>", "<no title>", "<no title>", "Update your Nightscout", "Google Translate links", "Troubleshoot MongoDB Atlas", "Troubleshoot Azure", "Cleanup", "Connection string", "Troubleshoot Dexcom Share", "Troubleshoot Fly.io", "Troubleshoot GitHub", "Troubleshoot Heroku", "Troubleshoot Northflank", "Troubleshoot Railway", "Troubleshoot Render", "<no title>", "Troubleshooting Nightscout", "Deploy another version", "Downgrade Nightscout", "Redeploy with GitHub", "Update the Heroku stack", "Update Nightscout", "Setup Uploaders", "Supported Uploaders", "xDrip+ for CareLink", "<no title>", "Nightscout in your Synology NAS", "<no title>", "Building Nightscout with Docker", "Building Nightscout in Ubuntu", "<no title>", "Nightscout in Azure (Docker)", "<no title>", "<no title>", "<no title>", "Nightscout in Fly.io", "Fork the Nightscout project", "<no title>", "Update GitHub", "<no title>", "Nightscout in Google Cloud", "<no title>", "Heroku Eco plan", "Heroku Basic plan", "Heroku MFA", "Migration?", "Nightscout in Heroku", "MongoDB Atlas Database", "<no title>", "Northflank Database", "<no title>", "<no title>", "Nightscout in Northflank", "Dexcom Bridge", "Dexcom Bridge", "<no title>", "<no title>", "Railway Database", "<no title>", "<no title>", "Nightscout in Railway", "Update your link.", "Mandatory variables", "
", "Mandatory variables", "<no title>", "Nightscout in Render", "Step 4: Add the render.yaml template", "Step 4: Create your Nightscout service", "<no title>", "<no title>"], "terms": {"unless": [1, 2, 4, 5, 8, 9, 20, 22, 25, 36, 43, 49, 50, 54, 60, 79, 83, 84], "specifi": [1, 9, 15, 22, 25, 36, 37, 60], "link": [1, 3, 4, 5, 7, 9, 10, 14, 15, 16, 22, 24, 25, 27, 34, 36, 37, 40, 42, 55, 58, 68, 78, 83, 84, 98], "within": [1, 3, 4, 10, 18, 23, 40, 63, 67, 89, 92], "text": [1, 9, 10, 15, 22, 36, 43, 60, 61, 67, 79, 92, 94, 96, 98], "ar": [1, 3, 5, 6, 7, 8, 9, 10, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 27, 30, 32, 36, 40, 41, 43, 48, 49, 54, 55, 60, 61, 63, 64, 65, 67, 77, 78, 79, 81, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "advanc": [1, 7, 9, 15, 22, 30, 36, 63, 84, 85], "explan": [1, 4, 9, 76], "underli": 1, "mechan": [1, 21, 24, 55], "don": [1, 4, 6, 8, 10, 13, 14, 15, 16, 17, 20, 21, 22, 25, 32, 36, 40, 41, 42, 43, 45, 48, 49, 51, 53, 54, 55, 56, 60, 61, 63, 64, 65, 67, 68, 69, 70, 74, 76, 77, 78, 79, 81, 83, 84, 85, 86, 90, 92, 94, 95, 96, 98, 99], "t": [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 24, 25, 27, 32, 36, 37, 40, 41, 42, 45, 46, 48, 49, 51, 52, 53, 54, 56, 60, 61, 63, 64, 65, 67, 68, 69, 70, 74, 76, 77, 79, 81, 83, 84, 85, 86, 89, 90, 92, 94, 95, 96, 99], "necessarili": [1, 22, 24, 63, 65], "add": [1, 3, 5, 10, 12, 15, 16, 18, 20, 21, 23, 24, 25, 27, 32, 36, 37, 40, 54, 61, 64, 67, 74, 75, 76, 78, 79, 81, 84, 85, 86, 90, 92, 94, 95, 96, 98, 100], "valu": [1, 2, 3, 5, 6, 9, 13, 21, 22, 23, 24, 36, 40, 43, 49, 53, 55, 56, 61, 64, 65, 67, 78, 79, 81, 84, 85, 86, 92, 94, 95, 96, 98, 100], "us": [1, 2, 3, 5, 6, 7, 8, 9, 12, 13, 15, 16, 17, 18, 20, 21, 22, 23, 27, 29, 36, 37, 40, 41, 44, 45, 48, 49, 50, 53, 54, 55, 60, 61, 63, 64, 65, 67, 70, 75, 76, 77, 79, 81, 83, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99, 100], "an": [1, 2, 3, 4, 5, 6, 7, 9, 10, 15, 16, 17, 18, 22, 23, 24, 27, 29, 30, 32, 33, 36, 37, 38, 45, 46, 48, 49, 52, 53, 54, 55, 56, 60, 61, 64, 67, 74, 75, 76, 77, 78, 84, 85, 86, 92, 94, 95, 96, 98, 100], "sourc": [1, 4, 7, 12, 15, 17, 25, 29, 45, 48, 49, 53, 55, 56, 60, 61, 63, 64, 65, 78, 84, 85, 86, 92, 95], "cloud": [1, 4, 8, 12, 14, 18, 20, 25, 29, 30, 34, 36, 40, 44, 48, 49, 53, 54, 55, 56, 60, 61, 70, 78, 79, 81, 84, 85, 86], "applic": [1, 4, 12, 15, 17, 24, 25, 36, 55, 61, 63, 64, 65, 67, 78], "visual": [1, 3, 4, 9, 25], "store": [1, 4, 6, 9, 17, 21, 23, 24, 25, 29, 40, 41, 61, 67, 76], "share": [1, 4, 5, 13, 16, 17, 24, 25, 27, 36, 43, 54, 55, 56, 63, 64, 65, 78, 79, 84, 85, 86, 92, 95, 98, 99, 100], "real": [1, 3, 4, 25, 43, 55, 67], "time": [1, 2, 3, 4, 5, 7, 9, 13, 15, 16, 17, 21, 22, 23, 24, 27, 30, 36, 43, 45, 49, 53, 55, 56, 60, 61, 63, 67, 78, 81, 84, 85, 86, 92, 94, 95, 96, 98], "from": [1, 2, 4, 9, 10, 15, 16, 17, 18, 20, 22, 23, 24, 25, 27, 29, 36, 40, 42, 43, 45, 48, 49, 51, 52, 53, 55, 56, 60, 61, 63, 64, 65, 67, 69, 72, 76, 77, 79, 85, 86, 89, 90, 94, 96, 98, 99, 100], "continu": [1, 3, 4, 7, 8, 13, 14, 29, 34, 36, 40, 41, 42, 45, 53, 55, 63, 64, 65, 67, 68, 76, 77, 78, 79, 81, 83, 84, 85, 86, 92, 94, 96, 98], "glucos": [1, 3, 4, 7, 9, 12, 23, 25, 29, 36, 55, 56], "monitor": [1, 4, 6, 7, 12, 16, 17, 22, 36, 41, 45, 48, 49, 50, 53, 60, 61, 63, 67, 69, 70, 71, 74, 85, 86, 89, 90, 94, 95, 96, 99, 100], "sensor": [1, 3, 4, 15, 20, 40, 48, 55], "manual": [1, 3, 9, 16, 18, 22, 29, 36, 43, 46, 53, 63, 79, 83, 84, 92, 95], "automat": [1, 3, 4, 5, 7, 22, 25, 36, 41, 43, 45, 49, 53, 55, 56, 60, 67, 92, 95], "log": [1, 5, 9, 14, 15, 16, 24, 27, 36, 37, 40, 41, 42, 44, 49, 51, 52, 53, 54, 60, 63, 64, 65, 68, 69, 70, 71, 74, 75, 76, 78, 81, 84, 85, 86, 90, 92, 95, 98], "treatment": [1, 2, 4, 15, 17, 24, 27, 36, 55, 56], "basal": [1, 2, 3, 7, 21, 22, 23, 36, 55, 60, 63, 64, 65, 78, 84, 85, 86], "rate": [1, 2, 3, 9, 21, 23, 25, 36], "pump": [1, 2, 3, 5, 7, 15, 21, 22, 48, 54, 55, 56, 60, 63, 64, 65, 78, 84, 85, 86], "option": [1, 4, 5, 7, 9, 15, 17, 22, 23, 24, 25, 27, 29, 30, 36, 40, 43, 55, 67, 72, 76, 77, 79, 83, 84, 85, 90, 92, 94, 95, 96], "your": [1, 5, 7, 10, 12, 13, 14, 16, 17, 20, 23, 24, 27, 30, 32, 33, 37, 38, 44, 46, 48, 50, 52, 54, 55, 56, 64, 65, 68, 69, 71, 75, 76, 77, 79, 83, 90, 94, 95, 96, 98, 99], "uniqu": [1, 63, 98, 100], "web": [1, 4, 6, 9, 15, 16, 17, 18, 22, 24, 25, 29, 36, 43, 45, 46, 48, 49, 50, 54, 55, 60, 65, 67, 72, 77, 78, 84, 98, 100], "you": [1, 2, 3, 4, 5, 7, 9, 10, 12, 13, 15, 16, 20, 21, 22, 23, 24, 25, 27, 29, 30, 32, 36, 37, 38, 40, 43, 44, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 60, 64, 65, 69, 70, 71, 76, 77, 83, 85, 86, 90, 94, 95, 96, 99, 100], "look": [1, 2, 3, 4, 5, 7, 9, 12, 21, 22, 24, 25, 27, 29, 30, 36, 38, 41, 48, 49, 50, 54, 60, 61, 77], "like": [1, 3, 4, 5, 8, 9, 10, 15, 17, 22, 23, 24, 25, 27, 36, 40, 41, 43, 45, 49, 54, 60, 61, 63, 64, 67, 74, 76, 77, 78, 79, 81, 84, 85, 86, 92, 94, 95, 96, 98, 99], "http": [1, 4, 5, 9, 12, 14, 15, 23, 25, 27, 32, 36, 40, 41, 42, 43, 48, 49, 50, 51, 52, 53, 54, 58, 60, 61, 63, 67, 68, 69, 70, 71, 74, 75, 78, 79, 81, 84, 90, 92, 98, 99], "name": [1, 5, 6, 10, 12, 15, 17, 20, 21, 22, 24, 25, 27, 32, 36, 37, 40, 41, 42, 43, 45, 49, 50, 51, 53, 54, 60, 61, 63, 64, 65, 67, 69, 77, 78, 79, 81, 85, 86, 94, 95, 96, 98, 99, 100], "domain": [1, 10, 12, 18, 60, 61, 92, 96], "ext": 1, "sinc": [1, 3, 8, 9, 15, 16, 17, 18, 21, 23, 25, 43, 45, 56, 67, 74, 75, 77, 78, 81, 92, 94, 96], "view": [1, 4, 5, 13, 15, 16, 23, 24, 27, 29, 36, 40, 49, 52, 53, 55, 67, 78, 84, 85, 86, 92, 94, 95, 96, 98], "anybodi": [1, 4, 5, 9, 24, 25, 27, 42, 51, 69, 84, 85, 86, 92, 95], "have": [1, 2, 4, 5, 6, 8, 9, 13, 15, 16, 17, 18, 20, 22, 24, 25, 27, 29, 30, 32, 36, 37, 38, 40, 41, 43, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 60, 61, 63, 64, 65, 67, 69, 70, 71, 74, 76, 77, 79, 81, 83, 85, 86, 89, 92, 94, 95, 96, 99, 100], "internet": [1, 4, 15, 17, 18, 29, 48, 56, 98], "caregiv": [1, 20, 22], "decid": [1, 8, 18, 22, 25, 29, 36, 40, 43, 61, 63, 74, 75, 77, 78], "make": [1, 4, 5, 9, 14, 15, 16, 17, 18, 21, 23, 24, 25, 27, 29, 36, 37, 40, 41, 42, 43, 45, 48, 49, 53, 55, 56, 60, 63, 64, 67, 68, 74, 75, 77, 78, 79, 84, 85, 86, 89, 92, 94, 95, 96, 98, 99, 100], "secur": [1, 4, 5, 9, 12, 13, 25, 27, 36, 43, 54, 63, 64, 67, 77, 78, 84, 85, 86, 92, 95, 98, 99, 100], "token": [1, 9, 12, 25, 84, 85, 86, 92, 95], "clinic": [1, 3, 4], "48aed625abb0ec86": 1, "need": [1, 3, 5, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 24, 25, 27, 29, 30, 36, 38, 40, 41, 42, 43, 44, 45, 46, 48, 49, 50, 52, 53, 54, 55, 56, 60, 61, 63, 64, 65, 67, 70, 71, 76, 77, 78, 79, 81, 83, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99, 100], "full": [1, 4, 5, 8, 24, 25, 27, 29, 42, 43, 44, 45, 48, 49, 51, 61, 63, 64, 69, 74, 78, 79, 84, 85, 86, 92, 95, 98, 99, 100], "provid": [1, 4, 5, 7, 10, 13, 17, 18, 20, 22, 24, 25, 27, 36, 48, 60, 61, 63, 67, 72, 77, 78, 79, 84, 92, 98], "ani": [1, 3, 4, 5, 9, 10, 13, 15, 17, 18, 22, 24, 25, 30, 36, 40, 43, 54, 55, 56, 61, 63, 64, 67, 78, 79, 84, 85, 86, 89, 92, 95, 98], "devic": [1, 3, 4, 5, 6, 17, 18, 20, 22, 24, 27, 29, 36, 40, 48, 55, 56, 76, 78, 84, 92], "connect": [1, 3, 4, 15, 16, 17, 22, 24, 29, 40, 43, 44, 45, 48, 49, 53, 54, 55, 56, 61, 63, 64, 67, 76, 78, 79, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99, 100], "experi": [1, 4, 18, 36, 40, 41, 43, 49, 53, 67, 77], "issu": [1, 4, 5, 6, 7, 8, 10, 16, 17, 18, 24, 25, 30, 40, 41, 42, 43, 49, 51, 53, 54, 63, 64, 67, 77, 78, 79, 84, 85, 86, 92, 95], "check": [1, 2, 3, 4, 6, 8, 10, 13, 14, 15, 17, 18, 23, 24, 25, 36, 37, 40, 41, 42, 43, 45, 48, 49, 50, 53, 54, 55, 61, 63, 64, 67, 68, 72, 74, 75, 78, 79, 81, 84, 85, 86, 89, 92, 94, 95, 96, 98], "IT": [1, 8, 18, 30, 63], "team": [1, 4, 18, 25, 77], "block": [1, 5, 18, 92], "local": [1, 4, 9, 22, 25, 43, 45, 48, 50, 67, 79], "safeti": [1, 18, 76, 78, 92], "rule": [1, 36, 60, 78], "mani": [1, 4, 7, 8, 9, 10, 15, 22, 25, 36, 43, 77, 92, 95], "who": [1, 5, 22, 24, 25, 27, 77], "build": [1, 8, 18, 25, 43, 48, 49, 52, 53, 63, 67, 76, 77, 79, 84, 85, 86], "own": [1, 6, 7, 10, 14, 16, 18, 22, 24, 25, 43, 49, 50, 53, 55, 60, 61, 67, 68, 69, 70, 71, 76, 78, 84, 90, 92, 94, 98, 99], "reli": [1, 4, 18, 25, 67, 74, 75, 76, 78, 98], "platform": [1, 4, 8, 14, 15, 24, 25, 34, 36, 40, 41, 43, 49, 53, 54, 63, 67, 72, 74, 75, 77, 78, 84, 92, 98], "servic": [1, 6, 8, 10, 15, 17, 18, 22, 25, 29, 36, 37, 40, 43, 44, 45, 49, 53, 54, 60, 61, 63, 64, 67, 72, 74, 75, 77, 78, 79, 81, 84, 85, 86, 89, 92, 94, 95, 96, 98], "free": [1, 4, 5, 6, 8, 10, 18, 25, 30, 33, 37, 43, 45, 49, 53, 63, 67, 72, 74, 75, 77, 78, 79, 81, 84, 89, 91, 92, 98, 100], "dn": [1, 18, 54, 84], "get": [1, 4, 23, 25, 29, 36, 40, 41, 43, 49, 55, 60, 61, 63, 64, 65, 67, 76, 84, 92, 94, 95, 96, 98], "classifi": 1, "unsaf": [1, 18, 98], "cybersecur": 1, "system": [1, 2, 3, 4, 8, 9, 12, 17, 23, 24, 25, 29, 36, 40, 48, 54, 63, 64, 78, 79], "ask": [1, 4, 16, 17, 21, 54, 61, 67], "perform": [1, 4, 5, 8, 15, 16, 36, 38, 49, 55, 63, 76, 84, 92], "all": [1, 3, 4, 5, 7, 9, 10, 13, 15, 16, 17, 21, 22, 23, 24, 25, 27, 29, 36, 38, 40, 41, 48, 49, 55, 61, 63, 65, 67, 77, 78, 79, 81, 85, 86, 90, 92, 94, 95, 96, 98, 99, 100], "necessari": [1, 2, 3, 5, 17, 22, 24, 27, 29, 36, 41, 42, 43, 51, 53, 60, 61, 63, 65, 67, 69, 74, 78, 84, 92, 94, 96, 98], "verif": [1, 14, 42, 68, 78, 84, 98], "allow": [1, 4, 5, 9, 12, 16, 18, 20, 22, 23, 24, 25, 27, 29, 36, 61, 63, 64, 67, 76, 78, 79, 83, 84, 85, 86, 90, 92, 95, 98, 99, 100], "itself": [1, 4, 22, 24], "safe": [1, 4, 5, 7, 24, 29, 36, 41, 42, 43, 45, 51, 61, 67, 69, 78, 79, 81, 89], "infrastructur": 1, "doesn": [1, 2, 3, 4, 9, 12, 17, 18, 21, 29, 36, 43, 46, 52, 61, 63, 67, 77, 92, 95], "contain": [1, 3, 5, 6, 18, 22, 36, 42, 43, 49, 50, 51, 53, 60, 61, 63, 69, 77, 92], "sort": [1, 2, 23], "cyberthread": 1, "malwar": 1, "host": [1, 2, 4, 6, 8, 10, 15, 17, 18, 24, 25, 32, 36, 53, 54, 60, 61, 63, 67, 72, 74, 75, 77, 78, 79, 81, 84, 89, 92, 98], "larg": [1, 8, 12, 15, 18, 24, 36, 38, 63, 72, 74, 75, 78], "varieti": 1, "expect": [1, 24, 25, 36, 49, 53, 63, 77], "follow": [1, 3, 5, 8, 9, 10, 13, 15, 18, 20, 22, 24, 25, 27, 30, 36, 40, 41, 43, 48, 49, 53, 54, 60, 61, 63, 64, 65, 67, 74, 77, 78, 79, 84, 85, 86, 92, 95, 98, 99, 100], "list": [1, 5, 6, 8, 9, 10, 15, 16, 17, 18, 20, 22, 23, 24, 25, 27, 41, 43, 45, 48, 49, 53, 60, 63, 64, 67, 78, 84, 85, 86, 92, 94, 95, 96, 98, 99], "heroku": [1, 4, 6, 8, 9, 14, 15, 17, 18, 22, 24, 25, 30, 36, 40, 49, 50, 53, 54, 63, 65, 70, 81, 83, 85, 86, 90], "com": [1, 4, 5, 14, 15, 20, 22, 24, 27, 32, 36, 40, 42, 43, 48, 49, 50, 51, 52, 53, 54, 58, 60, 61, 63, 67, 68, 69, 70, 71, 74, 75, 78, 79, 81, 84, 90, 92, 98, 99], "azurewebsit": [1, 32, 54], "net": [1, 25, 32, 36, 54, 78, 79], "railwai": [1, 6, 8, 14, 17, 18, 25, 30, 36, 40, 49, 50, 53, 54, 63, 64, 65, 70, 90, 91, 94, 95, 96], "app": [1, 4, 7, 16, 17, 18, 20, 22, 24, 25, 36, 40, 42, 48, 49, 50, 52, 53, 54, 55, 61, 64, 65, 67, 75, 83, 84, 85, 86, 89, 90, 92, 94, 95, 98, 99, 100], "fly": [1, 6, 8, 14, 17, 18, 25, 30, 36, 40, 49, 53, 54, 70], "dev": [1, 15, 20, 41, 49, 53, 54, 60, 61, 67], "onrend": 1, "t1pal": [1, 17, 30, 34, 54], "ns10be": [1, 17, 30, 48], "de": [1, 4, 9, 23, 25, 48, 54], "pro": [1, 8, 17, 18, 30, 34, 63, 67, 72, 74, 75, 78, 79, 81, 84, 89, 92, 98], "mooo": 1, "chickenkil": 1, "crabdanc": 1, "strangl": 1, "code": [1, 2, 4, 14, 16, 17, 22, 23, 36, 40, 41, 42, 43, 49, 51, 53, 54, 67, 68, 69, 77, 78, 84, 85, 86, 89, 92, 95, 98], "run": [1, 4, 6, 8, 9, 10, 13, 15, 17, 22, 23, 24, 25, 29, 36, 41, 43, 44, 45, 49, 53, 54, 55, 61, 63, 67, 77, 78, 84, 92, 98], "nightscout4u": [1, 17, 30, 34], "write": [1, 10, 22, 24, 36, 41, 43, 63, 64, 65, 67, 78, 79, 92], "protect": [1, 17, 24], "password": [1, 14, 16, 17, 20, 24, 32, 33, 42, 43, 48, 49, 51, 53, 60, 61, 67, 68, 69, 70, 71, 79, 81, 94, 96, 98, 99, 100], "call": [1, 3, 5, 15, 22, 24, 27, 36, 43, 76, 77, 79, 84], "api_secret": [1, 12, 17, 32, 43, 54, 60, 63, 64, 65, 67, 78, 83, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "displai": [1, 2, 4, 9, 15, 21, 23, 25, 29, 49, 53, 54, 55, 61, 63, 67, 70, 71, 78, 79, 84, 92, 94, 95, 96, 98, 99], "similar": [1, 9, 23, 25, 79], "thi": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 20, 21, 22, 23, 24, 27, 29, 30, 32, 36, 37, 40, 41, 42, 43, 45, 48, 49, 50, 51, 53, 54, 55, 56, 58, 60, 61, 63, 64, 65, 68, 69, 70, 71, 74, 76, 77, 83, 84, 85, 86, 90, 92, 94, 95, 96, 98, 99, 100], "If": [1, 3, 4, 5, 6, 9, 10, 12, 13, 15, 16, 17, 20, 21, 22, 23, 24, 25, 27, 29, 30, 32, 36, 37, 38, 40, 43, 44, 45, 46, 48, 49, 50, 52, 53, 54, 55, 56, 60, 61, 63, 64, 65, 67, 70, 71, 74, 76, 77, 81, 83, 85, 86, 89, 90, 92, 94, 95, 96, 99, 100], "mean": [1, 2, 4, 8, 17, 21, 23, 24, 29, 36, 43, 48, 77, 84, 85, 86, 92, 95], "forgot": [1, 36, 48], "send": [1, 3, 4, 5, 8, 9, 10, 14, 17, 21, 23, 24, 25, 27, 29, 42, 55, 56, 68, 74, 78, 79, 81, 83, 84, 98], "below": [1, 3, 4, 5, 6, 8, 9, 10, 14, 15, 16, 17, 18, 22, 23, 24, 25, 27, 30, 32, 36, 38, 40, 41, 43, 45, 48, 49, 53, 58, 60, 61, 63, 64, 65, 67, 72, 76, 77, 78, 79, 81, 84, 85, 86, 92, 94, 95, 96, 98], "setup": [1, 4, 5, 10, 15, 16, 22, 23, 24, 25, 27, 29, 40, 43, 48, 55, 56, 60, 64, 76, 77, 85, 86, 94, 95, 96, 99, 100], "main": [1, 4, 5, 15, 17, 25, 40, 42, 51, 62, 63, 64, 67, 69, 78, 82, 84, 85, 86, 91, 92, 93, 94, 95, 96, 98, 99, 100], "avail": [1, 3, 4, 8, 9, 10, 12, 15, 17, 18, 20, 25, 29, 32, 36, 40, 48, 50, 55, 61, 76, 77, 78, 89, 92], "inform": [1, 2, 3, 4, 5, 7, 9, 10, 13, 15, 21, 22, 23, 24, 25, 27, 32, 36, 49, 52, 53, 54, 55, 56, 60, 63, 64, 67, 74, 75, 76, 77, 78, 79, 84, 85, 86, 92, 94, 95, 96, 98], "gener": [1, 3, 4, 5, 7, 9, 18, 22, 23, 24, 25, 40, 54, 55, 78, 79, 84, 92, 96], "report": [1, 3, 4, 5, 9, 13, 17, 22, 24, 25, 27, 43, 63, 67, 78, 79, 84, 92, 98], "access": [2, 4, 5, 9, 10, 12, 13, 15, 16, 22, 25, 27, 29, 36, 40, 43, 63, 64, 67, 78, 79, 81, 83, 84, 85, 86, 92, 95, 98, 99, 100], "drawer": [2, 3, 23, 25], "menu": [2, 3, 4, 10, 13, 15, 16, 21, 23, 25, 36, 40, 45, 46, 49, 50, 53, 54, 63, 67, 78, 84, 92, 98, 99], "give": [2, 3, 4, 5, 9, 15, 16, 22, 23, 24, 25, 27, 30, 36, 40, 61, 76, 77], "import": [2, 14, 36, 40, 42, 43, 45, 48, 54, 55, 60, 63, 64, 67, 68, 77, 78, 83, 84, 90, 92, 94, 96, 98, 99], "patient": [2, 3, 4, 20, 23, 25, 30, 54, 61], "therapi": [2, 4], "paramet": [2, 3, 9, 25], "show": [2, 3, 12, 13, 15, 21, 22, 23, 24, 25, 30, 36, 40, 45, 49, 53, 54, 63, 67, 78, 84, 89, 92, 94, 96, 98], "addit": [2, 4, 9, 15, 17, 22, 23, 25, 54, 55, 76], "i": [2, 3, 5, 6, 7, 8, 9, 12, 14, 15, 16, 17, 18, 20, 21, 22, 23, 27, 29, 30, 33, 36, 37, 38, 41, 42, 44, 45, 46, 49, 50, 51, 52, 53, 55, 56, 58, 60, 61, 63, 64, 65, 67, 68, 69, 70, 71, 74, 75, 76, 77, 79, 83, 84, 85, 86, 90, 92, 94, 95, 96, 98, 99, 100], "": [2, 4, 6, 7, 8, 15, 22, 24, 25, 33, 36, 40, 41, 45, 48, 49, 53, 54, 55, 60, 61, 63, 64, 65, 77, 78, 79, 81, 83, 84, 85, 86, 89, 92, 95, 98, 99, 100], "dia": [2, 21, 25, 60], "durat": [2, 3, 4, 9, 15, 25], "insulin": [2, 3, 4, 7, 21, 23, 55], "action": [2, 5, 15, 22, 25, 36], "carb": [2, 3, 15, 21, 23], "absorpt": [2, 3, 9, 21], "complex": [2, 18, 21, 48, 50, 55, 76], "calcul": [2, 3, 21, 23, 25], "can": [2, 3, 5, 6, 8, 9, 10, 13, 15, 16, 17, 18, 21, 22, 23, 24, 25, 27, 29, 30, 36, 40, 41, 42, 45, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 60, 61, 63, 65, 67, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 84, 85, 86, 90, 92, 94, 95, 96, 98], "undefin": 2, "zero": [2, 25, 61, 79], "dii": [2, 3, 7, 8, 18, 25, 30, 48, 63, 64, 77, 78, 79], "updat": [2, 3, 4, 5, 9, 13, 14, 16, 17, 20, 21, 22, 23, 24, 25, 27, 29, 30, 36, 40, 41, 43, 45, 51, 54, 63, 67, 68, 71, 77, 78, 84, 85, 86, 89, 91, 92, 94, 95, 96, 98, 99], "when": [2, 4, 5, 9, 10, 15, 16, 17, 21, 22, 23, 24, 25, 30, 36, 37, 38, 40, 41, 42, 43, 45, 49, 51, 52, 54, 60, 61, 63, 64, 65, 67, 76, 77, 78, 84, 85, 86, 89, 90, 91, 92, 94, 95, 96, 98], "exist": [2, 4, 15, 18, 22, 45, 48, 49, 53, 67, 84, 89, 90, 91, 92, 98, 100], "ratio": [2, 7, 21, 25], "ic": 2, "sensit": [2, 7, 21, 25], "factor": [2, 7, 21, 76], "isf": [2, 7, 21], "defin": [2, 5, 21, 24, 25, 27, 36, 54, 60, 78, 92, 95, 98, 99, 100], "period": [2, 3, 21, 22, 23, 25, 43], "onli": [2, 3, 4, 5, 9, 10, 12, 14, 15, 16, 18, 20, 22, 23, 25, 27, 37, 40, 41, 42, 43, 45, 46, 49, 50, 51, 54, 55, 56, 58, 60, 61, 63, 64, 65, 67, 68, 69, 76, 77, 78, 79, 81, 83, 84, 85, 86, 90, 92, 94, 95, 98, 99, 100], "one": [2, 3, 4, 6, 8, 9, 10, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 29, 30, 40, 41, 42, 43, 45, 50, 54, 55, 60, 61, 63, 64, 65, 67, 72, 76, 77, 78, 79, 81, 83, 84, 85, 86, 89, 92, 95, 96, 98], "visibl": [2, 3, 5, 9, 24, 25, 84, 85, 86, 89, 91, 92, 95], "whole": [2, 21, 74, 75], "should": [2, 3, 5, 9, 13, 15, 21, 23, 24, 25, 27, 32, 36, 37, 40, 41, 45, 49, 53, 54, 55, 56, 60, 61, 63, 64, 67, 70, 71, 76, 77, 78, 79, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99, 100], "match": [2, 4, 9, 12, 15, 17, 20, 21, 22, 24, 25, 29, 36, 50, 61, 79, 98, 100], "set": [2, 3, 4, 5, 7, 8, 12, 15, 16, 17, 21, 22, 23, 24, 27, 30, 36, 40, 41, 42, 43, 45, 49, 50, 51, 52, 53, 54, 63, 64, 65, 69, 74, 75, 76, 77, 78, 81, 83, 85, 94, 95, 96, 98, 99, 100], "type": [2, 3, 4, 7, 8, 9, 12, 14, 15, 22, 23, 24, 36, 41, 42, 43, 49, 53, 54, 55, 60, 61, 63, 64, 67, 68, 74, 75, 76, 77, 78, 81, 84, 86, 89, 92, 94, 96, 98, 99, 100], "analyz": [2, 23, 36], "data": [2, 3, 4, 5, 8, 12, 13, 16, 17, 20, 22, 23, 24, 25, 27, 29, 38, 40, 43, 45, 54, 55, 56, 60, 61, 63, 64, 65, 67, 74, 77, 78, 84, 85, 86, 92, 94, 95, 96, 98], "enabl": [2, 3, 9, 12, 13, 20, 23, 24, 29, 36, 40, 43, 48, 54, 55, 60, 61, 63, 64, 65, 67, 76, 81, 84, 85, 86, 92, 94, 95, 96, 98], "box": [2, 15, 22, 23, 36, 40, 45, 50, 61, 63, 67, 79, 92, 94, 96, 98, 100], "either": [2, 8, 9, 10, 22, 23, 25, 36, 52, 55, 56], "date": [2, 5, 7, 21, 22, 23, 24, 27, 36, 38, 49, 52, 53, 70, 71, 74, 75, 78, 84, 92, 98], "interv": [2, 21], "todai": [2, 4, 15, 23], "last": [2, 3, 9, 15, 18, 22, 23, 25, 40, 43, 63, 67, 92, 94, 96], "2": [2, 3, 9, 22, 23, 24, 25, 32, 33, 36, 40, 76, 99], "3": [2, 4, 8, 9, 23, 25, 32, 33, 41, 43, 79, 81, 85, 86, 95], "month": [2, 4, 8, 10, 16, 18, 22, 23, 30, 41, 43, 60, 61, 63, 72, 77, 78, 79, 81, 89, 92], "avoid": [2, 4, 8, 17, 25, 38, 61, 67, 84, 92, 94, 96], "too": [2, 4, 15, 22, 25, 36, 41, 60, 77], "long": [2, 9, 20, 22, 23, 24, 25, 29, 36, 61, 63, 64, 67, 78, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "specif": [2, 4, 5, 7, 21, 22, 24, 25, 27, 43, 49, 60, 61], "note": [2, 4, 5, 8, 10, 12, 15, 16, 21, 23, 24, 25, 27, 29, 36, 40, 41, 43, 49, 53, 55, 60, 61, 63, 64, 65, 67, 76, 77, 78, 79, 92, 95], "event": [2, 9, 22, 23, 25, 43, 98], "leav": [2, 5, 13, 14, 15, 16, 36, 42, 43, 49, 52, 53, 56, 63, 67, 68, 77, 78, 79, 81, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99], "checkbox": 2, "disabl": [2, 10, 23, 40, 43, 56, 78, 81], "which": [2, 4, 6, 8, 9, 13, 15, 17, 18, 21, 22, 23, 24, 25, 36, 43, 49, 52, 53, 60, 63, 65, 67, 77, 78, 84, 85, 86, 92, 94, 96, 98], "confirm": [2, 10, 14, 16, 23, 36, 37, 41, 42, 43, 44, 45, 51, 52, 60, 61, 67, 68, 69, 76, 78, 79, 81, 84, 92, 95, 98, 99], "target": [2, 7, 10, 15, 21, 23, 25, 36], "bt": [2, 23], "rang": [2, 7, 9, 15, 21, 23, 25, 76], "bottom": [2, 10, 14, 15, 22, 23, 36, 42, 49, 52, 53, 61, 67, 68, 78, 84, 85, 86, 90, 92, 94, 96, 98], "top": [2, 3, 4, 5, 10, 12, 13, 15, 16, 21, 23, 24, 25, 27, 36, 37, 40, 43, 45, 49, 53, 54, 55, 63, 65, 67, 78, 83, 84, 89, 90, 92, 94, 96, 98, 99], "tir": [2, 23], "titr": 2, "graph": [2, 3, 4, 23, 25, 29, 67, 92, 94, 96], "line": [2, 3, 4, 9, 15, 18, 20, 22, 23, 25, 36, 40, 43, 45, 49, 53, 60, 61, 63, 64, 65, 67, 77, 78, 79, 81, 84, 89, 92, 94, 95, 96], "older": [2, 23, 55, 60, 81], "newer": [2, 23, 29, 55], "first": [2, 4, 9, 15, 22, 23, 25, 36, 38, 41, 43, 45, 48, 50, 63, 65, 76, 98], "click": [2, 3, 4, 5, 9, 10, 13, 14, 15, 16, 21, 22, 23, 24, 25, 27, 29, 30, 32, 36, 37, 41, 42, 43, 44, 45, 49, 51, 52, 53, 61, 63, 64, 65, 67, 68, 69, 70, 71, 74, 75, 77, 78, 79, 81, 83, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99, 100], "wait": [2, 4, 8, 14, 22, 23, 25, 36, 37, 40, 41, 42, 43, 44, 45, 49, 52, 53, 60, 61, 63, 67, 68, 77, 78, 81, 83, 84, 85, 86, 90, 92, 94, 95, 98, 99, 100], "load": [2, 23, 25, 48], "render": [2, 17, 18, 23, 25, 30, 36, 48, 49, 50, 53, 67, 70, 92, 94, 96, 100], "complet": [2, 4, 5, 9, 13, 15, 18, 23, 25, 36, 37, 41, 43, 44, 49, 52, 53, 60, 61, 63, 67, 72, 77, 78, 79, 81, 83, 84, 85, 86, 90, 92, 94, 95, 98, 99, 100], "might": [2, 3, 4, 5, 9, 10, 12, 13, 16, 17, 22, 23, 24, 25, 27, 30, 36, 38, 40, 41, 43, 45, 46, 48, 49, 52, 53, 54, 55, 61, 63, 65, 67, 74, 76, 78, 81, 84, 92, 98], "take": [2, 4, 8, 15, 22, 23, 24, 25, 30, 36, 49, 52, 53, 61, 63, 67, 76, 77, 78, 79, 81, 84, 85, 86, 92], "some": [2, 4, 6, 8, 9, 13, 14, 15, 16, 17, 18, 22, 23, 24, 25, 30, 36, 40, 41, 43, 54, 55, 61, 63, 64, 67, 77, 78, 79, 81, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "also": [2, 4, 5, 6, 7, 9, 10, 15, 17, 20, 21, 22, 23, 24, 25, 27, 29, 36, 41, 43, 49, 52, 53, 54, 55, 60, 61, 63, 67, 75, 76, 77, 78, 81, 84, 85, 86, 89, 92, 94, 95, 96, 98], "depend": [2, 4, 7, 9, 15, 20, 22, 24, 25, 36, 40, 45, 54, 55], "engin": [2, 17, 36, 77], "bg": [2, 7, 12, 13, 17, 21, 22, 23, 29, 36, 40, 55, 63, 64, 65, 67, 78, 84, 92, 94, 95, 96, 98], "includ": [2, 4, 5, 6, 8, 9, 12, 13, 15, 17, 18, 22, 23, 24, 25, 27, 29, 36, 40, 62, 63, 64, 65, 67, 77, 82, 84, 91, 92, 94, 95, 96], "consist": [2, 15], "chang": [2, 3, 4, 13, 15, 16, 21, 22, 23, 25, 29, 30, 32, 34, 43, 45, 49, 53, 54, 55, 60, 63, 64, 67, 74, 75, 76, 77, 78, 79, 85, 86, 89, 91, 94, 95, 96, 98, 99, 100], "again": [2, 15, 22, 23, 30, 36, 41, 42, 44, 45, 48, 51, 55, 60, 61, 63, 64, 67, 69, 92, 94, 96], "spaghetti": 2, "color": [2, 9, 23, 67, 92, 94, 96], "filter": [2, 23, 25, 49], "hour": [2, 3, 4, 9, 15, 22, 23, 25, 36, 45, 74, 92], "scroll": [2, 15, 23, 36, 42, 43, 45, 49, 51, 52, 53, 60, 61, 63, 65, 69, 78, 79, 83, 84, 85, 86, 89, 92, 95, 98, 99], "page": [2, 4, 5, 7, 9, 10, 12, 13, 14, 15, 23, 24, 25, 27, 32, 33, 36, 37, 40, 42, 44, 48, 49, 52, 53, 54, 55, 61, 62, 63, 64, 67, 68, 78, 79, 81, 82, 84, 85, 86, 89, 90, 91, 92, 93, 95, 98, 99], "quickli": [2, 15, 22, 55], "find": [2, 4, 7, 8, 9, 10, 15, 18, 22, 25, 29, 36, 40, 41, 48, 49, 53, 54, 55, 56, 60, 63, 76, 78, 84, 85, 86, 92, 95], "tur": 2, "tar": 2, "rough": [2, 23], "estim": [2, 7, 23], "hba1c": 2, "must": [2, 4, 5, 8, 16, 17, 24, 25, 27, 30, 32, 36, 40, 54, 55, 60, 61, 63, 67, 72, 81, 84, 85, 86, 92, 94, 95, 96], "modifi": [2, 3, 4, 7, 9, 13, 16, 20, 22, 24, 25, 36, 42, 43, 51, 53, 55, 60, 61, 67, 69, 78, 83, 84, 85, 86, 92, 95, 98, 99], "see": [2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 15, 16, 17, 21, 22, 23, 25, 27, 29, 36, 40, 41, 43, 45, 48, 49, 50, 53, 54, 55, 60, 61, 63, 64, 65, 67, 70, 71, 76, 77, 78, 81, 83, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98], "plot": [2, 23], "25": [2, 24], "75": [2, 25], "plu": [2, 9, 25, 63, 64, 78, 84, 85, 86, 92, 95, 98, 99, 100], "standard": [2, 8, 16, 25, 36], "deviat": [2, 23, 48], "statist": [2, 23], "tabl": [2, 4, 23, 84], "befor": [3, 4, 12, 14, 17, 18, 23, 25, 36, 40, 41, 42, 43, 44, 45, 49, 50, 53, 54, 55, 60, 61, 63, 64, 67, 68, 77, 78, 84, 85, 86, 92, 94, 95, 96, 98], "verifi": [3, 16, 24, 36, 41, 44, 45, 48, 49, 53, 54, 63, 74, 75, 79, 81, 83, 84, 92], "ha": [3, 4, 5, 9, 15, 18, 20, 21, 22, 23, 24, 25, 27, 29, 33, 36, 40, 41, 43, 45, 63, 67, 74, 75, 77, 78, 89, 91, 92, 95], "correctli": [3, 18, 40, 41, 48, 63], "upload": [3, 5, 6, 7, 9, 10, 13, 21, 22, 23, 24, 27, 48, 56, 63, 64, 67, 74, 78, 84, 85, 86, 92, 94, 95, 98, 99, 100], "The": [3, 4, 5, 6, 7, 8, 9, 13, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 27, 36, 38, 40, 41, 45, 48, 54, 55, 60, 61, 63, 64, 67, 74, 75, 76, 77, 78, 79, 81, 84, 85, 86, 89, 90, 91, 92, 94, 95, 96, 98, 99, 100], "probabl": [3, 4, 6, 17, 36, 44, 48, 60, 61, 63, 64, 76, 77, 78, 84, 85, 86, 92, 95, 98, 99, 100], "more": [3, 4, 7, 8, 9, 10, 13, 15, 17, 20, 21, 22, 24, 25, 30, 32, 36, 40, 41, 43, 45, 49, 52, 53, 54, 58, 60, 63, 67, 72, 75, 76, 77, 78, 79, 84, 89, 92, 98], "insight": 3, "re": [3, 4, 10, 12, 13, 15, 20, 24, 25, 36, 38, 40, 41, 42, 43, 48, 49, 50, 51, 53, 54, 55, 60, 64, 65, 69, 70, 77, 85, 86, 94, 95, 96, 99, 100], "skip": [3, 4, 14, 22, 32, 42, 43, 60, 61, 67, 68, 78, 79, 81, 84, 98, 99], "open": [3, 4, 5, 6, 7, 9, 13, 14, 15, 16, 17, 23, 24, 25, 27, 36, 41, 42, 45, 46, 49, 52, 53, 54, 55, 60, 63, 65, 67, 68, 70, 71, 78, 79, 81, 84, 85, 89, 90, 92, 94, 95, 96, 98, 99], "locat": [3, 4, 25, 40, 61, 98, 99], "right": [3, 5, 9, 10, 13, 15, 16, 24, 25, 27, 36, 37, 40, 43, 45, 49, 52, 53, 63, 65, 67, 78, 84, 85, 86, 89, 90, 92, 94, 96, 98, 99, 100], "window": [3, 13, 15, 25, 29, 36, 41, 49, 50, 52, 53, 63, 65, 67, 76, 77, 78, 79, 84, 92, 98], "select": [3, 4, 5, 8, 9, 10, 12, 13, 14, 15, 16, 21, 22, 23, 24, 25, 27, 29, 36, 37, 40, 41, 42, 43, 44, 45, 46, 49, 50, 51, 52, 53, 54, 56, 60, 63, 65, 67, 69, 70, 71, 74, 75, 76, 78, 79, 81, 83, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99, 100], "icon": [3, 5, 9, 13, 15, 16, 22, 24, 25, 27, 36, 43, 49, 54, 63, 67, 78, 81, 84, 89, 92, 98, 99], "unit": [3, 21, 63, 64, 67, 78, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "blood": [3, 4, 7, 9, 23, 25, 56], "languag": [3, 4, 92, 95], "nightscout": [3, 5, 7, 8, 10, 16, 18, 21, 27, 32, 36, 38, 40, 41, 43, 44, 45, 49, 52, 55, 56, 62, 64, 65, 71, 75, 76, 79, 81, 82, 83, 89, 90, 91, 94, 95, 96, 99], "its": [3, 4, 8, 9, 17, 18, 20, 22, 25, 36, 44, 56, 61, 63, 65, 67, 78, 79, 84, 92, 94, 96, 98], "program": [3, 15, 22, 36], "default": [3, 4, 5, 9, 13, 16, 22, 24, 27, 29, 49, 53, 60, 61, 63, 67, 78, 79, 84, 92, 94, 96, 98], "plugin": [3, 20, 36, 48, 54, 55, 56, 60, 63, 64, 67, 74, 78, 92, 94, 96], "save": [3, 4, 5, 9, 10, 13, 15, 21, 22, 24, 25, 27, 36, 41, 43, 48, 49, 50, 53, 61, 64, 65, 74, 75, 78, 84, 92, 98], "wai": [3, 4, 5, 9, 22, 24, 25, 27, 36, 38, 55, 76, 77], "It": [3, 6, 7, 9, 13, 15, 23, 25, 29, 30, 36, 40, 43, 45, 49, 50, 52, 53, 54, 56, 61, 63, 67, 74, 76, 77, 78, 79, 81, 84, 92, 95, 98], "interfer": [3, 49, 52, 53, 63], "A": [3, 4, 8, 10, 14, 17, 18, 22, 23, 25, 29, 36, 55, 60, 63, 67, 72, 77, 79, 81, 92, 94, 95, 96], "typic": [3, 36], "close": [3, 8, 14, 23, 29, 36, 41, 42, 48, 63, 64, 68, 78, 79, 84, 89, 98], "loop": [3, 8, 9, 13, 15, 22, 23, 36, 48, 63, 64, 65, 67, 78, 79, 84, 85, 86, 92, 98], "user": [3, 4, 5, 7, 8, 12, 13, 15, 18, 22, 25, 27, 33, 36, 40, 45, 50, 52, 55, 60, 61, 63, 67, 77, 78, 79, 84, 89, 91, 92, 98], "48": [3, 9, 22, 25], "upper": [3, 9, 13, 15, 25, 49, 52, 53, 63, 67, 78, 84, 92, 94, 96, 98], "scale": [3, 23, 25, 41, 49, 53, 67], "correspond": [3, 9, 21, 22, 48, 92], "length": [3, 23], "24": [3, 9, 25, 41, 60, 67, 81, 92, 94, 96], "slide": 3, "lower": [3, 9, 23, 25, 63, 67, 92, 94, 96], "round": 3, "rectangl": 3, "indic": [3, 9, 12, 15, 25, 43, 50], "pill": [3, 9, 36], "immedi": [3, 15, 24, 36, 77, 89, 92], "hover": [3, 25, 36], "them": [3, 4, 6, 10, 15, 16, 17, 21, 22, 23, 24, 25, 36, 41, 43, 48, 56, 63, 64, 67, 76, 78, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "mous": [3, 25, 89], "thei": [3, 4, 15, 22, 24, 25, 40, 43, 77, 78], "els": [3, 10, 16, 20, 30, 36, 40, 42, 43, 48, 49, 51, 53, 54, 60, 63, 67, 69, 70, 77, 79, 81], "empti": [3, 13, 36, 40, 63, 67, 78, 84, 92, 96, 98], "meaningless": 3, "As": [3, 20, 22, 63, 77], "warn": [3, 22, 25, 60, 61, 94, 96], "urgent": [3, 9, 22, 25, 67, 92, 94, 96], "limit": [3, 4, 5, 8, 17, 18, 22, 24, 25, 27, 37, 40, 45, 67, 74, 75, 77, 78, 79, 89, 92], "alwai": [3, 4, 9, 16, 17, 24, 25, 60, 77], "adjust": [3, 7, 25], "variabl": [3, 9, 12, 16, 18, 20, 23, 24, 29, 36, 40, 41, 48, 54, 60, 64, 65, 72, 77, 78, 83, 85, 86, 89, 90, 95, 99, 100], "appear": [3, 5, 9, 15, 22, 24, 25, 36, 40, 43, 67, 79, 92, 94, 96], "yellow": [3, 9, 25, 49, 53, 74, 75], "red": [3, 5, 9, 15, 22, 24, 25, 27, 36, 40, 45, 63, 65], "normal": [3, 25, 41, 49, 53, 98, 99], "usag": [3, 12, 25, 78], "current": [3, 4, 5, 7, 9, 10, 12, 14, 17, 20, 21, 22, 24, 25, 27, 36, 40, 42, 43, 45, 48, 49, 53, 60, 68, 74, 75, 78, 84, 98], "left": [3, 4, 9, 10, 15, 16, 25, 36, 43, 49, 53, 63, 67, 83, 84, 89, 92, 94, 96], "arrow": [3, 9, 25, 43], "differ": [3, 4, 5, 15, 24, 25, 27, 36, 37, 41, 55, 77, 79], "between": [3, 16, 22, 25, 56, 77], "measur": [3, 9, 23, 25], "previou": [3, 9, 18, 23, 43, 49, 50, 54, 63, 67, 74, 75, 78, 84, 92, 98], "ll": [3, 4, 8, 9, 10, 15, 16, 18, 20, 22, 24, 25, 29, 36, 40, 41, 42, 49, 50, 52, 53, 54, 55, 61, 77, 78, 79, 84, 85, 86, 92, 95, 98, 99, 100], "ag": [3, 9, 22, 60, 61], "iob": [3, 60, 63, 64, 65, 78, 84, 85, 86], "board": [3, 23], "profil": [3, 5, 13, 24, 27, 36, 40, 45, 48, 49, 53, 61, 63, 64, 65, 67, 78, 84, 85, 86, 92, 98], "extern": [3, 17, 43, 60, 84, 86], "algorithm": [3, 7, 25], "openap": [3, 9, 22, 60, 63, 64, 65, 78, 84, 85, 86], "cob": [3, 60, 63, 64, 65, 78, 84, 85, 86], "cage": [3, 22, 60, 63, 64, 65, 78, 84, 85, 86], "sage": [3, 22, 60, 63, 64, 65, 78, 84, 85, 86], "bage": [3, 60, 63, 64, 65, 78, 84, 85, 86], "iag": [3, 22, 60, 63, 64, 65, 78, 84, 85, 86], "timer": 3, "count": [3, 23, 25, 41, 48, 49, 53, 67], "cannula": [3, 15, 22], "infus": 3, "site": [3, 5, 6, 8, 10, 12, 13, 17, 18, 21, 25, 27, 29, 30, 32, 36, 41, 42, 45, 46, 48, 49, 51, 52, 53, 54, 55, 60, 61, 63, 64, 67, 69, 74, 75, 77, 79, 81, 83, 90, 94, 95, 96, 98, 99, 100], "batteri": [3, 5, 15, 22, 36], "cartridg": 3, "level": [3, 4, 9, 10, 12, 25], "storag": [3, 24, 81], "space": [3, 4, 8, 20, 25, 49, 53, 54, 61, 63, 64, 67, 77, 78, 79, 84, 85, 86, 89, 92, 94, 95, 96, 98, 99, 100], "interest": [3, 4, 15, 17, 23], "statu": [3, 13, 15, 23, 36, 41, 44, 48, 54, 63, 67, 78, 84, 92, 98], "regist": [3, 29, 76, 79], "activ": [3, 4, 9, 10, 15, 17, 18, 21, 22, 25, 37, 43, 48, 67, 74, 78, 92, 94, 96], "andoidap": 3, "freeap": [3, 29, 63], "iap": 3, "other": [3, 4, 5, 6, 8, 9, 13, 15, 17, 21, 22, 23, 24, 36, 40, 49, 54, 55, 56, 61, 63, 64, 67, 72, 76, 77, 78, 84, 85, 86, 92, 95, 98], "exclam": 3, "mark": [3, 25, 36], "configur": [3, 4, 7, 9, 17, 20, 24, 29, 32, 36, 41, 43, 45, 48, 49, 53, 55, 67, 78, 84, 85, 86, 90, 92, 94, 95], "fix": [3, 4, 5, 16, 30, 43, 49, 55, 92, 95, 98, 100], "so": [3, 4, 5, 8, 15, 17, 22, 24, 25, 27, 29, 36, 40, 43, 49, 50, 61, 63, 77, 78, 84, 85, 86, 98, 99], "receiv": [3, 10, 14, 16, 22, 25, 42, 52, 63, 64, 67, 68, 77, 78, 79, 84, 92, 94, 96, 98], "respons": [3, 4, 24], "dot": [3, 9, 40, 45, 53], "actual": [3, 9, 15, 22, 23, 36, 40, 54, 63, 64, 78, 84, 85, 86, 92, 95], "modul": 3, "exampl": [3, 5, 10, 12, 15, 16, 22, 23, 24, 25, 27, 29, 32, 36, 37, 40, 41, 45, 49, 53, 60, 61, 63, 67, 74, 76, 77, 78, 79, 81, 84, 85, 86, 92, 95], "rich": 3, "detail": [3, 7, 9, 12, 22, 23, 25, 30, 32, 36, 55, 58, 77, 78], "food": [3, 9, 60, 63, 64, 65, 78, 84, 85, 86], "decis": [3, 7, 25], "health": [4, 67], "profession": [4, 18, 25], "want": [4, 5, 6, 8, 9, 10, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 27, 29, 30, 36, 38, 40, 41, 42, 43, 49, 50, 51, 53, 54, 55, 60, 63, 64, 65, 67, 68, 69, 76, 77, 78, 79, 81, 83, 84, 85, 86, 92, 94, 95, 96, 98, 99], "just": [4, 6, 13, 15, 22, 24, 25, 36, 40, 41, 42, 43, 48, 49, 54, 60, 61, 63, 64, 67, 76, 78, 84, 85, 86, 90, 92, 94, 95, 96, 98, 99, 100], "out": [4, 15, 22, 23, 25, 36, 40, 50, 54, 60, 61, 63, 64, 78, 84, 85, 86, 92, 95], "jump": [4, 36], "dedic": [4, 12, 23, 41, 48, 54, 55], "here": [4, 6, 7, 8, 9, 12, 13, 14, 17, 18, 21, 22, 23, 24, 25, 29, 32, 34, 36, 37, 38, 39, 40, 41, 42, 48, 49, 51, 53, 54, 55, 56, 60, 61, 63, 64, 67, 68, 69, 70, 71, 72, 74, 75, 77, 78, 79, 81, 84, 85, 86, 89, 92, 93, 94, 95, 96, 98, 99], "known": [4, 17, 18, 25, 55, 63, 74, 75, 78], "cgm": [4, 6, 7, 12, 15, 16, 17, 24, 38, 40, 41, 45, 48, 49, 50, 53, 55, 60, 61, 63, 64, 67, 69, 70, 71, 85, 86, 90, 94, 95, 96, 99, 100], "peopl": [4, 7, 16, 18, 22, 40, 54, 55, 58, 61, 63, 64, 77, 78, 84, 85, 86, 92, 95], "diabet": [4, 7, 9, 21, 23, 30, 55, 76], "parent": [4, 22], "kid": [4, 15, 77], "onc": [4, 9, 13, 15, 16, 22, 24, 25, 29, 36, 40, 43, 48, 49, 53, 55, 56, 60, 61, 63, 67, 76, 77, 78, 84, 92, 94, 96, 98, 99, 100], "act": [4, 7, 55, 56], "central": [4, 9, 16], "repositori": [4, 5, 14, 16, 25, 29, 38, 42, 43, 45, 50, 51, 60, 61, 67, 68, 69, 70, 71, 78, 84, 90, 92, 94, 95, 98, 99], "dose": [4, 7, 25], "singl": [4, 15, 22, 25, 76, 77, 92], "person": [4, 9, 14, 16, 22, 32, 41, 42, 67, 68, 78, 84, 98], "anywher": [4, 36, 63, 64, 67, 79, 92, 94, 96], "browser": [4, 5, 9, 10, 15, 24, 27, 41, 43, 48, 54, 61, 63, 65, 67, 78, 79, 81, 84, 89, 92, 94, 96, 98], "There": [4, 5, 6, 8, 15, 17, 24, 27, 36, 45, 48, 50, 56, 60, 77, 79], "sever": [4, 5, 6, 10, 16, 17, 22, 24, 27, 36, 41, 43, 45, 67, 92], "part": [4, 9, 15, 21, 22, 36], "somewher": [4, 15, 17, 67, 79], "onlin": [4, 49, 53, 63], "process": [4, 24, 25, 49, 52, 53, 67, 78, 84, 92], "someth": [4, 5, 8, 15, 24, 40, 43, 54, 61, 63, 64, 76, 77, 78, 84, 85, 86, 92, 95], "instal": [4, 6, 17, 18, 22, 24, 25, 29, 37, 41, 45, 49, 50, 53, 55, 56, 76, 84, 90, 92, 94, 95, 96], "yourself": [4, 40, 53, 54, 77], "short": [4, 22, 23, 77], "variou": [4, 5, 9, 18, 21, 22, 25, 38, 56, 67, 76, 84, 92, 94, 96], "pai": [4, 17, 18, 36, 50, 63, 77, 81], "fulli": [4, 63, 81], "manag": [4, 16, 18, 21, 24, 29, 33, 41, 49, 52, 53, 78, 81, 84], "maintain": [4, 8, 12, 18, 29, 30, 41, 52, 60, 67, 77, 78], "usual": [4, 8, 17, 25, 36, 37, 40, 45, 48, 50, 54, 55, 63, 67, 76, 79, 83, 84], "sent": [4, 25], "mobil": [4, 40, 55, 76], "cellphon": 4, "xdrip": [4, 13, 14, 18, 34, 40, 55, 63, 67, 77, 78, 84, 92, 98], "spike": [4, 55], "xdrip4io": [4, 13, 55, 63, 67, 78, 84, 92, 98], "medtron": [4, 13, 25, 63, 67, 78, 84, 92, 98], "altern": [4, 10, 22, 25, 77], "pull": [4, 45, 49, 53, 55, 60], "directli": [4, 8, 9, 12, 16, 24, 25, 29, 40, 55, 63, 64, 65, 67, 84, 92, 94, 96, 98], "dexcom": [4, 13, 17, 22, 23, 24, 25, 43, 63, 64, 65, 74, 78, 84, 92, 95, 98], "account": [4, 6, 8, 10, 15, 16, 17, 18, 22, 24, 25, 30, 32, 33, 36, 38, 41, 43, 45, 48, 50, 54, 60, 61, 64, 68, 72, 74, 75, 76, 77, 79, 83, 85, 86, 90, 94, 95, 96, 99], "In": [4, 9, 12, 15, 16, 20, 22, 24, 25, 29, 36, 40, 41, 43, 45, 46, 49, 53, 55, 63, 64, 65, 67, 72, 78, 79, 84, 85, 86, 92, 96, 98, 99, 100], "smartwatch": [4, 40], "electron": [4, 55], "base": [4, 5, 7, 18, 24, 25, 27, 67, 74, 75, 78, 92, 94, 96], "interact": [4, 9, 16], "often": [4, 25, 67, 92, 94, 96], "wa": [4, 6, 8, 9, 18, 22, 25, 36, 41, 43, 45, 49, 63, 67, 74, 75, 77, 78, 79], "1": [4, 5, 10, 22, 24, 25, 27, 29, 32, 33, 36, 40, 41, 81, 83, 89, 99], "t1d": [4, 58, 77], "volunt": 4, "commerci": 4, "sponsorship": 4, "portal": [4, 25, 49, 53, 63], "made": [4, 15, 21, 22, 23, 24, 25, 30, 40, 77], "remot": [4, 6, 15, 17, 25, 41, 44, 45, 48, 49, 50, 53, 60, 61, 63, 67, 69, 70, 71, 85, 86, 90, 94, 95, 96, 99, 100], "contributor": 4, "commun": [4, 7, 8, 18, 60, 63, 74, 75, 78, 92, 95], "over": [4, 25, 67, 92, 94, 96], "year": [4, 8, 77], "implement": [4, 24, 48], "solut": [4, 6, 8, 17, 18, 30, 36, 43, 55, 56, 58, 63, 67, 72, 74, 75, 77, 78, 79, 81, 84, 89, 92, 98], "g4": 4, "nearli": [4, 55], "goal": 4, "project": [4, 6, 16, 29, 36, 38, 41, 44, 48, 49, 50, 53, 54, 55, 63, 65, 69, 70, 71, 81, 83, 85, 86, 89, 90, 92, 94, 95, 96, 99], "analysi": [4, 23, 24, 36], "we": [4, 6, 15, 22, 24, 25, 32, 55, 60, 61, 77, 79, 90, 92, 94, 96, 98, 100], "compel": 4, "pursuit": 4, "human": 4, "equit": 4, "technologi": 4, "liber": 4, "burden": [4, 16], "deliv": 4, "benefit": [4, 36], "ve": [4, 15, 21, 22, 30, 36, 60, 61, 63, 77, 89, 92], "found": [4, 15, 23, 25, 41, 77], "contribut": [4, 30, 77], "critic": [4, 79], "try": [4, 6, 17, 24, 25, 30, 36, 38, 40, 41, 43, 46, 48, 49, 50, 53, 54, 60, 61, 63, 64, 67, 77, 78, 84, 85, 86, 92, 95], "distribut": [4, 25], "demand": [4, 22], "respect": [4, 55, 77], "digniti": 4, "member": [4, 16, 24], "reput": 4, "affect": [4, 25], "qualiti": [4, 8, 81], "our": [4, 15, 17, 77, 92, 94, 96], "relationship": 4, "discuss": [4, 22], "treat": [4, 15], "each": [4, 7, 16, 21, 22, 24, 25, 36, 55, 84, 85, 86, 92, 95], "impact": [4, 42, 43, 51, 69], "reliabl": [4, 8, 17, 18, 63, 74, 75, 77, 78, 81, 98], "confidenti": 4, "therefor": 4, "strive": 4, "improv": [4, 22], "while": [4, 15, 22, 25, 36, 78], "opportun": 4, "longev": 4, "ecosystem": 4, "cultur": 4, "tool": [4, 9, 18, 23, 24, 27, 29, 48, 72], "dispos": [4, 24], "achiev": [4, 22], "sustain": [4, 20], "whatev": 4, "meet": [4, 77], "inhuman": 4, "collabor": 4, "against": [4, 8, 24], "creat": [4, 8, 9, 10, 18, 20, 21, 22, 25, 30, 32, 33, 36, 40, 41, 43, 48, 50, 51, 60, 64, 68, 69, 74, 75, 76, 77, 83, 85, 86, 90, 94, 95, 96, 99], "result": [4, 25, 36, 61, 78, 79, 81, 89, 92, 94, 96], "desir": [4, 7, 67], "phone": [4, 12, 15, 22, 25, 29, 54, 55, 56, 76, 78], "basic": [4, 5, 15, 16, 18, 22, 37, 43, 63, 74, 78], "comput": [4, 10, 17, 18, 24, 25, 36, 48, 49, 50, 53, 61, 67, 76, 77, 78, 83, 85, 86], "skill": [4, 61, 77], "abil": [4, 5, 22, 24, 25, 27], "carefulli": [4, 5, 89], "guid": [4, 17, 37, 60, 61, 76, 77], "shown": [4, 5, 13, 15, 24, 25, 27, 45, 49, 53, 54, 63, 67, 78, 84, 92, 98], "thoroughli": 4, "read": [4, 5, 9, 12, 17, 21, 23, 24, 25, 27, 40, 41, 55, 56, 61, 63, 65, 67, 76, 77, 78, 79, 92, 94, 96], "step": [4, 6, 22, 32, 33, 36, 40, 43, 50, 77, 83, 89, 95], "without": [4, 9, 16, 18, 24, 25, 36, 43, 55, 76], "up": [4, 5, 7, 9, 10, 13, 14, 15, 17, 18, 22, 25, 30, 32, 33, 36, 38, 42, 43, 49, 52, 53, 54, 60, 63, 67, 68, 70, 71, 74, 75, 77, 78, 81, 89, 94, 96, 98, 99], "think": [4, 36, 63, 64, 77, 78, 84, 85, 86, 92, 95, 98, 99, 100], "difficult": [4, 77, 92], "isn": [4, 22, 25, 40, 48, 49, 53, 54, 55, 63, 64, 67, 78, 84, 85, 86, 92, 95], "understand": [4, 7, 17, 21, 24, 36, 42, 43, 51, 69, 77], "compani": [4, 18, 92], "offici": [4, 16, 55, 67], "approv": [4, 76], "regul": 4, "agre": [4, 61, 63, 89, 92], "risk": 4, "requir": [4, 5, 8, 10, 17, 18, 22, 24, 27, 29, 30, 32, 36, 49, 53, 60, 61, 67, 76, 78, 81, 84, 92, 95, 98, 99], "work": [4, 5, 8, 12, 15, 16, 17, 22, 23, 24, 25, 27, 30, 36, 41, 48, 55, 60, 61, 77], "third": [4, 24], "parti": [4, 24], "know": [4, 7, 10, 13, 17, 21, 22, 24, 25, 42, 48, 49, 51, 61, 63, 65, 67, 69, 77, 78, 83, 84, 92, 95, 98, 100], "trend": [4, 9, 25, 67, 92, 94, 96], "sure": [4, 5, 14, 15, 16, 17, 18, 21, 23, 24, 25, 27, 29, 36, 37, 40, 42, 43, 45, 48, 49, 53, 55, 56, 63, 64, 67, 68, 74, 75, 77, 78, 84, 85, 86, 89, 92, 94, 95, 96, 98, 99, 100], "readi": [4, 17, 22, 30, 77, 98, 99], "cope": [4, 77], "unexpect": [4, 10, 78, 84, 92], "failur": [4, 22, 25, 43, 44, 48, 78], "simpl": [4, 6, 8, 15, 18, 30, 55, 61, 67, 77, 78, 81, 84, 89, 92, 94, 96, 98, 99], "answer": [4, 17, 29, 61, 67], "two": [4, 5, 16, 22, 23, 24, 25, 27, 36, 40, 41, 45, 63, 65, 76, 84, 85, 86, 92, 95, 98, 100], "instruct": [4, 8, 17, 18, 20, 24, 25, 29, 30, 32, 36, 41, 48, 49, 50, 53, 60, 61, 67, 77, 79, 84, 85, 86, 92, 94, 96], "websit": [4, 5, 7, 15, 22, 24, 25, 27, 55, 77], "offer": [4, 8, 17, 18, 23, 72, 77, 78, 81, 89], "monthli": [4, 17, 74, 75, 81], "0": [4, 5, 8, 15, 20, 24, 25, 27, 29, 36, 61, 72, 79, 81, 85, 86, 89, 99, 100], "histor": [4, 20, 29, 32, 33, 36], "vast": 4, "major": [4, 25, 36, 78, 79], "opt": [4, 36], "choic": [4, 25, 30, 60, 61, 63, 64, 77, 78, 84, 85, 86, 92, 95, 98, 99, 100], "Of": 4, "ensur": [4, 5, 17, 24, 27, 84, 85, 86, 92, 95], "aim": 4, "choos": [4, 15, 17, 22, 36, 37, 45, 60, 63, 77, 79, 81, 84, 90, 92, 94], "entir": [4, 5, 24, 25, 27, 40, 54, 63, 64, 78, 84, 85, 86, 92, 95], "driven": 4, "volut": 4, "effort": 4, "exchang": 4, "fee": [4, 16, 17, 84, 89, 92], "three": [4, 5, 15, 17, 24, 27, 36, 41, 45, 49, 53, 63, 64, 65, 67, 92, 94, 96, 98, 99, 100], "non": [4, 9, 18, 22, 23, 24, 25, 36, 48, 55], "great": [4, 17], "both": [4, 9, 16, 17, 21, 23, 24, 36, 76], "been": [4, 15, 18, 20, 22, 23, 24, 25, 29, 36, 41, 45, 63, 67, 74, 75, 77, 78, 89, 91, 92, 94, 96, 98, 99, 100], "digit": [4, 6, 8, 63, 64, 77, 78, 84, 85, 86, 92, 95, 98, 99, 100], "ocean": [4, 6, 8, 77], "microsoft": [4, 48, 63, 76], "azur": [4, 6, 8, 15, 17, 18, 25, 30, 36, 40, 48, 49, 50, 53, 54, 62, 65, 70], "salesforc": [4, 18, 74, 75, 78], "With": [4, 9, 25, 29, 40, 77], "were": [4, 15, 22, 43, 79, 84], "ad": [4, 9, 10, 16, 22, 25, 36, 48, 76], "author": [4, 29, 36, 43, 45, 49, 53, 84, 89, 90, 92, 94, 95, 98], "purpos": [4, 24, 25, 43], "new": [4, 5, 15, 16, 18, 20, 21, 22, 24, 25, 27, 33, 36, 40, 41, 43, 45, 48, 50, 55, 60, 64, 65, 74, 75, 77, 81, 83, 85, 86, 89, 90, 91, 94, 96, 99, 100], "document": [4, 6, 7, 13, 17, 18, 23, 24, 29, 36, 42, 51, 54, 55, 58, 60, 63, 67, 69, 74, 75, 76, 78, 79, 84, 85, 86, 89, 91, 92, 95, 98], "request": [4, 15, 17, 22, 25, 41, 67, 83, 84], "extrem": [4, 24, 36], "well": [4, 18, 22, 23, 25, 55, 63, 74, 75, 77, 78], "comment": [4, 9, 61], "subscript": [4, 18, 30, 37, 77], "11": [4, 41], "99": 4, "usd": 4, "ben": 4, "west": 4, "origin": [4, 6, 18, 29, 42, 48, 49, 50, 60, 61, 63, 70, 84], "lead": [4, 25, 48, 49, 52, 53, 74, 78, 79], "core": [4, 5, 22, 24, 25, 27, 84, 85, 86, 92, 95, 98, 99, 100], "databas": [4, 6, 9, 17, 18, 24, 32, 33, 43, 44, 48, 64, 72, 74, 75, 77, 83, 90, 94, 95, 96, 99, 100], "server": [4, 8, 17, 24, 25, 29, 32, 34, 41, 43, 55, 60, 61], "administr": [4, 16, 60, 61], "autom": [4, 15, 16, 25], "contact": [4, 22, 25, 34, 36, 53, 77], "featur": [4, 5, 9, 10, 24, 29, 41, 49, 67, 76, 77, 83, 84], "version": [4, 5, 9, 12, 16, 20, 24, 27, 29, 36, 41, 43, 50, 53, 54, 60, 61, 78, 79, 81], "pleas": [4, 15, 17, 55, 67, 79, 89, 92, 94, 96], "file": [4, 22, 29, 36, 41, 43, 49, 53, 54, 60, 61, 67, 84, 92, 94, 96, 98, 99], "ticket": 4, "email": [4, 5, 10, 14, 16, 24, 25, 27, 42, 43, 48, 49, 51, 52, 53, 60, 61, 68, 69, 70, 71, 77, 78, 79, 81, 84, 89, 92, 98], "my": [4, 9, 15, 16, 25, 33, 61, 77, 79], "n": [4, 14, 15, 25, 41, 42, 48, 49, 53, 54, 60, 63, 68, 78, 79, 84, 85, 86, 98], "10be": [4, 48, 54], "start": [4, 8, 14, 15, 17, 21, 22, 25, 30, 36, 42, 43, 49, 50, 52, 53, 60, 61, 63, 67, 68, 77, 78, 84, 92, 98], "nov": 4, "2017": 4, "few": [4, 17, 36, 37, 43, 49, 53, 60, 63, 65, 67, 77, 92, 98, 99], "won": [4, 9, 22, 36, 40, 41, 43, 55, 60, 76, 77, 78, 84, 85, 86, 89, 92], "worri": [4, 25, 41, 77], "about": [4, 7, 9, 17, 21, 22, 25, 36, 40, 41, 53, 55, 67, 77, 78, 84, 85, 86], "mainten": [4, 40, 77], "cpu": [4, 45, 67, 77], "backup": [4, 25, 41], "everi": [4, 7, 10, 16, 22, 25, 43, 60, 61, 63, 65, 67, 76], "6": [4, 9, 25, 30, 49, 60, 61, 98], "8": [4, 23, 25, 61, 84, 85, 86], "old": [4, 9, 15, 22, 25, 29, 40, 54, 55, 63, 64, 78, 84, 85, 86, 92, 95], "instanc": [4, 25, 98, 99, 100], "mongodb": [4, 5, 8, 17, 18, 25, 30, 33, 43, 44, 45, 48, 60, 67, 74, 75, 78, 81, 84, 89, 92, 94, 96, 98], "freestyl": 4, "omnipod": 4, "via": [4, 15, 22, 25, 55, 77], "csv": 4, "fail": [4, 22, 25, 36, 41, 43, 61, 74, 78, 92], "center": [4, 49, 53], "germani": 4, "finland": 4, "franc": 4, "uptimerobot": 4, "slackbot": 4, "goe": [4, 76], "down": [4, 9, 13, 16, 21, 23, 30, 36, 40, 41, 42, 43, 45, 46, 49, 50, 51, 52, 53, 55, 60, 63, 65, 67, 69, 78, 79, 83, 84, 85, 86, 89, 90, 92, 94, 95, 98, 99], "restart": [4, 25, 38, 48, 49, 52, 53, 60, 61, 78, 84, 85, 86, 92], "twitter": 4, "messag": [4, 15, 22, 25, 36, 40, 43, 60, 61, 67, 78, 92, 95], "4": [4, 8, 9, 25, 84, 89, 98], "discount": [4, 30], "increas": [4, 8, 10, 18, 20, 36, 45, 61, 63, 76, 78], "To": [4, 5, 9, 16, 22, 24, 25, 27, 40, 43, 54, 60, 63, 64, 67, 72, 76, 78, 84, 85, 86, 92, 95], "ns10": 4, "registr": [4, 76, 81], "en": [4, 48, 63], "html": [4, 48], "10be_d": 4, "www": [4, 36, 43, 48, 79], "2022": [4, 18, 41, 74, 75, 78], "andi": 4, "low": [4, 15, 21, 22, 25, 36, 67, 92, 94, 96], "scotland": 4, "uk": 4, "hand": [4, 77], "off": [4, 22, 41, 43, 53, 67, 77, 92, 94, 96], "approach": [4, 18, 77], "subscrib": [4, 48, 77, 78, 89, 92], "littl": [4, 15, 18, 58], "discord": 4, "translat": [4, 23, 25], "multipl": [4, 9, 17, 22, 24, 25, 63, 72, 76, 77, 84, 92], "accept": [4, 14, 15, 16, 17, 30, 42, 63, 64, 68, 76, 77, 78, 84, 85, 86, 92, 95, 98, 99, 100], "payment": [4, 81, 84, 85, 86], "currenc": 4, "price": [4, 43, 77, 81], "per": [4, 8, 10, 16, 18, 25, 30, 40, 63, 72, 74, 75, 76, 77, 78, 79, 92], "gbp": 4, "eur": 4, "pln": 4, "18": [4, 41], "z\u0142": 4, "background": [4, 9, 17, 29, 60, 90, 92, 94], "instant": 4, "deploy": [4, 17, 18, 25, 40, 41, 43, 45, 49, 52, 53, 63, 67, 84, 86, 90, 92], "liter": 4, "launch": [4, 9, 41, 49, 53, 67], "mongo": [4, 6, 8, 25, 30, 32, 48, 60, 61, 67, 77, 81, 89, 92, 94, 96], "shareabl": 4, "url": [4, 5, 9, 10, 12, 13, 15, 17, 18, 22, 24, 25, 27, 29, 32, 45, 49, 60, 63, 67, 78, 84, 85, 86, 92, 98, 100], "never": [4, 24, 43, 60, 78], "size": [4, 5, 8, 9, 23, 48, 77, 89], "reliabi": 4, "upgrad": [4, 16, 20, 36, 41, 43, 52, 53, 60, 61, 77, 78, 89, 92], "ui": [4, 9, 12, 25], "u": [4, 10, 20, 25, 40, 48, 54, 60, 61, 63, 64, 67, 77, 81, 84, 85, 86, 92, 94, 95, 96], "concern": 4, "built": [4, 36], "amazon": [4, 6], "favorit": 4, "netflix": 4, "appl": [4, 12, 25, 76], "airbnb": 4, "espn": 4, "global": [4, 41], "12": [4, 9, 18, 24, 32, 63, 64, 67, 78, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "payabl": 4, "credit": [4, 16, 17, 18, 37, 43, 48, 67, 74, 75, 78, 89, 92, 98], "card": [4, 17, 18, 43, 67, 74, 75, 78, 89, 92, 98], "2023": [4, 41, 55, 78], "possibl": [4, 5, 9, 10, 16, 22, 24, 25, 27, 29, 43, 53, 55, 76, 78], "suitabl": 4, "beginn": [4, 18], "euro": 4, "easi": [4, 15, 17, 18, 25, 29, 36, 77, 84, 92], "willing": 4, "heart": 4, "group": [4, 7, 12, 23, 25, 29, 54, 55, 61, 63], "abl": [4, 5, 10, 15, 16, 21, 24, 25, 27, 29, 41, 45, 55, 61, 76, 79, 84, 85, 86, 92, 95, 98, 99], "countri": [4, 40], "whilst": [4, 18], "almost": 4, "certainli": 4, "someon": [4, 24, 30, 40, 43, 67, 77, 84, 85, 86, 92, 95], "entitl": 4, "form": [4, 25, 61, 67, 92, 94, 96], "movement": 4, "idea": [4, 10, 15, 22, 36, 76, 77, 78], "forward": [4, 23, 55, 61], "learn": [4, 7, 8, 53, 79], "thing": [4, 15, 24, 40, 43, 49, 74, 78], "took": 4, "teach": 4, "nice": [4, 21, 25], "busi": 4, "d": [4, 10, 13, 14, 15, 22, 23, 25, 36, 40, 42, 45, 49, 51, 53, 60, 61, 63, 64, 65, 67, 68, 69, 78, 79, 81, 83, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99], "concentr": 4, "privat": [4, 6, 8, 10, 63, 78, 84, 92, 95], "friend": 4, "alreadi": [4, 6, 8, 15, 22, 25, 32, 36, 43, 60, 61, 67, 77, 81, 83, 85, 86, 89, 92, 95, 96], "clearli": 4, "easili": [4, 7, 15, 18, 22, 24, 43, 77, 92], "lot": [4, 8, 17, 23, 30, 77, 78, 92], "friendli": 4, "orient": 4, "best": [4, 30, 56, 77], "place": [4, 21, 24, 25, 36, 41, 43, 61, 63, 67, 78, 79, 81, 89], "express": [4, 24, 25, 54, 63, 64, 78, 84, 85, 86, 92, 95, 98, 99, 100], "rememb": [4, 9, 18, 36, 41, 63, 64, 77, 78, 84, 85, 86, 92, 94, 95, 98, 99, 100], "navig": [4, 22, 23, 24, 49, 50, 53, 67, 84], "screen": [4, 12, 15, 22, 25, 36, 40, 49, 89, 92, 95, 96], "section": [4, 5, 7, 13, 22, 24, 27, 41, 49, 53, 63, 67, 78, 84, 92, 98], "content": [4, 15, 20, 22, 25, 48, 67, 78], "side": [4, 15, 22, 63, 65], "search": [4, 10, 15, 20, 22, 25, 29, 36, 48, 49, 53, 63, 79], "enter": [4, 5, 7, 9, 10, 12, 13, 14, 15, 16, 22, 24, 25, 27, 32, 36, 40, 42, 49, 51, 53, 60, 61, 63, 67, 68, 69, 70, 71, 74, 75, 76, 78, 79, 81, 84, 89, 92, 96, 98, 99], "string": [4, 5, 24, 27, 43, 48, 63, 64, 67, 78, 79, 81, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99, 100], "english": [4, 25, 35], "logo": [4, 22, 84], "hesit": [4, 6, 17], "correct": [4, 7, 23, 24, 25, 36, 40, 48, 49, 53, 67, 92, 94, 96], "anyth": [4, 14, 15, 16, 42, 49, 52, 53, 60, 63, 67, 68, 78, 84, 98, 99], "error": [4, 36, 44, 61, 67, 94, 96], "unclear": 4, "typo": [4, 92, 95], "broken": [4, 49, 52, 53], "etc": [4, 15, 25, 45, 60, 61], "go": [4, 8, 15, 16, 18, 22, 23, 24, 25, 36, 40, 41, 43, 48, 49, 53, 54, 60, 61, 63, 64, 65, 67, 74, 75, 77, 78, 79, 83, 84, 85, 86, 89, 92, 94, 95, 96, 98], "github": [4, 12, 17, 29, 41, 46, 52, 58, 61, 63, 65, 67, 69, 71, 81, 90, 94, 95, 99], "final": [4, 78, 79], "feel": 4, "join": [4, 55], "channel": 4, "authent": [5, 13, 15, 17, 21, 23, 27, 29, 36, 41, 43, 48, 63, 67, 84, 92, 98], "those": [5, 10, 15, 17, 22, 24, 27, 36, 45, 61, 63, 65, 92, 95], "panel": [5, 10, 15, 24, 27], "horizont": [5, 24, 25, 27], "bar": [5, 15, 23, 24, 27], "api": [5, 13, 16, 21, 25, 27, 32, 41, 54, 55, 63, 67, 78, 84, 92, 98], "secret": [5, 9, 13, 16, 21, 24, 25, 27, 41, 60, 63, 78, 84, 92, 98], "predefin": [5, 9, 24, 27, 92, 95], "careport": [5, 24, 27, 40, 63, 64, 65, 78, 84, 85, 86], "readabl": [5, 25, 27, 84, 85, 86, 92, 95], "deni": [5, 24, 25, 27, 60, 84, 85, 86, 92, 95], "auth_default_rol": [5, 24, 27, 60, 84, 85, 86, 92, 95], "everyon": [5, 24, 27], "devicestatu": [5, 24, 27, 36, 45], "he": [5, 16, 22, 24, 25, 27], "cannot": [5, 24, 25, 27, 51, 63, 67, 69, 83, 84, 90, 92], "button": [5, 12, 15, 22, 24, 27, 29, 43, 45, 61, 67, 76, 78, 79, 92, 94, 95, 96, 98, 100], "fill": [5, 9, 15, 22, 24, 27, 81], "abov": [5, 8, 9, 15, 17, 20, 22, 24, 25, 27, 29, 30, 36, 40, 41, 45, 49, 50, 53, 55, 61, 63, 64, 67, 76, 77, 90, 92, 94, 96, 98, 99, 100], "grant": [5, 24, 27], "do": [5, 9, 10, 13, 15, 16, 17, 20, 22, 24, 25, 27, 29, 30, 32, 36, 40, 41, 42, 43, 49, 50, 51, 52, 53, 54, 60, 61, 63, 64, 65, 67, 69, 77, 78, 79, 84, 85, 86, 92, 94, 95, 98, 99, 100], "edit": [5, 15, 16, 18, 20, 24, 25, 27, 36, 43, 49, 53, 60, 61, 72, 79, 85, 86, 96, 99], "For": [5, 9, 12, 15, 18, 21, 22, 23, 24, 25, 27, 29, 32, 36, 40, 54, 55, 63, 67, 74, 75, 76, 78], "school": [5, 22, 24, 27], "nurs": [5, 22, 24, 27], "him": [5, 16, 24, 27], "aap": [5, 9, 13, 24, 27, 52, 63, 67, 77, 78, 84, 92, 98], "v3": [5, 24, 27], "copi": [5, 14, 15, 22, 24, 27, 36, 41, 42, 43, 45, 49, 50, 51, 53, 54, 61, 63, 64, 65, 67, 68, 69, 76, 77, 78, 79, 81, 83, 85, 86, 89, 92, 94, 95, 96, 98, 99], "address": [5, 10, 16, 18, 24, 27, 40, 54, 61, 79, 84], "e": [5, 9, 13, 14, 20, 23, 24, 25, 27, 36, 42, 45, 49, 51, 53, 60, 61, 63, 64, 65, 67, 68, 69, 77, 78, 79, 81, 83, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99], "g": [5, 13, 24, 25, 27, 36, 45, 61, 63, 64, 65, 67, 78, 79, 81, 83, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99], "past": [5, 9, 15, 24, 27, 36, 42, 43, 45, 51, 61, 63, 64, 65, 67, 69, 78, 79, 84, 85, 86, 92, 94, 96, 98, 99, 100], "effect": [5, 24, 25, 27, 36, 55], "a595d5f0aeff64c0": [5, 24, 27], "instead": [5, 15, 22, 24, 25, 27, 36, 49, 54, 55, 63, 64, 78], "minimum": [5, 17, 24, 25, 27, 78, 81], "14": [5, 24, 25, 27, 49, 54, 60], "yoursitenam": [5, 24, 27, 41, 54, 92], "yourplatform": [5, 24, 27], "bypass": [5, 24, 27], "strategi": [5, 16, 24, 27, 49, 53, 77], "put": [5, 10, 22, 24, 25, 27, 40, 43, 60, 63, 65, 84, 85, 86, 92, 95, 96, 98, 100], "tinyurl": [5, 24, 27, 84], "bit": [5, 15, 22, 24, 27], "ly": [5, 24, 27], "delet": [5, 9, 14, 16, 21, 22, 24, 27, 36, 40, 45, 54, 61, 67, 68, 78, 84, 92, 95, 98], "x": [5, 21, 24, 27, 29, 43, 60, 61, 63, 67, 92, 94, 96], "how": [5, 7, 9, 15, 17, 22, 23, 25, 27, 30, 32, 36, 45, 54, 63, 64, 78, 84, 85, 86, 92, 95, 98, 99, 100], "download": [5, 15, 22, 24, 27, 29, 49, 53, 56, 60, 63, 64, 78, 84, 85, 86, 92, 95, 98, 99, 100], "small": [5, 8, 18, 24, 61, 77], "atla": [5, 8, 17, 18, 24, 25, 30, 43, 44, 45, 63, 64, 67, 74, 75, 78, 84, 89, 90, 92, 98], "noth": [5, 48, 49, 52, 53, 77, 78], "cleanup": [5, 8, 78], "plan": [5, 8, 16, 17, 18, 30, 37, 43, 45, 48, 55, 63, 67, 77, 78, 83, 84, 85, 86, 89, 91, 92, 98], "larger": [5, 8, 79], "eventu": [5, 9, 13, 22, 36, 43, 63, 67, 76, 78, 84, 92, 95, 98], "dbsize": [5, 36, 63, 64, 65, 78, 84, 85, 86], "keep": [5, 7, 9, 17, 18, 21, 22, 24, 25, 36, 40, 41, 43, 60, 61, 63, 67, 72, 74, 76, 77, 78, 79, 81, 84, 89, 92], "under": [5, 9, 20, 43, 55], "control": [5, 9, 10, 25, 29, 53], "collect": [5, 12, 29, 36], "extra": [5, 22, 25, 38, 55, 77], "come": [5, 36, 49, 53, 63, 65, 67, 78, 84, 92, 95, 98], "evalu": 5, "histori": [5, 18, 25, 36, 43, 63, 74, 75, 78], "incorrect": [5, 36, 40], "zone": [5, 13, 25, 36, 42, 48, 49, 51, 53, 60, 63, 67, 69, 78, 84, 92, 98], "daylight": 5, "mistak": [5, 43, 63, 64, 78, 84, 85, 86, 92, 95, 98, 99, 100], "purg": 5, "unwant": 5, "detect": [5, 67], "record": [5, 22, 25, 77], "consid": [6, 8, 17, 18, 24, 25, 36, 61, 63, 67, 72, 74, 75, 77, 78, 79, 81, 84, 89, 92, 98], "easier": [6, 8, 17, 18, 43, 63, 67, 72, 74, 75, 78, 79, 81, 84, 89, 92, 94, 95, 98], "vendor": [6, 25, 48, 53, 54, 55, 60, 61, 77], "paid": [6, 8, 10, 36, 67], "northflank": [6, 8, 10, 14, 17, 18, 25, 30, 36, 40, 48, 49, 50, 53, 54, 63, 64, 70, 82, 83, 85, 86], "io": [6, 7, 8, 9, 14, 17, 18, 25, 29, 30, 36, 40, 49, 53, 54, 55, 60, 70], "easiest": [6, 17, 42, 51], "method": [6, 8, 15, 16, 17, 18, 22, 25, 42, 49, 50, 51, 53, 63, 76, 77, 79, 81, 84, 85, 86], "physic": [6, 9, 25], "develop": [6, 10, 15, 18, 20, 23, 25, 30, 42, 45, 48, 51, 55, 69, 77, 84, 89], "linux": [6, 60, 63], "command": [6, 7, 8, 15, 18, 36, 41, 43, 49, 53, 60, 61, 67, 77], "deploi": [6, 14, 15, 18, 25, 36, 38, 43, 44, 46, 48, 52, 55, 61, 63, 77, 81, 85, 86, 89, 90, 94, 95, 96, 100], "script": [6, 8, 14, 18], "vp": [6, 8, 10, 17, 60, 61, 77], "googl": [6, 7, 8, 14, 17, 18, 29, 30, 34, 36, 40, 49, 53, 54, 70, 76, 81], "oracl": [6, 8, 17, 30, 60, 61], "extens": [6, 24, 29, 98, 100], "npm": [6, 61], "docker": [6, 17, 18, 49, 53, 55, 61, 77, 84, 86, 92, 96, 98], "common": [6, 8, 25, 36, 40, 60, 79], "ubuntu": [6, 18, 60], "bui": [6, 55], "worth": [6, 18, 74, 75, 77, 78, 81, 84], "synologi": 6, "qnap": 6, "wrapper": 6, "around": [6, 24], "integr": [7, 18, 22, 25, 29, 55, 63], "optim": [7, 23], "head": 7, "overview": [7, 16, 23, 49, 53, 63], "support": [7, 8, 15, 17, 20, 25, 29, 30, 37, 40, 61, 77, 81, 83, 84], "facebook": [7, 12, 23, 29, 54, 55], "assist": [7, 12, 25], "face": [7, 29, 77], "dai": [7, 9, 21, 22, 25, 36, 40, 63], "schedul": 7, "carbohydr": 7, "cr": 7, "predict": [7, 15, 25, 67, 92, 94, 96], "meal": [7, 22, 23, 25], "entri": [7, 9, 22, 24, 25, 27, 36, 40, 54, 79], "deliveri": [7, 25], "attain": 7, "futur": [7, 8, 9, 77, 79], "androidap": 7, "live": [7, 41, 63, 67, 84, 98, 100], "artifici": 7, "pancrea": 7, "ap": [7, 25], "android": [7, 25, 54, 55, 56, 78], "smartphon": [7, 29], "softwar": [7, 55], "nsclient": 7, "mind": [7, 9, 30, 36, 43, 46, 48, 52, 58, 61, 63, 64, 77, 78, 79, 92, 95], "power": [7, 9, 48, 61], "design": [7, 8, 12, 18, 24, 63, 77, 79], "doe": [7, 15, 22, 23, 24, 43, 77], "obtain": [7, 16, 43, 61, 63, 64, 84, 85, 86], "recent": [7, 9, 12, 25, 40, 49, 53, 54, 55, 63, 77, 81], "bolus": [7, 22, 25], "commonli": [8, 18], "m0": [8, 36, 77, 79], "regularli": [8, 79, 89], "grow": [8, 25, 36, 79], "regular": 8, "crash": [8, 36, 44, 45, 74, 77, 78, 79, 81, 92, 95], "bought": [8, 29, 77, 79], "mlab": [8, 17, 25, 36, 77, 79], "2018": [8, 79], "shutdown": [8, 36, 79], "2020": [8, 16, 36, 79], "most": [8, 15, 16, 17, 18, 22, 25, 36, 38, 40, 48, 55, 60, 61, 74, 75, 77, 79], "migrat": [8, 18, 25, 36, 43, 49, 53, 65, 72, 79, 83], "512mb": [8, 36, 77, 79], "capac": [8, 36, 79], "cluster": [8, 25, 67, 79, 92, 94, 96], "adapt": [8, 79], "con": [8, 18, 63, 67, 72, 74, 75, 78, 79, 81, 84, 89, 92, 98], "test": [8, 15, 18, 20, 23, 25, 40, 45, 49, 54, 63, 64, 77, 78, 79, 84, 85, 86, 92, 95], "product": [8, 18, 25, 43, 60, 63, 77, 79], "guarante": [8, 18, 98], "warranti": [8, 79], "remain": [8, 25, 36, 67, 77, 79, 89], "m2": [8, 36, 77, 79], "cost": [8, 17, 18, 30, 63, 67, 72, 77, 79, 89], "9": [8, 25, 29, 60, 79], "competit": 8, "less": [8, 10, 30, 36, 56, 84, 85, 86, 89], "overhead": [8, 89], "than": [8, 9, 10, 15, 16, 18, 20, 21, 22, 25, 30, 36, 41, 42, 45, 49, 51, 52, 53, 54, 56, 63, 69, 72, 74, 75, 76, 77, 78, 79, 84, 85, 86, 89], "5": [8, 9, 18, 22, 25, 30, 44, 45, 77, 78, 81, 89, 92, 98], "hobbi": [8, 18, 45, 77, 89, 92], "bill": [8, 41, 43, 45, 48, 67, 74, 75, 77, 78, 79, 89, 92], "amount": [8, 25, 36, 38, 78], "togeth": [8, 22, 76], "200mib": 8, "econom": [8, 75, 81], "high": [8, 21, 22, 25, 67, 77, 81, 92, 94, 96], "replica": [8, 81], "occur": [8, 43, 55], "realli": [8, 18, 43, 63, 65, 74, 75, 77, 78], "gib": [8, 81], "reach": [8, 9, 22, 25, 36, 37], "1gb": [8, 72], "virtual": [8, 18, 36, 61, 84], "specialist": [8, 18, 63], "knowledg": [8, 30, 58], "progress": 8, "strongli": [9, 13, 63, 67, 78, 84, 92, 98], "recommend": [9, 12, 13, 14, 18, 24, 29, 36, 38, 41, 43, 50, 54, 55, 63, 64, 67, 76, 77, 78, 84, 85, 86, 98, 99, 100], "veri": [9, 14, 16, 17, 18, 23, 25, 36, 42, 43, 61, 67, 68, 74, 75, 76, 77, 78, 84, 98], "pale": 9, "blue": [9, 15, 22], "ar2": 9, "previs": 9, "explain": [9, 25, 43, 84], "brows": [9, 10, 13, 25, 36, 48, 63, 67, 78, 84, 85, 86, 92, 95, 98], "ago": [9, 77, 92], "delta": 9, "By": [9, 15, 25, 29], "order": [9, 15, 16, 20, 21, 22, 23, 24, 25, 36, 40, 55, 76, 78, 84, 92, 94, 95, 98, 99], "lock": [9, 13, 25, 43, 48, 63, 67, 74, 78, 84, 92, 98], "unlock": [9, 25, 29, 76], "whish": 9, "interfac": [9, 18, 24, 25, 72], "drop": [9, 16, 18, 21, 23, 25, 36, 40, 46, 49, 50, 53, 63, 74, 75, 78, 84, 90, 92, 94, 98, 99], "meter": [9, 55], "much": [9, 15, 25, 30], "now": [9, 10, 13, 14, 15, 16, 17, 22, 23, 25, 30, 36, 40, 41, 42, 45, 49, 50, 52, 53, 60, 61, 62, 63, 65, 67, 68, 70, 71, 74, 75, 76, 77, 78, 79, 81, 82, 84, 85, 86, 89, 90, 91, 92, 94, 95, 96, 98, 99, 100], "stabl": [9, 60], "due": [9, 36, 43, 48, 56, 77], "capillari": 9, "lag": 9, "inject": 9, "circl": [9, 15, 22], "half": 9, "These": [9, 17, 21, 25, 67, 92, 94, 96], "eat": [9, 15, 25], "higher": [9, 23, 25], "white": 9, "protein": 9, "fat": 9, "did": [9, 36, 43, 77], "total": [9, 23, 25, 67], "given": [9, 15, 22, 24], "break": [9, 16, 40, 55], "split": 9, "percentag": [9, 23, 25], "administ": [9, 16], "extend": [9, 36, 43], "classic": [9, 25, 49, 83, 84, 85], "reflect": [9, 21, 89, 91, 92], "viewer": 9, "anoth": [9, 17, 18, 21, 22, 25, 29, 36, 41, 42, 43, 48, 50, 55, 60, 61, 63, 67, 74, 75, 76, 78, 79, 83, 84, 85, 86, 90, 92], "acknowledg": [9, 22, 25], "return": [9, 25, 43, 50, 60, 61, 83, 84, 89, 90, 92, 94, 96], "help": [9, 15, 16, 17, 23, 25, 36, 43, 55, 74, 77, 78, 92], "expir": [9, 22, 40, 63], "temporari": [9, 15, 22, 36, 40, 98, 99], "percent": [9, 24, 25, 63, 64, 78, 84, 85, 86, 92, 95, 98, 99, 100], "absolut": [9, 23, 48], "synchron": [9, 23, 55], "dog": 9, "still": [9, 15, 25, 29, 36, 38, 49, 55, 63, 74, 75, 77, 92], "present": [9, 25, 41, 52, 54, 55], "move": [9, 15, 22, 29, 36, 39, 40, 54, 63, 64, 78, 84, 85, 86, 89, 92, 95], "drag": [9, 15], "black": [9, 15, 23], "area": [9, 15, 20, 63], "done": [9, 13, 15, 22, 24, 36, 48, 49, 53, 60, 61, 63, 65, 67, 78, 84, 85, 86, 92, 98], "exit": [9, 40, 41, 61], "drive": 9, "toolset": 9, "editor": [9, 13, 21, 25, 36, 43, 48, 61, 63, 65, 67, 78, 84, 94, 96, 98], "handl": [9, 24, 25], "admin": [9, 16, 24, 25, 27, 36, 48, 61], "clock": [9, 25, 60], "grei": [9, 15, 40], "simplifi": 9, "element": 9, "item": [9, 25, 36, 54], "sgv": 9, "minut": [9, 13, 14, 15, 18, 21, 25, 37, 40, 42, 44, 49, 52, 53, 55, 56, 60, 61, 63, 67, 68, 74, 75, 78, 79, 84, 85, 86, 89, 92, 94, 96, 98, 99, 100], "sg": 9, "invis": 9, "next": [9, 15, 21, 22, 23, 49, 53, 63, 65, 98, 100], "same": [9, 15, 16, 17, 18, 22, 24, 25, 36, 40, 43, 49, 63, 74, 75, 77, 78], "properti": 9, "even": [9, 17, 24, 30, 36, 40, 42, 45, 51, 58, 69, 74, 78], "mai": [9, 15, 22, 23, 25, 29], "apart": 9, "aspect": [9, 79], "threshold": [9, 67, 92, 94, 96], "green": [9, 15, 22, 25, 63, 65, 84, 85, 86], "after": [9, 13, 14, 15, 16, 18, 21, 22, 24, 25, 36, 38, 40, 41, 42, 45, 49, 53, 54, 63, 64, 67, 68, 70, 71, 76, 78, 84, 85, 86, 92, 98, 99, 100], "breach": 9, "turn": [9, 15, 22, 25, 40, 41, 43, 53, 61], "strike": 9, "through": [9, 12, 15, 22], "could": [9, 22, 25, 36], "bookmark": 9, "fullscreen": 9, "swipe": [9, 15], "gestur": 9, "appli": [9, 16, 24, 25, 98, 99], "reset": [9, 43, 44], "revers": [9, 15, 60, 61], "config": [9, 22, 41, 43, 49, 53, 65], "doc": [9, 22, 24, 25, 55], "v2": [9, 15, 41], "json": [9, 15], "advic": 10, "good": [10, 16, 25, 30, 36, 43, 50, 52, 76, 77, 78, 81, 84], "becaus": [10, 15, 22, 43, 45, 48, 63, 77], "simpli": [10, 22, 49, 77], "outag": 10, "hostnam": [10, 54, 67, 98, 100], "sign": [10, 14, 15, 21, 24, 25, 32, 33, 41, 42, 46, 49, 51, 53, 60, 63, 67, 68, 69, 70, 71, 78, 81, 84, 92, 98, 99], "yet": [10, 22, 36, 48, 49, 53, 67, 81], "dashboard": [10, 16, 41, 43, 45, 46, 49, 53, 54, 67, 83, 84, 89, 98, 100], "invent": [10, 36, 60, 61, 78, 79, 81, 84], "ipv4": 10, "alia": 10, "cname": 10, "ddn": [10, 60], "replac": [10, 20, 23, 36, 41, 43, 49, 50, 53, 60, 61, 67, 79], "propos": [10, 17, 18, 76, 84, 85, 86, 92, 95], "ipv6": 10, "thousand": 10, "flag": 10, "danger": [10, 42, 45, 51, 69], "cellular": 10, "public": [10, 41], "network": [10, 18, 36, 60, 77, 92], "fit": [10, 18, 67, 84, 92], "attempt": [10, 25, 36, 38, 41, 43, 45], "login": [10, 14, 15, 16, 22, 25, 36, 40, 41, 42, 45, 48, 49, 51, 52, 53, 60, 61, 63, 65, 67, 68, 69, 70, 71, 74, 75, 76, 78, 83, 84, 89, 90, 92, 98, 99], "six": 10, "inbox": [10, 14, 42, 68, 78, 84, 98], "spam": [10, 14, 42, 68, 78, 79, 84, 89, 98], "subdomain": 10, "destin": 10, "field": [10, 12, 13, 15, 22, 25, 36, 54, 61, 63, 67, 78, 81, 84, 92, 94, 96, 98, 100], "imag": [10, 49, 53, 60, 63, 84, 86, 92, 96, 98, 100], "popular": [10, 18, 61, 74, 75, 77, 78], "registri": [10, 98, 100], "compliant": 12, "tld": [12, 60, 61], "tablet": [12, 56], "dark": [12, 22], "night": [12, 25, 67, 77, 92, 94, 96], "wear": 12, "watch": [12, 15, 36], "anymor": [12, 29, 41, 43, 54, 55, 56, 63, 78, 84, 92, 98], "switch": [12, 25, 41, 43, 56, 74, 75], "mode": [12, 40, 67, 92, 94, 96], "bridg": [12, 20, 29, 40, 54, 55, 56, 63, 64, 65, 67, 74, 78, 84, 92, 94, 95, 96], "obscur": [12, 25, 29], "home": [12, 15, 43], "direct": [13, 15, 40, 49, 63, 67, 78, 84, 92, 98], "creation": [13, 15, 24, 36, 48, 63, 67, 78, 79, 81, 84, 92, 98], "b": [13, 14, 25, 36, 42, 44, 45, 49, 50, 51, 53, 60, 61, 63, 67, 68, 69, 78, 79, 81, 83, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99], "later": [13, 15, 24, 43, 61, 63, 67, 76, 78, 79, 81, 84, 89, 92, 94, 95, 98, 100], "c": [13, 14, 21, 25, 36, 42, 45, 49, 51, 53, 60, 61, 63, 64, 65, 67, 68, 69, 78, 79, 81, 83, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99], "pop": [13, 15, 43, 63, 67, 78, 84, 92, 98], "ok": [13, 25, 63, 64, 65, 67, 78, 84, 92, 98, 99], "f": [13, 14, 36, 42, 45, 49, 53, 61, 63, 64, 65, 67, 68, 78, 79, 81, 83, 84, 85, 86, 89, 90, 92, 94, 95, 96, 98, 99], "Then": [13, 15, 23, 41, 45, 50, 63, 64, 65, 67, 78, 79, 84, 90, 92, 94, 95, 98, 99, 100], "hamburg": [13, 63, 67, 78, 84, 92, 98], "anyon": [13, 24, 25, 63, 67, 78, 84, 92, 98], "flow": [13, 40, 60, 61, 63, 67, 78, 84, 92, 98], "carelink": [13, 17, 20, 24, 25, 43, 55, 63, 67, 78, 84, 92, 98], "consult": [13, 25, 63, 67, 78, 84, 92, 98], "rel": [13, 23, 63, 67, 78, 84, 92, 98], "mandatori": [14, 17, 18, 25, 49, 78, 92], "usernam": [14, 16, 20, 25, 32, 33, 36, 42, 49, 50, 51, 53, 54, 61, 63, 64, 67, 68, 69, 70, 71, 78, 79, 84, 85, 86, 92, 94, 95, 96, 98], "declin": [14, 42, 68, 78, 84, 98], "advertis": [14, 42, 68, 78, 84, 98], "plai": [14, 25, 29, 42, 68, 76, 78, 84, 98], "solv": [14, 42, 68, 78, 84, 98], "puzzl": [14, 42, 68, 78, 84, 98], "mail": [14, 42, 68, 78, 83, 84, 98], "folder": [14, 36, 41, 42, 49, 50, 53, 68, 78, 79, 84, 89, 98], "coupl": [14, 15, 42, 68, 78, 84, 98], "sequenc": [14, 42, 67, 68, 78, 84, 98], "deselect": [14, 42, 68, 78, 84, 98], "master": [14, 16, 20, 40, 42, 43, 50, 52, 53, 54, 55, 68, 70, 71, 78, 83, 84, 85, 92, 98, 99], "branch": [14, 15, 16, 20, 34, 42, 43, 49, 50, 52, 53, 68, 70, 71, 78, 83, 84, 85, 92, 98], "moment": [14, 21, 42, 45, 49, 53, 68, 70, 71, 78, 84, 92, 98], "That": 15, "press": [15, 22, 53, 61, 90, 92, 96], "overrid": [15, 22, 63, 64, 65, 78, 84, 85, 86], "gather": 15, "consol": [15, 25, 43, 60, 61], "hint": [15, 30, 60], "padlock": 15, "corner": [15, 78], "haven": [15, 22, 36, 49, 53, 81], "refresh": [15, 44, 92], "kei": [15, 21, 22, 23, 25, 41, 60, 61, 63, 84, 90, 92], "apisecrethash": 15, "xxxxxxxxxx": 15, "safari": 15, "mac": [15, 61, 90, 92], "prefer": [15, 16, 25, 67, 77, 81, 92, 94, 96], "problem": [15, 24, 40, 42, 54, 63, 64, 67, 78, 84, 85, 86, 92, 94, 95, 96], "triangl": [15, 40], "isauthent": 15, "object": 15, "screenshot": [15, 22], "chrome": 15, "tab": [15, 22, 45, 53, 54, 61, 63, 65, 79, 81, 84, 89, 92, 96], "row": [15, 22], "retreiv": 15, "why": [15, 40, 49, 77, 83, 84, 92, 95], "But": [15, 17, 77], "along": 15, "terminologi": 15, "cool": 15, "let": [15, 25, 54, 55, 63, 64, 77, 78, 92, 95], "Or": [15, 49, 60], "exercis": [15, 25], "aka": 15, "label": [15, 25, 60], "buttonwidget": 15, "widget": [15, 29], "twice": [15, 45, 84], "second": [15, 22, 25, 41, 63, 65, 76], "webhook": [15, 25], "blank": [15, 22], "templat": [15, 60, 92, 95, 98], "recip": [15, 22], "soon": [15, 16, 25], "four": 15, "describ": [15, 16, 78], "yoursit": [15, 54], "fqd": [15, 25, 78], "v1": [15, 24, 32, 41, 54, 67], "NOT": [15, 22, 25, 54, 63, 64, 65, 67, 78, 84, 85, 86, 92, 95, 98, 99, 100], "info": [15, 22, 25, 32, 36, 40, 54, 63, 64, 78, 84, 85, 86, 92, 95], "post": [15, 22], "bodi": [15, 24, 25], "would": [15, 22, 24, 25, 46, 67, 77], "particular": [15, 22], "math": 15, "though": [15, 22], "care": [15, 23, 25, 30, 49, 61, 77, 92], "giver": 15, "being": [15, 20, 22, 25, 40, 45, 50, 55, 76], "notic": [15, 22, 25, 40], "sampl": 15, "enteredbi": 15, "eventtyp": 15, "your_hashed_api_goes_her": 15, "hi": [15, 16, 22, 43], "mom": 15, "me": [15, 25, 77], "m": [15, 23, 63, 79, 84, 85, 86, 92, 96], "special": [15, 24, 25, 36, 67, 79, 92, 94, 96], "trigger": [15, 16, 22, 25, 49, 67, 92, 94, 96], "consider": 15, "herokuapp": [15, 54], "notif": [15, 56], "reason": [15, 36, 40, 43, 44, 48, 50, 63, 64, 77, 78, 84, 85, 86, 92, 95, 98, 99, 100], "reasondisplai": 15, "what": [15, 22, 25, 30, 33, 36, 41, 77], "preset": 15, "v": [15, 23, 25, 36, 67, 92, 94, 96], "indefinit": 15, "infinit": 15, "NO": [15, 78, 79], "emoji": 15, "hormon": 15, "cancel": 15, "finish": [15, 22, 41, 44, 63, 79, 92], "chanc": 15, "titl": [15, 21, 22], "meaning": 15, "slider": 15, "alert": [15, 25], "pebbl": 15, "successfulli": [15, 42, 45, 51, 67, 69, 98, 99], "repeat": [15, 22], "pretti": [15, 22], "maker": [15, 22, 63, 64, 65, 78, 84, 85, 86], "maker_kei": [15, 22, 25], "hard": [15, 22, 24, 77], "street": 15, "hold": [15, 17, 36], "finger": 15, "end": [15, 20, 22, 32, 36, 40, 41, 43, 45, 55, 63, 64, 78, 84, 85, 86, 89, 92, 95], "reorder": 15, "gear": 15, "pencil": 15, "quickscreen": 15, "And": [15, 36, 77], "earlier": 15, "amazonalexa": 15, "underscor": 15, "fyi": 15, "juggl": 16, "reduc": [16, 25], "rais": 16, "seriou": [16, 30], "malici": [16, 76], "ill": 16, "intent": 16, "fork": [16, 41, 49, 50, 53, 69, 90, 94, 95], "practic": [16, 52], "remov": [16, 18, 20, 24, 25, 27, 36, 41, 43, 45, 48, 49, 53, 61, 67, 77, 89, 91, 92, 98, 99], "releas": [16, 40, 41, 43, 53, 55, 56, 60, 67], "Not": [16, 42, 48, 77], "redeploi": [16, 38, 41, 45, 48, 49, 50, 53, 63, 67, 70, 71, 78, 84, 90, 92, 94, 98, 99], "merg": [16, 49, 53, 70, 71, 78, 84, 92, 93, 98], "charg": [16, 81], "eco": [16, 18, 30, 43, 48, 77, 78], "pen": [16, 43, 49, 63, 78], "everyth": [16, 17, 40, 60], "primari": 16, "task": [16, 41], "organ": [16, 36], "owner": [16, 41], "caret": [16, 92, 95], "back": [16, 36, 49, 50, 53, 61, 63, 65, 67, 77, 78, 79, 84, 85, 86, 90, 92, 94, 95, 98], "org": 16, "09": [16, 41], "20": [16, 22, 25, 61, 81, 84], "guest": [16, 54], "renam": [16, 43], "cog": [16, 36], "privileg": [16, 24], "observ": 16, "revok": [16, 43], "invite": 16, "wearenotwait": 17, "j": [17, 36, 41, 61, 63, 78, 79, 83, 84, 85, 86, 90, 92, 94, 95, 96, 98, 99], "wizard": [17, 18, 41, 49, 53, 77, 83, 84], "packag": 17, "programm": 17, "planet": 17, "spend": [17, 25, 30], "alarm": [17, 55, 84, 85, 86, 92, 95], "frontpag": 17, "mention": 17, "whenev": [17, 36, 67], "piec": [17, 36], "tradition": [17, 22], "serendip": [17, 30], "bio": [17, 30], "involv": [17, 50], "strict": 17, "abus": 17, "impli": 17, "cover": [17, 24, 25], "na": [17, 48], "guess": [17, 24], "compon": [17, 24], "relat": [17, 22, 24, 43, 77], "root": [17, 23, 24, 60, 61], "otherwis": [17, 24], "compromis": [17, 24], "latest": [17, 24, 25, 36, 40, 41, 43, 44, 49, 53, 56, 60, 61, 63, 84, 86, 92, 96, 98, 100], "oper": [17, 24, 55, 76, 84, 92, 98, 99, 100], "viru": [17, 24], "begin": [18, 63, 74, 75, 78, 84], "On": [18, 23, 49, 53, 54, 61, 74, 75, 77, 78, 92, 96], "august": [18, 74, 75, 78], "25th": [18, 74, 75, 78], "7": [18, 25, 74, 78], "compar": [18, 74, 75, 78], "tier": [18, 25, 43, 49, 53, 67, 77, 84], "trial": [18, 63], "maximum": [18, 25, 30, 36, 63], "stai": [18, 46, 63], "quota": [18, 25, 63], "f1": [18, 63], "cosmo": [18, 63, 64, 77], "troubleshoot": [18, 54, 63, 64, 78, 84, 85, 86, 92, 95], "nativ": [18, 84, 92], "model": [18, 24, 58, 92], "caus": [18, 22, 24, 25, 41, 67, 92, 94, 96], "imposs": [18, 76, 84], "util": [18, 23, 36, 77], "intuit": [18, 67], "rather": [18, 22, 25, 92], "technic": [18, 36, 37, 58], "5c": 18, "australia": [18, 72], "cina": 18, "No": [18, 36, 67, 79, 98], "sleep": [18, 36, 48, 98], "15": [18, 20, 25, 30, 40, 54, 55, 84, 85, 86, 98], "mmconnect": [20, 48, 54, 55, 56], "deprec": [20, 25, 55], "term": [20, 43, 78, 89, 92], "number": [20, 23, 24, 25, 36, 54, 61, 63, 64, 67, 78, 79, 84, 85, 86, 92, 94, 95, 96], "v15": 20, "guidelin": 20, "word": [20, 25, 36, 40, 67, 76, 84, 85, 86, 92, 94, 96], "separ": [20, 22, 25, 36, 63, 67, 78, 84, 85, 86, 92, 94, 96], "connect_sourc": [20, 54], "connect_share_serv": 20, "ou": [20, 54], "connect_share_account_nam": [20, 54], "connect_share_password": [20, 54], "mmconnnect": 20, "connect_carelink_region": [20, 54], "eu": [20, 25, 40, 48, 54, 55, 63, 64, 67, 84, 85, 86, 92, 94, 95, 96], "minim": [20, 23, 29, 48, 56], "connect_carelink_usernam": [20, 54], "connect_carelink_password": [20, 54], "connect_carelink_patient_usernam": [20, 54], "whom": 20, "format": [21, 22, 25, 29, 32, 33], "duplic": [21, 63], "clone": [21, 48, 49, 50, 53, 61, 67], "modif": [21, 43, 92, 98, 99], "timezon": [21, 25], "endocrinologist": 21, "subject": [21, 24, 27], "slice": 21, "30": [21, 22, 25, 55], "where": [21, 22, 24, 25, 30, 36, 41, 50, 54, 60, 63, 67, 77, 84, 92, 94, 96, 98, 100], "paragraph": 21, "valid": [21, 24, 25, 30, 40, 54, 58, 60, 61, 63, 64, 67, 74, 75, 77, 78, 84, 85, 86, 92, 94, 95, 96], "happen": [21, 22, 25, 36, 37, 40, 49, 52, 53, 78], "recreat": [21, 36, 45], "frame": 21, "iphon": [22, 25, 29], "function": [22, 25, 36, 43, 48, 54, 56, 78, 92], "combin": 22, "had": [22, 40, 43, 54, 63, 64, 78, 84, 85, 86, 89, 92, 95], "pushover_announcement_kei": [22, 25], "pushover_api_token": [22, 25], "pushover_user_kei": [22, 25], "drawback": 22, "fine": [22, 45], "tune": [22, 23, 25], "mayb": [22, 25, 48], "environ": [22, 25, 49, 55, 60, 63, 79, 84, 85, 86, 98, 100], "fatigu": 22, "fairli": 22, "howev": 22, "ones": [22, 25, 63, 65], "teenag": 22, "looper": [22, 36, 77], "her": 22, "reservoir": [22, 25, 60], "volum": [22, 25, 60], "inevit": 22, "lunch": 22, "child": 22, "perhap": 22, "emerg": 22, "quit": 22, "concept": [22, 77], "henc": 22, "refer": [22, 25, 53, 63, 77], "subsequ": [22, 24], "brief": 22, "roadmap": 22, "spreadsheet": 22, "onto": 22, "doubl": [22, 25], "newli": [22, 40, 41, 49, 53], "subfold": [22, 36], "numer": [22, 40, 54, 63, 64, 78, 84, 85, 86, 92, 95], "appropri": [22, 25], "bullet": 22, "wider": 22, "sheet": 22, "path": [22, 25, 36, 43, 49, 53, 61, 84, 86], "ingredi": 22, "value1": 22, "toggl": 22, "track": [22, 98], "previous": [22, 43, 79], "talk": 22, "reveal": [22, 43, 63, 65, 78], "var": [22, 43, 60, 65], "filenam": 22, "hasn": [22, 25, 67, 92, 94, 96], "week": 22, "partial": 22, "72": [22, 25], "bolu": [22, 23, 67, 92, 94, 96], "vari": 22, "prompt": [22, 41, 49, 53, 60, 61, 67], "columnc": 22, "column": [22, 63, 65], "columna": 22, "columnd": 22, "decent": 22, "prioriti": 22, "summari": [22, 63], "upbat": 22, "rig": 22, "suffici": 22, "defaultwarn": 22, "defaulturg": 22, "herokuset": 22, "cage_enable_alert": [22, 25], "truecage_warn": 22, "xxcage_urg": 22, "xx": 22, "164": [22, 25], "168": 22, "sage_enable_alert": [22, 25], "truesage_warn": 22, "xxsage_urg": 22, "iage_enable_alert": [22, 25], "trueiage_warn": 22, "xxiage_urg": 22, "60": [22, 25, 63], "loop_enable_alert": [22, 25], "trueloop_warn": 22, "xxloop_urg": 22, "openaps_enable_alert": [22, 25], "trueopenaps_warn": 22, "xxopenaps_urg": 22, "pump_clock": 22, "pump_enable_alert": [22, 25], "truepump_warn_clock": 22, "xxpump_urgent_clock": 22, "pump_r": 22, "10": [22, 25, 30, 40, 49, 52, 53, 56, 67, 83, 84, 85, 86], "truepump_warn_r": 22, "xxpump_urgent_r": 22, "pump_batt_p": 22, "truepump_warn_batt_p": 22, "xxpump_urgent_batt_p": 22, "pump_batt_v": 22, "35": [22, 25], "truepump_warn_batt_v": 22, "xxpump_urgent_batt_v": 22, "upbat_enable_alert": [22, 25], "trueupbat_warn": 22, "xxupbat_urg": 22, "sm": [22, 25], "downsid": 22, "100": [22, 36], "exce": [22, 25, 36], "distinguish": 22, "clear": [22, 32, 33, 55], "nor": [22, 29, 36, 79], "dure": [22, 23, 25, 36, 43, 48, 74, 75, 78, 84, 92], "notifi": [22, 24], "light": [22, 25], "collector": 22, "temp": [22, 25, 55], "2000": 22, "fast": [22, 23], "averag": [22, 23, 25], "clean": [22, 25, 60, 61, 89], "room": [22, 78], "fantast": 23, "crunch": 23, "video": [23, 36, 63], "gari": 23, "scheiner": 23, "better": [23, 25, 36, 42, 51, 69], "pattern": 23, "vertic": [23, 67], "logarithm": [23, 25], "linear": [23, 25, 67], "a1c": 23, "inaccur": 23, "formula": [23, 25, 67, 92, 94, 96], "taken": [23, 77], "nathan": 23, "david": 23, "et": 23, "al": 23, "assai": 23, "31": 23, "2008": 23, "1473": 23, "1478": 23, "fluctuat": 23, "rapid": 23, "examin": 23, "rapidli": 23, "sum": 23, "excurs": 23, "divid": [23, 25], "rm": 23, "squar": 23, "distanc": 23, "metric": 23, "weight": [23, 77], "far": 23, "gvi": 23, "glycem": 23, "index": 23, "pg": 23, "repres": 23, "timeshift": 23, "backward": 23, "obvious": [23, 42, 51, 69], "rest": [23, 24, 32], "sens": [23, 29], "shift": 23, "highlight": [23, 40], "dinner": 23, "autotun": 23, "temporarili": [23, 36], "nightrep": 23, "zreptil": 23, "pdf": 23, "cor": [23, 63, 64, 65, 78, 84, 85, 86], "assumpt": 24, "themselv": 24, "legal": [24, 77], "thu": 24, "assum": 24, "ownership": 24, "fashion": 24, "case": [24, 25, 36, 40, 43, 50, 54, 61, 63, 64, 67, 74, 75, 78, 84, 85, 86, 92, 94, 95, 96], "gain": 24, "alter": 24, "trust": 24, "scenario": [24, 25], "behalf": 24, "legisl": 24, "across": 24, "liabil": 24, "complic": [24, 29], "highli": [24, 25], "1password": 24, "reus": [24, 43, 61, 90, 92], "ever": 24, "One": [24, 40, 74, 75], "ssl": [24, 61], "encrypt": 24, "forc": [24, 29, 77], "crucial": 24, "wrong": [24, 25, 40, 43, 74, 76, 78], "complain": 24, "man": 24, "middl": 24, "mitm": 24, "attack": 24, "proceed": [24, 67], "problemat": 24, "introduc": 24, "megaphon": 24, "queue": 24, "cryptograph": 24, "guessabl": 24, "awai": 24, "least": [24, 25, 30, 36, 54, 63, 64, 67, 76, 78, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "charact": [24, 25, 32, 36, 63, 64, 67, 78, 79, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "longer": 24, "mix": [24, 40, 54, 63, 64, 78, 84, 85, 86, 92, 95, 98, 99, 100], "capit": 24, "letter": [24, 25, 36, 40, 41, 49, 53, 54, 60, 61, 63, 64, 78, 79, 84, 85, 86, 92, 95, 98, 99, 100], "alphanumer": [24, 40], "encod": [24, 63, 64, 78, 84, 85, 86, 92, 95, 98, 99, 100], "d0n": 24, "h4ck": 24, "m3": 24, "27t": 24, "2ah4ck": 24, "40m3": 24, "famili": [24, 77], "tri": [24, 36, 43], "credenti": [24, 40, 54, 63, 64, 74, 78, 84, 85, 86, 92, 95], "unexpectedli": 24, "ip": [24, 36, 61, 79], "brute": 24, "situat": [24, 43], "pick": [24, 63], "accordingli": [24, 40, 78], "advantag": [24, 43], "permiss": [24, 36, 84, 85, 86, 92, 95], "api3": [24, 55], "held": 25, "behavior": 25, "nightcsout": 25, "readm": 25, "shouldn": [25, 36, 37], "vital": [25, 43], "prevent": [25, 76], "svr": 25, "salli": 25, "sallypass": 25, "cluster0": [25, 36, 78, 79], "abcdef": 25, "retrywrit": [25, 36, 78, 79], "true": [25, 36, 49, 54, 60, 61, 78, 79], "w": [25, 36, 43, 78, 79], "tradit": 25, "myhosteddb": 25, "mongo_connect": [25, 32, 60, 63, 65, 67, 78, 84, 92, 98], "uncontrol": [25, 79], "expos": [25, 63, 64, 78, 84, 85, 86, 92, 95, 98, 99, 100], "publicli": [25, 41, 63, 64, 78, 81, 84, 85, 86, 92, 95, 98, 99, 100], "passphras": [25, 67, 92, 94, 96], "myv3ry53cr37": 25, "stick": 25, "mg": [25, 63, 64, 67, 78, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "dl": [25, 63, 64, 67, 78, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "mmol": [25, 40, 60, 63, 64, 67, 78, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "l": [25, 63, 64, 67, 78, 79, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "further": [25, 55], "enough": [25, 40, 61, 63, 77], "beta": 25, "delimit": [25, 67, 92, 94, 96], "role": [25, 61], "visit": [25, 41, 49, 53], "overridden": 25, "bg_": 25, "cross": [25, 45, 67, 92, 94, 95, 96], "certain": 25, "sound": [25, 42, 51, 69], "_min": 25, "snooz": [25, 29], "aren": [25, 40], "tag": [25, 49, 60, 63], "miss": [25, 74, 78], "timelin": 25, "am": [25, 41], "pm": 25, "bright": 25, "contrast": 25, "legaci": 25, "nois": 25, "wearer": [25, 67, 92, 94, 96], "colorblindfriendli": [25, 67, 92, 94, 96], "whether": [25, 67, 92, 94, 96], "mere": [25, 67, 92, 94, 96], "fals": 25, "earli": 25, "medic": 25, "chose": 25, "outlin": 25, "\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438": [25, 35], "\u010de\u0161tina": [25, 35], "deutsch": [25, 35], "dk": 25, "dansk": [25, 35], "el": 25, "\u03b5\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac": [25, 35], "espa\u00f1ol": [25, 35], "fi": 25, "suomi": [25, 35], "fr": 25, "fran\u00e7ai": [25, 35], "\u05e2\u05d1\u05e8\u05d9\u05ea": [25, 35], "hr": 25, "hrvatski": [25, 35], "italiano": [25, 35], "ko": 25, "\ud55c\uad6d\uc5b4": [25, 35], "nb": [25, 29], "norsk": [25, 35], "bokm\u00e5l": 25, "nl": 25, "nederland": [25, 35], "pl": [25, 58], "polski": [25, 35], "pt": 25, "portugu\u00ea": [25, 35], "brasil": 25, "ro": 25, "rom\u00e2n\u0103": [25, 35], "ru": 25, "\u0440\u0443\u0441\u0441\u043a\u0438\u0439": [25, 35], "sk": 25, "sloven\u010dina": [25, 35], "sv": 25, "svenska": [25, 35], "tr": 25, "turkish": [25, 35], "zh_cn": 25, "\u4e2d\u6587": [25, 35], "\u7b80\u4f53": [25, 35], "zh_tw": 25, "\u7e41\u9ad4": [25, 35], "y": [25, 60, 61, 67], "axi": 25, "chart": [25, 67, 92, 94, 96], "wide": 25, "toward": 25, "equidist": 25, "tick": [25, 63], "dynam": [25, 84], "wast": [25, 45], "bolus_render_ov": [25, 67, 92, 94, 96], "bolus_render_format": 25, "integ": 25, "float": 25, "hidden": [25, 36, 49, 53, 63, 74, 75], "concis": 25, "bolus_render_format_smal": 25, "frame_url_1": 25, "increment": 25, "frame_name_1": 25, "portion": 25, "janecgm": 25, "myurl": 25, "jane": 25, "frame_url_2": 25, "joecgm": 25, "frame_name_2": 25, "joe": 25, "myappnam": 25, "mainli": 25, "seen": [25, 60, 61, 67, 92, 94, 96], "touch": [25, 54], "upbat_warn": 25, "upbat_urg": 25, "timeago_enable_alert": 25, "stale": 25, "devicestatus_advanc": 25, "status": 25, "client": 25, "retrospect": 25, "hourglass": 25, "errorcodes_info": 25, "calibr": [25, 48], "errorcodes_warn": 25, "errorcodes_urg": 25, "OR": 25, "perman": [25, 48], "ar2_cone_factor": 25, "cone": 25, "loudspeak": 25, "playback": 25, "profile_histori": 25, "experiment": 25, "profile_multipl": 25, "declar": [25, 43], "mib": 25, "512mib": 25, "unabl": [25, 48], "regard": 25, "infer": 25, "max": 25, "realist": 25, "dbsize_max": 25, "properli": 25, "accord": 25, "db": [25, 32, 61], "stat": 25, "logic": 25, "self": 25, "parallel": 25, "splite": 25, "equal": 25, "beetween": 25, "fraction": 25, "wont": 25, "precis": 25, "mebibyt": 25, "1024": 25, "kib": 25, "496": 25, "maxim": 25, "dbsize_warn_percentag": 25, "dbsize_urgent_percentag": 25, "At": [25, 36, 63, 92, 95], "dbsize_enable_alert": 25, "dbsize_in_mib": 25, "transfer": 25, "unsmooth": 25, "unfilt": 25, "produc": 25, "smooth": 25, "exagger": 25, "sen": 25, "carbs_hr": 25, "carbratio": 25, "intend": 25, "sugar": 25, "secondli": 25, "benefici": 25, "glucomet": 25, "train": 25, "medicar": 25, "target_high": 25, "target_low": 25, "bwp_warn": 25, "50": [25, 72], "bwp_urgent": 25, "00": 25, "bwp_snooze_min": 25, "bwp_snooz": 25, "remind": [25, 77], "upcom": 25, "cage_info": 25, "44": 25, "cage_warn": 25, "cage_urg": 25, "persist": 25, "overdu": 25, "cage_displai": 25, "canula": 25, "greater": 25, "24h": 25, "sage_info": 25, "144": 25, "sage_warn": 25, "sage_urg": 25, "166": 25, "iage_info": 25, "iage_warn": 25, "iage_urg": 25, "bage_enable_alert": 25, "bage_displai": 25, "bage_info": 25, "312": 25, "13": 25, "bage_warn": 25, "336": 25, "bage_urg": 25, "360": 25, "treatmentnotify_snooze_min": 25, "suggest": [25, 84, 85, 86], "basal_rend": 25, "none": [25, 36], "icicl": 25, "invert": 25, "bridge_user_nam": [25, 40, 54, 63, 64, 65, 67, 92, 94, 96], "bridge_password": [25, 40, 54, 63, 64, 65, 67, 92, 94, 96], "bridge_interv": 25, "150000": 25, "millisecond": 25, "bridge_max_count": 25, "fetch": [25, 49, 53, 70, 71, 78, 84, 92, 98], "bridge_first_fetch_count": 25, "bridge_max_failur": 25, "bridge_minut": 25, "1400": 25, "bridge_serv": [25, 40, 54, 63, 64, 65, 67, 92, 94, 96], "obscure_device_proven": 25, "dont": 25, "explanatori": 25, "7xx": [25, 48, 54, 55], "mmconnect_user_nam": 25, "mmconnect_password": 25, "mmconnect_interv": 25, "60000": 25, "mmconnect_max_retry_dur": 25, "32": 25, "retri": [25, 43, 44, 92, 95], "mmconnect_sgv_limit": 25, "mmconnect_verbos": 25, "mmconnect_store_raw_data": 25, "carelink_raw": 25, "mmconnect_serv": [25, 54], "european": 25, "rileylink": 25, "slim": 25, "pump_warn_on_suspend": 25, "suspend": [25, 43], "pump_field": [25, 60], "pump_retro_field": 25, "retro": 25, "pump_warn_clock": 25, "pump_urgent_clock": 25, "pump_warn_r": 25, "pump_urgent_r": 25, "pump_warn_batt_p": 25, "pump_urgent_batt_p": 25, "pump_warn_batt_v": 25, "voltag": 25, "pump_urgent_batt_v": 25, "offlin": [25, 43], "openaps_warn": 25, "openaps_urg": 25, "openaps_field": 25, "symbol": [25, 40, 63, 64, 78, 84, 85, 86, 92, 95, 98, 99, 100], "rssi": 25, "freq": 25, "openaps_retro_field": 25, "openaps_pred_iob_color": 25, "1e88e5": 25, "rrggbb": 25, "css": 25, "openaps_pred_cob_color": 25, "fb8c00": 25, "openaps_pred_acob_color": 25, "acob": 25, "openaps_pred_zt_color": 25, "00d2d2": 25, "zt": 25, "openaps_pred_uam_color": 25, "c9bd60": 25, "uam": 25, "openaps_color_prediction_lin": 25, "purpl": 25, "loop_warn": 25, "exceed": 25, "loop_urg": 25, "loop_apns_kei": [25, 63], "push": [25, 40, 50], "apn": 25, "loop_apns_key_id": 25, "id": [25, 49, 52, 53, 54, 74, 75, 90, 92], "loop_developer_team_id": 25, "loop_push_server_environ": 25, "provis": [25, 89], "testflight": 25, "xdripjs_enable_alert": 25, "state": [25, 43, 45, 61], "fall": [25, 43, 55, 98, 100], "xdripjs_state_notify_intrvl": 25, "xdripjs_warn_bat_v": 25, "300": 25, "transmitt": 25, "synthesi": 25, "speak": 25, "cors_allow_origin": 25, "prefix": [25, 36], "_": 25, "myplugin_example_valu": 25, "1234": 25, "extendedset": 25, "examplevalu": 25, "myplugin": 25, "devicestatus_dai": 25, "roughli": 25, "bandwidth": 25, "cap": 25, "ignor": [25, 36, 38, 90, 92, 94], "pushover_alarm_kei": 25, "fallback": 25, "cwd": 25, "announc": [25, 48], "base_url": 25, "callback": 25, "localtunnel": 25, "tweet": 25, "hue": 25, "webpag": 25, "abcmyexampleabc123defjt1densiftttmak": 25, "xqb69p": 25, "maker_announcement_kei": 25, "catch": 25, "allclear": 25, "diyp": 25, "gram": 25, "mileston": 29, "2016": 29, "resourc": [29, 43, 49, 53, 63, 74, 75, 77, 81, 84, 89, 92], "archiv": [29, 50], "rebbl": 29, "apkmirror": 29, "apkpur": 29, "185084575": 29, "gm": 29, "pair": 29, "gp": 29, "posit": 29, "geminiman": 29, "fire": 29, "neither": [29, 36, 79], "wearabl": 29, "standalon": 29, "companion": 29, "pc": [29, 67], "klaus3d3": 29, "oem": 29, "usb": 29, "debug": 29, "IN": [29, 78], "ONE": 29, "apk": 29, "reboot": [29, 60, 61], "artem": 29, "seri": [29, 55], "calendar": 29, "ionic": 29, "versa": [29, 76], "phimbi": 29, "horsetooth": 29, "andrea": 29, "fredrik_": 29, "john_": 29, "floheigl": 29, "henri": 29, "haspden": 29, "question": [30, 36, 67, 77], "hopefulli": [30, 43], "thought": 30, "research": 30, "ye": [30, 41, 60, 67, 79], "10c": 30, "asap": 30, "disturb": 30, "myself": 30, "got": [30, 76], "auto": 32, "mqtt": 32, "webapp": [32, 74, 78], "cloudmqtt": 32, "port": [32, 43, 49, 53, 54, 60, 61, 67, 98, 100], "foobar": 32, "forget": [32, 40, 49, 77, 84], "mongolab": [32, 33], "ds012345": 32, "12345": 32, "databasenam": 32, "custom": [32, 42, 51, 60, 69, 78, 92], "uri": 33, "\u0639\u0631\u0628\u064a": 35, "\u65e5\u672c": 35, "leaf": 36, "insid": [36, 41, 45, 54, 67], "condit": [36, 41], "termin": [36, 60, 61, 67, 77], "until": [36, 37, 41, 43, 44, 49, 52, 53, 63, 65, 67, 78, 81, 83, 84, 85, 86, 90, 92, 94, 95, 98, 99, 100], "srv": [36, 78, 79], "heroku_0v50k8rf": 36, "ddfsjcpfu8fcoj9n6dueabfd5u": 36, "g03wh": 36, "johndo": 36, "v3ry53cr3t": 36, "a01bc": 36, "mycgmic": [36, 79], "layer": 36, "26": 36, "a1b2c3": 36, "ident": [36, 76], "dyno": [36, 48, 74, 75, 78], "didn": [36, 37, 43, 48, 49, 53, 60, 63, 67, 92, 95], "resum": [36, 61], "accur": [36, 77], "transient": 36, "restartyour": 36, "novemb": 36, "11th": 36, "brand": [36, 84], "atlasusernam": 36, "atlaspassword": 36, "zzzzz": 36, "dbname": [36, 79], "troubl": [36, 49, 53, 70, 71, 78, 84, 92, 98], "useless": [36, 43, 45], "point": [36, 43, 77, 84, 85, 86, 92, 95], "identifi": [36, 40, 43, 50, 63, 78], "mongdb": [36, 63], "notepad": [36, 79, 98, 99], "myfirstdatabas": 36, "xxxxx": [36, 78, 79], "soo5ecret": [36, 78, 79], "h": [36, 45, 63, 64, 65, 67, 78, 79, 81, 83, 84, 85, 86, 90, 92, 94, 95, 96, 98, 99], "k": [36, 63, 78, 79, 84, 85, 86, 90, 92, 96], "autogener": 36, "sandbox": [36, 77, 84], "5gb": 36, "m5": 36, "decreas": 36, "meantim": [36, 43], "ahead": [36, 40, 54, 63, 64, 65, 78, 84, 85, 86, 92, 95], "disk": 36, "null": [36, 60], "recoveri": [36, 43, 78], "reluct": 36, "lose": 36, "bin": [36, 43, 61, 63, 84, 98, 99], "80": [36, 61], "inde": [36, 78], "big": [36, 42], "720p": 36, "youtub": 36, "iipp0mfpknq": 36, "lost": [36, 43], "structur": 36, "wheel": 36, "belong": 36, "cli": [36, 41, 60], "handi": 36, "binari": 36, "export": [36, 61, 84], "mongodump": 36, "entual": 36, "cmd": 36, "64bit": 36, "cgmitc": 37, "pictur": [37, 41, 43, 45, 78], "unsuccess": 38, "confus": [38, 78], "loss": 38, "cautiou": 38, "effici": 38, "reconnect": [38, 42, 49, 52, 53], "clariti": [40, 48, 54, 63, 64, 78, 84, 85, 86, 92, 95], "symptom": 40, "children": 40, "wife": 40, "recov": [40, 42, 43, 48, 49, 53, 76, 78], "sugarm": 40, "happi": 40, "bob": 40, "ON": 40, "tap": 40, "invit": [40, 54], "mismatch": 40, "outsid": [40, 54, 63, 64, 67, 92, 94, 96], "usa": [40, 54, 63, 64, 78, 84, 85, 86, 92, 95], "sometim": 40, "autocorrect": 40, "spell": 40, "display_unit": [40, 60, 63, 64, 65, 67, 78, 84, 85, 86, 92, 94, 95, 96, 98, 99, 100], "disappear": [40, 45], "viewabl": 40, "underneath": 40, "sso": 40, "definit": [40, 43], "prolong": 40, "initi": [40, 54, 58, 63, 64, 78, 84, 85, 86, 92, 95], "incorrectli": [40, 54, 63, 64, 78, 84, 85, 86, 92, 95], "figur": [40, 54, 63, 64, 78, 84, 85, 86, 92, 95], "flyctl": [41, 49, 53], "git": [41, 49, 50, 53, 61, 67, 84, 85], "bash": [41, 43, 49, 53, 61, 67], "powershel": [41, 49, 53, 67], "elev": [41, 49, 53, 67], "auth": [41, 49, 53, 61, 67], "machin": [41, 49, 53, 61], "builder": [41, 67, 83, 84, 85], "healthi": [41, 67], "essenti": [41, 61], "ex": 41, "march": 41, "31st": 41, "stop": [41, 42, 51, 60, 61, 69, 74, 77, 78], "90": 41, "137": 41, "66": 41, "78": 41, "05": [41, 72], "26t07": 41, "51z": 41, "region": [41, 49, 53, 63, 67, 78, 81, 84, 98, 100], "AT": 41, "v4": 41, "13t14": 41, "17": 41, "58z": 41, "v6": 41, "3b09": 41, "8280": 41, "723c": 41, "00z": 41, "assign": 41, "alloc": 41, "turboku": 41, "obsolet": [41, 55, 63], "xxx": [41, 70, 71, 78, 84, 92, 98], "784e290f461048": 41, "success": [41, 61], "node": [41, 43, 61], "lib": 41, "encount": [42, 48, 51, 79], "scari": [42, 51, 69], "went": 43, "disconnect": [43, 44, 45, 49, 53, 92, 95], "proce": [43, 78], "asleep": [43, 46, 98, 100], "neg": 43, "convinc": 43, "Be": [43, 61], "awar": 43, "mongodb_uri": [43, 63, 64, 65, 67, 78, 79, 81, 83, 84, 85, 86, 89, 92, 94, 95, 96, 98, 99, 100], "session": 43, "rid": 43, "6309": 43, "memory_avail": 43, "512": 43, "node_env": [43, 60], "node_hom": 43, "oldpwd": 43, "yarn": 43, "usr": [43, 61], "node_modul": 43, "6489": 43, "ps1": 43, "033": 43, "01": 43, "34m": 43, "00m": 43, "32m": 43, "pwd": [43, 61], "shlvl": 43, "xterm": 43, "256color": 43, "web_concurr": 43, "web_memori": 43, "await": 43, "bug": 43, "minor": 43, "bad": [43, 48, 77], "feed": 43, "rollback": 43, "upon": [43, 61], "prior": 43, "upstream": [44, 49, 50, 53, 70, 71, 78, 84, 92, 98], "header": 44, "transport": 44, "delai": [44, 55, 56], "111": 44, "rollout": [44, 49, 53], "shortli": [44, 45], "jul": [45, 89, 91, 92], "3rd": [45, 89, 91, 92], "aug": [45, 89, 91, 92], "1st": [45, 89, 91, 92], "200": [45, 92], "500": 45, "gone": 45, "repo": [45, 84, 85, 90, 92, 94, 95], "memori": [45, 67], "unus": 45, "respond": 46, "fallen": 46, "uptim": [46, 74, 78], "robot": [46, 74, 78], "awak": 46, "sim": 48, "githubstatu": 48, "instatu": 48, "boot": 48, "toml": [48, 49, 53, 54, 67], "slow": 48, "timeout": [48, 81], "sn": 48, "md": 48, "antenna": 48, "nc": 48, "cd": [48, 49, 53, 61, 67], "rf": 48, "rare": 49, "occas": 49, "except": [49, 55, 58, 67], "ran": [49, 53, 70, 71, 78, 84, 92, 98], "popup": [49, 53], "interrupt": [49, 52, 53, 61, 63, 67, 78], "latest_dev": [49, 60], "whichev": [49, 60], "discard": [49, 53, 63], "directori": [49, 53, 67], "rebas": 49, "protocol": [49, 53], "tcp": [49, 53], "internal_port": [49, 53], "8080": [49, 53], "intern": [49, 53], "1337": [49, 53, 61, 67, 98, 100], "roll": [49, 50, 53], "1781944ae46438": [49, 53], "succeed": [49, 53], "downscal": [49, 53, 67], "experienc": 50, "attent": 50, "commit": [50, 70, 71, 78, 84, 92, 98, 99], "b627d31": 50, "checkout": 50, "compat": [52, 63], "matrix": 52, "habit": 52, "expand": [53, 84, 85, 86], "insecure_use_http": [54, 60], "entiti": 54, "freedn": 54, "dexcomshar": 54, "connect_share_region": 54, "tip": [54, 63, 64, 78, 84, 85, 86, 92, 95], "carelink_user_nam": 54, "carelink_password": 54, "minimedcarelink": 54, "qr": [54, 76], "scan": [54, 76], "autoconfig": 54, "my_nightscout_url": 54, "mirror": 55, "manufactur": 55, "plug": 55, "stock": 55, "useabl": 55, "categori": 55, "rebatteri": 55, "recharg": 55, "unfortun": 55, "600": 55, "otg": 55, "cabl": 55, "glucolog": 55, "aw": 55, "pipenv": 55, "bluetooth": 55, "limitt": 55, "blueread": 55, "blucon": 55, "miaomiao": 55, "bubbl": 55, "droplet": 55, "atom": 55, "evolv": 55, "proprietari": 55, "linkblucon": 55, "tomato": 55, "diabox": 55, "edroplet": 55, "relev": 55, "juggluco": 55, "libreview": 55, "esel": 55, "disaend": 55, "boli": 55, "cgv": 55, "camap": 55, "fx": 55, "pre": 56, "carri": 56, "poll": [56, 74, 78], "partner": 56, "sync": 56, "guardian": 56, "dzienia": 58, "nightscout_synology_tutori": 58, "vanelsberg": 58, "nightscoutsynologi": 58, "jason": 60, "andri": 60, "peter": 60, "traefik": 60, "justmara": 60, "ireneusz": 60, "coreo": 60, "comprehens": 60, "descript": 60, "yaml": [60, 98], "caddi": 60, "proxi": [60, 61], "sudo": [60, 61], "apt": [60, 61], "nano": [60, 61], "ca": 60, "certif": [60, 61], "curl": 60, "gnupg": 60, "lsb": 60, "mkdir": 60, "p": [60, 61, 79, 84, 85], "keyr": 60, "fssl": 60, "gpg": 60, "dearmor": 60, "o": [60, 61, 79, 84, 85, 86], "echo": 60, "deb": 60, "arch": 60, "dpkg": 60, "print": [60, 76, 78, 79], "architectur": 60, "lsb_releas": 60, "tee": 60, "ce": 60, "containerd": 60, "compos": 60, "mainus": [60, 61], "lowercas": [60, 61, 63, 64, 78, 84, 85, 86, 92, 95, 98, 99, 100], "addus": [60, 61], "hit": [60, 61, 67], "usermod": [60, 61], "startup": [60, 74, 78], "groupadd": 60, "systemctl": 60, "ctrl": [60, 61, 90, 92], "logout": 60, "yml": 60, "hub": [60, 63], "r": 60, "tz": 60, "your_timezon": 60, "your_api_secret": 60, "router": 60, "your_public_host_url": 60, "certificatesresolv": 60, "le": [60, 78], "acm": 60, "your_email": 60, "nohup": 60, "portain": 60, "ee": 60, "container_nam": 60, "sock": 60, "mydomain": 60, "entrypoint": 60, "loadbalanc": 60, "9000": 60, "8000": 60, "9443": 60, "env": [60, 61, 84], "europ": [60, 81], "moscow": 60, "time_format": [60, 67, 92, 94, 96], "boluscalc": [60, 63, 64, 65, 78, 84, 85, 86], "pushov": [60, 63, 64, 65, 78, 84, 85, 86], "rawbg": [60, 63, 64, 65, 78, 84, 85, 86], "show_forecast": 60, "depends_on": 60, "27017": [60, 61], "04": 61, "22": [61, 83, 84, 85], "shell": 61, "admin_nam": 61, "admin_password": 61, "createus": 61, "useradminanydatabas": 61, "bye": 61, "conf": 61, "authenticationdatabas": 61, "mongo_ns_db": 61, "uppercas": [61, 63, 64, 78, 84, 85, 86, 92, 95, 98, 99, 100], "mongo_ns_us": 61, "mongo_ns_password": 61, "readwrit": 61, "nodej": 61, "16": 61, "checkinstal": 61, "libssl": 61, "wget": 61, "qo": 61, "raw": [61, 63, 65, 94, 96], "githubusercont": 61, "creationix": 61, "nvm": 61, "v0": 61, "33": 61, "sh": 61, "ln": 61, "lightweight": 61, "hang": 61, "especi": 61, "helper": 61, "pm2": 61, "cat": 61, "superus": 61, "su": 61, "tailor": 61, "execut": 61, "refus": 61, "nginx": 61, "my_fullyqualifiednam": 61, "listen": 61, "server_nam": 61, "proxy_pass": 61, "127": 61, "proxy_http_vers": 61, "proxy_set_head": 61, "http_upgrad": 61, "proxy_cache_bypass": 61, "proto": 61, "firewal": 61, "ufw": 61, "ssh": 61, "kvm": 61, "openssh": 61, "certbot": 61, "python3": 61, "redirect": 61, "tos": 61, "eff": 61, "strong": 61, "diffi": 61, "hellman": 61, "src": 61, "openssl": 61, "dhparam": 61, "cert": 61, "pem": 61, "2048": 61, "renew": 61, "dry": 61, "transcript": 63, "geograph": [63, 84], "mongo_collect": [63, 65, 67, 78, 84, 92, 98], "moder": 63, "insuffici": 63, "provok": 63, "d1": 63, "quickstart": 63, "review": [63, 77], "sku": 63, "congratul": [63, 92, 98, 99, 100], "tell": 63, "sockettimeoutm": [63, 64], "bwp": [63, 64, 65, 78, 84, 85, 86], "treatmentnotifi": [63, 64, 65, 78, 84, 85, 86], "alexa": [63, 64, 65, 78, 84, 85, 86], "speech": [63, 64, 65, 78, 84, 85, 86], "keyword": [63, 64, 65, 79], "strictli": [63, 65], "ey": 63, "nmigtageambmgbyggsm49awehbhkwdwibaqqg7c8w00t5ju7n980r": [63, 84], "nern8n": [63, 84], "isnjoec": [63, 84], "ohieud0terbpmgcgyikozizj0daqehrancaarenrislsifgdn4": [63, 84], "nlbf44yikspxkr7gppbvshv3shoms2qhtdafrixxrpmbq7eajufrxpyoduu1dl9vo": [63, 84], "nouciw0j": [63, 84], "insert": 63, "prove": 67, "tweak": 67, "closest": 67, "1x": 67, "256mb": 67, "compil": [67, 92, 94, 96], "custom_titl": [67, 92, 94, 96], "theme": [67, 81, 84, 92, 94, 96], "show_plugin": [67, 92, 94, 96], "night_mod": [67, 92, 94, 96], "alarm_typ": [67, 92, 94, 96], "forecast": [67, 92, 94, 96], "alarm_urgent_high": [67, 92, 94, 96], "bg_high": [67, 92, 94, 96], "alarm_urgent_low": [67, 92, 94, 96], "bg_low": [67, 92, 94, 96], "alarm_high": [67, 92, 94, 96], "bg_target_top": [67, 92, 94, 96], "alarm_low": [67, 92, 94, 96], "bg_target_bottom": [67, 92, 94, 96], "alarm_timeago_urg": [67, 92, 94, 96], "alarm_timeago_urgent_min": [67, 92, 94, 96], "alarm_timeago_warn": [67, 92, 94, 96], "alarm_timeago_warn_min": [67, 92, 94, 96], "myflynightscout": 67, "clickabl": 67, "yourappnam": 67, "scale_i": 67, "unhealthi": 67, "pass": 67, "stage": 67, "behind": [70, 71, 78, 84, 92, 98], "10gb": 72, "outgo": 72, "traffic": 72, "kept": 72, "china": 72, "billabl": [74, 75], "1000": 74, "doubt": [74, 75], "trick": [74, 78], "aliv": [74, 78], "wors": [74, 78], "relic": [74, 78], "2fa": 76, "serious": [76, 77], "fingerprint": 76, "reader": 76, "passcod": 76, "phrase": 76, "perfect": 76, "biometr": 76, "identif": 76, "wish": [76, 78, 81], "vice": 76, "hardwar": 76, "reviv": 77, "univers": 77, "budget": 77, "everybodi": 77, "pretend": 77, "whoever": 77, "gratitud": 77, "bell": 77, "whistl": 77, "enjoi": 77, "unlimit": 77, "scare": 77, "innov": 77, "believ": 77, "hurrah": 77, "ah": 77, "thank": 77, "scott": 77, "shame": 77, "weak": 77, "er": 77, "versu": 77, "discov": 77, "suffer": 77, "safer": 77, "afraid": 77, "ugli": 77, "sponsor": 77, "spici": 77, "steam": 77, "ci95": 77, "l9xw": 77, "eas": 77, "harder": 78, "insist": 78, "hanc": 78, "signup": 78, "AND": 78, "TO": 78, "se": 78, "sei": 78, "resident": 78, "italia": 78, "abilita": 78, "interruttor": 78, "domicil": 78, "itali": 78, "leggi": 78, "accetta": 78, "condizioni": 78, "supplementari": 78, "june": 78, "14th": 78, "THERE": 78, "mydbhost": 78, "mydatabas": 78, "papertrail_api_token": 78, "tini": 78, "actuat": 78, "discrep": 79, "driver": 79, "mycgmitc": 79, "asid": 79, "sai": 79, "mo": [81, 84], "dbaa": 81, "addon": 81, "mongo_srv": 81, "smallest": [83, 84], "nf": [83, 84, 85, 86], "TOS": 84, "polici": 84, "random": [84, 85, 86], "attach": 84, "buid": [84, 85], "buildpack": [84, 85], "shorter": 84, "000231": 89, "gb": 89, "developp": 89, "unverifi": 89, "refund": [89, 92], "bank": [89, 92], "mongo_url": 89, "simultan": [90, 92], "redo": [90, 92], "starter": 92, "referr": [92, 95], "afterward": [92, 95], "came": [92, 95], "upercas": [92, 95], "j1": [92, 95], "j2": [92, 95], "j3": [92, 95], "FOR": 98, "closer": [98, 100], "blueprint": [98, 99], "txt": [98, 99]}, "objects": {}, "objtypes": {}, "objnames": {}, "titleterms": {"nightscout": [1, 2, 4, 6, 9, 12, 13, 14, 15, 17, 20, 22, 23, 24, 25, 29, 30, 34, 42, 48, 50, 51, 53, 54, 58, 60, 61, 63, 67, 68, 69, 70, 72, 74, 77, 78, 84, 85, 86, 92, 98, 100], "clinician": 1, "what": [1, 4, 6, 8, 17, 18, 54, 63, 67, 72, 74, 75, 78, 79, 81, 84, 89, 92, 98], "i": [1, 4, 24, 25, 34, 40, 43, 48, 54, 78, 81, 89], "how": [1, 4, 24, 49], "can": [1, 4, 43], "access": [1, 24, 42, 61, 76], "patient": 1, "data": [1, 9, 36, 48], "cannot": [1, 42, 43], "url": [1, 54], "read": [1, 36], "onli": [1, 24, 36], "should": 1, "see": [1, 24, 79], "when": 1, "open": [1, 44, 61], "site": [1, 4, 9, 15, 16, 22, 24, 43, 44, 78, 84, 85, 86, 92], "next": [1, 3], "step": [1, 3, 15, 49, 53, 60, 61, 63, 67, 78, 84, 85, 86, 92, 98, 99, 100], "report": [2, 23, 36, 48], "view": [2, 3, 9, 21, 25, 63], "profil": [2, 9, 21, 23, 25], "select": 2, "setup": [2, 3, 12, 13, 21, 54, 63, 67, 78, 84, 92, 98], "dai": [2, 23, 55], "To": [2, 23], "week": [2, 23], "daili": [2, 23], "stat": [2, 23], "distribut": [2, 23], "percentil": [2, 23], "chart": [2, 23], "hourli": [2, 23], "weekli": [2, 23], "main": 3, "custom": [3, 9, 25, 67, 94, 96], "your": [3, 4, 6, 8, 9, 15, 18, 21, 22, 25, 29, 34, 36, 40, 41, 42, 43, 45, 49, 51, 53, 58, 60, 61, 63, 67, 70, 74, 78, 81, 84, 85, 86, 89, 92, 93, 100], "identifi": 3, "displai": [3, 12], "item": [3, 5, 43], "welcom": [4, 30], "introduct": 4, "upload": [4, 25, 54, 55], "follow": [4, 12, 29, 56], "develop": [4, 24], "histori": 4, "ar": 4, "valu": [4, 25, 48, 63], "do": 4, "need": 4, "import": [4, 12, 25, 29, 81, 89], "safeti": 4, "much": 4, "doe": 4, "It": 4, "cost": [4, 81], "build": [4, 6, 17, 44, 60, 61], "own": [4, 41, 42, 51], "dii": [4, 6, 17, 54, 55], "servic": [4, 46, 48, 100], "t1pal": [4, 77], "ns10be": [4, 77], "pro": [4, 29, 77], "serendip": 4, "bio": 4, "nightscout4u": 4, "who": 4, "help": [4, 30], "me": [4, 30], "technic": 4, "support": [4, 16, 55], "facebook": 4, "privaci": [4, 9, 13, 24, 63, 67, 78, 84, 92, 98], "us": [4, 10, 24, 25, 43, 56, 74, 78], "These": 4, "doc": 4, "admin": 5, "tool": [5, 36], "subject": 5, "role": [5, 24, 27], "chang": [5, 9, 24, 27, 36, 40, 84, 92], "api_secret": [5, 24, 25, 27], "creat": [5, 14, 15, 23, 24, 27, 42, 61, 63, 67, 78, 79, 81, 84, 89, 92, 98, 100], "token": [5, 24, 27], "databas": [5, 8, 21, 25, 30, 36, 45, 61, 63, 67, 78, 79, 81, 84, 85, 86, 89, 92, 98], "mainten": [5, 43], "mongo": [5, 36], "statu": [5, 25], "treatment": [5, 9, 23, 25], "entri": 5, "remov": [5, 76], "futur": [5, 36, 48], "from": [5, 41, 74, 78, 84, 92, 95], "advanc": [6, 25], "deploy": 6, "too": [6, 8, 17, 18, 63, 67, 72, 74, 75, 78, 79, 81, 84, 89, 92, 98], "complic": [6, 8, 17, 18, 63, 67, 72, 74, 75, 78, 79, 81, 84, 89, 92, 98], "Not": [6, 8, 17, 18, 36, 63, 67, 72, 74, 75, 78, 79, 81, 84, 89, 92, 98], "you": [6, 8, 14, 17, 18, 41, 42, 61, 63, 67, 68, 72, 74, 75, 78, 79, 81, 84, 89, 92, 98], "re": [6, 8, 17, 18, 61, 63, 67, 72, 74, 75, 78, 79, 81, 84, 89, 92, 98], "look": [6, 8, 17, 18, 63, 67, 72, 74, 75, 78, 79, 81, 84, 89, 92, 98], "cloud": [6, 17, 72, 77], "platform": [6, 17, 18], "virtual": 6, "server": 6, "insid": 6, "na": [6, 58], "raspberri": 6, "pi": 6, "4": [6, 15, 29, 61, 85, 86, 99, 100], "home": [6, 25], "assist": 6, "add": [6, 9, 22, 63, 99], "On": 6, "close": [7, 54, 55], "loop": [7, 12, 25, 29, 54, 55], "system": [7, 55, 60, 61], "aap": [7, 20], "iap": 7, "openap": [7, 25], "choos": [8, 18, 30], "discov": 9, "authent": [9, 24, 25, 40, 76, 78], "yourself": 9, "careport": [9, 25], "bg": [9, 25, 48], "check": 9, "correct": 9, "bolu": [9, 25], "meal": 9, "carb": [9, 25], "snack": 9, "combo": 9, "announc": 9, "note": [9, 22], "question": 9, "exercis": 9, "pump": [9, 25], "cage": [9, 25], "cgm": [9, 14, 25, 29, 42, 43, 51, 68, 78, 84, 92, 98], "sensor": [9, 25], "start": 9, "sage": [9, 25], "insert": 9, "stop": [9, 43, 48, 79], "batteri": [9, 25], "bage": [9, 25], "insulin": [9, 25], "cartridg": 9, "iag": [9, 25], "temp": 9, "basal": [9, 25, 48], "switch": 9, "d": 9, "A": [9, 43], "alert": [9, 22], "edit": [9, 63, 67, 78, 84, 92, 98], "mode": [9, 25, 36, 43], "drawer": 9, "menu": [9, 12], "simpl": [9, 25], "set": [9, 25, 67, 84, 92], "unit": [9, 25], "display_unit": [9, 25], "date": 9, "format": [9, 61], "time_format": [9, 25], "languag": [9, 25], "scale": 9, "scale_i": [9, 25], "render": [9, 46, 98, 99], "basal_rend": 9, "amount": 9, "bolus_rend": [9, 25], "alarm": [9, 22, 25, 67, 94, 96], "show": [9, 48], "raw": [9, 25, 92], "rawbg": [9, 25], "titl": 9, "custom_titl": [9, 25], "theme": [9, 25], "plugin": [9, 25], "show_plugin": [9, 25], "api": [9, 15, 24], "dynam": 10, "dn": 10, "No": [10, 43, 48], "ip": [10, 41], "dynu": 10, "freedn": 10, "download": 12, "smartwatch": [12, 29], "android": [12, 15, 29], "xdrip": [12, 25, 29, 54, 56], "androidap": [12, 29], "nsclient": 12, "nightwatch": 12, "googl": [12, 22, 25, 35, 72, 77], "plai": 12, "store": 12, "legaci": 12, "glimp": [12, 29, 54], "diabox": [12, 54], "io": [12, 41, 48, 67, 77], "x": 12, "nightguard": [12, 29], "spike": [12, 54], "xdrip4io": [12, 54], "sugarm": [12, 29], "limit": [12, 29, 36, 63], "diabet": 12, "cockpit": 12, "gluco": [12, 29], "tracker": [12, 29], "nightscoutmenubar": 12, "bitbar": 12, "mac": 12, "maco": 12, "bar": 12, "window": 12, "floatingglucos": 12, "archiv": 12, "owlet": 12, "ns2win": 12, "m5stack": 12, "nightscoutmon": 12, "m5stick": 12, "bgbuddi": 12, "sugarpidisplai": 12, "other": [12, 25, 48], "new": [13, 17, 30, 61, 63, 67, 78, 84, 92, 98], "warn": [13, 24, 63, 67, 78, 84, 92, 98], "github": [14, 16, 38, 42, 43, 45, 48, 49, 50, 51, 53, 68, 70, 78, 84, 92, 98], "account": [14, 40, 42, 63, 67, 78, 81, 84, 89, 92, 98], "fork": [14, 42, 51, 68, 70, 78, 84, 92, 98], "project": [14, 42, 45, 51, 67, 68, 78, 84, 98], "If": [14, 41, 42, 68, 78, 79, 84, 98], "alreadi": [14, 42, 68, 78, 84, 98], "have": [14, 42, 68, 78, 84, 98], "remot": [14, 16, 22, 42, 43, 51, 68, 78, 84, 92, 98], "monitor": [14, 25, 29, 42, 43, 51, 68, 78, 84, 92, 98], "ifttt": [15, 22, 25], "integr": 15, "1": [15, 43, 49, 53, 55, 60, 61, 63, 67, 78, 84, 92, 98], "get": [15, 22, 78], "secret": [15, 67], "hash": 15, "2": [15, 29, 34, 43, 49, 53, 55, 60, 61, 63, 67, 78, 84, 92, 98], "applet": [15, 22], "3": [15, 29, 55, 60, 61, 63, 67, 78, 84, 92, 98], "enabl": [15, 16, 22, 25, 74, 78], "instal": [15, 36, 60, 61, 67], "app": [15, 29, 37, 41, 43, 45, 56, 63, 74, 76, 78], "iphon": 15, "extra": 15, "credit": 15, "alexa": [15, 25], "multipl": [16, 60, 78], "secur": [16, 17, 24, 61, 76], "automat": 16, "deploi": [16, 41, 49, 50, 53, 60, 67, 78, 84, 92, 98, 99], "heroku": [16, 38, 41, 43, 48, 52, 74, 75, 76, 77, 78, 84, 92, 95], "railwai": [16, 38, 45, 48, 77, 89, 92], "northflank": [16, 44, 77, 81, 84], "invit": 16, "someon": 16, "collabor": 16, "Being": 16, "atla": [16, 36, 38, 48, 77, 79], "anoth": [16, 49], "user": [16, 17, 20, 24, 30], "teammat": 16, "confus": [17, 77], "basic": [17, 75], "concept": 17, "vendor": 17, "comparison": 17, "tabl": 17, "free": [17, 36, 41], "paid": 17, "safekeep": [17, 24], "connect": [20, 25, 36, 39], "prerequisit": 20, "dexcomshar": 20, "minimedcarelink": 20, "modifi": [21, 63], "record": 21, "notif": [22, 25], "prep": 22, "drive": 22, "folder": 22, "make": [22, 61], "1st": 22, "log": [22, 25, 43], "n": [22, 29], "webhook": 22, "2nd": 22, "send": 22, "pushov": [22, 25], "revisit": 22, "level": 22, "final": 22, "calibr": 23, "loopalyz": 23, "power": 23, "bi": 23, "person": 24, "http": 24, "certif": 24, "error": [24, 25, 37, 40, 43, 48, 54, 63, 64, 78, 84, 85, 86, 92, 95], "administr": 24, "messag": 24, "m": 24, "about": 24, "being": 24, "weak": 24, "failur": 24, "readabl": 24, "world": 24, "renam": [24, 78], "turn": 24, "off": [24, 25], "unauthor": 24, "author": 24, "configur": [25, 40, 60, 61, 63], "config": [25, 63, 67, 78], "var": [25, 63, 67, 78], "requir": 25, "variabl": [25, 43, 61, 63, 67, 84, 92, 94, 96, 98], "mongodb_uri": [25, 36], "string": [25, 36, 39], "password": [25, 36, 40, 54, 63, 64, 76, 78, 84, 85, 86, 92, 95], "thi": [25, 67, 78, 79, 81, 89], "an": [25, 40, 41, 43, 50, 63, 79, 81, 89], "featur": 25, "disabl": 25, "auth_default_rol": 25, "alarm_typ": 25, "type": 25, "threshold": 25, "bg_high": 25, "bg_low": 25, "bg_target_bottom": 25, "bg_target_top": 25, "alarm_": 25, "alarm_urgent_": 25, "alarm_urgent_high": 25, "alarm_high": 25, "alarm_low": 25, "alarm_urgent_low": 25, "default": 25, "alarm_urgent_high_min": 25, "alarm_high_min": 25, "alarm_low_min": 25, "alarm_urgent_low_min": 25, "alarm_urgent_min": 25, "alarm_warn_min": 25, "timeago": 25, "alarm_timeago_urg": 25, "alarm_timeago_urgent_min": 25, "alarm_timeago_warn": 25, "alarm_timeago_warn_min": 25, "predefin": 25, "browser": 25, "12": 25, "night_mod": 25, "show_rawbg": 25, "never": 25, "color": 25, "show_forecast": 25, "ar2": 25, "en": 25, "edit_mod": 25, "split": 25, "delta": 25, "direct": 25, "upbat": 25, "time": [25, 48, 76], "ago": 25, "devicestatu": 25, "devic": 25, "errorcod": 25, "code": [25, 48, 76], "forecast": 25, "simplealarm": 25, "dbsize": 25, "size": [25, 36], "boluscalc": 25, "wizard": [25, 30], "food": 25, "iob": [25, 48], "board": 25, "cob": [25, 48], "bwp": 25, "preview": 25, "ag": 25, "pill": 25, "cannula": 25, "treatmentnotifi": 25, "bridg": [25, 85, 86], "share2nightscout": 25, "mmconnect": 25, "minim": 25, "overrid": 25, "xdripj": 25, "j": 25, "amazon": 25, "googlehom": 25, "dialogflow": 25, "speech": 25, "cor": 25, "extend": 25, "maker": 25, "watch": 29, "pebbl": 29, "urchin": 29, "wear": 29, "o": 29, "nightwear": 29, "amazfit": 29, "pace": 29, "strato": 29, "xiaomi": 29, "miband": 29, "5": [29, 61, 67, 74, 75, 99], "6": [29, 67, 99], "band": 29, "bip": 29, "lite": 29, "": [29, 43], "t": [29, 43, 44, 55, 78, 98], "rex": 29, "gtr2": 29, "gtr2e": 29, "gts2": 29, "gt": 29, "mini": 29, "gts2e": 29, "gtr42": 29, "47": 29, "appl": 29, "fitbit": 29, "glanc": 29, "sentinel": 29, "marclock": 29, "analog": 29, "watchfac": 29, "orbit": 29, "radial": 29, "samsung": 29, "gear": 29, "tasker": 29, "g": 29, "garmin": 29, "comput": [29, 41, 84, 92], "karoo": 29, "u": 30, "host": 30, "provid": 30, "vp": 30, "updat": [34, 42, 49, 52, 53, 60, 61, 70, 93], "The": 34, "latest": 34, "releas": [34, 49, 50], "15": 34, "0": [34, 63, 67, 78, 84, 92, 98], "translat": 35, "link": [35, 93], "troubleshoot": [36, 37, 40, 41, 42, 43, 44, 45, 46, 48], "mongodb": [36, 61, 77, 79], "one": 36, "cluster": 36, "meet": 36, "unabl": 36, "paus": 36, "miss": [36, 48], "gener": [36, 76], "bad": 36, "mongo_connect": 36, "recov": [36, 41], "full": 36, "restart": [36, 37, 41, 43, 44, 45, 46], "normal": 36, "cleanup": [36, 38, 41, 43, 45], "emerg": 36, "verif": 36, "slow": 36, "load": 36, "timeout": 36, "backup": [36, 43], "oper": 36, "dump": 36, "azur": [37, 63, 77], "403": 37, "bill": 37, "occur": 37, "dexcom": [40, 48, 54, 55, 67, 85, 86, 94, 96], "share": [40, 41, 67, 94, 96], "usernam": 40, "email": 40, "phone": 40, "number": 40, "obtain": [40, 41], "lock": 40, "verifi": 40, "fly": [41, 48, 67, 77], "toml": 41, "delet": [41, 42, 43, 51, 63, 69, 99], "local": 41, "repositori": [41, 49, 53], "web": [41, 63, 92], "termin": 41, "downscal": 41, "migrat": [41, 63, 77, 78, 84, 92, 95, 98], "lost": 42, "There": 43, "noth": [43, 45], "here": [43, 45], "applic": [43, 48], "valid": 43, "directori": [43, 61], "could": 43, "found": 43, "find": 43, "sourc": 43, "visibl": 43, "retriev": 43, "all": [43, 84], "dyno": 43, "sleep": 43, "method": [43, 92], "spreadsheet": 43, "export": 43, "roll": 43, "back": 43, "doesn": [44, 78, 98], "after": [44, 48], "reconnect": 45, "empti": 45, "befor": 48, "overal": 48, "third": 48, "parti": 48, "crash": 48, "issu": 48, "carelink": [48, 54, 56], "while": 48, "uptim": 48, "robot": 48, "shift": 48, "dst": 48, "instead": 48, "version": 49, "return": 49, "master": 49, "downgrad": [50, 60], "old": 50, "docker": [50, 60, 63], "redeploi": 51, "stack": 52, "my": 54, "most": [54, 63, 64, 78, 84, 85, 86, 92, 95], "common": [54, 63, 64, 78, 84, 85, 86, 92, 95], "medtron": [54, 55], "600": 54, "seri": 54, "mind": 54, "syntax": 54, "juggluco": 54, "linkblucon": 54, "tomato": 54, "g5": 55, "g6": 55, "ONE": 55, "g7": 55, "firefli": 55, "transmitt": 55, "glucomen": 55, "tandem": 55, "slim": 55, "x2": 55, "abbott": 55, "freestyl": 55, "libr": 55, "compat": 55, "eversens": 55, "diasend": 55, "companion": 56, "synologi": 58, "singl": 60, "instanc": 60, "run": 60, "ubuntu": 61, "sure": 61, "manag": 61, "startup": 61, "cpu": 63, "usag": 63, "save": [63, 67], "modif": 63, "flyctl": 67, "prepar": 67, "mandatori": [67, 94, 96], "instruct": 72, "eco": [74, 75], "plan": [74, 75], "month": [74, 75], "prevent": [74, 78], "fall": [74, 78], "asleep": [74, 78], "caution": [74, 78], "upgrad": 75, "7": 75, "mfa": 76, "lose": 76, "salesforc": 76, "built": 76, "In": 76, "One": 76, "kei": 76, "recoveri": 76, "tanstaafl": 77, "oracl": 77, "first": [78, 99], "attempt": 78, "includ": [78, 98], "factor": 78, "core": 78, "word": 78, "papertrail": 78, "ever": 79, "just": 79, "credenti": 79, "inform": [81, 89], "up": [84, 92], "name": [84, 92], "copi": 84, "attach": [85, 86], "recommend": [92, 94, 95], "interfac": 92, "editor": 92, "br": 95, "yaml": 99, "templat": 99, "branch": 99}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 8, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx": 57}, "alltitles": {"Nightscout for clinicians": [[1, "nightscout-for-clinicians"]], "What is Nightscout?": [[1, "what-is-nightscout"]], "How can I access patient data?": [[1, "how-can-i-access-patient-data"]], "Cannot access patient URL": [[1, null]], "Read only access": [[1, null]], "What should I see when I open a Nightscout site?": [[1, "what-should-i-see-when-i-open-a-nightscout-site"]], "Next steps:": [[1, "next-steps"]], "Nightscout reports": [[2, "nightscout-reports"]], "View profiles": [[2, "view-profiles"]], "Select a report": [[2, "select-a-report"]], "Setup the report": [[2, "setup-the-report"]], "Day To day": [[2, "day-to-day"], [23, "day-to-day"]], "Week to Week": [[2, "week-to-week"], [23, "week-to-week"]], "Daily stats": [[2, "daily-stats"], [23, "daily-stats"]], "Distribution": [[2, "distribution"], [23, "distribution"]], "Percentile Chart": [[2, "percentile-chart"], [23, "percentile-chart"]], "Hourly stats": [[2, "hourly-stats"], [23, "hourly-stats"]], "Weekly Distribution": [[2, "weekly-distribution"], [23, "weekly-distribution"]], "Setup the main view": [[3, "setup-the-main-view"]], "Customize your view": [[3, "customize-your-view"]], "Identify displayed items": [[3, "identify-displayed-items"]], "Next step:": [[3, "next-step"]], "Welcome to Nightscout": [[4, "welcome-to-nightscout"]], "Introduction": [[4, "introduction"]], "Nightscout Site": [[4, "nightscout-site"]], "Uploader": [[4, "uploader"]], "Followers": [[4, "followers"]], "Development History": [[4, "development-history"]], "What are the values of Nightscout": [[4, "what-are-the-values-of-nightscout"]], "What Do I Need?": [[4, "what-do-i-need"]], "IMPORTANT": [[4, null], [25, null]], "SAFETY": [[4, null]], "How Much Does It Cost?": [[4, "how-much-does-it-cost"]], "Build your own Nightscout DIY site": [[4, "build-your-own-nightscout-diy-site"]], "Nightscout as a Service": [[4, "nightscout-as-a-service"]], "T1Pal": [[4, "t1pal"], [77, "t1pal"]], "NS10BE": [[4, "ns10be"], [77, "ns10be"]], "Nightscout Pro": [[4, "nightscout-pro"]], "Serendipity Bio": [[4, "serendipity-bio"]], "Nightscout4u": [[4, "nightscout4u"]], "Who Can Help Me?": [[4, "who-can-help-me"]], "Technical Support": [[4, null]], "Facebook Privacy": [[4, null]], "How to Use These Docs": [[4, "how-to-use-these-docs"]], "How Can I Help?": [[4, "how-can-i-help"]], "Admin Tools": [[5, "admin-tools"]], "Subjects and Roles": [[5, "subjects-and-roles"]], "Changing API_SECRET": [[5, null], [24, null], [27, null]], "Roles": [[5, "roles"], [24, "roles"], [27, "roles"]], "Create a Token": [[5, "create-a-token"], [24, "create-a-token"], [27, "create-a-token"]], "Database Maintenance": [[5, "database-maintenance"]], "Mongo status Database": [[5, "mongo-status-database"]], "Mongo treatments Database": [[5, "mongo-treatments-database"]], "Mongo entries Database": [[5, "mongo-entries-database"]], "Remove future items from Database": [[5, "remove-future-items-from-database"]], "Advanced Nightscout deployments": [[6, "advanced-nightscout-deployments"]], "Too complicated? Not what you\u2019re looking for?": [[6, null], [8, null], [17, null], [18, null], [63, null], [67, null], [72, null], [74, null], [75, null], [78, null], [79, null], [81, null], [84, null], [89, null], [92, null], [98, null]], "Building Nightscout DIY in a cloud platform": [[6, "building-nightscout-diy-in-a-cloud-platform"], [17, "building-nightscout-diy-in-a-cloud-platform"]], "Building Nightscout DIY in a virtual server": [[6, "building-nightscout-diy-in-a-virtual-server"]], "Building Nightscout inside your NAS": [[6, "building-nightscout-inside-your-nas"]], "Building Nightscout with a Raspberry PI 4": [[6, "building-nightscout-with-a-raspberry-pi-4"]], "Home Assistant Add-On for Nightscout": [[6, "home-assistant-add-on-for-nightscout"]], "Closed loop systems": [[7, "closed-loop-systems"]], "Loop": [[7, "loop"]], "AAPS": [[7, "aaps"]], "iAPS": [[7, "iaps"]], "OpenAPS": [[7, "openaps"]], "Choose your database": [[8, "choose-your-database"]], "Discover your Nightscout site": [[9, "discover-your-nightscout-site"]], "Privacy": [[9, null]], "Authenticate yourself": [[9, "authenticate-yourself"]], "Add a treatment (careportal)": [[9, "add-a-treatment-careportal"]], "BG Check": [[9, "bg-check"]], "Correction Bolus": [[9, "correction-bolus"]], "Meal Bolus": [[9, "meal-bolus"]], "Carb Correction": [[9, "carb-correction"]], "Snack Bolus": [[9, "snack-bolus"]], "Combo Bolus": [[9, "combo-bolus"]], "Announcement": [[9, "announcement"]], "Note": [[9, "note"]], "Question": [[9, "question"]], "Exercise": [[9, "exercise"]], "Pump Site Change cage": [[9, "pump-site-change-cage"]], "CGM Sensor Start sage": [[9, "cgm-sensor-start-sage"]], "CGM Sensor Insert": [[9, "cgm-sensor-insert"]], "CGM Sensor Stop": [[9, "cgm-sensor-stop"]], "Pump Battery Change bage": [[9, "pump-battery-change-bage"]], "Insulin Cartridge Change iage": [[9, "insulin-cartridge-change-iage"]], "Temp Basal Start": [[9, "temp-basal-start"]], "Temp Basal Stop": [[9, "temp-basal-stop"]], "Profile Switch": [[9, "profile-switch"]], "D.A.D. Alert": [[9, "d-a-d-alert"]], "Edit Mode (edit)": [[9, "edit-mode-edit"]], "Drawer Menu": [[9, "drawer-menu"]], "Simple views:": [[9, "simple-views"]], "Settings:": [[9, "settings"]], "Units DISPLAY_UNITS": [[9, "units-display-units"]], "Date Format TIME_FORMAT": [[9, "date-format-time-format"]], "Language LANGUAGE": [[9, "language-language"]], "Scale SCALE_Y": [[9, "scale-scale-y"]], "Render Basal BASAL_RENDER": [[9, "render-basal-basal-render"]], "Render Bolus Amount BOLUS_RENDER": [[9, "render-bolus-amount-bolus-render"]], "Alarms ALARM": [[9, "alarms-alarm"]], "Edit Mode EDIT": [[9, "id1"]], "Show Raw BG Data rawbg": [[9, "show-raw-bg-data-rawbg"]], "Custom Title CUSTOM_TITLE": [[9, "custom-title-custom-title"]], "Theme THEME": [[9, "theme-theme"]], "Show Plugins SHOW_PLUGINS": [[9, "show-plugins-show-plugins"]], "API": [[9, "api"]], "Use a Dynamic DNS": [[10, "use-a-dynamic-dns"]], "No-IP": [[10, "no-ip"]], "Dynu": [[10, "dynu"]], "FreeDNS": [[10, "freedns"]], "Setup Downloaders - Followers": [[12, "setup-downloaders-followers"]], "Smartwatches": [[12, null]], "Android": [[12, "android"]], "xDrip+": [[12, "xdrip"], [29, "xdrip"], [29, "id1"], [29, "id2"], [29, "id3"], [54, "xdrip"]], "AndroidAPS NSClient": [[12, "androidaps-nsclient"]], "Nightwatch (Google Play Store)": [[12, "nightwatch-google-play-store"]], "Nightwatch (legacy)": [[12, "nightwatch-legacy"]], "Glimp": [[12, "glimp"], [29, "glimp"], [54, "glimp"]], "Diabox": [[12, "diabox"], [54, "diabox"]], "iOS": [[12, "ios"]], "Nightscout X": [[12, "nightscout-x"]], "Nightguard": [[12, "nightguard"], [29, "nightguard"]], "Nightscouter": [[12, "nightscouter"]], "Loop Follow": [[12, "loop-follow"], [29, "loop-follow"]], "Spike": [[12, "spike"], [54, "spike"]], "xDrip4iOS": [[12, "xdrip4ios"], [54, "xdrip4ios"]], "sugarmate": [[12, "sugarmate"], [29, "sugarmate"]], "Important limitation": [[12, null], [29, null]], "Diabetes Cockpit": [[12, "diabetes-cockpit"]], "Gluco-Tracker": [[12, "gluco-tracker"], [29, "gluco-tracker"]], "NightscoutMenuBar": [[12, "nightscoutmenubar"]], "BitBar Nightscout": [[12, "bitbar-nightscout"]], "Mac": [[12, "mac"]], "Nightscout MacOS Menu Bar": [[12, "nightscout-macos-menu-bar"]], "Windows": [[12, "windows"]], "FloatingGlucose (archived)": [[12, "floatingglucose-archived"]], "Owlet": [[12, "owlet"]], "NS2Win": [[12, "ns2win"]], "Displays": [[12, "displays"]], "M5Stack NightscoutMon": [[12, "m5stack-nightscoutmon"]], "M5Stick NightscoutMon": [[12, "m5stick-nightscoutmon"]], "BGBuddy": [[12, "bgbuddy"]], "SugarPiDisplay": [[12, "sugarpidisplay"]], "Other": [[12, "other"]], "New Nightscout Setup": [[13, "new-nightscout-setup"], [63, "new-nightscout-setup"], [67, "new-nightscout-setup"], [78, "new-nightscout-setup"], [84, "new-nightscout-setup"], [92, "new-nightscout-setup"], [98, "new-nightscout-setup"]], "Privacy warning": [[13, null], [24, null], [63, null], [67, null], [78, null], [84, null], [92, null], [98, null]], "GitHub": [[14, "github"], [38, "github"], [48, "github"], [50, "github"]], "Create a GitHub account": [[14, "create-a-github-account"], [42, "create-a-github-account"]], "Fork the Nightscout project": [[14, "fork-the-nightscout-project"], [42, "fork-the-nightscout-project"], [42, "id1"], [51, "fork-the-nightscout-project"], [68, "fork-the-nightscout-project"]], "If you already have a fork of cgm-remote-monitor in GitHub": [[14, null], [42, null], [68, null], [78, null], [84, null], [98, null]], "IFTTT Integration": [[15, "ifttt-integration"]], "Step 1: Get your API Secret Hash": [[15, "step-1-get-your-api-secret-hash"]], "Step 2: Create your \u201cApplets\u201d": [[15, "step-2-create-your-applets"]], "Step 3: Enable IFTTT in your Nightscout site": [[15, "step-3-enable-ifttt-in-your-nightscout-site"]], "Step 4: Install IFTTT app on your iPhone/Android": [[15, "step-4-install-ifttt-app-on-your-iphone-android"]], "Extra Credit: Alexa integration": [[15, "extra-credit-alexa-integration"]], "Multiple sites and support": [[16, "multiple-sites-and-support"]], "Remote support and security": [[16, "remote-support-and-security"]], "Github": [[16, "github"]], "Enable automatic deploys in Heroku": [[16, "enable-automatic-deploys-in-heroku"]], "Automatic deploys in Railway and Northflank": [[16, "automatic-deploys-in-railway-and-northflank"]], "Heroku": [[16, "heroku"], [38, "heroku"], [48, "heroku"], [77, "heroku"]], "Invite someone as a collaborator": [[16, "invite-someone-as-a-collaborator"]], "Being a collaborator": [[16, "being-a-collaborator"]], "Atlas": [[16, "atlas"], [38, "atlas"], [48, "atlas"]], "Invite another user": [[16, "invite-another-user"]], "Being invited": [[16, "being-invited"], [16, "id1"], [16, "id2"]], "Northflank": [[16, "northflank"], [77, "northflank"]], "Invite a teammate": [[16, "invite-a-teammate"]], "Railway": [[16, "railway"], [38, "railway"], [48, "railway"], [77, "railway"]], "New Nightscout Users": [[17, "new-nightscout-users"]], "Confusing?": [[17, null], [77, null]], "Basic concepts": [[17, "basic-concepts"]], "Vendors comparison table": [[17, "vendors-comparison-table"]], "Free DIY": [[17, "free-diy"]], "Paid DIY": [[17, "paid-diy"]], "Security and safekeeping": [[17, "security-and-safekeeping"], [24, "security-and-safekeeping"]], "Choose your platform": [[18, "choose-your-platform"]], "Nightscout-connect": [[20, "nightscout-connect"]], "Prerequisites": [[20, "prerequisites"]], "AAPS users": [[20, null]], "dexcomshare": [[20, "dexcomshare"]], "minimedcarelink": [[20, "minimedcarelink"]], "Setup your Profile": [[21, "setup-your-profile"]], "Profile view": [[21, "profile-view"]], "Modifying a profile and Database records": [[21, "modifying-a-profile-and-database-records"]], "Remote notifications": [[22, "remote-notifications"]], "Get Prepped": [[22, "get-prepped"]], "Add a Google Drive folder": [[22, "add-a-google-drive-folder"]], "Make 1st IFTTT Applet to Log NS Alarms": [[22, "make-1st-ifttt-applet-to-log-ns-alarms"]], "Enable IFTTT Webhooks in your Nightscout site": [[22, "enable-ifttt-webhooks-in-your-nightscout-site"]], "Make 2nd IFTTT Applet to send Pushover notifications": [[22, "make-2nd-ifttt-applet-to-send-pushover-notifications"]], "Revisit Nightscout Alert Levels": [[22, "revisit-nightscout-alert-levels"]], "Final notes": [[22, "final-notes"]], "Create Reports": [[23, "create-reports"]], "Calibrations": [[23, "calibrations"]], "Treatments": [[23, "treatments"]], "Profiles": [[23, "profiles"]], "Loopalyzer": [[23, "loopalyzer"]], "Nightscout Reporter": [[23, "nightscout-reporter"]], "Power BI": [[23, "power-bi"]], "Nightscout Security and Privacy": [[24, "nightscout-security-and-privacy"]], "Personal use only": [[24, null]], "HTTPS and certificate errors": [[24, "https-and-certificate-errors"]], "Administration messages": [[24, "administration-messages"]], "I\u2019m seeing a message about the API_SECRET being weak": [[24, "i-m-seeing-a-message-about-the-api-secret-being-weak"]], "I\u2019m seeing a message about authentication failures": [[24, "i-m-seeing-a-message-about-authentication-failures"]], "I\u2019m seeing a message Nightscout is readable by the world": [[24, "i-m-seeing-a-message-nightscout-is-readable-by-the-world"]], "Renaming the Nightscout site": [[24, "renaming-the-nightscout-site"]], "How to Turn Off Unauthorized Access": [[24, "how-to-turn-off-unauthorized-access"]], "Create Authentication Tokens for Users": [[24, "create-authentication-tokens-for-users"]], "Developers: API authorization": [[24, "developers-api-authorization"]], "Nightscout Configuration": [[25, "nightscout-configuration"]], "Nightscout Config Vars": [[25, "nightscout-config-vars"]], "Required variables": [[25, "required-variables"]], "MONGODB_URI (Database connection string)": [[25, "mongodb-uri-database-connection-string"]], "API_SECRET (Nightscout password)": [[25, "api-secret-nightscout-password"]], "This is an important password": [[25, null]], "DISPLAY_UNITS (Units to use)": [[25, "display-units-units-to-use"]], "Features": [[25, "features"]], "ENABLE (Enable Plugins)": [[25, "enable-enable-plugins"]], "DISABLE (Disable Plugins)": [[25, "disable-disable-plugins"]], "AUTH_DEFAULT_ROLES (Authentication)": [[25, "auth-default-roles-authentication"]], "Alarms": [[25, "alarms"], [67, "alarms"], [94, "alarms"], [96, "alarms"]], "ALARM_TYPES": [[25, "alarm-types"]], "TYPES": [[25, null]], "BG Thresholds": [[25, null]], "BG_HIGH": [[25, "bg-high"]], "BG_LOW": [[25, "bg-low"]], "BG_TARGET_BOTTOM": [[25, "bg-target-bottom"]], "BG_TARGET_TOP": [[25, "bg-target-top"]], "ALARM_* and ALARM_URGENT_*": [[25, null]], "ALARM_URGENT_HIGH": [[25, "alarm-urgent-high"]], "ALARM_HIGH": [[25, "alarm-high"]], "ALARM_LOW": [[25, "alarm-low"]], "ALARM_URGENT_LOW": [[25, "alarm-urgent-low"]], "Other Alarms on by Default": [[25, "other-alarms-on-by-default"]], "Pushover": [[25, null], [25, "pushover"]], "ALARM_URGENT_HIGH_MINS": [[25, "alarm-urgent-high-mins"]], "ALARM_HIGH_MINS": [[25, "alarm-high-mins"]], "ALARM_LOW_MINS": [[25, "alarm-low-mins"]], "ALARM_URGENT_LOW_MINS": [[25, "alarm-urgent-low-mins"]], "ALARM_URGENT_MINS": [[25, "alarm-urgent-mins"]], "ALARM_WARN_MINS": [[25, "alarm-warn-mins"]], "TIMEAGO": [[25, null]], "ALARM_TIMEAGO_URGENT": [[25, "alarm-timeago-urgent"]], "ALARM_TIMEAGO_URGENT_MINS": [[25, "alarm-timeago-urgent-mins"]], "ALARM_TIMEAGO_WARN": [[25, "alarm-timeago-warn"]], "ALARM_TIMEAGO_WARN_MINS": [[25, "alarm-timeago-warn-mins"]], "Predefined values for your browser settings (default)": [[25, "predefined-values-for-your-browser-settings-default"]], "TIME_FORMAT (12)": [[25, "time-format-12"]], "NIGHT_MODE (off)": [[25, "night-mode-off"]], "SHOW_RAWBG (never)": [[25, "show-rawbg-never"]], "CUSTOM_TITLE (Nightscout)": [[25, "custom-title-nightscout"]], "THEME (colors)": [[25, "theme-colors"]], "SHOW_PLUGINS": [[25, "show-plugins"]], "SHOW_FORECAST (ar2)": [[25, "show-forecast-ar2"]], "LANGUAGE (en)": [[25, "language-en"]], "SCALE_Y (log)": [[25, "scale-y-log"]], "EDIT_MODE (on)": [[25, "edit-mode-on"]], "BOLUS_RENDER": [[25, "bolus-render"]], "Split View": [[25, "split-view"]], "Plugins": [[25, "plugins"]], "Default Plugins": [[25, "default-plugins"]], "delta (BG Delta)": [[25, "delta-bg-delta"]], "direction (BG Direction)": [[25, "direction-bg-direction"]], "upbat (Uploader Battery)": [[25, "upbat-uploader-battery"]], "timeago (Time Ago)": [[25, "timeago-time-ago"]], "devicestatus (Device Status)": [[25, "devicestatus-device-status"]], "errorcodes (CGM Error Codes)": [[25, "errorcodes-cgm-error-codes"]], "ar2 (AR2 Forecasting)": [[25, "ar2-ar2-forecasting"]], "simplealarms (Simple BG Alarms)": [[25, "simplealarms-simple-bg-alarms"]], "profile (Treatment Profile)": [[25, "profile-treatment-profile"]], "dbsize (Database Size)": [[25, "dbsize-database-size"]], "Advanced Plugins:": [[25, "advanced-plugins"]], "careportal (Careportal)": [[25, "careportal-careportal"]], "boluscalc (Bolus Wizard)": [[25, "boluscalc-bolus-wizard"]], "food (Custom Foods)": [[25, "food-custom-foods"]], "rawbg (Raw BG)": [[25, "rawbg-raw-bg"]], "iob (Insulin-on-Board) - cob (Carbs-on-Board)": [[25, "iob-insulin-on-board-cob-carbs-on-board"]], "iob (Insulin-on-Board)": [[25, "iob-insulin-on-board"]], "cob (Carbs-on-Board)": [[25, "cob-carbs-on-board"]], "bwp (Bolus Wizard Preview)": [[25, "bwp-bolus-wizard-preview"]], "Age pills": [[25, "age-pills"]], "cage (Cannula Age)": [[25, "cage-cannula-age"]], "sage (Sensor Age)": [[25, "sage-sensor-age"]], "iage (Insulin Age)": [[25, "iage-insulin-age"]], "bage (Battery Age)": [[25, "bage-battery-age"]], "treatmentnotify (Treatment Notifications)": [[25, "treatmentnotify-treatment-notifications"]], "basal (Basal Profile)": [[25, "basal-basal-profile"]], "bridge (Share2Nightscout bridge)": [[25, "bridge-share2nightscout-bridge"]], "mmconnect (MiniMed Connect bridge)": [[25, "mmconnect-minimed-connect-bridge"]], "pump (Pump Monitoring)": [[25, "pump-pump-monitoring"]], "openaps (OpenAPS)": [[25, "openaps-openaps"]], "loop (Loop)": [[25, "loop-loop"]], "override (Override Mode)": [[25, "override-override-mode"]], "xdripjs (xDrip-js)": [[25, "xdripjs-xdrip-js"]], "alexa (Amazon Alexa)": [[25, "alexa-amazon-alexa"]], "googlehome (Google Home/DialogFlow)": [[25, "googlehome-google-home-dialogflow"]], "speech (Speech)": [[25, "speech-speech"]], "cors (CORS)": [[25, "cors-cors"]], "Extended Settings": [[25, "extended-settings"]], "IFTTT Maker": [[25, "ifttt-maker"]], "Treatment Profile": [[25, "treatment-profile"]], "Nightscout on your Watch": [[29, "nightscout-on-your-watch"]], "Pebble Smartwatches": [[29, "pebble-smartwatches"]], "urchin": [[29, "urchin"]], "Android Wear OS smartwatches": [[29, "android-wear-os-smartwatches"]], "AndroidAPS": [[29, "androidaps"]], "NightWear": [[29, "nightwear"]], "Amazfit Pace & Stratos": [[29, "amazfit-pace-stratos"]], "Xiaomi MiBand 2, 3, 4, 5 and 6": [[29, "xiaomi-miband-2-3-4-5-and-6"]], "Amazfit Band 5, Bip, Bip Lite, Bip S and Bip S lite, T-Rex Pro": [[29, "amazfit-band-5-bip-bip-lite-bip-s-and-bip-s-lite-t-rex-pro"]], "Amazfit GTR2, GTR2e, GTS2, GTS 2 mini, GTS2e, GTR42 and 47": [[29, "amazfit-gtr2-gtr2e-gts2-gts-2-mini-gts2e-gtr42-and-47"]], "Apple Watch": [[29, "apple-watch"]], "Fitbit": [[29, "fitbit"]], "Nightscout Monitor": [[29, "nightscout-monitor"]], "Glance": [[29, "glance"]], "Sentinel": [[29, "sentinel"]], "Marclock": [[29, "marclock"]], "Analog watchfaces": [[29, "analog-watchfaces"]], "Analog CGM": [[29, "analog-cgm"]], "Orbits NS": [[29, "orbits-ns"]], "Radial CGM": [[29, "radial-cgm"]], "Samsung Gear Smartwatches": [[29, "samsung-gear-smartwatches"]], "xDrip+ with Tasker": [[29, "xdrip-with-tasker"]], "G-Watch app": [[29, "g-watch-app"]], "Garmin Smartwatches and Computers": [[29, "garmin-smartwatches-and-computers"]], "Karoo/Karoo 2": [[29, "karoo-karoo-2"]], "Help me choose": [[30, "help-me-choose"]], "Welcome to the Nightscout new user wizard.": [[30, "welcome-to-the-nightscout-new-user-wizard"]], "Hosted": [[30, "hosted"]], "Database": [[30, "database"]], "Provider": [[30, "provider"]], "VPS": [[30, "vps"]], "Update your Nightscout": [[34, "update-your-nightscout"]], "The latest release is 15.0.2.": [[34, "the-latest-release-is-15-0-2"]], "Google Translate links": [[35, "google-translate-links"]], "Troubleshoot MongoDB Atlas": [[36, "troubleshoot-mongodb-atlas"]], "Limit of one free cluster.": [[36, "limit-of-one-free-cluster"]], "Meet your connection string": [[36, "meet-your-connection-string"]], "Unable to connect to Mongo": [[36, "unable-to-connect-to-mongo"]], "MongoDB paused": [[36, "mongodb-paused"]], "MongoDB in read only mode": [[36, "mongodb-in-read-only-mode"]], "MONGODB_URI missing": [[36, "mongodb-uri-missing"]], "Generic Unable to connect to Mongo": [[36, "generic-unable-to-connect-to-mongo"]], "Bad connection string": [[36, "bad-connection-string"]], "MONGODB_URI or MONGO_CONNECTION": [[36, null]], "Recover your connection string": [[36, "recover-your-connection-string"]], "Change your Atlas database password": [[36, "change-your-atlas-database-password"]], "Database full": [[36, "database-full"]], "Restart": [[36, "restart"], [44, "restart"]], "Normal cleanup": [[36, "normal-cleanup"]], "Emergency cleanup": [[36, "emergency-cleanup"]], "Atlas database size verification": [[36, "atlas-database-size-verification"]], "Reports slow loading or timeout": [[36, "reports-slow-loading-or-timeout"]], "Data in the future": [[36, "data-in-the-future"], [48, "data-in-the-future"]], "Cleanup": [[36, "cleanup"], [38, "cleanup"], [41, "cleanup"], [43, "cleanup"], [45, "cleanup"]], "Backup your database": [[36, "backup-your-database"]], "Not a normal operation": [[36, null]], "Install the database tools": [[36, "install-the-database-tools"]], "Dump your database": [[36, "dump-your-database"]], "Troubleshoot Azure": [[37, "troubleshoot-azure"]], "Error 403": [[37, "error-403"]], "Restart app": [[37, "restart-app"]], "Billing occurred": [[37, "billing-occurred"]], "Connection string": [[39, "connection-string"]], "Troubleshoot Dexcom Share": [[40, "troubleshoot-dexcom-share"]], "Username and password": [[40, "username-and-password"]], "Password": [[40, null], [54, null], [63, null], [64, null], [78, null], [84, null], [84, null], [85, null], [86, null], [92, null], [95, null]], "Changing password": [[40, null]], "Username is an email": [[40, "username-is-an-email"]], "Username is a phone number": [[40, "username-is-a-phone-number"]], "Obtaining a username": [[40, "obtaining-a-username"]], "Account lock": [[40, "account-lock"]], "Dexcom Share": [[40, "dexcom-share"], [67, "dexcom-share"], [94, "dexcom-share"], [96, "dexcom-share"]], "Verify your configuration": [[40, "verify-your-configuration"]], "Authentication errors": [[40, "authentication-errors"]], "Troubleshoot Fly.io": [[41, "troubleshoot-fly-io"]], "Restart your app": [[41, "restart-your-app"], [45, "restart-your-app"]], "Recover fly.toml": [[41, "recover-fly-toml"]], "Delete an app": [[41, "delete-an-app"], [43, "delete-an-app"]], "Delete your local repository": [[41, "delete-your-local-repository"]], "If you deployed with your own computer.": [[41, "if-you-deployed-with-your-own-computer"]], "If you deployed from the web terminal.": [[41, "if-you-deployed-from-the-web-terminal"]], "Downscale your app": [[41, "downscale-your-app"]], "Obtain a free shared IP": [[41, "obtain-a-free-shared-ip"]], "Migrate from Heroku": [[41, "migrate-from-heroku"]], "Troubleshoot GitHub": [[42, "troubleshoot-github"]], "Lost access to GitHub": [[42, "lost-access-to-github"]], "Cannot update GitHub": [[42, "cannot-update-github"]], "Delete your own fork of cgm-remote-monitor": [[42, "delete-your-own-fork-of-cgm-remote-monitor"], [51, "delete-your-own-fork-of-cgm-remote-monitor"]], "Delete Nightscout?": [[42, null], [51, null], [69, null]], "Troubleshoot Heroku": [[43, "troubleshoot-heroku"]], "There\u2019s nothing here": [[43, "there-s-nothing-here"]], "Application Error": [[43, "application-error"]], "A valid GitHub Directory could not be found.": [[43, "a-valid-github-directory-could-not-be-found"]], "Cannot find cgm-remote-monitor in Heroku / No GitHub source visible": [[43, "cannot-find-cgm-remote-monitor-in-heroku-no-github-source-visible"]], "Cannot find cgm-remote-monitor in Heroku: Item cannot be retrieved": [[43, "cannot-find-cgm-remote-monitor-in-heroku-item-cannot-be-retrieved"]], "I can\u2019t log into Heroku": [[43, "i-can-t-log-into-heroku"]], "Restart all dynos": [[43, "restart-all-dynos"]], "Sleeping app": [[43, "sleeping-app"]], "Maintenance mode": [[43, "maintenance-mode"]], "Backup your site variables": [[43, "backup-your-site-variables"]], "Method 1 - Spreadsheet": [[43, "method-1-spreadsheet"]], "Method 2 - Export": [[43, "method-2-export"]], "Roll back Heroku": [[43, "roll-back-heroku"]], "Stop using Heroku": [[43, "stop-using-heroku"]], "Troubleshoot Northflank": [[44, "troubleshoot-northflank"]], "Site doesn\u2019t open after build": [[44, "site-doesn-t-open-after-build"]], "Troubleshoot Railway": [[45, "troubleshoot-railway"]], "Nothing here": [[45, "nothing-here"]], "Reconnect GitHub to your project": [[45, "reconnect-github-to-your-project"]], "Empty projects": [[45, "empty-projects"]], "Databases": [[45, "databases"]], "Troubleshoot Render": [[46, "troubleshoot-render"]], "Restart service": [[46, "restart-service"]], "Troubleshooting Nightscout": [[48, "troubleshooting-nightscout"]], "Before troubleshooting": [[48, "before-troubleshooting"]], "Overall third party services": [[48, "overall-third-party-services"]], "Application crashed": [[48, "application-crashed"]], "Fly.io": [[48, "fly-io"], [77, "fly-io"]], "Other issues": [[48, "other-issues"]], "Reports": [[48, "reports"]], "No data in Nightscout": [[48, "no-data-in-nightscout"]], "Dexcom data not showing": [[48, "dexcom-data-not-showing"]], "Dexcom or CareLink data stopping after a while": [[48, "dexcom-or-carelink-data-stopping-after-a-while"]], "UpTime Robot": [[48, null]], "Data timing issues": [[48, "data-timing-issues"]], "Basal is shifted in time": [[48, "basal-is-shifted-in-time"]], "Basal / IOB / COB missing after DST": [[48, "basal-iob-cob-missing-after-dst"]], "Error code instead of a BG value": [[48, "error-code-instead-of-a-bg-value"]], "Deploy another version": [[49, "deploy-another-version"]], "Step 1: Update your repository in GitHub": [[49, "step-1-update-your-repository-in-github"], [53, "step-1-update-your-repository-in-github"]], "Step 2: Deploy": [[49, "step-2-deploy"], [53, "step-2-deploy"]], "How to return to the master release": [[49, "how-to-return-to-the-master-release"]], "Downgrade Nightscout": [[50, "downgrade-nightscout"]], "Deploy an old release": [[50, "deploy-an-old-release"]], "Docker": [[50, "docker"]], "Redeploy with GitHub": [[51, "redeploy-with-github"]], "Update the Heroku stack": [[52, "update-the-heroku-stack"]], "Update Nightscout": [[53, "update-nightscout"]], "Setup Uploaders": [[54, "setup-uploaders"]], "What is my Nightscout URL?": [[54, "what-is-my-nightscout-url"]], "Dexcom": [[54, "dexcom"], [55, "dexcom"]], "MOST COMMON ERRORS": [[54, null], [63, null], [64, null], [78, null], [84, null], [84, null], [85, null], [86, null], [92, null], [95, null]], "Medtronic CareLink": [[54, "medtronic-carelink"]], "Medtronic 600 Series with uploader": [[54, "medtronic-600-series-with-uploader"]], "Mind the syntax!": [[54, null]], "Juggluco": [[54, "juggluco"]], "LinkBluCon": [[54, "linkblucon"]], "Tomato": [[54, "tomato"]], "DIY Closed Loop": [[54, "diy-closed-loop"]], "Supported Uploaders": [[55, "supported-uploaders"]], "DIY Closed loop Systems": [[55, "diy-closed-loop-systems"]], "Dexcom G5/G6/ONE/G7": [[55, "dexcom-g5-g6-one-g7"]], "Dexcom \u201cFirefly\u201d Transmitters": [[55, null]], "Medtronic": [[55, "medtronic"]], "Glucomen Day": [[55, "glucomen-day"]], "Tandem t:slim X2": [[55, "tandem-t-slim-x2"]], "Abbott Freestyle Libre": [[55, "abbott-freestyle-libre"]], "Libre 1": [[55, "libre-1"]], "Transmitter Compatibility": [[55, null]], "Libre 2": [[55, "libre-2"]], "Libre 2/3": [[55, "libre-2-3"]], "Eversense": [[55, "eversense"]], "Diasend": [[55, "diasend"]], "xDrip+ for CareLink": [[56, "xdrip-for-carelink"]], "Using CareLink follower": [[56, "using-carelink-follower"]], "Using Companion app": [[56, "using-companion-app"]], "Nightscout in your Synology NAS": [[58, "nightscout-in-your-synology-nas"]], "Building Nightscout with Docker": [[60, "building-nightscout-with-docker"]], "Update your system": [[60, "update-your-system"], [61, "update-your-system"]], "Deploy a single instance": [[60, "deploy-a-single-instance"]], "Step 1 - Install Docker": [[60, "step-1-install-docker"]], "Step 2 - Configure Nightscout": [[60, "step-2-configure-nightscout"]], "Step 3 - Build and run Nightscout": [[60, "step-3-build-and-run-nightscout"]], "Update or downgrade": [[60, "update-or-downgrade"]], "Deploy multiple instances": [[60, "deploy-multiple-instances"]], "Building Nightscout in Ubuntu": [[61, "building-nightscout-in-ubuntu"]], "Step 1 - Install MongoDB": [[61, "step-1-install-mongodb"]], "Step 2 - Create a new database": [[61, "step-2-create-a-new-database"]], "Step 3 - Install Nightscout": [[61, "step-3-install-nightscout"]], "Make sure you\u2019re in your nightscout directory": [[61, null]], "Step 4 - Configure Nightscout": [[61, "step-4-configure-nightscout"]], "Variables format": [[61, null]], "Manage Nightscout startup": [[61, "manage-nightscout-startup"]], "Step 5 - Open and secure your access": [[61, "step-5-open-and-secure-your-access"]], "Nightscout in Azure (Docker)": [[63, "nightscout-in-azure-docker"]], "Step 0: Create a database": [[63, "step-0-create-a-database"], [67, "step-0-create-a-database"], [78, "step-0-create-a-database"], [84, "step-0-create-a-database"], [92, "step-0-create-a-database"], [98, "step-0-create-a-database"]], "Migrating?": [[63, null], [78, null], [84, null], [92, null], [98, null]], "Step 1: Create an Azure account": [[63, "step-1-create-an-azure-account"]], "Step 2: Create your Nightscout web app": [[63, "step-2-create-your-nightscout-web-app"]], "Limited CPU usage": [[63, null]], "Step 3: Configure your Nightscout web app": [[63, "step-3-configure-your-nightscout-web-app"]], "Editing Config Vars in Azure": [[63, "editing-config-vars-in-azure"]], "View a variable value": [[63, "view-a-variable-value"]], "Modify a variable": [[63, "modify-a-variable"]], "Delete a variable": [[63, "delete-a-variable"]], "Add a variable": [[63, "add-a-variable"]], "Save your modifications": [[63, "save-your-modifications"]], "Nightscout in Fly.io": [[67, "nightscout-in-fly-io"]], "Step 1: Create a fly.io account": [[67, "step-1-create-a-fly-io-account"]], "Step 2: Install flyctl": [[67, "step-2-install-flyctl"]], "Step 3: Prepare the Nightscout project": [[67, "step-3-prepare-the-nightscout-project"]], "Step 5: Set your Nightscout secrets": [[67, "step-5-set-your-nightscout-secrets"]], "Mandatory variables": [[67, "mandatory-variables"], [94, "mandatory-variables"], [96, "mandatory-variables"]], "Customizations": [[67, "customizations"], [94, "customizations"], [96, "customizations"]], "Save this!": [[67, null]], "Step 6: Deploy Nightscout": [[67, "step-6-deploy-nightscout"]], "Editing Config Vars in Fly.io": [[67, "editing-config-vars-in-fly-io"]], "Secrets": [[67, null]], "Update GitHub": [[70, "update-github"]], "Update your Nightscout fork": [[70, "update-your-nightscout-fork"]], "Nightscout in Google Cloud": [[72, "nightscout-in-google-cloud"]], "Instructions": [[72, "instructions"]], "Heroku Eco plan": [[74, "heroku-eco-plan"]], "Enable a 5$/month Eco Plan": [[74, "enable-a-5-month-eco-plan"]], "Prevent your Nightscout app from falling asleep": [[74, "prevent-your-nightscout-app-from-falling-asleep"], [78, "prevent-your-nightscout-app-from-falling-asleep"]], "Use with caution": [[74, null], [78, null]], "Heroku Basic plan": [[75, "heroku-basic-plan"]], "Upgrade to 7$/month Basic Plan": [[75, "upgrade-to-7-month-basic-plan"]], "5$/month Eco Plan": [[75, null]], "Heroku MFA": [[76, "heroku-mfa"]], "Losing access": [[76, null]], "Salesforce Authenticator": [[76, "salesforce-authenticator"]], "Losing or removing the Authenticator app": [[76, null]], "Built-In Authenticator": [[76, "built-in-authenticator"]], "One-Time Password Generator": [[76, "one-time-password-generator"]], "Security Key": [[76, "security-key"]], "Recovery Codes": [[76, "recovery-codes"]], "Migration?": [[77, "migration"]], "TANSTAAFL": [[77, "tanstaafl"]], "Nightscout.Pro": [[77, "nightscout-pro"]], "Google Cloud": [[77, "google-cloud"]], "Azure": [[77, "azure"]], "MongoDB Atlas": [[77, "mongodb-atlas"]], "Oracle Cloud": [[77, "oracle-cloud"]], "Nightscout in Heroku": [[78, "nightscout-in-heroku"]], "If this is not your first attempt to deploy Nightscout": [[78, null]], "Heroku doesn\u2019t include a database": [[78, null]], "Step 1: Create a GitHub account and fork the Nightscout project": [[78, "step-1-create-a-github-account-and-fork-the-nightscout-project"], [84, "step-1-create-a-github-account-and-fork-the-nightscout-project"], [98, "step-1-create-a-github-account-and-fork-the-nightscout-project"]], "Step 2: Create a Heroku account": [[78, "step-2-create-a-heroku-account"]], "Multiple factor authentication": [[78, null]], "Step 3: Fork and deploy cgm-remote-monitor": [[78, "step-3-fork-and-deploy-cgm-remote-monitor"]], "You\u2019re getting into the core setup of your site": [[78, null]], "ENABLE words": [[78, null]], "Papertrail": [[78, "papertrail"]], "Editing Config Vars in Heroku": [[78, "editing-config-vars-in-heroku"]], "Renaming your Nightscout site": [[78, "renaming-your-nightscout-site"]], "MongoDB Atlas Database": [[79, "mongodb-atlas-database"]], "Create an Atlas database": [[79, "create-an-atlas-database"]], "If you ever see this, just STOP": [[79, null]], "Database credentials": [[79, null]], "Northflank Database": [[81, "northflank-database"]], "Create an account with Northflank": [[81, "create-an-account-with-northflank"]], "Create your database": [[81, "create-your-database"], [89, "create-your-database"]], "Costs": [[81, null]], "This is an important information": [[81, null], [89, null]], "Nightscout in Northflank": [[84, "nightscout-in-northflank"]], "Set up a new Nightscout": [[84, "set-up-a-new-nightscout"], [92, "set-up-a-new-nightscout"]], "Create your Northflank and GitHub accounts from a computer.": [[84, "create-your-northflank-and-github-accounts-from-a-computer"]], "Step 2: Create a Northflank account": [[84, "step-2-create-a-northflank-account"]], "Step 3: Deploy Nightscout in Northflank": [[84, "step-3-deploy-nightscout-in-northflank"]], "Change your Northflank Nightscout site name": [[84, "change-your-northflank-nightscout-site-name"]], "Editing Variables in Northflank": [[84, "editing-variables-in-northflank"]], "Copy all variables from Heroku": [[84, "copy-all-variables-from-heroku"]], "Dexcom Bridge": [[85, "dexcom-bridge"], [86, "dexcom-bridge"]], "Step 4: Attach your database to your Nightscout site": [[85, "step-4-attach-your-database-to-your-nightscout-site"], [86, "step-4-attach-your-database-to-your-nightscout-site"]], "Railway Database": [[89, "railway-database"]], "Create a Railway account": [[89, "create-a-railway-account"]], "Nightscout in Railway": [[92, "nightscout-in-railway"]], "Create your Railway and GitHub accounts from a computer.": [[92, "create-your-railway-and-github-accounts-from-a-computer"]], "Step 1: Fork cgm-remote-monitor": [[92, "step-1-fork-cgm-remote-monitor"]], "Step 2: Create a Railway account": [[92, "step-2-create-a-railway-account"]], "Step 3 - Deploy Nightscout in Railway": [[92, "step-3-deploy-nightscout-in-railway"]], "Migrating from Heroku": [[92, null], [95, null]], "Recommended": [[92, null], [92, null], [94, null], [95, null]], "Change your Nightscout site name": [[92, "change-your-nightscout-site-name"]], "Editing Variables in Railway": [[92, "editing-variables-in-railway"]], "Method 1 - Web interface": [[92, "method-1-web-interface"]], "Method 2 - Raw Editor": [[92, "method-2-raw-editor"]], "Update your link.": [[93, "update-your-link"]], "
": [[95, "id1"]], "Nightscout in Render": [[98, "nightscout-in-render"]], "Render doesn\u2019t include a database": [[98, null]], "Step 2: Create a Render account": [[98, "step-2-create-a-render-account"]], "Step 3 - Deploy Nightscout in Render": [[98, "step-3-deploy-nightscout-in-render"]], "Editing Variables in Render": [[98, "editing-variables-in-render"]], "Step 4: Add the render.yaml template": [[99, "step-4-add-the-render-yaml-template"]], "Step 5: First deploy in Render": [[99, "step-5-first-deploy-in-render"]], "Step 6: Delete the render branch": [[99, "step-6-delete-the-render-branch"]], "Step 4: Create your Nightscout service": [[100, "step-4-create-your-nightscout-service"]]}, "indexentries": {}}) \ No newline at end of file diff --git a/translate/index.html b/translate/index.html new file mode 100644 index 00000000..2d36edce --- /dev/null +++ b/translate/index.html @@ -0,0 +1,219 @@ + + + + + + + Google Translate links — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+ +
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/troubleshoot/atlas/index.html b/troubleshoot/atlas/index.html new file mode 100644 index 00000000..c40e791f --- /dev/null +++ b/troubleshoot/atlas/index.html @@ -0,0 +1,1005 @@ + + + + + + + Troubleshoot MongoDB Atlas — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Troubleshoot MongoDB Atlas

+
+
+

Limit of one free cluster.

+

When creating a new site or migrating (usually not the first attempt), when reaching Target Cluster.

+../../_images/TShoot17.png +
    +
  • Click the leaf top left in your Atlas account. Look at the Project Name you wanted to use when creating your new cluster, it shouldn’t contain a cluster yet (like the example below, I tried to create a new Nightscout site but there is already a cluster inside the project I wanted to use). You can’t have two clusters in a free project. Click your Project Name.

  • +
  • This should not happen in normal conditions. Before deleting a cluster, check it doesn’t contain your data!

  • +
+../../_images/TShoot18.png +
    +
  • Click on Collections in the cluster you selected.

  • +
+../../_images/TShoot19.png +
    +
  • Click on entries

  • +
+../../_images/TShoot20.png +
    +
  • In the case there is data, like in the example below, don’t use this cluster. Leave it like this and create a new one.

  • +
+../../_images/TShoot21.png +
    +
  • If there no data, you can safely delete it.

  • +
+../../_images/TShoot22.png +
    +
  • In this cluster you want to delete click ... then Terminate

  • +
+../../_images/TShoot23.png +
    +
  • Copy the cluster name to confirm then click Terminate

  • +
+../../_images/TShoot24.png +
    +
  • Wait until the operation completes.

  • +
  • You can now use this project name to create a new site.

  • +
+
+
+
+

Meet your connection string

+

For technical details look here.

+

A typical mLab migrated string will look like this:

+

mongodb+srv://heroku_0v50k8rf:ddfsjcpfu8fcoj9n6dueabfd5u@cluster0.g03wh.mongodb.net/  +heroku_0v50k8rf?retryWrites=true&w=majority

+

A typical new string created with Atlas will look like this:

+

mongodb+srv://johndoe:V3ry53cr3t@cluster0.a01bc.mongodb.net/myCGMiC?retryWrites=true&w=majority

+
    +
  • It will start by mongodb+srv:// with mongodb a standard prefix for a connection string, and +srv adding a security layer.

  • +
  • After :// you’ll find your database username, that is not your Atlas account username. In the examples above heroku_0v50k8rf or johndoe.

  • +
  • Following the username, a separator : and your database password that is not your Atlas account password. In the examples above a typical 26 characters password created automatically with the mLab add-on ddfsjcpfu8fcoj9n6dueabfd5u and a user created password V3ry53cr3t.

  • +
  • Following the password, a separator @ then the host name that was provided by Atlas after you created you cluster. typically it will look like cluster0.a1b2c3.mongodb.net

  • +
  • [Optional] After the host name and the separator / you’ll see your Nightscout database name. If you migrated from mLab it will be identical to your database username (unless you modified it). If you created your Atlas cluster it will be the one you decided. In the examples above heroku_0v50k8rf or myCGMiC.

  • +
  • Another separator ? and you’ll see two options: retryWrites=true&w=majority

  • +
+
+
+
+

Unable to connect to Mongo

+../../_images/TShoot54.png +

Common reasons:

+
    +
  • The database is not available. If you don’t have a database yet, create a new one.
    +If you do have a database, check it’s functional then restart your web app:

  • +
+
+ + + + + + + + + + + + +
+
    +
  • Your Atlas connection string is incorrect. Check here.

  • +
+
+

MongoDB paused

+
    +
  • If you haven’t been using Nightscout for a while but it was working before, check the database didn’t go to sleep mode. If it did, select Resume to restart it.

  • +
  • Once done:

  • +
+
+ + + + + + + + + + + + +
+../../_images/TShoot53.png +
+

If you see this message

+../../_images/TShoot06.png + +
+
+
+
+

MongoDB in read only mode

+

If you see this message:

+../../_images/TShoot44.png +
    +
  • Verify your database is not read only, else click Edit

  • +
+../../_images/TShoot15.png +
    +
  • Change the permissions to Atlas Admin and Update User

  • +
+../../_images/TShoot16.png +
    +
  • Once done:

  • +
+
+ + + + + + + + + + + + +
+
+
+
+

MONGODB_URI missing

+

If you see this message:

+../../_images/TShoot45.png +
    +
  • If you don’t have a database yet, create a new one.

  • +
  • It might be a transient error in MongoDB Atlas, try to restartyour web app:

  • +
+
+ + + + + + + + + + + + +
+
    +
  • Check your database is not full!

  • +
  • If your Nightscout was still functional after November 11th 2020, continue below to recover:

  • +
+
+
+
+

Generic Unable to connect to Mongo

+

If you see this message:

+../../_images/TShoot47.png +
    +
  • Check you authorized all IPs to access your Atlas database:

  • +
  • Open your Atlas cluster and select your Nightscout project, then Network access

  • +
+../../_images/TShoot48.png +
    +
  • If you see an IP (in red above) instead of 0.0.0.0/0 click Edit select ALLOW ACCESS FROM ANYWHERE then Confirm.

  • +
+../../_images/TShoot49.png +
    +
  • Once done:

  • +
+
+ + + + + + + + + + + + +
+
+
+
+

Bad connection string

+

If you see this message:

+../../_images/TShoot46.png +
+ +
+

MONGODB_URI or MONGO_CONNECTION

+

There should be at least one and only one of them, not both.

+
+

If you migrated from mLab Heroku add-on it is usually MONGO_CONNECTION

+

if you deployed a brand new Nightscout it should be MONGODB_URI

+
    +
  • Verify it is looking like this:

  • +
+

mongodb+srv://atlasusername:atlaspassword@cluster0.zzzzz.mongodb.net/dbname?retryWrites=true&w=majority

+

Note that your atlasusername, atlaspassword and dbname will be different from the example above.

+
    +
  • Paste the string in the box below:

  • +
+ +
+
    +
  • Click the Analyze text below:

  • +
+

+

Analysis result will appear here.

+

If the analysis result doesn’t show any error, check below the data is what you actually wanted:

+

Database Username:

+Database Password:

+Database name:

(No database name is not an error)

+ +
+

Hint

+

If you migrated from Heroku mLab add-on, your database username and database name should be identical.

+
+../../_images/TShoot41.png +
+

If you’ve just created a new site, try to use this help page to verify or recreate it.

+
+

If you’re still in trouble continue below:

+
+
+
+

Recover your connection string

+

If you’ve tried several times to deploy or migrate, you might end-up with many useless items in your accounts. At this point, you could benefit doing some cleanup in order to identify the correct Atlas database you want to connect to. Consider cleanup before continuing.

+
+

a) Go to your MongDB account. Log in if necessary https://cloud.mongodb.com/

+

b) Click Connect below your cluster name (in the example below Cluster0, but it might have another name)

+../../_images/TShoot07.png +
+

c) Click Connect your application

+../../_images/TShoot09.png +
+

d) A new view opens, in (2) Add your connection string into your application code you will find your MONGODB_URI or MONGO_CONNECTION string.

+

Click Copy then Close

+../../_images/TShoot10.png +
+

e) Paste it into a place where you can edit the text (i.e. a Word or a Notepad document).

+

Edit your string so that you add the database user password after the database user info. You defined them during your MongoDB Atlas database creation, when you reached step e).

+

Here’s an example of how the string is built up (myFirstDatabase might not show, this is normal):

+

mongodb+srv:// nightscout :<password>@cluster0.xxxxx.mongodb.net/myFirstDatabase?retryWrites=true&w=majority

+
+

f) Edit your string in order to replace <password> with your database password.

+

g) If you don’t remember your Atlas database password (which should not be your mongoDB Atlas account password) invent a new one (only letters and numbers).

+

Your string will now look like this: (do not use the same password as the example). Note there are no remaining < and >.
+If you don’t see a database name like myFirstDatabase before the question mark, just ignore it.

+

mongodb+srv://nightscout:soo5ecret@cluster0.xxxxx.mongodb.net/myFirstDatabase?retryWrites=true&w=majority

+
+

h) Copy this resulting string above into your MONGODB_URI or MONGO_CONNECTION variable. There must be only one of these variables, not both.

+

See here how to edit your configuration variables.

+

i) If there is neither one nor the other create a new MONGODB_URI variable and paste the string in the value field.

+

j) If you remembered your password restart your web app, and you should be done.

+

k) If you changed your password or your Nightscout page still fails to open continue.

+
+
+
+

Change your Atlas database password

+
    +
  • If you changed the password in the string you will need to change it in the database too:

  • +
  • Click Database Access

  • +
+../../_images/TShoot11.png +
+
    +
  • At the end of the line, click Edit

  • +
+../../_images/TShoot08.png +
+
    +
  • In Password click Edit Password

  • +
+
+

Hint

+

Take a look at the top of this view, after Edit User you can see your database user name before @. Check it’s matching the one in your connection string.

+
+../../_images/TShoot12.png +
+
    +
  • If you forgot your password invent a new one (use only letters and numbers: no special characters) or better: use Autogenerate Secure Password and click Copy

  • +
  • Else make it the same than the one in your MONGODB_URI connection string variable

  • +
+../../_images/TShoot13.png +
+
    +
  • Click Update User

  • +
+../../_images/TShoot14.png +
+
    +
  • Make sure the password matches in your connection string variable MONGODB_URI or MONGO_CONNECTION

  • +
+
+
+
+

Database full

+

Free databases like M0 Sandbox provided by Atlas will only hold a limited amount of data (512MB) and you will eventually need to manually cleanup. You can extend the capacity to 2 and 5GB paying for an M2 or M5 Shared cluster.

+

Note: If you consider paying for a database upgrade, also think about a paid hosting service.

+
+

Warning

+

Make sure your Nightscout site has Database Size enabled to monitor database capacity.
+In order to have the database size pill, add dbsize in the ENABLE variable.
+Look here for more information on this plugin.

+
+../../_images/TShoot35.png +
+
+

Hint

+

Your database size might not decrease immediately (it might even increase temporarily) after you perform cleanup with Admin Tools (see below: Normal cleanup). Allow a few hours to see the effects. In the meantime your site should recover functionality.
If your site keeps crashing, go ahead to emergency cleanup.

+
+
+
+

Restart

+

Try to recover temporary access to Nightscout to perform normal cleanup:

+
+ +
+
+
+ + + + + + + + + + + + + +
+

The probability your database is full is very low, make sure you selected the maximum disk size for your compute engine. See Here.

+
+ +
+

Contact your provider. The probability your database is full is virtually null.

+
+
+
+
+

Normal cleanup

+

You can cleanup (enter the number of days to keep) or delete your devices status (recommended as a first recovery action):

+../../_images/TShoot37.png +

Same for Treatments:

+../../_images/TShoot38.png +

And Glucose entries. If you are reluctant to lose historical data you should consider opting for a paid database solution or hosted Nightscout.

+../../_images/TShoot39.png +

If your Nightscout page doesn’t open after restarting your app and you want to rule out a full database, you can try an emergency cleanup of the less important part of your Nightscout site: devicestatus.

+
+
+
+

Emergency cleanup

+
    +
  • Log in Atlas

  • +
  • Open your Nightscout database and select Browse collections in Database

  • +
+../../_images/TShoot32.png +
    +
  • Select the devicestatus collection and click the bin icon to delete it.

  • +
  • You will lose all device status history (battery, ..) but you won’t lose neither BG, treatments nor profiles.

  • +
+../../_images/TShoot55.png +
    +
  • Write devicestatus in the box then click Drop

  • +
+../../_images/TShoot56.png +
    +
  • Restart your site and when it opens, consider again cleanup from Admin Tools if your database size exceeds 80%.

  • +
+
+
+
+

Atlas database size verification

+
    +
  • Log in Atlas

  • +
  • Open your Nightscout database and select Collections

  • +
+../../_images/TShoot32.png +
+
    +
  • Click your database name (hidden left). Check theDATABASE SIZE is indeed close to or at the limit (512MB) then look at these three collections Documents size: devicestatus, entries and treatments.

  • +
+../../_images/TShoot36.png +
    +
  • Open Nightscout Admin tools. If your site doesn’t open jump to Emergency cleanup.

  • +
  • Depending on the collection you identified above, choose which of the following you want to cleanup.

  • +
+
+
+
+
+

Reports slow loading or timeout

+

Loopers might experience Nightscout taking an extremely long time or even timing out when creating reports due to the profiles collection database growing too big.

+

Two solutions are available:

+
    +
  1. Follow this video (set it full screen in 720p) to selectively delete profiles https://www.youtube.com/watch?v=iipp0MfPKNQ

  2. +
  3. Delete all profiles in Atlas

  4. +
+

Log in to Atlas https://account.mongodb.com/account/login

+

Select your cluster then COLLECTIONS

+../../_images/TShoot50.png +
+

Select the profile collection and click the bin icon to delete all profiles.

+../../_images/TShoot51.png +
+

Write profile in the box then click Drop

+../../_images/TShoot52.png +
+

Open your Nightscout and create a new profile (mind the time zone!), authenticate and save it.

+

If you are using Loop, temporarily change a basal rate in Loop, and confirm your profiles now show up in Nightscout.

+
+
+
+

Data in the future

+

First try to remove future items with the Admin Tools.

+

If it doesn’t give the expected result:

+
    +
  • Check in Atlas

  • +
  • Open your Nightscout cluster and select Collections

  • +
+../../_images/TShoot32.png +
+
    +
  • In Entries type {date:-1} and click Find

  • +
+../../_images/TShoot33.png +
+
    +
  • Delete the entries in the future (manually) with the bin icon

  • +
+../../_images/TShoot34.png +
+
+
+

Cleanup

+

It is very easy to get lost in Atlas.

+

The structure from top to bottom is: Organization, Projects and Databases. You can have several organizations, each of them several projects and each of them several databases.

+
+

Hint

+

If you are deploying a brand new Nightscout make sure you have one organization, one project and one cluster created. No more no less.

+
+

If you want to cleanup Atlas, unless you don’t have data, you must first find out which database contains your data. For this, start from View All Organizations:

+../../_images/Cleanup03.png +

You can delete empty organizations (those without any project inside).

+../../_images/Cleanup04.png +

Select the organization, then top left the cog wheel to go in Settings, then scroll down to Delete Organization: Delete.

+../../_images/Cleanup06.png +

Deleting an organization without projects will not delete your data.

+../../_images/Cleanup05.png +
+

Once inside an organization, you will see its projects. You can safely delete projects without clusters.

+../../_images/Cleanup07.png +

Deleting an empty project doesn’t delete your Nightscout data.

+../../_images/Cleanup08.png +

For non-empty projects continue reading before deciding to delete them.

+
+

You can then move to your project (select it) and check its database(s) selecting COLLECTIONS

+../../_images/Cleanup09.png +

An empty project will look like below, and this is typically what you have before deploying Nightscout. Once Nightscout is deployed in a project, a new database will be created there.

+../../_images/Cleanup10.png +

The database currently used by your Nightscout is the one specified in the connection string, in the example below dbname. Whenever you change the database name in the connection string, a new database will be created in your project.

+

mongodb+srv://atlasusername:atlaspassword@cluster0.zzzzz.mongodb.net/dbname?retryWrites=true&w=majority

+

There is usually one database for Nightscout, if there are several, select one and then the other(s) to understand which one contains your data. For this, select entries.

+../../_images/Cleanup11.png +

A large database is most probably one you want to keep.

+../../_images/Cleanup12.png +

You can safely delete empty databases (check the size first).

+../../_images/Cleanup13.png +
+

Warning

+

If you’re not sure you’re deleting the right database, just leave it.

+
+

Hover on the database name and click the bin icon. Confirm deletion by copying the database name and click Drop.

+../../_images/Cleanup14.png +

If your database gets recreated after you deleted it this means your MONGODB_URI or MONGO_CONNECTION string is pointing to it.

+
+

If you want to delete a non-empty Project you need to terminate all clusters belonging to it.

+../../_images/Cleanup15.png +
+

Warning

+

Terminating a cluster will delete all information and databases in this cluster!

+
+

Confirm with your cluster name and wait until shutdown is complete.

+../../_images/Cleanup16.png +

You can then delete the empty project.

+
+
+
+

Backup your database

+
+

Not a normal operation

+

Making a backup of your database is either a good idea or necessary if you want to migrate it to another database. +This is not an easy operation and requires command line instructions using a computer.

+
+
+

Install the database tools

+

Follow this link to install the CLI tool on your computer.

+
+
+

Dump your database

+

Get your MONGODB_URI handy to find the missing pieces (password and database name).

+

Log in your MongoDB account https://cloud.mongodb.com/.

+
    +
  1. Select your organization

  2. +
  3. Select your database

  4. +
  5. In the advanced options menu, select Command line tools

  6. +
+../../_images/AtlasX01.png +
+

Scroll down to Binary import and Export tools, copy the mongodump command line.

+../../_images/AtlasX02.png +

Paste the command line in a text editor.

+

Look into your MONGODB_URI and replace <PASSWORD> with your database password and entually (if you have one) <DATABASE> with your database name.

+../../_images/AtlasX03.png +
+

Open a command line utility (CMD, Terminal, …) and make your way to the utility folder (if you don’t want to include it in your system path).
+For example in Windows 64bits it’s in C:\Program Files\MongoDB\Tools\100\bin.

+

Copy and paste your mongodump command, run it.

+../../_images/AtlasX04.png +
+

You will find the database dump in a subfolder called dump with your database name in a subfolder.

+../../_images/AtlasX07.png +
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/troubleshoot/azure/index.html b/troubleshoot/azure/index.html new file mode 100644 index 00000000..cb0ce980 --- /dev/null +++ b/troubleshoot/azure/index.html @@ -0,0 +1,222 @@ + + + + + + + Troubleshoot Azure — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Troubleshoot Azure

+
+
+

Error 403

+

This usually happens when you reach free credits limit.
+Make sure you have an active Basic plan subscription. If you only used free services as specified in the installation guide, you shouldn’t be billed.

+../../_images/AzureT01.png +



+
+
+

Restart app

+

Log in Azure and select your App Service (cgmitc in the picture is an example, yours will have a different name).

+../../_images/AzureT02.png +
+

Click on Restart and confirm. Wait a few minutes until restart completes.

+../../_images/AzureT03.png +



+
+
+

Billing occurred

+

Make sure you didn’t add technical support.

+

Check here and click the link at the top of the page: Choose the right support plan.

+

You should have a Basic support plan, that is free.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/troubleshoot/cleanup/index.html b/troubleshoot/cleanup/index.html new file mode 100644 index 00000000..85755c77 --- /dev/null +++ b/troubleshoot/cleanup/index.html @@ -0,0 +1,216 @@ + + + + + + + Cleanup — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Cleanup

+

After unsuccessful attempts you might want to cleanup the various accounts to avoid confusion.

+

If you’re still trying to deploy your first Nightscout, ignore all data loss recommendations below.

+

If you have a large amount of CGM data, be extra cautious when performing Atlas cleanup.

+
+
+

GitHub

+

The most efficient way to cleanup GitHub and restart with an up-to-date Nightscout project is to redeploy it.

+

You will then need to reconnect your repository to Heroku or Railway.

+
+
+
+

Heroku

+

Look here.

+
+
+
+

Atlas

+

Look here.

+
+
+
+

Railway

+

Look here.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/troubleshoot/connection_string/index.html b/troubleshoot/connection_string/index.html new file mode 100644 index 00000000..2d846c68 --- /dev/null +++ b/troubleshoot/connection_string/index.html @@ -0,0 +1,193 @@ + + + + + + + Connection string — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Connection string

+

Moved here.

+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/troubleshoot/dexcom_bridge/index.html b/troubleshoot/dexcom_bridge/index.html new file mode 100644 index 00000000..3d9e94d2 --- /dev/null +++ b/troubleshoot/dexcom_bridge/index.html @@ -0,0 +1,338 @@ + + + + + + + Troubleshoot Dexcom Share — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Troubleshoot Dexcom Share

+
+
+

Username and password

+

Your Dexcom account is the one that identifies you to access all services: Store, Clarity and mobile apps. In order to make sure you’re accessing the right account, log into Clarity to check your credentials are valid.

+

For US account: https://clarity.dexcom.com/
+For all others: https://clarity.dexcom.eu/

+../../_images/DexShare01.png +

In the case you have linked accounts, check you are using the right credentials for the profile you want to bridge to Nightscout.

+

Verify you actually have current data in this profile/account! You want to put the username and password of the account that has CGM data in BRIDGE, this is usually the credentials you are using with the master phone (the one connected to the sensor).

+../../_images/DexShare05.png +
+

Password

+

Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.

+
+
+

Changing password

+

Before you decide to change your password, make sure to update your Nightscout variables accordingly and make sure you have recent data in Clarity before exiting maintenance mode.

+
+
+
+
+

Username is an email

+

Newly created Dexcom users do not have an username but only an email address.

+../../_images/DexShare01b.png +

This can be an issue if you want to use bridge to have your data directly in Nightscout. Make sure you’re using the latest release if you experience problems.

+

Common symptoms are:

+
    +
  • no data in Nightscout even with correct credentials

  • +
  • account locking once or more per day even with correct credentials

  • +
+
+
+
+

Username is a phone number

+

New users might have the phone app setup with their phone number including country code and the symbol +. This is not supported by Nightscout. Continue below and create a dependent account with an alphanumerical username.

+
+
+
+

Obtaining a username

+

Dependent accounts can have a username.

+../../_images/DexShare02.png +

You can create your Dexcom account and add dependent accounts for children, wife, …

+

Some dependent accounts with an email address can generate problems when trying to connect directly to Nightscout.

+
+
+
+

Account lock

+

You can check if your account is locked by trying to log into Clarity.

+../../_images/DexShare00.png +

If you see this message, you must disable (enter an empty username for example) all devices and apps trying to get data from or push data into Dexcom share.

+

In order to recover from an account lock, it is usually enough to wait for 10-15 minutes after you disabled all devices and apps trying to access the account with a wrong password.

+

Do not forget any app or device!

+
    +
  • Nightscout

  • +
  • Smartwatches apps

  • +
  • Sugarmate, Happy Bob, xDrip+,…

  • +
  • +
+
+
+
+

Dexcom Share

+

Make sure you have Dexcom Share turned ON in your Dexcom app. In the Dexcom app’s main screen, find the triangle made of dots. If the dots are grey, you do not have Share turned on. Tap the triangle, and follow the directions to add a follower (yourself if you don’t have someone else you’d like to invite) and turn on Share.

+../../_images/sharing.jpg +
+

If you are using a Dexcom system, and your data is not appearing in Nightscout, there are only a limited number of reasons for that. You should check your (1) Heroku settings and (2) Dexcom Share.

+

NOTE: The #1 reason why BGs aren’t showing is that you have mismatched password and user names in Heroku settings and Dexcom.

+
+

Verify your configuration

+

Variables location will depend on the platform you use:

+
+ + + + + + + + + + + + +
+
+
    +
  1. You must use the same BRIDGE_PASSWORD or BRIDGE_USER_NAME that your Dexcom mobile app is using.

  2. +
  3. You must have bridge and careportal on the ENABLE line (you can have other values there…but don’t forget these two).

  4. +
  5. If you are outside the USA, you must add BRIDGE_SERVER set to EU in Heroku settings.

  6. +
  7. Your careportal must be one word in the ENABLE line, sometimes autocorrect makes it two words.

  8. +
  9. If using mmol, make sure you have spelled that value correctly in the DISPLAY_UNITS.

  10. +
+
+
+
+

Authentication errors

+

One thing that can happen if you have an incorrect Dexcom login/password in your Share account settings and/or in your Nightscout BRIDGE settings is that Dexcom will lock your account…and you won’t see CGM data in Nightscout. If you notice your CGM readings disappeared, but everything else is flowing…
+Check your Heroku logs that are viewable by selecting View Logs from the drop-down menu underneath the More option.

+../../_images/heroku-logs.png +

With Railway they are available selecting your app, then Deployments and View Logs at the end of the top (last) deployment line.

+../../_images/railway-logs.png +
+

Do your logs have “SSO authentication errors” like in the red box highlighted above? If you do, then:

+
    +
  1. Delete your BRIDGE entries within Heroku settings. Don’t delete the variables, just delete the values of BRIDGE_PASSWORD and BRIDGE_USER_NAME.

  2. +
  3. Wait 15 minutes and then follow the directions below. It is important to wait 15 minutes: the reason you can’t log in right now is that your Dexcom account has a temporary lock from the passwords in the step above being incorrect. The temporary lock will expire after 10-15 minutes of giving the account login a break from the incorrect logins. So, definitely wait or else you’ll just keep prolonging the issue.

  4. +
+
+

Hint

+

About your Bridge password and user name +The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom’s Clarity page (check here for USA accounts and here for the others) and try logging in to your Dexcom account. If your account info isn’t valid, or you don’t see any data in your Clarity account… you need to figure out your actual credentials before moving ahead.

+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/troubleshoot/fly.io/index.html b/troubleshoot/fly.io/index.html new file mode 100644 index 00000000..eaa913c1 --- /dev/null +++ b/troubleshoot/fly.io/index.html @@ -0,0 +1,422 @@ + + + + + + + Troubleshoot Fly.io — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Troubleshoot Fly.io

+
+
+

Warning

+

The web terminal feature was removed from Fly.io. +You need a computer with flyctl.

+
+

Follow these instructions to install flyctl on your computer. You also need to install git if you’re using a Windows computer.

+

Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.

+



+
+

Restart your app

+

Follow these instructions to install flyctl on your computer.

+

Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.

+
    +
  • Log in Fly.io:

  • +
+

flyctl auth login

+
    +
  • Verify your Nightscout app name

  • +
+

flyctl app list

+
    +
  • Restart your app (replace example-ns by the name of your Nightscout app in Fly.io)

  • +
+

flyctl machine restart --app example-ns

+
+
+
+

Recover fly.toml

+

Follow these instructions to install flyctl on your computer.

+

Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.

+
    +
  • Log in Fly.io:

  • +
+

flyctl auth login

+
    +
  • Verify your Nightscout app name

  • +
+

flyctl app list

+
    +
  • Copy your Nightscout app (replace example-ns with your own) configuration file fly.toml.

  • +
+

flyctl config save --app example-ns

+
    +
  • Keep this file in a safe place as you’ll need it to redeploy or upgrade your Nightscout.

  • +
+
+
+
+

Cleanup

+

After several failed attempts to deploy or migrate, you might need to delete some apps.

+

Log into Fly.io https://fly.io/app/sign-in (GitHub recommended)

+../../_images/FlyIO00.png +

In normal running condition you will see only two apps on your dashboard:
+The first one is your Nightscout site and the second one the builder (necessary).
+If you used the migration wizard you will see another builder (three apps).

+../../_images/FlyT01.png +
+

Clicking on your site you will see if it’s healthy and running. This is where you go to open your site.

+../../_images/FlyT01.png +
+
+

Delete an app

+

Select an app from the dashboard. Then click Settings.
+Click Delete app.

+../../_images/FlyT03.png +

Confirm copying the app name below, then click Yes, delete it.

+../../_images/FlyT04.png +

You have deleted your app.

+

If you delete the builder (like in the picture above) you won’t be able to deploy anymore.

+
+
+
+

Delete your local repository

+
+

If you deployed with your own computer.

+
+

Warning

+

Make a backup of the fly.toml file present in the cgm-remote-monitor folder! +This is essential to make your site maintainable!

+
+

You can delete the cgm-remote-monitor folder on your computer and fork it again.

+

Exit the folder before deleting it, in task manager end the flyctl.exe task.

+
+
+

If you deployed from the web terminal.

+

You don’t have a local repository.

+
+
+
+
+
+

Downscale your app

+

Follow these instructions to install flyctl on your computer.

+

Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.

+
+

March 31st 2023, apps deploy in V2 and V1 apps are automatically migrated too.
+This causes some issues as V2 automatically deploys in a more than one machine, your Nightscout site might not work correctly.

+

Type the following command in the terminal (replace example-ns with your own app name):

+
    +
  • Authenticate in Fly.io:

  • +
+

flyctl auth login

+
    +
  • Verify your Nightscout app name

  • +
+

flyctl app list

+
    +
  • Downscale your app:

  • +
+

flyctl scale --app example-ns count 1

+../../_images/FlyT08.png +
    +
  • Your app should now only be running on one machine. Check here.

  • +
+

Note: the builder app is normal, it is stopped: don’t worry about it.

+../../_images/FlyT09.png +
+
+
+

Obtain a free shared IP

+

Follow these instructions to install flyctl on your computer.

+

Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.

+
+

Apps migrated from Heroku will use a dedicated IP billed $1.90/month.

+

If you want to run your Nightscout site in Fly.io for free, you will need to release the IP and request a shared IP.

+

Follow the instructions below. The IP 137.66.11.78 and the site name example-ns are examples, yours will be different. Use your own IP and site name.

+

Open a browser and authenticate:

+

flyctl auth login

+

List the apps to see the name of your Nightscout project:

+

flyctl app list

+
NAME         OWNER           STATUS          PLATFORM        LATEST DEPLOY
+example-ns   personal        deployed        machines        2023-05-26T07:24:51Z
+
+
+

List the IPs used by your app (replace example-ns by your own):

+

flyctl ips list -a example-ns

+
VERSION IP                      TYPE    REGION  CREATED AT
+v4      137.66.11.78            public  global  2022-09-13T14:17:58Z
+v6      3b09:8280:1::3:723c     public  global  2022-09-13T14:18:00Z
+
+
+

Release the dedicated IP you found above (example: 137.66.11.78):

+

flyctl ips release 137.66.11.78 -a example-ns

+
Released 137.66.11.78 from example-ns
+
+
+

Assign a shared IP to your Nightscout site:

+

flyctl ips allocate-v4 --shared -a example-ns

+
v4      <new-ip-assigned> shared  global
+
+
+

You do not need to remember your new IP, just continue using your site name as before: https://yoursitename.fly.dev

+
+
+
+

Migrate from Heroku

+
+

Warning

+

Turboku has been removed from the CLI. This section is obsolete.

+
+

Log into Heroku.

+
    +
  • Write down your Nightscout app name from the dashboard.

  • +
  • Get your API Key from your account settings. Do not share it publicly.

  • +
+

Look into this list and find a free region close to where you live. This is a 3 letters code, for example ams.

+

Open a terminal or an elevated command prompt.

+

Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.

+
    +
  • Log in Fly.io:

  • +
+

flyctl auth login

+
    +
  • Replace example-ns with your Nightscout app from Heroku, API-Key with your Heroku API Key and xxx with the region you selected.

  • +
+

flyctl turboku example-ns API-Key --region xxx

+
    +
  • Your Heroku app will deploy in Fly.io. Wait until deployment completes.

  • +
  • You’ll see the name of your new Nightscout site with Fly.io.

  • +
+
Finished launching new machines
+-------
+ ✔ Machine 784e290f461048 [app] update finished: success
+-------
+Visit your newly deployed app at https://example-ns.fly.dev/
+
+
+
    +
  • Downscale the app, confirm when requested.

  • +
+

flyctl scale --app example-ns count 1

+
    +
  • Turn your Heroku site off (the switch web node lib/server/server.js) and check your new Fly.io Nightscout is running.

  • +
  • Log into Fly.io, select your app and verify it’s using a share V4 IP, release the V6 IP.

  • +
+
+
+

Warning

+

Make a backup of your fly.toml! +This is essential to make your site maintainable!

+
+
    +
  • Fly deployment created a folder with your app name, you’ll find your fly.toml file inside. This file is all what you need to redeploy your project. You will need it to upgrade your Nightscout site or redeploy it.

  • +
+
+

Warning

+

Make a backup of your Heroku variables! +Fly.io will store then as secrets and you won’t be able to read them!

+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/troubleshoot/github/index.html b/troubleshoot/github/index.html new file mode 100644 index 00000000..a1ef9a33 --- /dev/null +++ b/troubleshoot/github/index.html @@ -0,0 +1,296 @@ + + + + + + + Troubleshoot GitHub — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Troubleshoot GitHub

+
+
+

Lost access to GitHub

+

Not a big problem, just create another account if you can’t recover access to the original one:

+
+

Create a GitHub account

+

a) Click this link to create a GitHub account: https://github.com/

+

Enter your email and click Sign up for GitHub

+

../../_images/NewNS00a.png

+

b) Enter a password and a username (anything you want and that is accepted, not very important).
+Type n to decline advertisement emails.

+

../../_images/NewNS00.png

+

c) Play and solve the puzzle then click Create account

+

../../_images/NewNS01.png

+

d) GitHub will send you a verification code. Open your mail and check your inbox (check your spam-folder if not received after a couple of minutes).

+

../../_images/NewNS02.png

+

e) If a personalization sequence starts, click Skip personalization at the bottom.

+

../../_images/NewNS03.png

+

f) Leave the page that opened as it is. Don’t close it.

+

../../_images/NewNS04.png

+

You have created your GitHub account. Now fork the Nightscout project.

+
+
+
+

Fork the Nightscout project

+

a) Click here to log in at GitHub: https://github.com/login.
+Enter your username or email and your password. Click Sign in

+

../../_images/UpdateNS00.png

+
+

If you already have a fork of cgm-remote-monitor in GitHub

+

Delete or update your current cgm-remote-monitor fork before continuing.

+
+

b) Open this link https://github.com/nightscout/cgm-remote-monitor. Click on Fork

+

../../_images/NewNS29.png

+

Confirm with Create fork

+
+

Warning

+

Make sure you deselect Copy the master branch only.

+
+

../../_images/NewNS51.png

+

c) Wait for a moment

+

../../_images/NewNS30.png

+

d) You now have a copy (fork) of the Nightscout project repository in your own GitHub.

+

../../_images/UpdateNS30.png

+

You’ll need to reconnect your app to GitHub.

+
+
+
+
+
+

Cannot update GitHub

+

When encountering update issues with GitHub, the easiest method it to delete it and fork the project again.

+
+

Delete your own fork of cgm-remote-monitor

+
+

Delete Nightscout?

+

Your GitHub only contains a copy of the code necessary to create a Nightscout site.
+Deleting your fork of cgm-remote-monitor will not impact or stop your Nightscout site.
+Even if it sounds scary to delete it, you can do it safely and copy (fork) it again from the main repository.
+You cannot delete the main Nightscout (nightscout/cgm-remote.monitor) repository.

+
+

Obviously if you’re a Nightscout developer and you customized or modified the repository code, you know better than anybody else you don’t want to delete it… (this documentation is not for you).

+
+
+

a) Click here to log in at GitHub: https://github.com/login.
+Enter your username or email and your password. Click Sign in

+../../_images/UpdateNS00.png +
+

b) Select your own cgm-remote-monitor project (not nightscout/cgm-remote-monitor)

+../../_images/UpdateNS01.png +
+

c) Click Settings

+../../_images/UpdateNS26.png +
+

d) Scroll down to Danger zone and click Delete this repository

+../../_images/UpdateNS27.png +
+

e) Copy and paste your full repository name to confirm then click I understand...

+../../_images/UpdateNS28.png +
+

You have successfully deleted your copy of the cgm-remote-monitor project.

+
+
+
+

Fork the Nightscout project

+
+

You’ll need to reconnect your app to GitHub.

+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/troubleshoot/heroku/index.html b/troubleshoot/heroku/index.html new file mode 100644 index 00000000..edd23722 --- /dev/null +++ b/troubleshoot/heroku/index.html @@ -0,0 +1,425 @@ + + + + + + + Troubleshoot Heroku — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Troubleshoot Heroku

+
+
+

There’s nothing here

+../../_images/TShoot57.png +

If you didn’t upgrade Heroku to an Eco or Basic plan, you need to create a new Nightscout site and recover your MongoDB Atlas connection string.

+

If you just upgraded to an Eco or Basic plan, make sure you enabled the web app (that turned off when the Free plan was removed).

+../../_images/TShoot58.png +

If you just tried to deploy a new Nightscout site, something went wrong. Cleanup your Heroku apps and retry…

+
+
+
+

Application Error

+../../_images/TShoot05.png +

Update Nightscout to latest release. It might not fix your issue but it will help find a solution.

+ +
+
+
+

A valid GitHub Directory could not be found.

+

When trying to deploy a new Nightscout site, this message appears when clicking Deploy to Heroku.

+../../_images/TShoot00.png +
    +
  • Change browser and retry.

  • +
+
+
+
+

Cannot find cgm-remote-monitor in Heroku / No GitHub source visible

+

When updating Nightscout, cgm-remote-monitor doesn’t appear automatically in Heroku under your repository name.

+../../_images/TShoot01.png +

When updating Nightscout, your repository name doesn’t appear in Manual Deploy so that you can’t select the master branch.

+../../_images/TShoot04.png +
    +
  • Disconnect and re-Connect like this:

  • +
+../../_images/UpdateNS22.png +../../_images/UpdateNS21.png +
    +
  • If it doesn’t help try to re-authorize as explained below:

  • +
+
+
+
+

Cannot find cgm-remote-monitor in Heroku: Item cannot be retrieved

+

When updating Nightscout, cgm-remote-monitor doesn’t appear automatically in Heroku under your repository name and an error message appears when you try to connect to GitHub.

+../../_images/TShoot02.png +
    +
  • In Heroku, go to Account Settings

  • +
+../../_images/NewNS13.png +
    +
  • Select Applications and click Re-authorize

  • +
+../../_images/TShoot03.png +
    +
  • Click Authorize GitHub in the pop-up.

  • +
  • If it doesn’t help, you can also try to Revoke access… before going back to Re-Connect your GitHub account. This is necessary if someone else did setup Nightscout for you and left his own GitHub connected to your Heroku account.

  • +
+
+
+
+

I can’t log into Heroku

+

If you lost your password use the password reset option.

+

If you lost your authenticator use the recovery codes (that you hopefully saved when securing your account).

+

If you lost or don’t have anymore access to the email you used to create your Heroku account you will need to deploy a new Nightscout site. You can use the same GitHub account and the same MongodB Atlas database you currently have but will have to use another Nightscout site name in Heroku as the current one is already in use. First recover your connection string, and proceed to creating a new Nightscout skipping Step 3.

+
+
+
+

Restart all dynos

+
    +
  • Log in Heroku, go to Settings, More, Restart all dynos.

  • +
+../../_images/MigrateNS57.png +
+
+
+

Sleeping app

+

Check you app didn’t fall asleep:

+../../_images/TShoot25.png +
+

A sleeping app can be due to your Heroku Eco plan: a Basic plan makes the app never sleep. https://www.heroku.com/pricing

+

Another reason for a sleeping app can be due to a failure to obtain data from Dexcom Share, check the logs to understand the reasons.

+
+
+
+

Cleanup

+

If you experience issues during deployment you might end up with many apps. Make sure you keep the last one that was functional or delete all before attempting a new deployment. This will just make it easier to find which app you’re trying to build. Keeping sleeping apps doesn’t have any negative impact but no real advantage unless you do it on purpose.

+

Make sure the app you’re using for Nightscout is running on an Eco/Basic tier.

+

If you’re not convinced you want to delete an app, make sure to put it in maintenance mode to understand if you use it as the related Nightscout site will report offline for maintenance.

+
+
+

Maintenance mode

+

Maintenance mode is useful to troubleshoot Dexcom and CareLink accounts locked and also if you need to modify several variables without having Nightscout restarting every change.

+

You can also put your Nightscout in maintenance mode if you won’t use it for an extended period of time.

+
+

Warning

+

Putting your site in maintenance mode won’t stop billing!

+You also need to disable the web service for this.

+../../_images/TShoot59.png

+
+

Be aware that your MongoDB Atlas database might also go in sleep mode and you will need to restart it manually.

+../../_images/Cleanup00a.png +
+
+
+

Delete an app

+

Deleting an Heroku app does not delete your Nightscout data, but you might want to write down your variables (definitely backup your connection string) if your site was functional before. Note that you can also rename an app (unless the name is already in use in heroku.com).

+../../_images/Cleanup00.png +

To delete an app, select it and go to Settings, scroll down to Delete App

+../../_images/Cleanup01.png +

Copy and paste your app name to confirm deletion,

+../../_images/Cleanup02.png +
+
+
+
+

Backup your site variables

+

Having a copy of your variables is very important since some of them are vital to your site like MONGODB_URI and your access to it like API_SECRET.

+
+

Method 1 - Spreadsheet

+

Log into Heroku, select your app.
+Reveal your Heroku Nightscout app Config Vars and copy all variables names and values in a spreadsheet.

+
+
+

Method 2 - Export

+

Log into Heroku, select your app.
+Click on the top right More button and select Run console.

+../../_images/HerokuM01.png +

In the console command line type the command below, then click Run.

+
export `heroku config -s`
+
+
+../../_images/HerokuM02.png +

Wait until the command completes.

+../../_images/HerokuM03.png +

Save the session: it contains all your variables and values (and a few useless things).

+../../_images/HerokuM04.png +

Edit the file with a text editor and remove the first line (bash: line 1: heroku: command not found).
+Using find and replace, get rid of all declare -x.
+Delete the following Heroku specific variables:

+

DYNO="run.6309" HOME="/app" MEMORY_AVAILABLE="512" NODE_ENV="production" NODE_HOME="/app/.heroku/node" OLDPWD PATH="/app/.heroku/node/bin:/app/.heroku/yarn/bin:/usr/local/bin:/usr/bin:/bin:/app/bin:/app/node_modules/.bin" PORT="6489" PS1="\\[\\033[01;34m\\]\\w\\[\\033[00m\\] \\[\\033[01;32m\\]\$ \\[\\033[00m\\]" PWD="/app" SHLVL="1" TERM="xterm-256color" WEB_CONCURRENCY="1" WEB_MEMORY="512"

+
+

Warning

+

Save this file in a safe place

+
+
+
+
+
+

Roll back Heroku

+
+

Roll back can be really useful in case of mistakes and when awaiting bug fixes in minor releases.

+
+

Warning

+

You can only roll back to a version that was previously deployed to your Heroku app.

+
+

Heroku keeps history of variables modifications and previous deploys so that you can return to a previous state easily in the cases of a configuration mistake or a bad deploy (like a bugged version). When rolling back to a previous deploy keep in mind all variables modified in the mean time will return to the value they had at that time.

+

Since the database is external to Heroku, it will not be impacted by a roll back.

+
+
    +
  • Log into Heroku.

  • +
  • Select your Nightscout app and go to Activity

  • +
+../../_images/Downgrade00.png +
+
    +
  • You will see a list of events called Activity Feed and some indicated as possible roll-back points. Identify the last good situation and select Roll back to here

  • +
+../../_images/Downgrade01.png +
+
    +
  • Identify and eventually write down the values of the variables that were changed in the meantime (arrows in the picture below) before selecting Rollback.

  • +
+../../_images/Downgrade02.png +
+

Upon completion your Heroku will be returned to the state it was at the selected rollback point.

+

You can use it like this or upgrade to the latest released version later on.

+
+
    +
  • If you change your mind later you can rollback prior to your rollback and return to the starting point.

  • +
+../../_images/Downgrade03.png +
+
+
+

Stop using Heroku

+

If you want to migrate your data, it is recommended that you do it before switching off your Heroku Nightscout.

+

To stop using Heroku and suspend billing, you only need to switch off all apps like this:

+
    +
  • Log into Heroku.

  • +
  • Select your app(s) in the dashboard.

  • +
+../../_images/MultiNS00.png +
    +
  • In Resources, edit (pen icon) and turn off the web server switch.

  • +
+../../_images/Cleanup031.png +
    +
  • Your Heroku Nightscout site will stop and only the current month will be billed.

  • +
  • You can keep your Heroku account and leave the credit card, once no app is active billing will stop.

  • +
  • Your data will not be deleted, make a copy of the MONGODB_URI variable if you want to reuse it with another platform, or migrate your database.

  • +
  • If you decide you will not use it anymore, once last billing has occurred, you can delete your app(s), credit card and Heroku account.

  • +
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/troubleshoot/northflank/index.html b/troubleshoot/northflank/index.html new file mode 100644 index 00000000..ccd1a59f --- /dev/null +++ b/troubleshoot/northflank/index.html @@ -0,0 +1,216 @@ + + + + + + + Troubleshoot Northflank — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Troubleshoot Northflank

+
+
+

Site doesn’t open after build

+

upstream connect error or disconnect/reset before headers. retried and the latest reset reason: remote connection failure, transport failure reason: delayed connect error: 111

+

You probably need to wait until the deploy is finished. Refresh the page after 5 minutes.

+
+
+
+

Restart

+

a) Log into Northflank and select your Nightscout project, then its service.

+../../_images/NorthflankT01.png +
+

b) Click Rollout Restart and confirm Restart Service.
+Wait until restart is complete with the cloud status Running.

+../../_images/NorthflankT02.png +
+

If your site crashes again shortly after, verify your database is not full if you use MongoDB Atlas.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/troubleshoot/railway/index.html b/troubleshoot/railway/index.html new file mode 100644 index 00000000..4ea5fb2d --- /dev/null +++ b/troubleshoot/railway/index.html @@ -0,0 +1,309 @@ + + + + + + + Troubleshoot Railway — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Troubleshoot Railway

+
+
+

Nothing here

+
+
+

Warning

+

The free plan has been removed Jul 3rd for new users and Aug 1st for existing users.

+
+
+

It has been running fine for the first 200/500 hours and now it’s gone. Even the project disappeared in Railway.

+../../_images/RailwayT12.png +

This is usually because you need a Developer plan to run your Nightscout app in Railway.

+
+
+
+

Restart your app

+

a) Open the Railway Dashboard and select your project then your app.

+../../_images/RailwayT13.png +
+

b) In your web deployments select the current one (top of the list) and in the three dots menu on the right, Restart.

+../../_images/RailwayT14.png +
+

b) Confirm Restart. Wait a moment and check your Nightscout site state clicking the URL.
+If your site crashes again shortly after, verify your database is not full if you use MongoDB Atlas.

+../../_images/RailwayT15.png +
+
+
+

Reconnect GitHub to your project

+

a) Open Railway and click login. Login with GitHub.

+../../_images/Railway00.png +../../_images/Railway01.png +
+

b) Select your Nightscout project.

+../../_images/RailwayM15.png +
+

c) Select your web app.

+../../_images/RailwayM16.png +
+

d) Select Settings and scroll down to Service.
+Disconnect your Source Repo with the cross at the end of the line.

+../../_images/RailwayT01.png +
+

e) Confirm Disconnect.

+../../_images/RailwayT02.png +
+

f) Select Connect Repo.

+../../_images/RailwayT03.png +

You should be able to select your GitHub cgm-remote-monitor repository.
+You have now successfully reconnected your GitHub project to Railway.
+If your GitHub repository cgm-remote-monitor was changed (updated for example), your Railway app will automatically redeploy.

+../../_images/RailwayM03.png +

If you don’t see the picture above: continue below.

+
+

g) If you redeployed (deleted and recreated) cgm-remote-monitor in GitHub select Configure GitHub app.

+../../_images/RailwayM02.png +
+

h) Select your GitHub account.

+../../_images/RailwayT04.png +
+

i) Click Only Select repositories and from the Select Repositories button choose your cgm-remote-monitor Nightscout project. Click then Install & Authorize.

+../../_images/Railway08.png +

You have now successfully reconnected your GitHub project to Railway.
+If your GitHub repository cgm-remote-monitor was changed (updated for example), your Railway app will automatically redeploy.

+
+
+
+

Cleanup

+

After several deployment attempts your Railway account might show more than one app. Since there is a 5$ limit to hobby plan before increased billing, depending on how you use it, it is important to make sure you don’t have useless apps wasting CPU time and memory.

+

Open Railway and click login. Login with GitHub.

+../../_images/Railway00.png +
+

If you see more than one (or two if you have a local database) projects on your dashboard, you should delete those unused.

+../../_images/RailwayT05.png +
+
+

Empty projects

+

You can safely delete empty projects (in red in the picture above).

+

Select your project then click on Settings.

+../../_images/RailwayT06.png +
+

Click on Danger.

+../../_images/RailwayT07.png +
+

Then Delete project.

+../../_images/RailwayT08.png +
+

Copy and paste the project name in the box below and click Delete.

+../../_images/RailwayT09.png +
+
+
+

Databases

+

Before deleting a database you need to check it’s empty.

+

Click twice on the database project and select Data.

+

This example below is not an empty database. You need to check it’s not being used by Nightscout before deleting it.
+You can see data inside: profile, devicestatus, etc…

+../../_images/RailwayT10.png +
+

This example below is empty, you can safely delete it (like shown above for an empty project).
+There is no data inside this database. When you pull down the Database tab, there is only test and it’s empty.

+../../_images/RailwayT11.png +
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/troubleshoot/render/index.html b/troubleshoot/render/index.html new file mode 100644 index 00000000..25e8bba1 --- /dev/null +++ b/troubleshoot/render/index.html @@ -0,0 +1,215 @@ + + + + + + + Troubleshoot Render — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Troubleshoot Render

+
+
+

Restart service

+

If your site is not responding (doesn’t open), you can try to restart it.
+Mind it might only have fallen asleep and would need an uptime robot to stay awake.

+
    +
  • Sign in Render with GitHub

  • +
+

../../_images/Render02.png

+
    +
  • Select your web service

  • +
+../../_images/Render16.png +
    +
  • In the Dashboard, open the Manual Deploy drop down menu and select Restart service.

  • +
+../../_images/RenderT01.png +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/troubleshoot/troublehoot/index.html b/troubleshoot/troublehoot/index.html new file mode 100644 index 00000000..1c5fbff5 --- /dev/null +++ b/troubleshoot/troublehoot/index.html @@ -0,0 +1,192 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/troubleshoot/troubleshoot/index.html b/troubleshoot/troubleshoot/index.html new file mode 100644 index 00000000..45c89be4 --- /dev/null +++ b/troubleshoot/troubleshoot/index.html @@ -0,0 +1,439 @@ + + + + + + + Troubleshooting Nightscout — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Troubleshooting Nightscout

+
+
+

Before troubleshooting

+
    +
  1. Check your email (maybe you missed an important announcement)

  2. +
  3. Check your internet provider / SIM credit (can all devices browse internet?)

  4. +
  5. Try another browser/computer (if building your Nightscout site)

    +
    +
  6. +
+
+
+

Overall third party services

+

Check the services you’re using are available

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Vendor

Check here:

Dexcom
Dexcom US account
Dexcom non-US account

https://status.dexcom.com/
https://clarity.dexcom.com/
https://clarity.dexcom.eu/

Carelink US account
Carelink non-US account

https://carelink.minimed.com/
https://carelink.minimed.eu/app/login

GitHub

https://www.githubstatus.com/

Heroku

https://status.heroku.com/

Railway

https://railway.instatus.com/

MongoDB Atlas

https://status.cloud.mongodb.com/

Northflank

https://status.northflank.com/

Azure

https://azure.status.microsoft/

NS10BE

https://ns.10be.de/en/status.html

+
+
+
+
+

Application crashed

+

Not knowing if it’s a permanent issue, first try to restart it…

+
+ + + + + + + + + + + + +
+
+
+
+

GitHub

+

Follow these instructions.

+
+
+

Heroku

+

Search your issue there.

+

There’s nothing here, yet can be due to billing issues.

+

An Application error means Heroku crashed. Restart it and check database size.

+
+
+

Atlas

+

Issues during database creation look there.

+

The usual reason for failure at build time is a bad connection string (Atlas).

+

If you encounter a Boot Error - Unable to connect to Mongo it might be due to a Database Full

+
+
+

Railway

+

Mind you can’t deploy Railway if you just created a new GitHub account.

+

Nothing there is usually because you forgot to subscribe to a Developer plan.

+

Else go there.

+
+
+

Fly.io

+

Fly.io troubleshooting is complex if you didn’t save your fly.toml configuration. Check in your local clone of the cgm-remote-monitor project. If you can’t find it, recover it first.

+

Try to redeploy your app.

+

Once done, issues are most probably due to your fly.toml contents or variables.

+
+
+
+
+

Other issues

+
+

Reports

+

Reports slow loading or timeout

+
+
+

No data in Nightscout

+

Check your uploader is configured correctly.

+

Make sure your Nightscout time zone is correct.

+

If you use a DIY closed loop system make sure it’s setup correctly.

+
+
+

Dexcom data not showing

+

See this dedicated page.

+
+ +
+

Data timing issues

+
+

Basal is shifted in time

+
    +
  • Check the time zone is correct for your currently active profile in your Nightscout Profile editor.

  • +
+../../_images/TShoot30.png +
+
+
+

Data in the future

+
    +
  • Check you don’t have data in the future with the Admin tools. Remove them if existing.

  • +
+../../_images/TShoot31.png +
+
    +
  • If this isn’t working, or shows no future data, check in your database (Atlas see here)

  • +
+
+
+
+

Basal / IOB / COB missing after DST

+
    +
  • Setup again your time zone in profile editor (authenticate and save).

  • +
+
+
+
+
+

Error code instead of a BG value

+

Nightscout implements Dexcom error codes as listed below:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Code

Corresponding error

?SN

Sensor not active

?MD

Minimal deviation

?NA

No antenna

?NC

Sensor not calibrated

?CD

Counts deviation

?AD

Absolute deviation

???

Power deviation

?RF

Bad RF

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/update/dev_branch/index.html b/update/dev_branch/index.html new file mode 100644 index 00000000..83ede1bc --- /dev/null +++ b/update/dev_branch/index.html @@ -0,0 +1,466 @@ + + + + + + + Deploy another version — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Deploy another version

+

If you need to return to the previous Nightscout version, or in rare occasions, like testing a specific fix or a feature that is not released yet (i.e. not in the master branch), you might need to deploy another branch like dev in the example below.

+

Do not deploy dev or a branch other than master unless directed to do so (except if you know why you are doing so).

+
+

Step 1: Update your repository in GitHub

+

Select your platform below:

+
+ +
+
+
+ +
+


- Click here to log in at GitHub: https://github.com/login.

+
    +
  • Enter your username or email and your password. Click Sign in

    +../../_images/UpdateNS00.png

  • +
  • Select your own cgm-remote-monitor project (not nightscout/cgm-remote-monitor)

    +../../_images/UpdateNS01.png

  • +
  • Your repository will open.

    +../../_images/Dev00.png

  • +
  • In the branch drop down menu (normally showing master) select dev

    +../../_images/Dev01.png

  • +
  • ClickFetch upstream to update it, then Fetch and merge

    +../../_images/Dev03.png

  • +
  • After a moment, your repository should display This branch is up to date with nightscout:dev

    +../../_images/Dev04.png

  • +
  • If you ran into trouble, try to Redeploy (and this is mandatory if you don’t see dev in GitHub.)

  • +
+
+ +
+


You don’t need to update your GitHub repository.

+
+ +
+


You don’t need to update your GitHub repository if you deployed from https://github.com/nightscout/cgm-remote-monitor.

+
+
+
+
+
+

Step 2: Deploy

+

Select your platform below:

+
+ +
+
+
+ +
+

Here

+
+ +
+
    +
  • Log in Heroku https://id.heroku.com/login

    +../../_images/UpdateNS15.png

  • +
  • Select your app (hidden in yellow)

    +../../_images/UpdateNS16.png

  • +
  • Click on Deploy

    +../../_images/UpdateNS17.png

  • +
  • Verify Heroku is connected to GitHub, if not, click Connect to GitHub

    +../../_images/UpdateNS18.png

  • +
  • If Heroku is not connected to GitHub, scroll down and click Connect to GitHub, if a popup window opens and requires authorization, click Authorize Heroku

    +../../_images/UpdateNS19.png

  • +
  • Verify your app cgm-remote-monitor is connected to GitHub

    +../../_images/UpdateNS20.png

  • +
  • If it isn’t, In Connect to GitHub, type cgm-remote-monitor and click Search then click Connect

    +../../_images/UpdateNS21.png

  • +
  • If you have trouble connecting your app, click Disconnect and reconnect it as shown above

    +../../_images/UpdateNS22.png

  • +
  • Scroll down to the bottom of the page, select the dev branch and click Deploy Branch

    +../../_images/Dev05.png

  • +
  • Build will start and information will scroll in the log window. Do not leave the page, do not interfere and wait for completion. It might take more than 10 minutes. Interrupting the process will lead to a broken site and you’ll need to restart deployment.

    +../../_images/UpdateNS24.png

  • +
  • Wait until the deploy process completes and click View (if nothing happens click Manage App then upper right Open App)

    +../../_images/UpdateNS25.png

  • +
+
+ +
+
    +
  • Open Railway and click login. Login with GitHub.

    +../../_images/Railway00.png

    +../../_images/Railway01.png

  • +
  • Select your Nightscout project.

    +../../_images/RailwayM15.png

  • +
  • Select your web app.

    +../../_images/RailwayM16.png

  • +
  • Still in Settings look at Environment.

  • +
  • Change the Deployment Trigger with dev (it was showing master).

    +../../_images/Dev07.png

  • +
  • If you only see master in the list you need to redeploy taking care to select all branches and not only master.
    +../../_images/Dev06.png

  • +
  • Once dev selected Railway will deploy automatically.

  • +
+
+ +
+


a) Open Railway and click login. Login with GitHub.

+../../_images/Railway00.png

+../../_images/Railway01.png

+b) Select your Nightscout project.

+../../_images/RailwayM15.png

+c) Select your Docker service.

+../../_images/RailwayD05.png

+d) Click on Settings, disconnect the source image.

+../../_images/RailwayD09.png

+e) Select Connect image and replace nightscout/cgm-remote-monitor:latest with the version you want to deploy (for example nightscout/cgm-remote-monitor:latest_dev).

+../../_images/RailwayD10.png

+../../_images/RailwayD04.png

+f) On the top left of the screen Deploy.

+../../_images/RailwayD06.png

+
    +
  • Your site will redeploy with the latest version.

  • +
+
+ +
+
    +
  • Log into Northflank: https://app.northflank.com/login

  • +
  • Select your Nightscout project

    +../../_images/Dev14.png

  • +
  • Select your Nightscout service

    +../../_images/Dev15.png

  • +
  • Click on the pen icon after the current branch (example below: master)

    +../../_images/Dev16.png

  • +
  • In the branch list, select the version you want to deploy, then click Update Build Source

    +../../_images/Dev17.png

  • +
  • Your site will redeploy with the selected branch

  • +
+
+ +
+
    +
  • Log into Northflank: https://app.northflank.com/login

  • +
  • Select your Nightscout project

    +../../_images/Dev14.png

  • +
  • Select your Nightscout service

    +../../_images/Dev15.png

  • +
  • In Overview, Edit deployment

    +../../_images/Dev18.png

  • +
  • In the image path, replace nightscout/cgm-remote-monitor:latest with the version you want to deploy (for example nightscout/cgm-remote-monitor:latest_dev), then click Update & rollout restart

    +../../_images/Dev19.png

  • +
  • Your site will redeploy with the selected branch

  • +
+
+ +
+
    +
  • Log into Azure : https://portal.azure.com/

  • +
  • Select your App service, your Nightscout site name (you should see it in recent resources)

    +../../_images/Azure42.png

  • +
  • If you didn’t find it, it will show in App Services

    +../../_images/Azure43.png

  • +
  • In the left menu select Deployment Center, in Full Image Name and Tag change the version to:

    +nightscout/cgm-remote-monitor:latest_dev (example for dev)

    +Or whichever version (change filter tag find the version) in the list.

    +nightscout/cgm-remote-monitor:14.2.6 (example for 14.2.6)

    +../../_images/Dev12.png

  • +
  • Click Save (or Discard if you don’t want to save).
    +Your site will redeploy if you changed the configuration. Expect a few minutes before it comes back online.

    +../../_images/Dev13.png

  • +
+
+ +
+

Follow these instructions to install flyctl on your computer. You also need to install git if you’re using a Windows computer.

+Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.

+
    +
  • Log in Fly.io:

    +flyctl auth login

  • +
  • Verify your Nightscout app name, use it to replace example-ns in the following lines.

    +flyctl app list

  • +
  • Verify your app current region (three letters code) and make sure it’s in the free tier.

    +flyctl app list

  • +
  • Navigate to the cgm-remote-monitor folder from which you deployed Nightscout on your computer. Verify it contains the fly.toml configuration file you used to deploy your site.

    +
      +
    • If you don’t see this file, recover it:

      +flyctl config save --app example-ns

    • +
    +
  • +
  • If you migrated from Heroku using the wizard, or if you can’t find this folder on your computer, follow the next steps to recover your Fly.io configuration:

    +
      +
    • Fork a copy of the Nightscout repository and change directory

      +git clone https://github.com/nightscout/cgm-remote-monitor

      +cd cgm-remote-monitor

    • +
    • Download a default fly.toml configuration file

      +flyctl config save --app example-ns

    • +
    +
  • +
  • Update your Nightscout repository

    +git config pull.rebase true

    +git pull origin dev

  • +
  • Edit your fly.toml configuration and search this section:

  • +
+
[[services]]
+  protocol = "tcp"
+  internal_port = 8080
+  processes = ["app"]
+
+
+
    +
  • Change the internal port value to 1337, do not change anything else, do not remove the spaces before internal_port.

    +internal_port = 1337

  • +
  • Save the fly.toml file.

  • +
  • Deploy Nightscout:

    +flyctl launch

  • +
  • Wait until completion, you site should now be running the latest Nightscout version.

  • +
+
Updating existing machines in 'example-ns' with rolling strategy
+
+-------
+ ✔ Machine 1781944ae46438 [app] update succeeded
+-------
+
+Visit your newly deployed app at https://example-ns.fly.dev/
+
+
+
    +
  • Don’t forget to downscale the app if you haven’t yet!

    +flyctl scale --app example-ns count 1

    +

  • +
+
+ +
+
    +
  • Log into Render: https://dashboard.render.com/

  • +
  • Select your Nightscout project

    +../../_images/Render16.png

  • +
  • Go to Settings and scroll down to Deploy. Edit the URL of the image deployed

    +../../_images/RenderD10.png

  • +
  • Change it to:

    +nightscout/cgm-remote-monitor:latest_dev (example for dev)
    +Or whichever version (change filter tag find the version) in the list.
    +nightscout/cgm-remote-monitor:14.2.6 (example for 14.2.6)

    +../../_images/RenderD11.png

  • +
  • Click Save changes.

  • +
  • Your site will redeploy with the selected branch

  • +
+
+
+
+

Check your profile time zone is correct. You’re done!

+
+
+
+
+

How to return to the master release

+

If things don’t go as expected you can simply redeploy your master branch performing the same steps and using master instead of dev.

+

When the dev branch gets merged into release, just follow the classic update method.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/update/downgrade/index.html b/update/downgrade/index.html new file mode 100644 index 00000000..07407bc0 --- /dev/null +++ b/update/downgrade/index.html @@ -0,0 +1,233 @@ + + + + + + + Downgrade Nightscout — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Downgrade Nightscout

+
+

There is usually no good reason to downgrade Nightscout unless being instructed to do so.

+

First try to deploy another version if available: see Deploy another version.

+

If you use Heroku and you want to return to the previous version, see Roll back Heroku.

+
+
+

Deploy an old release

+
+
+

Docker

+

You deployed a Docker container: you’re not using GitHub (Azure, Northflank, Railway, Render) use this method.

+
+
+
+

GitHub

+

You forked Nightscout in your own GitHub account and used it to deploy.

+

Experienced users only - not recommended

+

Deploying an archived release of Nightscout is complex and involves using Git on your computer (You need to install git if you’re using a Windows computer).

+

Before starting you need to have the project nightscout/cgm-remote-monitor forked in your GitHub repository, with not only the master fork copied (look out for the check box!). It is recommended to redeploy paying attention to this step.

+

Clone it locally (navigate to the folder where you’ll want it saved locally before cloning). Replace YOUR-USERNAME by your GitHub user name.

+

git clone https://github.com/YOUR-USERNAME/cgm-remote-monitor

+

First identify the commit matching the release you want to use, look into the released versions.

+../../_images/Downgrade04.png +
+

Then create a branch out of this commit (replace BRANCH by the branch name you want and indicate the COMMIT matching the one you need, in the case above b627d31):

+

git checkout -b BRANCH COMMIT

+

Push this new branch to your repository

+

git push --set-upstream origin BRANCH

+
+

You can now deploy it in your web app, selecting it in the drop down menu.

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/update/redeploy/index.html b/update/redeploy/index.html new file mode 100644 index 00000000..0b8bd1de --- /dev/null +++ b/update/redeploy/index.html @@ -0,0 +1,234 @@ + + + + + + + Redeploy with GitHub — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Redeploy with GitHub

+

When encountering update issues with GitHub, the easiest method it to delete it and fork the project again.

+
+

Delete your own fork of cgm-remote-monitor

+
+

Delete Nightscout?

+

Your GitHub only contains a copy of the code necessary to create a Nightscout site.
+Deleting your fork of cgm-remote-monitor will not impact or stop your Nightscout site.
+Even if it sounds scary to delete it, you can do it safely and copy (fork) it again from the main repository.
+You cannot delete the main Nightscout (nightscout/cgm-remote.monitor) repository.

+
+

Obviously if you’re a Nightscout developer and you customized or modified the repository code, you know better than anybody else you don’t want to delete it… (this documentation is not for you).

+
+
+

a) Click here to log in at GitHub: https://github.com/login.
+Enter your username or email and your password. Click Sign in

+../../_images/UpdateNS00.png +
+

b) Select your own cgm-remote-monitor project (not nightscout/cgm-remote-monitor)

+../../_images/UpdateNS01.png +
+

c) Click Settings

+../../_images/UpdateNS26.png +
+

d) Scroll down to Danger zone and click Delete this repository

+../../_images/UpdateNS27.png +
+

e) Copy and paste your full repository name to confirm then click I understand...

+../../_images/UpdateNS28.png +
+

You have successfully deleted your copy of the cgm-remote-monitor project.

+
+
+
+

Fork the Nightscout project

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/update/upd_stack/index.html b/update/upd_stack/index.html new file mode 100644 index 00000000..67d173c1 --- /dev/null +++ b/update/upd_stack/index.html @@ -0,0 +1,255 @@ + + + + + + + Update the Heroku stack — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Update the Heroku stack

+
+

AAPS users: mind the compatibility matrix!

+
+

It is good practice to maintain your Heroku stack up to date. Either when you receive an email from Heroku or when you update your Nightscout site (which is also a good habit).

+
+ +
+../../_images/UpdateNS15.png +
+
    +
  • Select your app

  • +
+../../_images/SetupNS00.png +
+
    +
  • Click Settings

  • +
+../../_images/SetupNS01.png +
+
    +
  • If present select Upgrade Stack

  • +
+../../_images/UpdateHK01.png +
+
    +
  • Confirm the upgrade

  • +
+../../_images/UpdateHK02.png +
+
    +
  • Now you need to deploy to upgrade the stack

  • +
+../../_images/UpdateHK03.png +
+
    +
  • Click on Deploy

  • +
+../../_images/UpdateNS17.png +
+
    +
  • Scroll down to the bottom of the page, select the master branch and click Deploy Branch

  • +
+
+

Hint

+

If you can’t select the master branch or Deploy Branch doesn’t do anything reconnect GitHub.

+
+../../_images/UpdateNS23.png +
+
    +
  • Build will start and information will scroll in the log window. Do not leave the page, do not interfere and wait for completion. It might take more than 10 minutes. Interrupting the process will lead to a broken site and you’ll need to restart deployment.

  • +
+../../_images/UpdateNS24.png +
+
    +
  • Wait until the deploy process completes and click View (if nothing happens click Manage App then upper right Open App)

  • +
+../../_images/UpdateNS25.png +
+

You have upgraded your Heroku stack.

+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/update/update/index.html b/update/update/index.html new file mode 100644 index 00000000..2149c933 --- /dev/null +++ b/update/update/index.html @@ -0,0 +1,427 @@ + + + + + + + Update Nightscout — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Update Nightscout

+
+

Tip

+

You don’t need to follow these instructions if you use a hosted service.
Contact the vendor to learn more about possible updates.

+
+
+

See here which is the current released version before updating.

+
+
+

Step 1: Update your repository in GitHub

+

Select your current platform below:

+
+ +
+
+
+ +
+


- Click here to log in at GitHub: https://github.com/login.

+
    +
  • Enter your username or email and your password. Click Sign in

    +../../_images/UpdateNS00.png

  • +
  • Select your own cgm-remote-monitor project (not nightscout/cgm-remote-monitor)

    +../../_images/UpdateNS01.png

  • +
  • Your repository will open.

    +../../_images/Dev00.png

  • +
  • In the branch drop down menu (normally showing master) select dev

    +../../_images/Dev01.png

  • +
  • ClickFetch upstream to update it, then Fetch and merge

    +../../_images/Dev03.png

  • +
  • After a moment, your repository should display This branch is up to date with nightscout:latest

    +../../_images/Dev04.png

  • +
  • If you ran into trouble, try to Redeploy

  • +
+
+ +
+


You don’t need to update your GitHub repository.

+
+ +
+


You don’t need to update your GitHub repository if you deployed from https://github.com/nightscout/cgm-remote-monitor.

+
+
+
+
+
+

Step 2: Deploy

+
+ +
+
+
+ +
+


Continue here

+
+ +
+
    +
  • Log in Heroku https://id.heroku.com/login
    +
    ../../_images/UpdateNS15.png

  • +
  • Select your app (hidden in yellow)
    +
    ../../_images/UpdateNS16.png

  • +
  • Click on Deploy
    +
    ../../_images/UpdateNS17.png

  • +
  • Verify Heroku is connected to GitHub, if not, clickConnect to GitHub
    +
    ../../_images/UpdateNS18.png

  • +
  • If Heroku is not connected to GitHub, scroll down and click Connect to GitHub, if a popup window opens and requires authorization, click Authorize Heroku
    +
    ../../_images/UpdateNS19.png

  • +
  • Verify your app cgm-remote-monitor is connected to GitHub
    +
    ../../_images/UpdateNS20.png

  • +
  • If it isn’t, In Connect to GitHub, type cgm-remote-monitor and click Search then click Connect
    +
    ../../_images/UpdateNS21.png

  • +
  • If you have trouble connecting your app, click Disconnect and reconnect it as shown above
    +
    ../../_images/UpdateNS22.png

  • +
  • Scroll down to the bottom of the page, select the master branch and click Deploy Branch
    +
    ../../_images/UpdateNS23.png

  • +
  • Build will start and information will scroll in the log window. Do not leave the page, do not interfere and wait for completion. It might take more than 10 minutes.
    Interrupting the process will lead to a broken site and you’ll need to restart deployment.
    +
    ../../_images/UpdateNS24.png

  • +
  • Wait until the deploy process completes and click View (if nothing happens click Manage App then upper right Open App)
    +
    ../../_images/UpdateNS25.png

  • +
  • Your site will open and should be at the latest version.

  • +
  • Check your profile time zone is correct. You’re done!
    +If you ran into trouble, try the Redeploy method

  • +
+
+ +
+
    +
  • Log into Azure : https://portal.azure.com/

  • +
  • Select your App service, your Nightscout site name (you should see it in recent resources)
    +
    ../../_images/Azure42.png

  • +
  • If you didn’t find it, it will show in App Services
    +
    ../../_images/Azure43.png

  • +
  • In the left menu select Deployment Center and change Continuous Deployment to On.
    +
    ../../_images/AzureU02.png

  • +
  • Click Save (or Discard if you don’t want to update). +Your site will redeploy with the latest cgm-remote-monitor version.
    +Expect a few minutes before it comes back online.
    +
    ../../_images/Dev13.png


  • +
  • You can leave Continuous Deployment On if you want upgrades to happen automatically, or turn it back to Off (and save) to control upgrades manually yourself. +

  • +
+
+ +
+

Follow these instructions to install flyctl on your computer. You also need to install git if you’re using a Windows computer.

+Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.

+
    +
  • Log in Fly.io:

    +flyctl auth login

  • +
  • Verify your Nightscout app name, use it to replace example-ns in the following lines.

    +flyctl app list

  • +
  • Verify your app current region (three letters code) and make sure it’s in the free tier.

    +flyctl app list

  • +
  • Navigate to the cgm-remote-monitor folder from which you deployed Nightscout on your computer. Verify it contains the fly.toml configuration file you used to deploy your site.

    +
      +
    • If you don’t see this file, recover it:

      +flyctl config save --app example-ns

    • +
    +
  • +
  • If you migrated from Heroku using the wizard, or if you can’t find this folder on your computer, follow the next steps to recover your Fly.io configuration:

    +
      +
    • Fork a copy of the Nightscout repository and change directory

      +git clone https://github.com/nightscout/cgm-remote-monitor

      +cd cgm-remote-monitor

    • +
    • Download a default fly.toml configuration file

      +flyctl config save --app example-ns

    • +
    +
  • +
  • Update your Nightscout repository

    +git pull

  • +
  • Edit your fly.toml configuration and search this section:

  • +
+
[[services]]
+  protocol = "tcp"
+  internal_port = 8080
+  processes = ["app"]
+
+
+
    +
  • Change the internal port value to 1337, do not change anything else, do not remove the spaces before internal_port.

    +internal_port = 1337

  • +
  • Save the fly.toml file.

  • +
  • Deploy Nightscout:

    +flyctl launch

  • +
  • Wait until completion, you site should now be running the latest Nightscout version.

  • +
+
Updating existing machines in 'example-ns' with rolling strategy
+
+-------
+ ✔ Machine 1781944ae46438 [app] update succeeded
+-------
+
+Visit your newly deployed app at https://example-ns.fly.dev/
+
+
+
    +
  • Downscale the app if you haven’t yet +flyctl scale --app example-ns count 1 +

  • +
+
+ +
+


Once GitHub updated, your Nightscout should automatically deploy with the latest version.

+
+ +
+


- Log into Northflank: https://app.northflank.com/login

+
    +
  • Select your Nightscout project

    +../../_images/Dev14.png

  • +
  • Select your Nightscout service

    +../../_images/Dev15.png

  • +
  • In Overview, Edit deployment

    +../../_images/Dev18.png

  • +
  • In the image path, check the image is nightscout/cgm-remote-monitor:latest (modify if necessary), then click Update & rollout restart

    +../../_images/Dev19.png

  • +
  • Your site will redeploy with the latest version.


  • +
+
+ +
+


a) Open Railway and click login. Login with GitHub.

+../../_images/Railway00.png

+../../_images/Railway01.png

+b) Select your Nightscout project.

+../../_images/RailwayM15.png

+c) Select your Docker service.

+../../_images/RailwayD05.png

+d) Click on Settings, disconnect the source image.

+../../_images/RailwayD09.png

+e) Select Connect image and type nightscout/cgm-remote-monitor:latest then press enter.

+../../_images/RailwayD10.png

+../../_images/RailwayD04.png

+f) Go to the Deployment tab and from the three dots menu of the top deployment select Redeploy.

+../../_images/RailwayD11.png

+
    +
  • Your site will redeploy with the latest version.

  • +
+
+ +
+
    +
  • Log into Render: https://dashboard.render.com/

  • +
  • Select your Nightscout project

    +../../_images/Render16.png

  • +
  • Go to Settings and top right expand Manual Deploy, Select Deploy latest reference

    +../../_images/RenderD12.png

  • +
  • Your site will redeploy with the updated Nightscout version

  • +
+
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/uploader/setup/index.html b/uploader/setup/index.html new file mode 100644 index 00000000..922269e5 --- /dev/null +++ b/uploader/setup/index.html @@ -0,0 +1,429 @@ + + + + + + + Setup Uploaders — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Setup Uploaders

+
+
+

Hint

+

You usually should express the Nightscout URL in secure **https://**, not only http://. +(Unless you set INSECURE_USE_HTTP to true)

+
+
+

What is my Nightscout URL?

+

This is the address you type in any browser to display your Nightscout web site.

+

If you’re using a hosted service, ask the vendor.

+
+ +
+
+
+ +
+

Your Nightscout URL defined in Heroku by your App name, is the one that shows when you open your Nightscout site in a browser. +It usually looks like: https://yoursitename.herokuapp.com

+../../_images/SetupNS44.png +
+ +
+

Your Nightscout URL is defined in Railway by your Web app name, as shown in your Dashboard. +It usually looks like: https://yoursitename.up.railway.app

+../../_images/RailwayM14.png +
+ +
+

Your Nightscout URL is defined in Northflank by your Web app name, as shown in your project services. +It usually looks like: https://port-name--service-name--project-name--entity-dns-id.code.run

+../../_images/Northflank29.png +
+ +
+

Your Nightscout URL is defined in Azure by your Web app name, as shown in your App services. +It usually looks like: https://yoursitename.azurewebsites.net

+../../_images/AzureName.png +
+ +
+

Your Nightscout URL is defined in Fly.io by the app variable in your fly.toml file. +You can also find it in your Dashboard. +It usually looks like: https://yoursitename.fly.dev

+../../_images/FlyIO05.png +
+ +
+

Your Nightscout URL is defined in FreeDNS. +You can find it in Status - Hostname.

+
+
+
+
+
+

Dexcom

+

You need at least one follower to use Nightscout share or nightscout-connect plugins.

+
+

Hint

+

If you use a DIY closed loop system it is recommended that you let it upload to Nightscout instead of importing data using Dexcom Share and a Nightscout plugin.

+
+

On your master phone, touch the Share icon, enable Sharing. If you have no follower, add one. You can also invite yourself.

+../../_images/UploadCFG09.png +
+
+ +
+
+
+ +
+

Verify, update or add these variables:

+BRIDGE_USER_NAME
+BRIDGE_PASSWORD
+BRIDGE_SERVER
+
+You need to add bridge in the ENABLE variable. Do not delete other entries, just add bridge after a space.

+
+ +
+

Verify, update or add these variables:

+CONNECT_SOURCE set to dexcomshare
+CONNECT_SHARE_ACCOUNT_NAME
+CONNECT_SHARE_PASSWORD
+CONNECT_SHARE_REGION (must be set to ous if outside of the US, else don’t add this variable)
+
+You need to add connect in the ENABLE variable. Do not delete other entries, just add connect after a space.

+
+
+
+
+

MOST COMMON ERRORS

+

The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom’s Clarity page (check here for USA accounts and here for the others) and try logging in to your Dexcom account. If your account info isn’t valid, or you don’t see any data in your Clarity account… you need to figure out your actual credentials before moving ahead. See here for troubleshooting tips and information on your Dexcom account.

+
+
+

Password

+

Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.

+
+
+
+ +
+

Medtronic 600 Series with uploader

+../../_images/UploadCFG08.png +

You can also use this QR code generator and the menu item Scan NS-Autoconfig QR Code to copy the information.

+

For hosted Nightscout you’ll find the QR code generator in Uploaders, select the HTTP tab.

+

You might want to setup additional fields for your pump.

+

Facebook Group Nightscout for Medtronic

+
+
+
+

xDrip+

+
+

Mind the syntax!

+

https://API_SECRET@my_nightscout_url/api/v1/
+my_nightscout_url will depend on where your site is hosted (see top of this page)
+You will find your API_SECRETin your site variables.

+
+

Here is how it will look like for some vendors:

+
https://API_SECRET@yoursite.herokuapp.com/api/v1/
+https://API_SECRET@yoursite.up.railway.app/api/v1/
+https://API_SECRET@yoursite.guest.t1pal.com/api/v1/
+https://API_SECRET@yoursite.10be.de/api/v1/
+
+
+
+../../_images/UploadCFG00.png +

Facebook Group xDrip

+
+
+
+

Glimp

+../../_images/UploadCFG02.png +
+
+
+

Juggluco

+../../_images/UploadCFG11.png +
+
+
+

Diabox

+../../_images/UploadCFG03.png +
+
+
+

LinkBluCon

+../../_images/UploadCFG04.png +
+
+
+

Tomato

+../../_images/UploadCFG05.png +
+
+
+

Spike

+

Look here.

+../../_images/UploadCFG10.png +

Facebook group Spike App

+
+
+
+

xDrip4iOS

+../../_images/UploadCFG06.png +

Facebook group xDrip4iOS

+
+
+
+

DIY Closed Loop

+

See the app documentation in the dedicated page.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/uploader/uploaders/index.html b/uploader/uploaders/index.html new file mode 100644 index 00000000..86d52f71 --- /dev/null +++ b/uploader/uploaders/index.html @@ -0,0 +1,300 @@ + + + + + + + Supported Uploaders — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Supported Uploaders

+

An Uploader is a mechanism or system for uploading the CGM data from your sensor to your Nightscout site. This can be either an electronic solution (usually for older devices), a simple app installed on your phone (for most newer systems) that connects to the sensor/pump and then uploads this data but also another app in the cloud acting as a “bridge” and mirroring data to Nightscout.

+

The type of Uploader needed will depend on the type of CGM system being used. In this page, we will break the different systems down by manufacturer, then further by sensor type.

+

Once you are clear about the type of sensor and upload system you will be using, you can find detailed configuration information for each one here. +

+

If you’re developing an uploader, you’ll find the API information in your own Nightscout site at /api-docs and /api3-docs.

+
+
+

DIY Closed loop Systems

+

Only your loop app should upload BG to Nightscout.

+

See this dedicated page for setup links.

+
+
+
+

Dexcom

+
+

Dexcom G5/G6/ONE/G7

+../../_images/Upload02.png +

If you are using the Dexcom sensor (except ONE) connected to the Dexcom app on your phone, it will upload directly to the Dexcom servers (also still known as “Dexcom Share”) and you won’t need to use any extra uploader or master device.

+
+

Note

+

Dexcom Share is not available with Dexcom ONE. Use xDrip+ or xDrip4iOS.

+
+

For this to work, Nightscout must be configured to use the bridge plug-in and will then automatically pull the CGM information directly from the Dexcom servers in real-time.

+
+

Note

+

If you use a DIY closed loop system it is recommended that you let it upload to Nightscout instead of importing data using Dexcom Share and the bridge plugin.

+
+

Please note that at this time (end 2023), the Dexcom G5 system is effectively obsolete but some people are still using stocks of old sensors and transmitters.

+

If you don’t want to use the official Dexcom apps, you can use open-source software apps for your Dexcom sensor to connect, display, alarm and also upload to Nightscout:

+

Android: xDrip+ for G5, G6, ONE and G7.

+

iOS:
+Spike for G5 and older G6 transmitters (not Firefly)
+xDrip4iOS for G5, G6 and ONE transmitters

+../../_images/Upload03.png +
+

Dexcom “Firefly” Transmitters

+

Most of the useable transmitters that fall into this category at the present time are generally rebatteried or rechargeable/modified transmitters.

+
+
+
+
+

Medtronic

+

If your sensor system is able to directly upload to CareLink then Nightscout might be able to get the information directly from the cloud using the mmconnect (deprecated) plugin. Unfortunately, this is not possible anymore with recent pumps (7xx series and above).

+../../_images/Upload04.png +

If this isn’t an option and your sensor/transmitter is connected to your pump (Medtronic 600 series pumps), then you’ll need an Android phone connected with an OTG cable to your pump’s connected glucose meter. The phone will need to run the 600 Series Uploader app.

+../../_images/Upload05.png +
+
+

Glucomen Day

+

You can forward your data from GlucoLog Web using an AWS bridge documented here.

+
+
+

Tandem t:slim X2

+

You can synchronize your treatments one way from your Tandem Diabetes t:connect web/mobile application to Nightscout using a bridge app running via Pipenv or Docker as documented here.

+
+
+

Abbott Freestyle Libre

+
+

Libre 1

+

Non Bluetooth-enabled Freestyle Libre sensors will need an additional transmitter device fixed on top of the sensor to send readings to the uploader device. In release order here are some transmitter options: LimiTTer, BlueReader, Blucon, MiaoMiao, Bubble, Droplet and Atom.

+
+

Transmitter Compatibility

+

The Libre environment is complex and evolves quickly. Before buying a transmitter, please join the respective Facebook groups and make sure that the transmitter you are planning to buy is compatible with your sensor type.

+
+

Most of the transmitters have their own proprietary apps. Nearly all of these support the uploading of data to Nightscout (LinkBluCon, Tomato, Diabox, eDroplet, …). Again, check the transmitter manufacturer’s website and the relevant Facebook support groups for information.

+

Open-source apps such as xDrip+, Juggluco, Spike and xDrip4iOS also support some of the above transmitter devices.

+
+
+

Libre 2

+

You can connect to the Libre 2 sensor (EU only) without an additional transmitter using xDrip+, and xDrip4iOS.
+Other Libre 2 sensors can be used directly with Juggluco and Diabox.

+
+
+

Libre 2/3

+

You can use the sensor connected with Juggluco or upload to Nightscout automatically from LibreView servers deploying this project, or use xDrip+ to perform this operation.

+

A new plugin in Nightscout 15 (under development) will integrate the project above.

+
+
+
+

Eversense

+

In order to get data from the Eversense CGM system, you will need to use the ESEL app running on an Android phone with the modified vendor app.

+../../_images/Upload06.png +
+
+

Diasend

+

disaend-nightscout-bridge synchronizes treatments (insulin boli, temp basal changes) as well as continuous glucose values (CGV) from Diasend to Nightscout. This can help CamAPS FX users to view their treatments and glucose values via Nightscout. A 30 minutes delay might occur.

+

A new plugin in Nightscout 15 (under development) will integrate the project above.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/uploader/xdripcarelink/index.html b/uploader/xdripcarelink/index.html new file mode 100644 index 00000000..b23df9fc --- /dev/null +++ b/uploader/xdripcarelink/index.html @@ -0,0 +1,220 @@ + + + + + + + xDrip+ for CareLink — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/10BE/index.html b/vendors/10BE/index.html new file mode 100644 index 00000000..0fe80898 --- /dev/null +++ b/vendors/10BE/index.html @@ -0,0 +1,192 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/NAS/synology/index.html b/vendors/NAS/synology/index.html new file mode 100644 index 00000000..65e16093 --- /dev/null +++ b/vendors/NAS/synology/index.html @@ -0,0 +1,200 @@ + + + + + + + Nightscout in your Synology NAS — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout in your Synology NAS

+
+

Even if this is a valid solution for knowledgeable people, there is little detailed documentation except for https://t1d.dzienia.pl/nightscout_synology_tutorial/.

+

More links below.

+

Nightscout on Synology + model, initially for the technically minded only

+

https://github.com/vanelsberg/NightScoutSynology

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/T1Pal/new_user/index.html b/vendors/T1Pal/new_user/index.html new file mode 100644 index 00000000..745c2299 --- /dev/null +++ b/vendors/T1Pal/new_user/index.html @@ -0,0 +1,192 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/VPS/docker/index.html b/vendors/VPS/docker/index.html new file mode 100644 index 00000000..a0e4e13b --- /dev/null +++ b/vendors/VPS/docker/index.html @@ -0,0 +1,416 @@ + + + + + + + Building Nightscout with Docker — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Building Nightscout with Docker

+
+
+

Tip

+

The most complete guide for building your site step by step is the one used for Oracle Cloud.
+If you use another hosting provider, skip Oracle specific instructions and follow the flow.

+
+
+

Original documentation from Jason.
+More from Andries and Peter (traefik as below), justmara and Ireneusz.

+

If you want to deploy with CoreOS look here.

+

A comprehensive description of the yaml file for mongo and Nightscout setup here.

+

If you don’t own a domain name, get a DDNS name now: see here.

+

You can also use Caddy as reverse proxy.

+
+
+

Update your system

+

Update your Ubuntu system (you should type this is a command every 3 or 6 months to keep it updated).

+
sudo apt update
+sudo apt upgrade -y
+sudo apt clean
+
+
+

You will see it’s completed when the terminal stops scrolling text and you’re returned to the prompt.

+

If you see the following message: *** System restart required *** you will need to reboot. Do not skip this step: reboot and wait a minute before opening again the console.

+
sudo reboot
+
+
+

You must probably already have nano installed. If necessary:

+
sudo apt install nano -y
+
+
+
+
+
+

Deploy a single instance

+
+

Step 1 - Install Docker

+

Note: instructions from the vendor

+

a) Install keys

+
sudo apt-get -y install ca-certificates curl gnupg lsb-release
+sudo mkdir -p /etc/apt/keyrings
+curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg --yes
+
+
+

b) Install Docker

+
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
+sudo apt-get update
+sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
+
+
+
+
+
+

Step 2 - Configure Nightscout

+

a) If you’re running your VPS as root: Create a new user. Else go to d)
+Don’t try to run Nightscout as root, it will not work.
+Replace mainuser with a name of your choice, like your name, only lowercase letters.

+
sudo adduser mainuser
+
+
+

You need to invent a password for your new user.
+Confirm it then just hit Enter for the following lines, when done key Y then Enter.

+

b) Make your user an administrator.

+

Replace mainuser with your new user name.

+
sudo usermod -aG sudo mainuser
+
+
+

c) Enable current user and make docker startup automatically.
+Replace mainuser with your new user name.

+
sudo groupadd docker
+sudo usermod -aG docker mainuser
+sudo systemctl enable docker
+
+
+

d) Login to the VPS using the account we just created.

+

!!!warning “Do not run Nightscout as root”
+From now on use your Nightscout user.

+

Replace mainuser with your new user name.

+
sudo -u mainuser -s
+
+
+

Log out (Ctrl-D or ⌘-D) or type logout, and log in with with your new user.

+

e) Customize your Docker Compose configuration file

+

You can use the default docker-compose.yml file from the Nightscout repository or download this one.

+

There are few information you need to update:

+ +
image: nightscout/cgm-remote-monitor:latest
+
+
+ +
TZ: YOUR_TIMEZONE
+
+
+
    +
  • Your Nightscout site API_SECRET password.

  • +
+
API_SECRET: YOUR_API_SECRET
+
+
+

Note: now you’ve also seen where your Nightscout variables are defined.

+
    +
  • You need to update your Nightscout site URL (your DDNS name looking like name.domain.tld)

  • +
+
- 'traefik.http.routers.nightscout.rule=Host(`YOUR_PUBLIC_HOST_URL`)'
+
+
+
    +
  • You need to put a valid email too for important certificate emails (i.e. probably never)

  • +
+
- '--certificatesresolvers.le.acme.email=YOUR_EMAIL'
+
+
+
+
+
+

Step 3 - Build and run Nightscout

+

To start your Nightscout:

+
sudo docker compose up -d
+
+
+

Or, if you want to start it in background (once everything is working as you won’t see the log):

+
nohup sudo docker compose up -d &
+
+
+

To stop it (if you didn’t select always restart for your containers):

+
sudo docker compose down
+
+
+

Note that you need to start it if you modify your docker-compose.yml configuration (to validate the changes).

+
+
+
+
+

Update or downgrade

+

Edit your docker-compose.yml configuration and change the image to whichever you want in the community maintained images.

+

If you’re using image: nightscout/cgm-remote-monitor:latest and you want to upgrade it to latest release, don’t change anything. You can update to cgm-remote-monitor:latest_dev or choose an older version like cgm-remote-monitor:14.2.6

+
sudo docker compose down
+sudo docker compose pull
+nohup sudo docker compose up -d &
+
+
+
+
+
+

Deploy multiple instances

+

Hints from justmara

+

Portainer configuration used in docker-compose:

+
  portainer:
+    image: portainer/portainer-ee:latest
+    container_name: portainer
+    restart: unless-stopped
+    volumes:
+      - ./portainer-data:/data
+      - /var/run/docker.sock:/var/run/docker.sock
+    labels:
+      - 'traefik.enable=true'
+      - 'traefik.http.routers.portainer.rule=Host(`portainer.<MYDOMAIN>`)'
+      - 'traefik.http.routers.portainer.entrypoints=web'
+      - 'traefik.http.routers.portainer.service=portainer-service'
+      - 'traefik.http.services.portainer-service.loadbalancer.server.port=9000'
+    ports:
+      - "8000:8000"
+      - "9443:9443"
+      - "9000:9000"
+    networks:
+      - dia
+
+
+

Portainer custom template used to start new Nightscout instances:

+
version: '3.9'
+
+x-ns-common-env: &ns-common-env
+  NODE_ENV: production
+  TZ: Europe/Moscow
+  TIME_FORMAT: 24
+  INSECURE_USE_HTTP: 'true'
+  ENABLE: basal iob cob boluscalc cage sage iage bage pump openaps pushover food rawbg
+  SHOW_FORECAST: openaps
+  PUMP_FIELDS: clock reservoir
+  DISPLAY_UNITS: mmol
+  AUTH_DEFAULT_ROLES: denied
+
+services:
+  nightscout-{{ns-name}}:
+    image: nightscout/cgm-remote-monitor:latest
+    container_name: dia-ns-{{ns-name}}
+    restart: always
+    depends_on:
+      - mongo
+    labels:
+      - 'traefik.enable=true'
+      - 'traefik.http.routers.ns-{{ns-name}}.rule=Host(`{{ns-name}}.<MYDOMAIN>`)'
+      - 'traefik.http.routers.ns-{{ns-name}}.entrypoints=web'
+    environment:
+      <<: *ns-common-env
+      MONGO_CONNECTION: mongodb://mongo:27017/ns-{{ns-name}}
+      API_SECRET: {{ns-secret}}
+    networks:
+      - dia
+
+networks:
+  dia:
+    external: true
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/VPS/ubuntu/index.html b/vendors/VPS/ubuntu/index.html new file mode 100644 index 00000000..8282e44b --- /dev/null +++ b/vendors/VPS/ubuntu/index.html @@ -0,0 +1,474 @@ + + + + + + + Building Nightscout in Ubuntu — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Building Nightscout in Ubuntu

+
+
+

Tip

+

The most complete guide for building your site step by step is the one used for Oracle Cloud.
+If you use another hosting provider, skip Oracle specific instructions and follow the flow.

+
+
+

Deploying in Ubuntu is very popular for skilled people, see also here and here.

+

If you don’t own a domain, get one now, see here.

+
+
+

Update your system

+

Update your Ubuntu system (you should type this is a command every 3 or 6 months to keep it updated).

+
sudo apt update
+sudo apt upgrade -y
+sudo apt clean
+
+
+

You will see it’s completed when the terminal stops scrolling text and you’re returned to the prompt.

+

If you see the following message: *** System restart required *** you will need to reboot. Do not skip this step: reboot and wait a minute before opening again the console.

+
sudo reboot
+
+
+

You must probably already have nano installed. If necessary:

+
sudo apt install nano -y
+
+
+
+
+
+

Step 1 - Install MongoDB

+

a) Follow the vendor instructions

+

MongoDB 5 with Ubuntu 20.04 or MongoDB 6 with Ubuntu 22.04

+

b) Enter in Mongo shell

+
mongo --port 27017
+
+
+

You will know you’ve entered the mongo shell when the prompt > is displayed.

+

c) Create an admin user. Decide on a name and a password.
+Avoid reusing other usernames and passwords.

+

Replace ADMIN_NAME and ADMIN_PASSWORD with those your own. Keep all " ".

+
use admin
+
+
+
db.createUser({user: "ADMIN_NAME", pwd: "ADMIN_PASSWORD", roles: [ { role: "userAdminAnyDatabase", db: "admin" }] })
+
+
+

Exit mongo.

+
exit
+
+
+

Mongo will answer bye and you’ll be back to Ubuntu’s command prompt.

+
+

d) Turn Mongo security on

+
sudo nano /etc/mongodb.conf
+
+
+

Go to the line reading #auth = true and remove the comment #. +Save the modified file:

+
    +
  1. Press Ctrl-O (the letter O not zero)

  2. +
  3. Press Enter

  4. +
  5. Press Ctrl-X

  6. +
+

Note: if you use a Mac the Ctrl key is

+

e) Restart Mongo with this command:

+
sudo service mongodb restart
+
+
+

You have installed the MongoDB application.

+
+
+
+

Step 2 - Create a new database

+

a) Login into Mongo as an admin
+Replace ADMIN_NAME with your own database administrator name.

+
mongo -u ADMIN_NAME -p --authenticationDatabase admin
+
+
+

You will be asked to enter the password matching your admin user.

+

b) Create a database name.
+Make it simple (letters), this is just the place your Nightscout data will be stored. +Replace MONGO_NS_DB with your own database name.

+
use MONGO_NS_DB
+
+
+

c) Create a database user.
+Invent a name (letters and numbers) and a password (letters and numbers, uppercase and lowercase). +Replace MONGO_NS_USER with your database user name, MONGO_NS_PASSWORD with its matching password and MONGO_NS_DB with the database name you created above.

+
db.createUser({user: "MONGO_NS_USER", pwd: "MONGO_NS_PASSWORD", roles: [ { role: "readWrite", db: "MONGO_NS_DB" }]})
+
+
+

Exit the shell

+
exit
+
+
+

d) Check you can login into Mongo with this user
+Replace MONGO_NS_USER with your own database administrator name, and replace MONGO_NS_DB with your own database name.

+
mongo -u MONGO_NS_USER -p --authenticationDatabase MONGO_NS_DB
+
+
+

You will be asked to enter the password matching your user.

+

Exit the shell.

+
exit
+
+
+

You have created your Nightscout MongoDB database and its user.

+
+
+
+

Step 3 - Install Nightscout

+

a) Create a new user.
+Don’t try to run Nightscout as root, it will not work.
+Replace mainuser with a name of your choice, like your name, only lowercase letters.

+
sudo adduser mainuser
+
+
+

You need to invent a password for your new user.
+Confirm it then just hit Enter for the following lines, when done key Y then Enter.

+

b) Make your user an administrator.

+

Replace mainuser with your new user name.

+
sudo usermod -aG sudo mainuser
+
+
+

c) Login to the machine using the account we just created.

+

!!!warning “Do not run Nightscout as root”
+From now on use your Nightscout user.

+

Replace mainuser with your new user name.

+
sudo -u mainuser -s
+
+
+

d) Install nodejs and npm.

+

Mind some small VPS will not be powerful enough to deploy with npm, consider using a Docker container in this case.

+

The example below is with the latest supported npm version: 16.20.1

+
sudo apt install nodejs
+sudo apt install build-essential checkinstall
+sudo apt install libssl-dev
+wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
+source /etc/profile
+nvm install 16.20.1
+nvm use 16.20.1
+
+
+

Once complete, install npm

+
sudo apt-get install -y npm
+
+
+
+

e) Clone the Nightscout repository cgm-remote-monitor.

+
cd
+git clone https://github.com/nightscout/cgm-remote-monitor.git
+ln -s cgm-remote-monitor nightscout
+cd nightscout
+
+
+
+

Make sure you’re in your nightscout directory

+

Should you exit your terminal and resume working later make sure to return to this state.
+1- you’re using your nightscout user
+2- you are in your nightscout directory

+
+

f) Install Nightscout.

+
npm install
+
+
+

It will take a long time to complete. Be patient.
+On some lightweight virtual computers install might fail or hang, especially if you installed the default latest node.js version.
+You can try to interrupt and run another time npm install.

+
+
+
+

Step 4 - Configure Nightscout

+

a) Edit the configuration file.

+
nano my.env
+
+
+

You can use the helper page in a new browser tab.

+

File all necessary fields, click on the Validate button at the bottom of the form, if no error is seen you will have all variables displayed in the text box at the bottom, click on the Copy All button.

+
+

Variables format

+

1- do not addexport before the variable name
+2- safe format is VARIABLE="value"
+3- all spaces in the values must be replaced by %20

+
+

b) Return to the text editor. Paste the result in nano.

+

c) Save the modified file:

+
    +
  1. Press Ctrl-O (the letter O not zero)

  2. +
  3. Press Enter

  4. +
  5. Press Ctrl-X

  6. +
+

Note: if you use a Mac the Ctrl key is

+
+
+

Manage Nightscout startup

+

d) Install pm2

+
sudo npm install pm2 -g
+
+
+

e) Start cgm-remote-monitor with pm2.

+
env $(cat my.env)  PORT=1337 pm2 start server.js
+
+
+

f) Make pm2 start cgm-remote-monitor on startup

+
pm2 startup
+
+
+

This will give you a command you need to run as superuser to allow pm2 to start the app on reboot. +The command will be something like: sudo su -c "env PATH=$PATH:/usr/bin pm2 startup ..."

+

Copy the tailored command, paste and execute it.

+

g) Save it.

+
pm2 save
+
+
+

Your Nightscout site is now available at http:// and the IP address of your computer/VPS but it’s not secured so most browsers will refuse it.

+
+
+
+
+

Step 5 - Open and secure your access

+

a) Create a reverse nginx proxy

+
sudo apt-get install nginx
+
+
+

b) Delete and replace the original /etc/nginx/sites-available/default with this one.
+Replace MY_FULLYQUALIFIEDNAME with your own (it will look like name.domain.tld). You don’t have one? Look here.

+
server {
+	listen 80;
+	server_name MY_FULLYQUALIFIEDNAME;
+	location / {
+		proxy_pass http://127.0.0.1:1337;
+		proxy_http_version 1.1;
+		proxy_set_header Upgrade $http_upgrade;
+		proxy_set_header Connection 'upgrade';
+		proxy_set_header Host $host;
+		proxy_cache_bypass $http_upgrade;
+		proxy_set_header X-Forwarded-Proto "https";
+	}
+}
+
+
+

Your Nightscout site is now available at http://MY_FULLYQUALIFIEDNAME but it’s not secured so most browsers will refuse it.

+

c) If your VPS doesn’t provide a firewall you should install and configure ufw.
+Make sure to open ssh if you don’t have KVM access!

+
sudo apt install ufw
+sudo ufw allow 'Nginx Full'
+sudo ufw allow OpenSSH
+sudo ufw enable
+
+
+

d) Obtain a certificate for your site name.

+
sudo apt install certbot python3-certbot-nginx -y
+sudo certbot --nginx -d "MY_FULLYQUALIFIEDNAME" --redirect --agree-tos --no-eff-email
+
+
+

You can increase ssl security with a strong Diffie-Hellman group (src):

+
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
+
+
+

e) Make sure certbot takes care of renewing your certificate:

+
sudo certbot renew --dry-run
+
+
+

f) Restart the service:

+
sudo service nginx restart
+
+
+

Upon success you will be able to access your Nightscout site from any browser using https://.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/azure/migrate/index.html b/vendors/azure/migrate/index.html new file mode 100644 index 00000000..aead3a13 --- /dev/null +++ b/vendors/azure/migrate/index.html @@ -0,0 +1,190 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Now included in the main Nightscout with Azure page!

+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/azure/new_user/index.html b/vendors/azure/new_user/index.html new file mode 100644 index 00000000..ee726692 --- /dev/null +++ b/vendors/azure/new_user/index.html @@ -0,0 +1,578 @@ + + + + + + + Nightscout in Azure (Docker) — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout in Azure (Docker)

+
+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+
+
+

Azure

+

Azure

+
+
+

Nightscout DIY was originally created with Azure but most users dropped it after costs increased.
+A new deployment method has been created using a Docker container.

+

Pros:

+
    +
  • Large platform with a reliable history

  • +
  • Well known by the community IT specialists

  • +
  • Using a basic plan and free services keep it free

  • +
+

Cons:

+
    +
  • Trial account lasts maximum 12 months

  • +
  • Basic plan and pay as you go is free if you stay within quotas

  • +
  • The F1 free app service plan is designed for testing, not production

  • +
  • The Cosmos database doesn’t integrate correctly with Nightscout

  • +
+
+
+
+

This is a transcript of the original video which cannot be used as-is anymore because the Cosmos (MongDB) database which was used at the time of the video isn’t fully compatible with Nightscout and can’t be deployed in some geographical areas. For reference the obsolete video is here.

+
+
+

Step 0: Create a database

+
+

Note

+

Make sure you created one before starting your Nightscout web app creation with Azure. +Come back here when you have a MONGODB_URI connection string.

+
+
+

Migrating?

+

Copy the connection string from your previous platform: edit the variables and look for MONGODB_URI. +If you don’t see MONGODB_URI but see MONGO_CONNECTION (NOT MONGO_COLLECTION): use its value.

+
+
+
+
+

Step 1: Create an Azure account

+

a) Open a web page in https://azure.microsoft.com/en-us/free/ and click Start Free.

+../../../_images/Azure01.png +
+

b) Sign in with your Microsoft account if you have one, else use GitHub.

+../../../_images/Azure02.png +
+

c) Agree and click Next.
+Perform necessary authentication.

+../../../_images/Azure03.png +
+
+
+

Step 2: Create your Nightscout web app

+

a) From the top left ☰ menu or the Azure Services icons, select + Create a resource.

+../../../_images/Azure05.png +
+

b) Search Web app and click Create.

+../../../_images/Azure22.png +
+

c) Check you’re still using your Free Trial or 3-Month free Trial.
+Open the list in Resource group and pick your group (the one you created in Step 2.f.).

+../../../_images/Azure23.png +

If your free trial expired, select Pay-As-You-Go. It will be free if you use free resources like the Free F1 resource (see below).

+
+

d) Decide your site name (only lowercase and you can use - as a separator).
+It must be unique: check the tick box at the end of the line is green.
+If it isn’t: you need to choose another name…

+../../../_images/Azure24.png +
+

e) Now select a Docker container, in Linux.

+

Pick a place close to where you live in the Region selection.
+Make sure it is the same than the database region you selected in Step 2.g.

+../../../_images/Azure25.png +
+

f) Select the free F1 plan.

+../../../_images/Azure26.png +
+

Limited CPU usage

+

The Free F1 plan includes 60 CPU minutes per day. It usually is enough for a moderate Nightscout usage but can also be insufficient and provoke interruptions in your Nightscout site. Not recommended for FreeAPS X and OpenAPS users. +If you want a more reliable CPU, consider another plan like Shared D1 ($).

+
+
+

g) Click Next: Database > down in the page.

+../../../_images/Azure27.png +
+

g) Do not change anything and click Next: Docker > down in the page.

+../../../_images/Azure28.png +
+

h) In Image source select Docker Hub instead of Quickstart.

+../../../_images/Azure29.png +
+

i) In Image and tag paste the following name:

+

nightscout/cgm-remote-monitor:latest

+../../../_images/Azure30.png +
+

j) Click Review + create in the lower left of the page.

+../../../_images/Azure12.png +
+

k) Verify the summary information:
+Free sku
+Check the site Name is what you wanted
+then click Create.

+../../../_images/Azure31.png +
+

Wait for the deployment to complete. Do not interfere.

+../../../_images/Azure33.png +
+

Congratulations, you have created your Nightscout web app.

+
+
+
+

Step 3: Configure your Nightscout web app

+
+

Now you need to tell it where the database is and other important information

+
+

a) Click Go to resource

+../../../_images/Azure32.png +
+

b) In the left menu select Configuration

+../../../_images/Azure34.png +
+

Check which deployment you’re doing now!:

+
+ +
+

c) Click + New application setting

+

../../../_images/Azure35.png

+
+

d) In Name write MONGODB_URI

+

Mind your database type!

+
+ +
+

In the line below, Value, paste the connection string you obtained after creating your database.

+
+ +
+

In the line below, Value, paste the connection string with socketTimeoutMS.

+
+
+

../../../_images/Azure36.png

+Then click OK.

+
+

e) Click again + New application setting (like in c. above) and write API_SECRET in Name.
+API_SECRET will be your Nightscout site password, it needs to be at least 12 characters long and you should NOT use spaces if you use @ or ! symbols remember you will probably need to express them using Percent encoding in your uploader and downloader apps. If you’re not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits.

+
+

Warning

+

The API_SECRET is the main password allowing full access to your Nightscout site. Make sure it’s reasonably secure (mix uppercase and lowercase letters, plus digits) and do no not share it publicly. If you think you exposed it by mistake, it is recommended that you change it.

+
+

../../../_images/Azure37.png

+

Click OK.

+
+

f) Click again + New application setting and write DISPLAY_UNITS in Name.
+Acceptable choices for the units used in Nightscout are mg/dl or mmol/L (or just mmol).

+

../../../_images/Azure38.png

+

Click OK.

+
+

g) Click again + New application setting and write ENABLE in Name.
+If you don’t use Dexcom Share to get your BG data in Nightscout, copy the line below to Value:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors

+

If you want to use Dexcom Share as a data source copy this one (it includes the keyword bridge):

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge

+

Click OK.

+
+

h) If you want to use Dexcom Share to have your data in Nightscout directly, you will need to add these three variable Names:

+

BRIDGE_USER_NAME Your Dexcom account username to receive CGM data from the Dexcom Share service.
+BRIDGE_PASSWORD Your Dexcom account password to receive CGM data from the Dexcom Share service.
+BRIDGE_SERVER US if your Dexcom account is in the US, or, if you are bridging from the Dexcom Share service and are anywhere outside the US change this to EU.

+

!!!note
+If you use a DIY closed loop system it is recommended that you let it upload to Nightscout instead of importing using Dexcom Share and the bridge plugin.

+

../../../_images/Azure15.png

+
+

Remember to add bridge at the end of the enable variable in the list below.

+
+
+

MOST COMMON ERRORS

+

The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom’s Clarity page (check here for USA accounts and here for the others) and try logging in to your Dexcom account. If your account info isn’t valid, or you don’t see any data in your Clarity account… you need to figure out your actual credentials before moving ahead. See here for troubleshooting tips and information on your Dexcom account.

+
+
+

Password

+

Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.

+
+
+

Hint

+

You need to have at least one follower to use Dexcom Share. See here.

+
+
+

i) Click Save, then Continue.

+

../../../_images/Azure39.png

+
+
+ +
+
+ +
+

c) Open a new browser tab or window and Log in Heroku, select your app

+../../../_images/SetupNS00.png

+d) Click Settings

+../../../_images/SetupNS01.png

+e) Scroll down and click Reveal Config Vars

+../../../_images/SetupNS02.png

+f) Put the two windows Heroku and Azure side by side

+../../../_images/Azure16.png

+Now for every (no, not necessarily, read until i and come back) variable you need to do the following:

+
+ +
+

c) Open Railway and click login. Login with GitHub.

+../../../_images/Railway00.png

+../../../_images/Railway01.png

+d) Select your Nightscout project.

+../../../_images/RailwayM15.png

+Select your web app.

+../../../_images/RailwayM16.png

+e) Click on Variables.

+../../../_images/RailwayM17.png

+Click on RAW Editor top right

+../../../_images/Railway39.png

+f) Put the two windows Railway and Azure side by side

+../../../_images/Azure16r.png

+Now for every variable you need to do the following:

+
+
+
+

g) Click + New application setting

+

../../../_images/Azure35.png

+
+

h) In Name write the variable name from the first column in Heroku or the one in red with Railway
+Then, in the line below, Value, paste the value from the second column in Heroku or the one in green with Railway.

+

../../../_images/Azure38.png

+

Then click OK and go for the next one.

+
+

You might not need to copy ALL the values, if you know which ones you need you can go ahead.
+If you don’t really know which ones you want to copy there’s only few that are strictly necessary:

+

API_SECRET
+MONGODB_URI Note: if you don’t see MONGODB_URI but see MONGO_CONNECTION (NOT MONGO_COLLECTION) use its value.
+DISPLAY_UNITS

+

in ENABLE paste this:

+

If you don’t use Dexcom Share to get your BG data in Nightscout, copy the line below to Value:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors

+

If you want to use Dexcom Share as a data source copy this one (it includes the keyword bridge):

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge

+

If you have your data coming directly from Dexcom share those three:

+

BRIDGE_USER_NAME
+BRIDGE_PASSWORD
+BRIDGE_SERVER

+

../../../_images/Azure15.png

+
+

i) When you’re done copying, click Save, then Continue.

+

../../../_images/Azure39.png

+
+
+
+

j) From the menu select Overview, then Browse.

+../../../_images/Azure40.png +

It will take some time before the window opens.

+
+
+
+

New Nightscout Setup

+
+

a) Your Nightscout site should open and direct you to a new profile creation.

+../../../_images/NewNS50.png +
+

b) Setup your Time zone and eventually all other fields. Do not leave any fields empty. If you don’t know which value to use, just use the default value. You can change these values later at any time.

+../../../_images/NewNS44.png +
+

c) Browse down to Authentication status and click Authenticate. Enter your API secret. Click Update.

+../../../_images/NewNS45.png +
+

d) Click Save.

+../../../_images/NewNS46.png +
+

e) If the following pop-up shows up click OK, and check status (upper right of the window).

+../../../_images/NewNS47.png +
+

f) If you need to modify your profile after this, authenticate with the lock icon (top right of the page): enter your API secret. Then click on the hamburger menu and select Profile Editor.

+../../../_images/NewNS43.png +
+
+

Privacy warning

+

Anyone with access to the URL of your Nightscout site, can view your BG and run reports of your data. It it strongly recommended that you enable security to your site once you’re done with the setup

+
+
+

g) Dexcom Share users should see data flowing in after some minutes. +xDrip+ users (including Medtronic CareLink followers) should setup the uploader as shown here. +xDrip4iOS users here. +AAPS and Loop: consult the relative documentation.

+../../../_images/NewNS48.png +
+
+

You have completed a new Nightscout site creation. You can continue here now.

+

The following section provides more information that you might not need to use now.

+
+
+
+
+
+

Editing Config Vars in Azure

+
+

a) Log into Azure : https://portal.azure.com/

+

b) Select your App service, your Nightscout site name (you should see it in recent resources)

+../../../_images/Azure42.png +

If you didn’t find it, it will show in App Services

+../../../_images/Azure43.png +

c) In the left menu select Environment variables

+../../../_images/Azure34.png +
+

View a variable value

+

Click the eye icon to display the hidden value

+../../../_images/Azure45.png +
+
+

Modify a variable

+

Identify the line with the variable you want to change and click the pen icon at the end of the line
+Click OK to save it when finished
+Remember to save modifications when done with your variables!

+../../../_images/Azure44.png +
+
+

Delete a variable

+

Identify the line with the variable you want to delete and click the bin icon at the end of the line
+Remember to save modifications when done with your variables!

+../../../_images/Azure46.png +
+
+

Add a variable

+

Select New Application Setting and type variable name and value
+Remember to save modifications when done with your variables!

+../../../_images/Azure35.png +
+

Note

+

Multiple lines values with \n should be edited manually as the character \ will be duplicated.
+Example: LOOP_APNS_KEY

+
----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGBygGSM49AwEHBHkwdwIBAQQg7c8w00t5ju7N980r\nerN8N+isnJoec+ohIEuD0teRbPmgCgYIKoZIzj0DAQehRANCAAREnRISLSiFgdn4\nLbf44yIKspXKr7GpPBVshv3ShOms2qHTdAFriXXRPmbq7eAJuFrxpYOduU1dl9vo\nouciW0je\n-----END PRIVATE KEY-----
+
+
+
+

Insert the value like you’ve done for all the others.

+../../../_images/Azure48.png +

At the top of the Environment variables view, select Advanced edit.

+../../../_images/Azure49.png +

Scroll down the list to your variable name and delete all duplicated \ so that there will be no more \\n separators but only \n.

+../../../_images/Azure50.png +

Click OK to save the modified variable.

+
+
+
+

Save your modifications

+

When you’re done modifying your variables, click Save (or Discard if you don’t want to save).
+Your site will redeploy if you changed the configuration. Expect a few minutes before it comes back online.

+../../../_images/Azure47.png +
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/azure/new_user_a/index.html b/vendors/azure/new_user_a/index.html new file mode 100644 index 00000000..078d6784 --- /dev/null +++ b/vendors/azure/new_user_a/index.html @@ -0,0 +1,255 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

c) Click + New application setting

+

../../../_images/Azure35.png

+
+

d) In Name write MONGODB_URI

+

Mind your database type!

+
+ +
+

In the line below, Value, paste the connection string you obtained after creating your database.

+
+ +
+

In the line below, Value, paste the connection string with socketTimeoutMS.

+
+
+

../../../_images/Azure36.png

+Then click OK.

+
+

e) Click again + New application setting (like in c. above) and write API_SECRET in Name.
+API_SECRET will be your Nightscout site password, it needs to be at least 12 characters long and you should NOT use spaces if you use @ or ! symbols remember you will probably need to express them using Percent encoding in your uploader and downloader apps. If you’re not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits.

+
+

Warning

+

The API_SECRET is the main password allowing full access to your Nightscout site. Make sure it’s reasonably secure (mix uppercase and lowercase letters, plus digits) and do no not share it publicly. If you think you exposed it by mistake, it is recommended that you change it.

+
+

../../../_images/Azure37.png

+

Click OK.

+
+

f) Click again + New application setting and write DISPLAY_UNITS in Name.
+Acceptable choices for the units used in Nightscout are mg/dl or mmol/L (or just mmol).

+

../../../_images/Azure38.png

+

Click OK.

+
+

g) Click again + New application setting and write ENABLE in Name.
+If you don’t use Dexcom Share to get your BG data in Nightscout, copy the line below to Value:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors

+

If you want to use Dexcom Share as a data source copy this one (it includes the keyword bridge):

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge

+

Click OK.

+
+

h) If you want to use Dexcom Share to have your data in Nightscout directly, you will need to add these three variable Names:

+

BRIDGE_USER_NAME Your Dexcom account username to receive CGM data from the Dexcom Share service.
+BRIDGE_PASSWORD Your Dexcom account password to receive CGM data from the Dexcom Share service.
+BRIDGE_SERVER US if your Dexcom account is in the US, or, if you are bridging from the Dexcom Share service and are anywhere outside the US change this to EU.

+

!!!note
+If you use a DIY closed loop system it is recommended that you let it upload to Nightscout instead of importing using Dexcom Share and the bridge plugin.

+

../../../_images/Azure15.png

+
+

Remember to add bridge at the end of the enable variable in the list below.

+
+
+

MOST COMMON ERRORS

+

The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom’s Clarity page (check here for USA accounts and here for the others) and try logging in to your Dexcom account. If your account info isn’t valid, or you don’t see any data in your Clarity account… you need to figure out your actual credentials before moving ahead. See here for troubleshooting tips and information on your Dexcom account.

+
+
+

Password

+

Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.

+
+
+

Hint

+

You need to have at least one follower to use Dexcom Share. See here.

+
+
+

i) Click Save, then Continue.

+

../../../_images/Azure39.png

+
+ +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/azure/new_user_b/index.html b/vendors/azure/new_user_b/index.html new file mode 100644 index 00000000..ba4aeb59 --- /dev/null +++ b/vendors/azure/new_user_b/index.html @@ -0,0 +1,249 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+ +
+

c) Open a new browser tab or window and Log in Heroku, select your app

+../../../_images/SetupNS00.png

+d) Click Settings

+../../../_images/SetupNS01.png

+e) Scroll down and click Reveal Config Vars

+../../../_images/SetupNS02.png

+f) Put the two windows Heroku and Azure side by side

+../../../_images/Azure16.png

+Now for every (no, not necessarily, read until i and come back) variable you need to do the following:

+
+ +
+

c) Open Railway and click login. Login with GitHub.

+../../../_images/Railway00.png

+../../../_images/Railway01.png

+d) Select your Nightscout project.

+../../../_images/RailwayM15.png

+Select your web app.

+../../../_images/RailwayM16.png

+e) Click on Variables.

+../../../_images/RailwayM17.png

+Click on RAW Editor top right

+../../../_images/Railway39.png

+f) Put the two windows Railway and Azure side by side

+../../../_images/Azure16r.png

+Now for every variable you need to do the following:

+
+
+
+

g) Click + New application setting

+

../../../_images/Azure35.png

+
+

h) In Name write the variable name from the first column in Heroku or the one in red with Railway
+Then, in the line below, Value, paste the value from the second column in Heroku or the one in green with Railway.

+

../../../_images/Azure38.png

+

Then click OK and go for the next one.

+
+

You might not need to copy ALL the values, if you know which ones you need you can go ahead.
+If you don’t really know which ones you want to copy there’s only few that are strictly necessary:

+

API_SECRET
+MONGODB_URI Note: if you don’t see MONGODB_URI but see MONGO_CONNECTION (NOT MONGO_COLLECTION) use its value.
+DISPLAY_UNITS

+

in ENABLE paste this:

+

If you don’t use Dexcom Share to get your BG data in Nightscout, copy the line below to Value:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors

+

If you want to use Dexcom Share as a data source copy this one (it includes the keyword bridge):

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge

+

If you have your data coming directly from Dexcom share those three:

+

BRIDGE_USER_NAME
+BRIDGE_PASSWORD
+BRIDGE_SERVER

+

../../../_images/Azure15.png

+
+

i) When you’re done copying, click Save, then Continue.

+

../../../_images/Azure39.png

+
+ +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/digitalocean/new_user/index.html b/vendors/digitalocean/new_user/index.html new file mode 100644 index 00000000..6c8a7358 --- /dev/null +++ b/vendors/digitalocean/new_user/index.html @@ -0,0 +1,192 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/fly.io/new_user/index.html b/vendors/fly.io/new_user/index.html new file mode 100644 index 00000000..0f148e85 --- /dev/null +++ b/vendors/fly.io/new_user/index.html @@ -0,0 +1,705 @@ + + + + + + + Nightscout in Fly.io — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout in Fly.io

+
+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+
+
+

Fly.io

+

Fly.io

+
+
+

You can create your new Nightscout site in Fly.io.

+

Pros:

+
    +
  • Nightscout fits in the free tier

  • +
+

Cons:

+
    +
  • Maintaining your site requires the use of command line instructions, not very intuitive

  • +
  • Fly.io stores variables as secrets: you cannot read them

  • +
  • Relying on the MongoDB Atlas database

  • +
+
+
+



+
+

Step 0: Create a database

+
+ +
+


Make sure you create one before starting your Nightscout web app creation with Fly.io.

+Come back here when you have a MONGODB_URI connection string.

+
+ +
+


Copy the connection string from your previous platform: edit the variables and look for MONGODB_URI.

+If you don’t see MONGODB_URI but see MONGO_CONNECTION (NOT MONGO_COLLECTION): use its value.

+
+
+



+
+
+

Step 1: Create a fly.io account

+

Sign up to Fly.io.

+
+

You will need to add credit card information to get Nightscout running.
+Whenever requested, add one to prove you’re a real person:

+../../../_images/FlyIOA1.png +../../../_images/FlyM10.png +
+

Nightscout should run for free within the allowances. If you get billed, please report costs here to have the documentation updated.

+



+
+
+

Step 2: Install flyctl

+
+

Warning

+

The web terminal feature was removed from Fly.io. +You need a computer with flyctl.

+
+

Follow these instructions to install flyctl on your computer.

+

Note for Windows: you might experience issues with Git Bash or PowerShell, try an elevated command prompt.

+



+
+
+

Step 3: Prepare the Nightscout project

+

Type (or copy and paste) the following command in the terminal:

+

a) Authenticate in Fly.io:

+

flyctl auth login

+

Clone the official Nightscout repository:

+

git clone https://github.com/nightscout/cgm-remote-monitor

+
+

b) Navigate to the Nightscout code directory copied locally with:

+

cd cgm-remote-monitor

+
+

c) Deploy your site with Fly.io.

+

flyctl launch

+../../../_images/FlyIO06.png +
+

To the question Would you like to tweak these setting before proceeding? answer Y (yes).

+

A web page to your new project will open in Fly.io.

+

d) Type your new Nightscout site name, make sure it is valid and isn’t already used by someone else.

+../../../_images/FlyIO07.png +
+

e) Select the region closest to where you live, but make sure it doesn’t require a paid plan.

+../../../_images/FlyIO08.png +../../../_images/FlyIO09.png +
+

f) In services set the port to 1337.

+../../../_images/FlyIO10.png +
+

g) Make sure to select a shared CPU 1x with only 256MB of memory to remain within the free allowances limits.

+../../../_images/FlyIO11.png +
+

h) Don’t select any database and Confirm Settings.

+../../../_images/FlyIO12.png +
+

i) Deployment will start. Wait until it completes.

+../../../_images/FlyIO13.png +../../../_images/FlyIO14.png +



+
+
+

Step 5: Set your Nightscout secrets

+

a) Compile the information below.

+

File all necessary fields, click on the Validate button at the bottom of the form, if no error is seen you will have all variables displayed in the text box at the bottom, click on the Copy All button.

+
+
+

Mandatory variables

+

These three variables below must have a value.

+

MONGODB_URI

+

The MongoDB Connection String to connect to your MongoDB cluster. If you don’t have this from your Mongo database, please re-read installation instructions at Nightscout database before continuing

+


+

API_SECRET

+


+

A passphrase that must be at least 12 characters long. Avoid special characters, which can cause problems in some cases

+

DISPLAY_UNITS

+
+


Preferred BG units for the site: mg/dl or mmol/l (or just mmol)

+
+
+
+

Customizations

+

Leave default values if you don’t want to change them

+

CUSTOM_TITLE

+


+

The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer

+

THEME

+
+


Default setting for new browser views for the color theme of the CGM graph. (default colors or colorblindfriendly)

+

ENABLE

+


+

Plugins to enable for your site. Must be a space-delimited lower-case list. Include the word bridge here if you are receiving data from the Dexcom Share service

+

SHOW_PLUGINS

+


+

Default setting for whether or not these plugins are checked (active) by default not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case

+

TIME_FORMAT

+
+


Default setting for new browser views for the time mode. (12 or 24)

+

NIGHT_MODE

+
+


Default setting for new browser views for whether Night Mode should be enabled. (on or off)

+

BOLUS_RENDER_OVER

+


+

U value over which the bolus values are rendered on the chart if the x U and Over option is selected

+
+
+
+

Dexcom Share

+

If you want Nightscout to import directly from Dexcom Share

+

BRIDGE_USER_NAME

+


+

Your Dexcom account username to receive CGM data from the Dexcom Share service. Also make sure to include bridge in your ENABLE line.

+

BRIDGE_PASSWORD

+


+

Your Dexcom account password to receive CGM data from the Dexcom Share service. Also make sure to include bridge in your ENABLE line

+

BRIDGE_SERVER

+
+


If you are bridging from the Dexcom Share service and are anywhere outside the US change this to EU. (US or EU)

+
+
+
+

Alarms

+

You can customize alarms or leave them to default values

+

ALARM_TYPES

+
+


simple and/or predictv. Simple alarms trigger when BG crosses the various thresholds set below. Predict alarms use a formula that forecasts where the BG is going based on its trend. You will not get warnings when crossing the BG thresholds set below when using the predict type

+

ALARM_URGENT_HIGH

+

+

Urgent High BG threshold triggers the ALARM_URGENT_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_URGENT_LOW

+

+

Urgent Low BG threshold triggers the ALARM_URGENT_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_HIGH

+

+

High BG threshold triggers the ALARM_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_LOW

+

+

Low BG threshold triggers the ALARM_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_TIMEAGO_URGENT

+

+

Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_URGENT alarm

+

ALARM_TIMEAGO_WARN

+

+

Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_WARN alarm

+ +

Now click on the Validate button below

+

+

If errors show up below, please correct them and click Validate again.

+

Click the button Validate above.

+

+

+
+



+ +

+
+

Save this!

+

What you just copied is the secrets configuration used to build your site.
+This is important information to maintain your Nightscout.
+Make sure you keep a copy of it somewhere safe.

+
+
+

b) Click on the Copy all button above.

+
+

Tip

+

Now do not copy anything else!
+If you do another copy/paste after you clicked the Copy All button, click again now before pasting the configuration!

+
+
+

c) Then, in the terminal, paste what you copied above, hit Enter

+../../../_images/FlyIO21.png +
+

Wait until setting secrets complete.

+../../../_images/FlyIO22.png +



+
+
+
+

Step 6: Deploy Nightscout

+

a) In the terminal type:

+

flyctl deploy

+

You app will deploy. It will take time (about 10 minutes).

+../../../_images/FlyIO17.png +
+

Do not interrupt the process.

+
+

When deploy completes you should see your new Nightscout site name.

+../../../_images/FlyIO18.png +
+

b) Last but not least: downscale your app typing the following command (replace myflynightscout with your own name):

+

flyctl scale --app myflynightscout count 1

+

Confirm with y when asked.

+../../../_images/FlyIO15.png +
+

c) You can now see your site in the fly.io dashboard at https://fly.io/dashboard click on the application (not the builder):

+../../../_images/FlyIOA2.png +
+

d) Inside your app you should see that it is running and has a clickable hostname.

+../../../_images/FlyIO05.png +




+
+
+

New Nightscout Setup

+
+

a) Your Nightscout site should open and direct you to a new profile creation.

+../../../_images/NewNS50.png +
+

b) Setup your Time zone and eventually all other fields. Do not leave any fields empty. If you don’t know which value to use, just use the default value. You can change these values later at any time.

+../../../_images/NewNS44.png +
+

c) Browse down to Authentication status and click Authenticate. Enter your API secret. Click Update.

+../../../_images/NewNS45.png +
+

d) Click Save.

+../../../_images/NewNS46.png +
+

e) If the following pop-up shows up click OK, and check status (upper right of the window).

+../../../_images/NewNS47.png +
+

f) If you need to modify your profile after this, authenticate with the lock icon (top right of the page): enter your API secret. Then click on the hamburger menu and select Profile Editor.

+../../../_images/NewNS43.png +
+
+

Privacy warning

+

Anyone with access to the URL of your Nightscout site, can view your BG and run reports of your data. It it strongly recommended that you enable security to your site once you’re done with the setup

+
+
+

g) Dexcom Share users should see data flowing in after some minutes. +xDrip+ users (including Medtronic CareLink followers) should setup the uploader as shown here. +xDrip4iOS users here. +AAPS and Loop: consult the relative documentation.

+../../../_images/NewNS48.png +
+
+

You have completed a new Nightscout site creation. You can continue here now.

+

The following section provides more information that you might not need to use now.

+
+
+
+
+
+

Editing Config Vars in Fly.io

+
+

Warning

+

The web terminal feature was removed from Fly.io. +You need a computer with flyctl.

+
+

Follow these instructions to install flyctl on your computer.

+

Note for Windows: do not use Git Bash on your PC, prefer a PowerShell terminal.

+

Authenticate in Fly.io:

+

flyctl auth login

+



+
+

Secrets

+

Fly.io variables are Secrets, you cannot see the values of your secret variables.
+You can only delete them and set them: you cannot edit them.
+Please make sure you write them down somewhere!

+
+
+

If you want to create a new secret or modify an existing one you need to use the flyctl secrets set command.

+

In the command line below replace yourappname by the app name (usually your Nightscout site name: yourappname.fly.dev). +For example if you want to set your Nightscout site vertical scale to linear:

+

flyctl secrets set SCALE_Y="linear" -a yourappname`

+

If your SCALE_Y secret was already set to linear you will see the following message:

+
Error No change detected to secrets. Skipping release.
+
+
+

When changing a secret, the app will automatically redeploy. You will see this sequence (it will take a few minutes):

+
Release v1 created
+==> Monitoring deployment
+
+ 1 desired, 1 placed, 1 healthy, 0 unhealthy [health checks: 1 total, 1 passing]
+--> v1 deployed successfully
+
+
+
+
+

Hint

+

If you know you will change several secrets, add --stage to all the lines except the last one. +

+flyctl secrets set SCALE_Y="linear" -a yourappname --stage +
+flyctl secrets set SCALE_Y="linear" -a yourappname --stage +
+… +
+flyctl secrets set SCALE_Y="linear" -a yourappname +

+This will avoid your app to redeploy every time.

+
+
+

If the app didn’t deploy automatically continue here.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/github/create/index.html b/vendors/github/create/index.html new file mode 100644 index 00000000..a3a30222 --- /dev/null +++ b/vendors/github/create/index.html @@ -0,0 +1,227 @@ + + + + + + + Fork the Nightscout project — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

a) Click this link to create a GitHub account: https://github.com/

+

Enter your email and click Sign up for GitHub

+

../../../_images/NewNS00a.png

+

b) Enter a password and a username (anything you want and that is accepted, not very important).
+Type n to decline advertisement emails.

+

../../../_images/NewNS00.png

+

c) Play and solve the puzzle then click Create account

+

../../../_images/NewNS01.png

+

d) GitHub will send you a verification code. Open your mail and check your inbox (check your spam-folder if not received after a couple of minutes).

+

../../../_images/NewNS02.png

+

e) If a personalization sequence starts, click Skip personalization at the bottom.

+

../../../_images/NewNS03.png

+

f) Leave the page that opened as it is. Don’t close it.

+

../../../_images/NewNS04.png

+

You have created your GitHub account. Now fork the Nightscout project.

+
+
+

Fork the Nightscout project

+

a) Click here to log in at GitHub: https://github.com/login.
+Enter your username or email and your password. Click Sign in

+

../../../_images/UpdateNS00.png

+
+

If you already have a fork of cgm-remote-monitor in GitHub

+

Delete or update your current cgm-remote-monitor fork before continuing.

+
+

b) Open this link https://github.com/nightscout/cgm-remote-monitor. Click on Fork

+

../../../_images/NewNS29.png

+

Confirm with Create fork

+
+

Warning

+

Make sure you deselect Copy the master branch only.

+
+

../../../_images/NewNS51.png

+

c) Wait for a moment

+

../../../_images/NewNS30.png

+

d) You now have a copy (fork) of the Nightscout project repository in your own GitHub.

+

../../../_images/UpdateNS30.png

+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/github/delete/index.html b/vendors/github/delete/index.html new file mode 100644 index 00000000..80eadab0 --- /dev/null +++ b/vendors/github/delete/index.html @@ -0,0 +1,216 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Delete Nightscout?

+

Your GitHub only contains a copy of the code necessary to create a Nightscout site.
+Deleting your fork of cgm-remote-monitor will not impact or stop your Nightscout site.
+Even if it sounds scary to delete it, you can do it safely and copy (fork) it again from the main repository.
+You cannot delete the main Nightscout (nightscout/cgm-remote.monitor) repository.

+
+

Obviously if you’re a Nightscout developer and you customized or modified the repository code, you know better than anybody else you don’t want to delete it… (this documentation is not for you).

+
+
+

a) Click here to log in at GitHub: https://github.com/login.
+Enter your username or email and your password. Click Sign in

+../../../_images/UpdateNS00.png +
+

b) Select your own cgm-remote-monitor project (not nightscout/cgm-remote-monitor)

+../../../_images/UpdateNS01.png +
+

c) Click Settings

+../../../_images/UpdateNS26.png +
+

d) Scroll down to Danger zone and click Delete this repository

+../../../_images/UpdateNS27.png +
+

e) Copy and paste your full repository name to confirm then click I understand...

+../../../_images/UpdateNS28.png +
+

You have successfully deleted your copy of the cgm-remote-monitor project.

+
+ +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/github/update/index.html b/vendors/github/update/index.html new file mode 100644 index 00000000..cc4fcfe1 --- /dev/null +++ b/vendors/github/update/index.html @@ -0,0 +1,273 @@ + + + + + + + Update GitHub — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Update GitHub

+
+
+

Update your Nightscout fork

+
+ +
+


You need to update your GitHub repository. +

+
    +
  • Click here to log in at GitHub: https://github.com/login.

  • +
  • Enter your username or email and your password. Click Sign in

  • +
+

../../../_images/UpdateNS00.png

+
    +
  • Select your own cgm-remote-monitor project (not nightscout/cgm-remote-monitor)

  • +
+

../../../_images/UpdateNS01.png

+
    +
  • Your repository will open. If you see This branch is xxx commits behind nightscout:master you need to update.

  • +
  • Select Fetch upstream

  • +
+

../../../_images/UpdateNS01a.png

+
    +
  • Select Fetch and merge

  • +
+

../../../_images/UpdateNS01b.png

+
    +
  • After a moment, your repository should display This branch is up to date with nightscout:master

  • +
+

../../../_images/UpdateNS01c.png

+

You have now updated your GitHub cgm-remote-monitor repository.

+
+

If you ran into trouble, you can redeploy the project.

+
+
+ +
+


If you’re using Fly.io with the original cgm-remote-monitor repository you don’t need to update in GitHub.

+Else you need to update your GitHub repository.

+
    +
  • Click here to log in at GitHub: https://github.com/login.

  • +
  • Enter your username or email and your password. Click Sign in

  • +
+

../../../_images/UpdateNS00.png

+
    +
  • Select your own cgm-remote-monitor project (not nightscout/cgm-remote-monitor)

  • +
+

../../../_images/UpdateNS01.png

+
    +
  • Your repository will open. If you see This branch is xxx commits behind nightscout:master you need to update.

  • +
  • Select Fetch upstream

  • +
+

../../../_images/UpdateNS01a.png

+
    +
  • Select Fetch and merge

  • +
+

../../../_images/UpdateNS01b.png

+
    +
  • After a moment, your repository should display This branch is up to date with nightscout:master

  • +
+

../../../_images/UpdateNS01c.png

+

You have now updated your GitHub cgm-remote-monitor repository.

+
+

If you ran into trouble, you can redeploy the project.

+
+
+ +
+


You don’t need to update your GitHub repository.

+
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/github/update_b/index.html b/vendors/github/update_b/index.html new file mode 100644 index 00000000..a83ec25f --- /dev/null +++ b/vendors/github/update_b/index.html @@ -0,0 +1,214 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
    +
  • Click here to log in at GitHub: https://github.com/login.

  • +
  • Enter your username or email and your password. Click Sign in

  • +
+

../../../_images/UpdateNS00.png

+
    +
  • Select your own cgm-remote-monitor project (not nightscout/cgm-remote-monitor)

  • +
+

../../../_images/UpdateNS01.png

+
    +
  • Your repository will open. If you see This branch is xxx commits behind nightscout:master you need to update.

  • +
  • Select Fetch upstream

  • +
+

../../../_images/UpdateNS01a.png

+
    +
  • Select Fetch and merge

  • +
+

../../../_images/UpdateNS01b.png

+
    +
  • After a moment, your repository should display This branch is up to date with nightscout:master

  • +
+

../../../_images/UpdateNS01c.png

+

You have now updated your GitHub cgm-remote-monitor repository.

+
+

If you ran into trouble, you can redeploy the project.

+
+ +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/google/new_user/index.html b/vendors/google/new_user/index.html new file mode 100644 index 00000000..762ff80f --- /dev/null +++ b/vendors/google/new_user/index.html @@ -0,0 +1,227 @@ + + + + + + + Nightscout in Google Cloud — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout in Google Cloud

+
+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+
+
+

Google Cloud Nightscout

+

+
+
+

Pros:

+
    +
  • Complete solution offering a large, > 10GB, free database

  • +
  • Tools provided to migrate the database from other platforms

  • +
  • A web interface for editing variables

  • +
  • Option of multiple Nightscout accounts, one per Google account

  • +
+

Cons:

+
    +
  • Not free! To keep the cost below $0.05 a month, outgoing traffic must be kept below 1GB per month.

  • +
  • In Australia or China, cost can be more than $0.50 a month.

  • +
+
+
+
+
+

Instructions

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/heroku/ecoplan/index.html b/vendors/heroku/ecoplan/index.html new file mode 100644 index 00000000..866a3170 --- /dev/null +++ b/vendors/heroku/ecoplan/index.html @@ -0,0 +1,292 @@ + + + + + + + Heroku Eco plan — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Heroku Eco plan

+
+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+
+
+

Heroku

+

Heroku Eco

+
+
+

Since the beginning Heroku has been a very popular platform for Nightscout. Most of the documentation was based on a Heroku Nightscout.
+On August 25th 2022, Salesforce decided to drop the free plan. +You can create your new Nightscout site with Heroku using an Eco plan (5$/month).

+

Pros:

+
    +
  • Large platform with a reliable history

  • +
  • Well documented, well known by the community

  • +
+

Cons:

+
    +
  • The Eco plan has the same limitations than the previous Free plan, for 5$ per month

  • +
  • For a Nightscout site a 7$ per month Basic plan is not really worth it (compared to hosted solutions)

  • +
  • Relying on the MongoDB Atlas database

  • +
+
+
+
+
+

Enable a 5$/month Eco Plan

+
+
+

Warning

+

Heroku billing is monthly.
+One minute of Eco plan will be billed 5$ in the current month.
+Switching billable plan during the same month with add another plan billing for the whole month.

+
+
+ +../../../_images/UpdateNS15.png +
+
    +
  • Select your app (hidden in yellow)

  • +
+../../../_images/UpdateNS16.png +
+
    +
  • Click Resources then select Change Dyno Type

  • +
+../../../_images/HerokuH01.png +
+
    +
  • Select Eco ($5 for 1000 Dyno Hours/Month) then click Save

  • +
+../../../_images/HerokuE02.png +
+
    +
  • Your Nightscout Heroku app is now using an Eco plan.

  • +
+../../../_images/HerokuH03.png +
    +
  • Make sure your credit card information is up to date!
    +Go to your Account settings.

  • +
+../../../_images/NewNS13.png +
    +
  • Billing

  • +
+../../../_images/NewNS14.png +
    +
  • Verify the credit card you used is still valid, in case of doubt Change credit card and enter a valid credit card.

  • +
+../../../_images/HerokuH04.png +
+
+
+

Prevent your Nightscout app from falling asleep

+
+

Use with caution

+

If an app fails and crashes at startup (database full), if you entered wrong credentials and the app stops for missing data activity, using this trick to keep it alive will not help. It might even make things worse in the case of wrong Dexcom credentials and lead to a locked account.

+
+

This is necessary if you don’t have an uploader sending data to Nightscout, or a follower polling data from it.
+For example using the bridge plugin.

+
    +
  • You can use monitoring webapps like Uptime Robot, New Relic, …

  • +
+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/heroku/hobbyplan/index.html b/vendors/heroku/hobbyplan/index.html new file mode 100644 index 00000000..3f1becba --- /dev/null +++ b/vendors/heroku/hobbyplan/index.html @@ -0,0 +1,280 @@ + + + + + + + Heroku Basic plan — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Heroku Basic plan

+
+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+
+
+

Heroku

+

Heroku Eco

+
+
+

Since the beginning Heroku has been a very popular platform for Nightscout. Most of the documentation was based on a Heroku Nightscout.
+On August 25th 2022, Salesforce decided to drop the free plan. +You can create your new Nightscout site with Heroku using an Eco plan (5$/month).

+

Pros:

+
    +
  • Large platform with a reliable history

  • +
  • Well documented, well known by the community

  • +
+

Cons:

+
    +
  • The Eco plan has the same limitations than the previous Free plan, for 5$ per month

  • +
  • For a Nightscout site a 7$ per month Basic plan is not really worth it (compared to hosted solutions)

  • +
  • Relying on the MongoDB Atlas database

  • +
+
+
+
+
+

Upgrade to 7$/month Basic Plan

+
+
+

5$/month Eco Plan

+

You can also select a more economic eco plan upgrade.

+
+
+
+

Warning

+

Heroku billing is monthly.
+One minute of Eco plan will be billed 5$ in the current month.
+Switching billable plan during the same month with add another plan billing for the whole month.

+
+
+ +../../../_images/UpdateNS15.png +
+
    +
  • Select your app (hidden in yellow)

  • +
+../../../_images/UpdateNS16.png +
+
    +
  • Click Resources then select Change Dyno Type

  • +
+../../../_images/HerokuH01.png +
+
    +
  • Select Basic ($7/dyno/month) then click Save

  • +
+../../../_images/HerokuH02.png +
+
    +
  • Your Nightscout Heroku app is now using a Basic plan.

  • +
+../../../_images/HerokuH03.png +
    +
  • Make sure your credit card information is up to date!
    +Go to your Account settings.

  • +
+../../../_images/NewNS13.png +
    +
  • Billing

  • +
+../../../_images/NewNS14.png +
    +
  • Verify the credit card you used is still valid, in case of doubt Change credit card and enter a valid credit card.

  • +
+../../../_images/HerokuH04.png +
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/heroku/index.html b/vendors/heroku/index.html new file mode 100644 index 00000000..191fcaac --- /dev/null +++ b/vendors/heroku/index.html @@ -0,0 +1,192 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/heroku/mfa/index.html b/vendors/heroku/mfa/index.html new file mode 100644 index 00000000..a4af08fc --- /dev/null +++ b/vendors/heroku/mfa/index.html @@ -0,0 +1,282 @@ + + + + + + + Heroku MFA — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Heroku MFA

+

Multiple factor authentication (MFA) also called 2 factors authentication (2FA) is a safety feature preventing malicious access to an account. Once authenticated with your login and password you will be required to confirm your identity with another method, a second factor authentication.

+
+

Losing access

+

It is recommended to setup at least two MFAs, one being a copy of the recovery codes. Salesforce take security very seriously and recovering your account after losing access might range from very complex to impossible. For increased safety, setup more than one authentication method on more than one device.

+
+
+

To setup MFA and secure your account select Continue.
+If you don’t want to secure your account, select Later.

+

If you want to enter your account without setting MFA just select Later.

+../../../_images/MFA01.png +
+

You will also find the possibility to perform this operation from your Heroku account settings.

+../../../_images/MFA00.png +../../../_images/MFA00a.png +
+

You will be proposed various authentication options, see the explanation below.

+

You should select at least one (Salesforce Authenticator is recommended) but might use more than one (registering a build in authenticator like a fingerprint reader is also a good idea) and you should print your Recovery Codes and keep them together with your Nightscout information.

+../../../_images/MFA02.png +
+
+

Salesforce Authenticator

+

Salesforce Authenticator relies on an additional app you will need to install on your phone. It is available in the Google Play Store and the Apple Store.

+
+

Losing or removing the Authenticator app

+

It is recommended to setup at least two MFAs, one being a copy of the recovery codes. If your only authentication method is this app you will lose access if you remove it or lose/change phone!

+
+

If you select this option (use the Add button) you will need to install the app to get the passcode called Two-Word Phrase

+

Install the app and Add an Account.

+../../../_images/MFA03b.png +
+

The app will give you a Two-Word Phrase (perfect guide in the example below)

+../../../_images/MFA03c.png +
+

Copy it or type it into the authentication connection window in Salesforce Heroku and select Connect.

+../../../_images/MFA03.png +
+

In the app, confirm with Connect then Got It.

+../../../_images/MFA03d.png +../../../_images/MFA03e.png +
+

You will now see Heroku in the app, with a single use code (that you usually won’t need).

+../../../_images/MFA03f.png +
+

Now, every time you will log into Heroku, you will have to confirm using your phone. Just accept the access.

+
+

Once the account added into Salesforce Authenticator you will be able to add another option that is Built-In Authenticator (like a fingerprint reader).

+../../../_images/MFA03g.png +
+
+
+

Built-In Authenticator

+

You need Salesforce Authenticator setup in order to use this method (see above).

+

Adding a built in authenticator will allow you to use your device biometric devices like a fingerprint reader.

+

Select Register to add this identification method as a second factor. You will not be required to use the Salesforce Authenticator after registration. You can now remove it if you wish (not recommended).

+../../../_images/MFA08.png +

Note that you won’t be able to use your fingerprint if created on a computer to unlock your account when using your phone and vice versa. You should add one fingerprint per device type.

+
+
+
+

One-Time Password Generator

+

You can use other apps to create your second factor, like Google Authenticator or Microsoft Authenticator apps. You will find both these apps in the Google Play Store and the Apple Store.

+

First install one of these apps on your mobile device, then select Add.

+

Scan the QR code with the app and Connect.

+../../../_images/MFA04.png +
+

Your Heroku will now be connected to this second factor authentication method and you will have to approve access, when logging into Heroku, with the app you selected.

+../../../_images/MFA04a.png +
+
+
+

Security Key

+

Security key authentication requires you to use a hardware key. You probably won’t be reading this if you own one.

+../../../_images/MFA05.png +
+
+
+

Recovery Codes

+

You should enable and keep a copy of your recovery codes. This might eventually be the only way to recover your account access if something goes wrong with the other authentication method. Print a copy and keep it with your Nightscout information together with your diabetes documentation.

+../../../_images/MFA06.png +../../../_images/MFA07.png +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/heroku/migrate/index.html b/vendors/heroku/migrate/index.html new file mode 100644 index 00000000..d0b09831 --- /dev/null +++ b/vendors/heroku/migrate/index.html @@ -0,0 +1,277 @@ + + + + + + + Migration? — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Migration?

+

As Heroku and Railway stopped their free plan, if you would like to revive your site, one question remains: “What should I do with my Nightscout, should I migrate, where? What is recommended?”

+

There is no universal solution. So, you’ll have to read between the lines and understand what’s the best strategy for you, as we have different needs, skills and budgets.

+
+

TANSTAAFL

+

This is an important concept everybody needs to understand: what we call free means we don’t have to pay for it but it also means someone else is paying for it. It doesn’t mean it’s bad, we all know the price of T1D is already too high for us and our kids but we can’t pretend that someone else will pay for it. Whoever offers a free service should have our respect and gratitude, and when they understand the weight of free users is too high and decide to start billing, we should accept it.

+ +
+
+

T1Pal

+

You need a simple reliable Nightscout but don’t want to build it and maintain it?

+

T1Pal is made by developers who contribute to Nightscout development, it doesn’t include all bells and whistles (see the differences here) but you won’t have to worry about security, upgrades or database size. If you will want to pay a vendor for your DIY Nightscout you should seriously consider T1Pal. Also, if you need to support multiple T1D people in a family that’s surely something to think about as you can have up to 5 sites in one subscription. Data migration is not available, contact T1Pal support for settings migration.

+
+
+

NS10BE

+

You need a simple reliable Nightscout but don’t want to build it and maintain it?

+

You can create Nightscout with a few clicks and won’t have to worry about maintenance, updates, database space and CPU limits. Some features are not available for legal reasons and if you need extra variables setup you can contact NS10BE support. You will need to copy your Nightscout settings but can migrate your Mongo database easily in NS10BE.

+
+
+

Nightscout.Pro

+

You need a simple reliable Nightscout but don’t want to build it and maintain it?

+

A completely ‘hands-off’ approach to Nightscout. Simply subscribe via the website and you’ll receive an email once your site is ready. Enjoy unlimited database and resources and do not have to worry about updating your nightscout site as it all taken care of for you.

+
+
+

Google Cloud

+

You’re not scared to innovate with a new easy and reliable way to build and maintain your Nightscout? Give this a try!

+

With the xDrip+ team trying to make it so easy that the solutions above will look difficult, you need to try it to believe it.

+

Note: You can use this method to deploy in Digital Ocean and other VPS

+
+
+

Azure

+

You need a reliable engine for your Nightscout site, well Azure sure is the way to go.

+

Azure is back hurrah hurrah. Wait, why did we leave it some years ago? Ah, sure, costs. But we believe we have a free solution thanks to Scott. Shame the Cosmos database doesn’t always meet expectations… And keep in mind the free tier is designed for testing, not production.

+
+
+

Heroku

+

You liked the Heroku experience and don’t want to change? An Eco plan subscription is all it takes to continue like that.

+

Heroku is still a valid choice for running Nightscout. Someone reminded me they’ve been offering a free account to many of us for years so there’s no reason not to pay for an Eco account and let it go as before. Still, it is not set it and forget it and you will need to keep it updated yourself. And that MongoDB Atlas database still is a weak point.

+
+
+

MongoDB Atlas

+

You need a small free database? An M0 Atlas does that and nothing more.

+

Since they bought mLab, most have a database in MongoDB. This is a weak point of Nightscout DIY and forced our developers to do a lot of work to cope with it. An M0 free database is very limited in size and DIY Loopers/AAPS’ers should be very careful to keep the database below 512MB before their site crashes. Also, recently MongoDB Atlas is recording us this is a sandbox database (i.e. for testing) and not for production (continuous use). An M2 database only removes size limitations and is not worth the cost versus hosted solutions.

+
+
+

Railway

+

You want an alternative to Heroku? Railway costs the same than the Eco plan.

+

We really liked the Railway solution when we found it: it’s very simple to migrate from Heroku and the platform is simple to use. Still, we discovered some Nightscout followers are suffering network related issues. The free plan has been removed and the Hobby plan is starting at 5$ per month (which should be enough for a single Nightscout site).

+
+
+

Northflank

+

Everybody else is going for Railway and you prefer a safer alternative because you’re not afraid of an ugly Nightscout site name? Northflank is a good idea.

+

Not very sponsored, Northflank is also a good option, simple of use and offering a migration utility. The only issue is trying to remember your Nightscout site name (try night--spicy-steam--nightscout--ci95-l9xw.code.run for example). Still, Northflank is a reliable provider. But they will most probably review their free plan in the future.

+
+
+

Fly.io

+

Fly.io still offers a free tier but if you don’t like typing commands on your computer you’ll short be facing a hard stop.

+

Fly.io was immediately popular due to the ease of migration from Heroku (the migration wizard has been removed). Now, if you want to maintain your site you’ll have to use command line instructions in the web terminal. On the other hand, it is a good solution.

+
+
+

Oracle Cloud

+

You’re ready to type commands in a terminal window, following an accurate step by step guide? Oracle Cloud solution is worth a try.

+

Follow this very detailed guide to build your Nightscout site. It also contains a lot of reference information for VPS DIY Nightscout, including Docker.

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/heroku/new_user/index.html b/vendors/heroku/new_user/index.html new file mode 100644 index 00000000..64fdef0c --- /dev/null +++ b/vendors/heroku/new_user/index.html @@ -0,0 +1,587 @@ + + + + + + + Nightscout in Heroku — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout in Heroku

+
+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+
+
+

Heroku

+

Heroku Eco

+
+
+

Since the beginning Heroku has been a very popular platform for Nightscout. Most of the documentation was based on a Heroku Nightscout.
+On August 25th 2022, Salesforce decided to drop the free plan. +You can create your new Nightscout site with Heroku using an Eco plan (5$/month).

+

Pros:

+
    +
  • Large platform with a reliable history

  • +
  • Well documented, well known by the community

  • +
+

Cons:

+
    +
  • The Eco plan has the same limitations than the previous Free plan, for 5$ per month

  • +
  • For a Nightscout site a 7$ per month Basic plan is not really worth it (compared to hosted solutions)

  • +
  • Relying on the MongoDB Atlas database

  • +
  • New sites naming add an identifier after the app name making it harder to remember

  • +
+
+
+
+
+

Create your Heroku account from a computer.

+

Do not change device/computer/browser during the setup process!

+
+

Hint

+

If you have unexpected issues when creating your site, restart with another browser.

+
+
+

If this is not your first attempt to deploy Nightscout

+

You might want to do some cleanup before.

+
+
+
+

Step 0: Create a database

+
+

Heroku doesn’t include a database

+

Make sure you created one before starting your Nightscout web app creation with Heroku. +Come back here when you have a MONGODB_URI connection string.

+
+
+

Migrating?

+

Copy the connection string from your previous platform: edit the variables and look for MONGODB_URI. +If you don’t see MONGODB_URI but see MONGO_CONNECTION (NOT MONGO_COLLECTION): use its value.

+
+
+
+
+

Step 1: Create a GitHub account and fork the Nightscout project

+
+ +
+

Create a GitHub account

+

a) Click this link to create a GitHub account: https://github.com/

+

Enter your email and click Sign up for GitHub

+

../../../_images/NewNS00a.png

+

b) Enter a password and a username (anything you want and that is accepted, not very important).
+Type n to decline advertisement emails.

+

../../../_images/NewNS00.png

+

c) Play and solve the puzzle then click Create account

+

../../../_images/NewNS01.png

+

d) GitHub will send you a verification code. Open your mail and check your inbox (check your spam-folder if not received after a couple of minutes).

+

../../../_images/NewNS02.png

+

e) If a personalization sequence starts, click Skip personalization at the bottom.

+

../../../_images/NewNS03.png

+

f) Leave the page that opened as it is. Don’t close it.

+

../../../_images/NewNS04.png

+

You have created your GitHub account. Now fork the Nightscout project.

+
+

Fork the Nightscout project

+

a) Click here to log in at GitHub: https://github.com/login.
+Enter your username or email and your password. Click Sign in

+

../../../_images/UpdateNS00.png

+
+

If you already have a fork of cgm-remote-monitor in GitHub

+

Delete or update your current cgm-remote-monitor fork before continuing.

+
+

b) Open this link https://github.com/nightscout/cgm-remote-monitor. Click on Fork

+

../../../_images/NewNS29.png

+

Confirm with Create fork

+
+

Warning

+

Make sure you deselect Copy the master branch only.

+
+

../../../_images/NewNS51.png

+

c) Wait for a moment

+

../../../_images/NewNS30.png

+

d) You now have a copy (fork) of the Nightscout project repository in your own GitHub.

+

../../../_images/UpdateNS30.png

+
+ +
+

Update your Nightscout fork

+
    +
  • Click here to log in at GitHub: https://github.com/login.

  • +
  • Enter your username or email and your password. Click Sign in

  • +
+

../../../_images/UpdateNS00.png

+
    +
  • Select your own cgm-remote-monitor project (not nightscout/cgm-remote-monitor)

  • +
+

../../../_images/UpdateNS01.png

+
    +
  • Your repository will open. If you see This branch is xxx commits behind nightscout:master you need to update.

  • +
  • Select Fetch upstream

  • +
+

../../../_images/UpdateNS01a.png

+
    +
  • Select Fetch and merge

  • +
+

../../../_images/UpdateNS01b.png

+
    +
  • After a moment, your repository should display This branch is up to date with nightscout:master

  • +
+

../../../_images/UpdateNS01c.png

+

You have now updated your GitHub cgm-remote-monitor repository.

+
+

If you ran into trouble, you can redeploy the project.

+
+
+
+
+
+
+

Step 2: Create a Heroku account

+
+
+

Multiple factor authentication

+

Salesforce will insist you should enable multiple factor authentication. +While this is indeed a good idea to increase safety, should you decide to enable it, make sure:

+
    +
  • To print your recovery codes and keep them in a safe place

  • +
  • To never delete the authenticator app on your phone. +Failure to follow these rules will end up in an account you can’t log into, hance can’t restart and maintain your Nightscout site. +More information here.

  • +
+
+
+

a) Click this link to create an Heroku account: https://signup.heroku.com/login

+

b) Enter mandatory data (*) and click CREATE FREE ACCOUNT

+../../../_images/NewNS07.png +
+

c) Heroku will send a confirmation email, open your mail and check your inbox (check your spam-folder if not received after a couple of minutes).

+../../../_images/NewNS09.png +
+

d) Click on the activation link

+../../../_images/NewNS10.png +
+

e) Create a password, it is important that you write it down for later usage. Click SET PASSWORD AND LOG IN

+../../../_images/NewNS11.png +
+

f) Click CLICK HERE TO PROCEED

+../../../_images/NewNS12.png +

Read and accept Salesforce terms of service.

+

Se sei residente in Italia, abilita l’interruttore Are you domiciled in Italy, leggi e accetta le condizioni supplementari.

+../../../_images/NewNS12a.png +
+

g) Your Heroku page will open, click on your profile picture, in the top right corner, and select Account Settings

+../../../_images/NewNS13.png +
+

h) Click on Billing

+../../../_images/NewNS14.png +
+

i) Click Add credit card

+../../../_images/NewNS15.png +
+

j) Enter your credit card information and click Save Details

+
+../../../_images/NewNS16.png +
+

k) Subscribe to the Eco plan for 5$ per month. You can upgrade to Basic later if you wish.

+../../../_images/HerokuE03.png +
+

l) You should now have 2 pages open: Heroku and GitHub. Leave them open.

+
+
+

Step 3: Fork and deploy cgm-remote-monitor

+

a) Fork the Nightscout cgm-remote-monitor project.

+
+

b) Click the Deploy to Heroku button below:

+

https://www.herokucdn.com/deploy/button.png

+
+
+

You’re getting into the core setup of your site

+

Below you’ll see the minimum required configuration, you can modify the variables later in Heroku.

+
+
+

c) Enter your CGM in the Cloud site name: invent a name you will use to see your BG in the cloud. Confirm that the name is available.

+
+

Hint

+

Starting June 14th 2023, site names will include an application name identifier after your app name.

+
+

d) Don’t change the region.

+../../../_images/NewNS33.png +
+

Scroll down and setup the following variables:

+
+

e) API_SECRET will be your Nightscout site password, it needs to be at least 12 characters long and you should NOT use spaces if you use @ or ! symbols remember you will probably need to express them using Percent encoding in your uploader and downloader apps. If you’re not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits.

+
+

Warning

+

The API_SECRET is the main password allowing full access to your Nightscout site. Make sure it’s reasonably secure (mix uppercase and lowercase letters, plus digits) and do no not share it publicly. If you think you exposed it by mistake, it is recommended that you change it.

+
+../../../_images/NewNS34.png +
+

f) If you want to link your Dexcom Share account as a data source, complete the following lines:

+
+

Note

+

If you use a DIY closed loop system it is recommended that you let it upload to Nightscout instead of importing using Dexcom Share and the bridge plugin.

+
+../../../_images/NewNS35.png +
+
+

MOST COMMON ERRORS

+

The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom’s Clarity page (check here for USA accounts and here for the others) and try logging in to your Dexcom account. If your account info isn’t valid, or you don’t see any data in your Clarity account… you need to figure out your actual credentials before moving ahead. See here for troubleshooting tips and information on your Dexcom account.

+
+
+

Password

+

Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.

+
+
+

Hint

+

You need to have at least one follower to use Dexcom Share. See here.

+
+
+

g) Linking your CareLink account as a data source is not possible anymore using cloud hosted Nightscout sites.
+Use an Android bridge device with a private version of xDrip+.
+More information here.

+../../../_images/NewNS36.png +
+

j) Select the units you’re using in DISPLAY_UNITS acceptable choices are mg/dl or mmol/L (or just mmol).

+../../../_images/NewNS37.png +
+

h) In ENABLE, copy and paste the following words (separated by a space) so that won’t have to think about which you want now:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors

+

If you are using your Dexcom share account as a data source also add bridge at the end, after a space like this:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge

+../../../_images/NewNS38.png +
+

ENABLE words

+

You find more information about the ENABLE words on the: Setup page

+
+
+

i) Now you need the connection string you defined during the database creation (as the example below, but not the string below). Copy and paste it in the MONGODB_URI variable field.

+../../../_images/NewNS39.png +

Make sure it looks like this one below and NOTE: THERE ARE NO < AND > CHARACTERS:

+

Example for MongoDB Atlas:

+

mongodb+srv://nightscout:soo5ecret@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority

+

Example for a MongoDB database:

+

mongodb://nightscout:soo5ecret@mydbhosting.fqd/mydatabase

+
+

j) Scroll down to the end of the list and click Deploy app

+../../../_images/NewNS40.png +
+

k) WAIT until completion (will take some time). Do not interrupt the process until it’s complete.

+../../../_images/NewNS41.png +
+

l) Then click View (if nothing happens, click Manage App -> Open App, in upper right corner)

+../../../_images/NewNS42.png +
+
+
+

New Nightscout Setup

+
+

a) Your Nightscout site should open and direct you to a new profile creation.

+../../../_images/NewNS50.png +
+

b) Setup your Time zone and eventually all other fields. Do not leave any fields empty. If you don’t know which value to use, just use the default value. You can change these values later at any time.

+../../../_images/NewNS44.png +
+

c) Browse down to Authentication status and click Authenticate. Enter your API secret. Click Update.

+../../../_images/NewNS45.png +
+

d) Click Save.

+../../../_images/NewNS46.png +
+

e) If the following pop-up shows up click OK, and check status (upper right of the window).

+../../../_images/NewNS47.png +
+

f) If you need to modify your profile after this, authenticate with the lock icon (top right of the page): enter your API secret. Then click on the hamburger menu and select Profile Editor.

+../../../_images/NewNS43.png +
+
+

Privacy warning

+

Anyone with access to the URL of your Nightscout site, can view your BG and run reports of your data. It it strongly recommended that you enable security to your site once you’re done with the setup

+
+
+

g) Dexcom Share users should see data flowing in after some minutes. +xDrip+ users (including Medtronic CareLink followers) should setup the uploader as shown here. +xDrip4iOS users here. +AAPS and Loop: consult the relative documentation.

+../../../_images/NewNS48.png +
+
+

You have completed a new Nightscout site creation. You can continue here now.

+

The following section provides more information that you might not need to use now.

+
+
+
+
+

Papertrail

+
    +
  • Finally, you might want to modify the PAPERTRAIL_API_TOKEN line. Heroku offers a free, tiny amount of Papertrail service (this is like a logging service for how the site is running), but this generates a lot of confusion to most people later on, when they get a message that their “Free Papertrail Service has run out of room”. Papertrail is not needed, edit the line and add DISABLED at the end, so that you can recover the function if you need it later.

  • +
+../../../_images/NewNS49.png +



+
+
+
+

Editing Config Vars in Heroku

+
+

Once Nightscout deployed, you can access your variables from Heroku in order to change or customize your site. +Variables are described here.

+
    +
  • Select your app

  • +
+../../../_images/SetupNS00.png +
+
    +
  • Click Settings

  • +
+../../../_images/SetupNS01.png +
+
    +
  • Scroll down and click Reveal Config Vars

  • +
+../../../_images/SetupNS02.png +
+
    +
  • You can modify the values clicking on the pen icon

  • +
+../../../_images/SetupNS03.png +
+
    +
  • Change the contents of Value as needed then click Save Changes

  • +
+../../../_images/SetupNS04.png +
+

Changing a variable and saving a new value will restart your site, if the change is not actuated you might also want to restart all dynos.

+
+
+
+
+

Prevent your Nightscout app from falling asleep

+
+

Use with caution

+

If an app fails and crashes at startup (database full), if you entered wrong credentials and the app stops for missing data activity, using this trick to keep it alive will not help. It might even make things worse in the case of wrong Dexcom credentials and lead to a locked account.

+
+

This is necessary if you don’t have an uploader sending data to Nightscout, or a follower polling data from it.
+For example using the bridge plugin.

+
    +
  • You can use monitoring webapps like Uptime Robot, New Relic, …

  • +
+
+
+

You have completed a new Nightscout site creation. The following section provides more information for variables edition that you might not need to use now.

+
+
+
+
+

Renaming your Nightscout site

+
+

Warning

+

Starting June 14th 2023, site names will include an application name identifier after your app name.
+Keep this in mind if you want to rename your site: the result might not be as simple as it was before.

+
+

You can rename your Nightscout site URL in your app Settings.

+../../../_images/Security01.png +

Once done, make sure all apps (uploaders and downloaders) are updated accordingly.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/mongodb/atlas/index.html b/vendors/mongodb/atlas/index.html new file mode 100644 index 00000000..b717b0ab --- /dev/null +++ b/vendors/mongodb/atlas/index.html @@ -0,0 +1,376 @@ + + + + + + + MongoDB Atlas Database — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

MongoDB Atlas Database

+
+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+
+
+

MongoDB Atlas Database

+

MongoDB Atlas

+
+
+

MongoDB bought mLab in 2018 and shutdown its service in 2020. Most users migrated to MongoDB Atlas, using a free M0 database with a limited 512MB capacity. Leaving the database grow uncontrolled usually leads to a Nightscout crash.

+

Pros:

+
    +
  • The M0 cluster is free

  • +
  • Nightscout was adapted to MongoDB Atlas

  • +
+

Cons:

+
    +
  • M0 clusters are designed for learning and testing, not production

  • +
  • There is no warranty the M0 cluster will remain in the future

  • +
  • A larger M2 cluster costs 9$ per month (consider hosted Nightscout)

  • +
  • A full M0 database crashes Nightscout, this is a common issue for DIY closed loop system users

  • +
+
+
+
+
+

Note

+

MongoDB Atlas regularly changes the site aspect. If you encounter a page not matching this documentation search for keywords like not now, skip or later to continue. Report discrepancies here.

+
+
+
+

Create an Atlas database

+

a) Open a browser tab at: https://www.mongodb.com/cloud/atlas/register

+

b) Enter your information, click Continue then Create account

+../../../_images/NewNS18.png +
+

MongoDB Atlas will send you an email, if you don’t receive it check your Spam folder.

+../../../_images/NewNS18b.png +
+

In the email you received from MongoDB Atlas (mongodb-atlas @ mongodb.com), click on Verify email

+../../../_images/NewNS18c.png +
+

Another browser tab will open with your confirmed MongoDB account, Continue.

+../../../_images/NewNS18d.png +
+

Enter some information (like below) and click Finish.

+../../../_images/NewNS18e.png +
+

c) Select Create a cluster in Shared Clusters (FREE)

+../../../_images/NewNS19.png +
+

If you ever see this, just STOP

+

We’re building a free cluster: you don’t need to provide any billing information. +../../../_images/NewNS19b.png

+
+
+

d) Check you selected Shared, leave all default values and click Create Cluster

+../../../_images/NewNS20.png +
+

e) Select Username and Password and invent a database username (for example nightscout) and a database password (for example soo5ecret but please make one that’s yours!).

+
+

Database credentials

+

Do not use your Atlas account credentials. +Do not use special characters: only letters and numbers. No spaces.

+
+../../../_images/NewNS25.png +

Write down the password in the line below (yes, in this browser window you’re reading now, unless you’re reading a printed version). You’ll need it later.

+ + + + + + +

Database password (write here ->)

+
+

Then click Create User.

+

f) Select My Local Environment and in the box My IP address write 0.0.0.0/0 (mind these are all zeroes, not the letter O)

+
+

Warning

+

If you don’t allow access from anywhere (IP 0.0.0.0/0) Nightscout will not be able to access your database.”

+
+../../../_images/NewNS23.png +

Then click Add Entry.

+
+

g) Click on Finish and Close

+../../../_images/NewNS24.png +
+

h) Click on Go to Databases

+../../../_images/NewNS24b.png +
+

i) Atlas will create your default cluster, it can take more than 3 minutes

+../../../_images/NewNS21.png +
+

j) Click on CONNECT

+../../../_images/NewNS22.png +
+

k) If displayed, click on Choose a connection method (else skip)

+../../../_images/NewNS26.png +
+

l) Select Drivers

+../../../_images/NewNS27.png +
+

m) Scroll down (do not change any value) and copy the connection string: click Copy and paste it somewhere to edit it (like Notepad).

+../../../_images/NewNS28.png +
+

n) Paste the string in the line below (yes, in this browser window you’re reading now, unless you’re reading a printed version).

+

(paste here ->)

+
+
+

Hint

+

It should be similar to this (xxxxx will be different):

+

mongodb+srv://nightscout:<password>@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority

+
+
+

o) (Optional) Invent a name for your database, this is not a critical information (for example myCGMitc). Only letters and numbers, no spaces.

+ + + + + +

Database Name (write here ->)

+
+

p) Click on the button Generate (just here below this line: in this browser window you’re reading):

+

+

The connection string will appear here

+
+ +
+
+

Warning

+

Keep this string safely aside, it is called your MONGODB_URI

+
+
+

p) If you want to do it manually: replace <password> with your database password as noted previously (in the example below soo5ecret) and <dbname> by any text you want, say mycgmic for example. The result will be like this:

+

mongodb+srv://nightscout:soo5ecret@cluster0.xxxxx.mongodb.net/myCGMitc?retryWrites=true&w=majority

+
+

Hint

+

There should be NO < and NO > characters in the final string, neither for password nor for database name.

+
+
+

You have completed a MongoDB Atlas database creation. +Now that you have copied the resulting MONGODB_URI string to a safe place, go back to the instructions page you were following.

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/nightscout4u/new_user/index.html b/vendors/nightscout4u/new_user/index.html new file mode 100644 index 00000000..c2891190 --- /dev/null +++ b/vendors/nightscout4u/new_user/index.html @@ -0,0 +1,192 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/northflank/database/index.html b/vendors/northflank/database/index.html new file mode 100644 index 00000000..85a821c0 --- /dev/null +++ b/vendors/northflank/database/index.html @@ -0,0 +1,313 @@ + + + + + + + Northflank Database — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Northflank Database

+
+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+
+
+

Northflank Mongo Database

+

Northflank MongoDB

+
+
+

Northflank offers a Mongo database.

+

Pros:

+
    +
  • Simple to create

  • +
  • Economic reliable database

  • +
  • High quality Mongo database with a replica set

  • +
  • You can deploy up to $20/mo worth of free resources on Northflank’s managed cloud

  • +
+

Cons:

+
    +
  • Heroku Nightscout might crash with database timeouts

  • +
+
+
+
+

If you already have a Northflank account, log in and continue (skip new account creation).

+

Else

+
+

Create an account with Northflank

+

a) Sign-up to Northflank in a new browser tab.
+Fill all required fields and Sign up.
+You can also sign up with Google, GitHub, … if you wish.

+../../../_images/Northflank00a.png +
+

Northflank will send you an email to complete the registration.

+../../../_images/Northflank00b.png +
+

b) Open your email and confirm with Verify email.

+../../../_images/Northflank00c.png +
+

c) Click Choose theme.

+../../../_images/Northflank04.png +
+

d) Select Skip for now.

+../../../_images/Northflank05.png +
+

e) Click Create free project

+../../../_images/Northflank06.png +
+

f) Invent a project name (nightscout for example) and select a region (Europe or US) then click Create project

+../../../_images/Northflank07.png +
+
+
+
+

Create your database

+
+

Costs

+
    +
  • The Mongo database is free, you only pay for the storage

  • +
  • Minimum price is 0.3$/month, cost is then 0.3$/GiB/month

  • +
  • A good database is important for your Nightscout site reliability

  • +
+
+
+

a) Open a new browser page https://northflank.com/dbaas/mongodb-on-northflank and click Deploy MongoDB on Northflank for free

+../../../_images/NorthflankDB01.png +
+

b) Select your account and your project name (see below if you don’t have one yet).

+../../../_images/NorthflankDB02.png +
+

If you don’t have a project in Northflank, create a new one with Create project and then select Create free project else skip to c).

+../../../_images/NorthflankDB02a.png +../../../_images/Northflank06.png +

Invent a project name (nightscout for example) and select a region (Europe or US) then click Create project

+../../../_images/Northflank07.png +
+

c) Select Deploy addons.

+../../../_images/NorthflankDB07.png +
+

d) Select MongoDB and type a name for your addon (not important) in Addon name.

+../../../_images/NorthflankDB08.png +
+

e) Select a Mongo version if you want.

+

All Mongo versions are supported by Nightscout: you can select the one you prefer.
+Since recent versions don’t add value, you can safely select an older version like 5.0.24.

+../../../_images/NorthflankDB10.png +
+

Important: If you will use this database with a Nightscout that is not in Northflank, you must enable Publicly accessible.
+If you will deploy Nightscout in Northflank, you can leave it disabled.

+../../../_images/NorthflankDB06.png +
+

f) Select Create addon

+../../../_images/NorthflankDB03.png +
+

g) If you haven’t yet, you need to add a payment method into Northflank.
+You will be charged monthly for your database (0.3$ up to 1 GiB, then 0.3$/GiB).

+../../../_images/Northflank23.png +
+

g) Enter your password and click Confirm to see your MongoDB information.

+../../../_images/NorthflankDB04.png +
+

h) Click the copy icon of the line MONGO_SRV.

+../../../_images/NorthflankDB05.png +
+
+

This is an important information

+

Now that you have copied the resulting MONGODB_URI string, keep it in a safe place, you will need it later.

+
+
+

i) Wait until your database is fully created. It might take some time.

+../../../_images/NorthflankDB09.png +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/northflank/migrate/index.html b/vendors/northflank/migrate/index.html new file mode 100644 index 00000000..c184fabe --- /dev/null +++ b/vendors/northflank/migrate/index.html @@ -0,0 +1,190 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Now included in the main Nightscout with Northflank page!

+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/northflank/migrate_a/index.html b/vendors/northflank/migrate_a/index.html new file mode 100644 index 00000000..dbd65f9b --- /dev/null +++ b/vendors/northflank/migrate_a/index.html @@ -0,0 +1,229 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Warning

+

If you already have a Northflank database, you cannot use this wizard. +Create a new Northflank Nightscout site with only MONGODB_URI and API_SECRET then manually copy your Heroku variables.

+
+

a) Go to your Account Dashboard - Settings and scroll down to Import.
+Select Heroku.

+../../../_images/NorthflankM01.png +
+

Note

+

If you don’t see this option, send a mail to Northflank support to request access to the feature.

+
+



+

b) Click Link Heroku.

+../../../_images/NorthflankM02.png +



+

c) Login in Heroku.

+../../../_images/NorthflankM03.png +



+

d) Click Allow.

+../../../_images/NorthflankM04.png +



+

e) Select your Nightscout Heroku app then click Continue.

+../../../_images/NorthflankM05.png +



+

f) Select your project (the one you created in Step 1.g) then click Continue.

+../../../_images/NorthflankM06.png +



+

g) Verify the branch you want to migrate, usually it’s master unless you know why you need another one.

+../../../_images/NorthflankM07.png +



+

h) Select heroku/builder-classic:22.

+../../../_images/NorthflankM08.png +



+

i) Modify your compute plan to the smallest nf-compute-10 and click Continue.

+../../../_images/NorthflankM09.png +



+

j) Wait until import completes then return to your Dashboard (top left).

+../../../_images/NorthflankM10.png +



+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/northflank/new_user/index.html b/vendors/northflank/new_user/index.html new file mode 100644 index 00000000..c489cc4e --- /dev/null +++ b/vendors/northflank/new_user/index.html @@ -0,0 +1,747 @@ + + + + + + + Nightscout in Northflank — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout in Northflank

+
+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+
+
+

Northflank

+

+
+
+

You can create your new Northflank Nightscout site with a MongoDB Atlas database or with its own Northflank database.

+

Pros:

+
    +
  • Nightscout fits in the free tier

  • +
  • Easy to deploy or migrate an existing site from Heroku

  • +
  • Simple to use and troubleshoot

  • +
  • Can use a native Northflank MongoDB database

  • +
  • You can deploy up to $20/mo worth of free resources on Northflank’s managed cloud

  • +
+

Cons:

+
    +
  • The Nightscout address generated for your site is virtually impossible to remember

  • +
+
+
+
+
+

Set up a new Nightscout

+
+

Create your Northflank and GitHub accounts from a computer.

+
+

Note

+

Do not change device/computer/browser during the setup process!
+If you have unexpected issues when creating your site, restart with another browser.

+
+
+
+
+

Step 0: Create a database

+
+

Note

+

Make sure you created one before starting your Nightscout web app creation with Northflank. +Come back here when you have a MONGODB_URI connection string.

+
+
+

Migrating?

+

Copy the connection string from your previous platform: edit the variables and look for MONGODB_URI. +If you don’t see MONGODB_URI but see MONGO_CONNECTION (NOT MONGO_COLLECTION): use its value.

+
+
+
+
+

Step 1: Create a GitHub account and fork the Nightscout project

+
+ +
+

Continue with Step 2.

+
+ +
+

Create a GitHub account

+

a) Click this link to create a GitHub account: https://github.com/

+

Enter your email and click Sign up for GitHub

+

../../../_images/NewNS00a.png

+

b) Enter a password and a username (anything you want and that is accepted, not very important).
+Type n to decline advertisement emails.

+

../../../_images/NewNS00.png

+

c) Play and solve the puzzle then click Create account

+

../../../_images/NewNS01.png

+

d) GitHub will send you a verification code. Open your mail and check your inbox (check your spam-folder if not received after a couple of minutes).

+

../../../_images/NewNS02.png

+

e) If a personalization sequence starts, click Skip personalization at the bottom.

+

../../../_images/NewNS03.png

+

f) Leave the page that opened as it is. Don’t close it.

+

../../../_images/NewNS04.png

+

You have created your GitHub account. Now fork the Nightscout project.

+
+

Fork the Nightscout project

+

a) Click here to log in at GitHub: https://github.com/login.
+Enter your username or email and your password. Click Sign in

+

../../../_images/UpdateNS00.png

+
+

If you already have a fork of cgm-remote-monitor in GitHub

+

Delete or update your current cgm-remote-monitor fork before continuing.

+
+

b) Open this link https://github.com/nightscout/cgm-remote-monitor. Click on Fork

+

../../../_images/NewNS29.png

+

Confirm with Create fork

+
+

Warning

+

Make sure you deselect Copy the master branch only.

+
+

../../../_images/NewNS51.png

+

c) Wait for a moment

+

../../../_images/NewNS30.png

+

d) You now have a copy (fork) of the Nightscout project repository in your own GitHub.

+

../../../_images/UpdateNS30.png

+
+ +
+

Update your Nightscout fork

+
    +
  • Click here to log in at GitHub: https://github.com/login.

  • +
  • Enter your username or email and your password. Click Sign in

  • +
+

../../../_images/UpdateNS00.png

+
    +
  • Select your own cgm-remote-monitor project (not nightscout/cgm-remote-monitor)

  • +
+

../../../_images/UpdateNS01.png

+
    +
  • Your repository will open. If you see This branch is xxx commits behind nightscout:master you need to update.

  • +
  • Select Fetch upstream

  • +
+

../../../_images/UpdateNS01a.png

+
    +
  • Select Fetch and merge

  • +
+

../../../_images/UpdateNS01b.png

+
    +
  • After a moment, your repository should display This branch is up to date with nightscout:master

  • +
+

../../../_images/UpdateNS01c.png

+

You have now updated your GitHub cgm-remote-monitor repository.

+
+

If you ran into trouble, you can redeploy the project.

+
+
+
+
+
+
+

Step 2: Create a Northflank account

+

If you already created your database in Northflank, skip to step 3.

+

a) Sign-up to Northflank in a new browser tab. Login with GitHub (click on the logo).

+../../../_images/Northflank00.png +
+

b) Confirm your GitHub account if required.

+../../../_images/Northflank01.png +
+

c) Select Only select repositories, in the drop-down list select cgm-remote-monitor then click Install & Authorize.

+../../../_images/Northflank02.png +
+

c) Enter a user name, your email address and invent a password (type it twice to confirm). Accept the TOS and Privacy Policy then click Continue .

+../../../_images/Northflank03.png +
+

d) Click Choose theme.

+../../../_images/Northflank04.png +
+

e) Select Skip for now.

+../../../_images/Northflank05.png +
+

f) Select Create free project.

+../../../_images/Northflank06.png +
+

g) Enter a project name (for example nightscout) and select a region (you can make it geographically close to where you live) then click Create project.

+../../../_images/Northflank07.png +
+
+
+

Step 3: Deploy Nightscout in Northflank

+

What are you trying to do now?

+
+ +
+

If you already created a Nightscout project (for example if you created your database in Northflank), select it now.

+

../../../_images/Northflank32.png

+
+

a) Select Add new service or New service.

+

../../../_images/Northflank08.png

+
+

b) Select Deploy a Docker image. Scroll down and put a name in Service name or click Suggest random name.

+

../../../_images/Northflank33.png

+
+

c) In Deployment, select External image and type nightscout/cgm-remote-monitor:latest in Image path.

+

../../../_images/Northflank34.png

+
+

d) Expand Variables and click Add variable.

+

../../../_images/Northflank12.png

+
+

e) Setup your Nightscout core variables.

+
+

Tip

+

If you want to copy all variables from Heroku, follow these instructions and then continue to l) below.

+
+

API_SECRET will be your Nightscout site password, it needs to be at least 12 characters long and you should NOT use spaces if you use @ or ! symbols remember you will probably need to express them using Percent encoding in your uploader and downloader apps. If you’re not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits.

+
+

Warning

+

The API_SECRET is the main password allowing full access to your Nightscout site. Make sure it’s reasonably secure (mix uppercase and lowercase letters, plus digits) and do no not share it publicly. If you think you exposed it by mistake, it is recommended that you change it.

+
+

../../../_images/Northflank13.png

+

Click Add variable each time to add another one.

+
+

Dexcom Bridge

+

f) If you use Dexcom bridge you need to configure these two variables with your Dexcom credentials:

+

../../../_images/Northflank14.png

+

../../../_images/Northflank15.png

+

If you’re using Dexcom Share in the US you should put US, in any other case it must be EU.
+If you don’t see it proposed at this point you’ll need to browse the list below to find it and modify it.

+

../../../_images/Northflank16.png

+

Remember to add bridge at the end of the enable variable in the list below.

+
+
+

MOST COMMON ERRORS

+

The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom’s Clarity page (check here for USA accounts and here for the others) and try logging in to your Dexcom account. If your account info isn’t valid, or you don’t see any data in your Clarity account… you need to figure out your actual credentials before moving ahead. See here for troubleshooting tips and information on your Dexcom account.

+
+
+

Password

+

Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.

+
+
+

Hint

+

You need to have at least one follower to use Dexcom Share. See here.

+
+
+

g) Select the units you’re using in DISPLAY_UNITS acceptable choices are mg/dl or mmol/L (or just mmol).

+

../../../_images/Northflank17.png

+
+

h) You can add alarms values. See here for the meaning of each one.

+

../../../_images/Northflank18.png

+
+

i) If you want to ensure that ONLY someone with permission to view your site (e.g., a token or the API_SECRET) is able to view the data, you should configure the AUTH_DEFAULT_ROLES variable in as denied.
+If you want your site to be visible to anybody leave it as readable.

+

../../../_images/Northflank19.png

+
+

j) In ENABLE, copy and paste the following words (separated by a space) so that won’t have to think about which you want now:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors

+

If you are using your Dexcom share account as a data source also add bridge at the end, after a space like this:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge

+

../../../_images/Northflank20.png

+
+

k) You can modify the variables values, check the documentation for the meaning of each one.

+
+

l) You can modify the 3 to 8 letter code to your URL.

+

../../../_images/Northflank21.png

+
+

m) Scroll down and check you’re using an nf-compute-10 plan, then click: Create Service

+

../../../_images/Northflank22a.png

+

../../../_images/Northflank22.png

+
+

n) If not done before, you now need to add a payment method.

+

../../../_images/Northflank23.png

+
+

o) Wait until your build completes. You will see a green cloud when done, it will take less than 15 minutes.

+

../../../_images/Northflank24.png

+
+
+

Step 4: Attach your database to your Nightscout site

+
+

a) Browse back into your project Service then Environment, click Edit.

+

../../../_images/Northflank25.png

+
+

b) Select Add variable at the end of the list.

+

../../../_images/Northflank26.png

+
+

c) Name it MONGODB_URI and paste the string you obtained at Step 0.

+

../../../_images/Northflank27.png

+
+

d) Click Update and restart bottom right.

+

../../../_images/Northflank28.png

+
+
+ +
+

If you already created a Nightscout project (for example if you created your database in Northflank), select it now.

+

../../../_images/Northflank32.png

+
+

a) Select Add new service or New service.

+

../../../_images/Northflank08.png

+
+

b) Select Build and deploy a Git repo. Scroll down and put a name in Service name or click Suggest random name.

+

../../../_images/Northflank09.png

+
+

c) Select your cgm-remote-monitor and the master branch.

+

../../../_images/Northflank10.png

+
+

d) In Buid options select Buildpack.

+

../../../_images/Northflank11.png

+
+

Open Advanced build settings and select heroku/builder-classic:22.

+

../../../_images/Northflank11b.png

+
+

e) Expand Variables and click Add variable.

+
+

Tip

+

If you want to copy all variables from Heroku, follow these instructions and then continue to m) below.

+
+

../../../_images/Northflank12.png

+
+

f) Setup your Nightscout core variables.

+

API_SECRET will be your Nightscout site password, it needs to be at least 12 characters long and you should NOT use spaces if you use @ or ! symbols remember you will probably need to express them using Percent encoding in your uploader and downloader apps. If you’re not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits.

+
+

Warning

+

The API_SECRET is the main password allowing full access to your Nightscout site. Make sure it’s reasonably secure (mix uppercase and lowercase letters, plus digits) and do no not share it publicly. If you think you exposed it by mistake, it is recommended that you change it.

+
+

../../../_images/Northflank13.png

+

Click Add variable each time to add another one.

+
+

Dexcom Bridge

+

g) If you use Dexcom bridge you need to configure these two variables with your Dexcom credentials:

+

../../../_images/Northflank14.png

+

../../../_images/Northflank15.png

+

If you’re using Dexcom Share in the US you should put US, in any other case it must be EU.
+If you don’t see it proposed at this point you’ll need to browse the list below to find it and modify it.

+

../../../_images/Northflank16.png

+

Remember to add bridge at the end of the enable variable in the list below.

+
+
+

MOST COMMON ERRORS

+

The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom’s Clarity page (check here for USA accounts and here for the others) and try logging in to your Dexcom account. If your account info isn’t valid, or you don’t see any data in your Clarity account… you need to figure out your actual credentials before moving ahead. See here for troubleshooting tips and information on your Dexcom account.

+
+
+

Password

+

Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.

+
+
+

Hint

+

You need to have at least one follower to use Dexcom Share. See here.

+
+
+

h) Select the units you’re using in DISPLAY_UNITS acceptable choices are mg/dl or mmol/L (or just mmol).

+

../../../_images/Northflank17.png

+
+

i) You can add alarms values. See here for the meaning of each one.

+

../../../_images/Northflank18.png

+
+

j) If you want to ensure that ONLY someone with permission to view your site (e.g., a token or the API_SECRET) is able to view the data, you should configure the AUTH_DEFAULT_ROLES variable in as denied.
+If you want your site to be visible to anybody leave it as readable.

+

../../../_images/Northflank19.png

+
+

k) In ENABLE, copy and paste the following words (separated by a space) so that won’t have to think about which you want now:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors

+

If you are using your Dexcom share account as a data source also add bridge at the end, after a space like this:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge

+

../../../_images/Northflank20.png

+
+

l) You can modify the variables values, check the documentation for the meaning of each one.

+
+

m) You can modify the 3 to 8 letter code to your URL.

+

../../../_images/Northflank21.png

+
+

n) Scroll down and check you’re using an nf-compute-10 plan, then click: Create Service

+

../../../_images/Northflank22a.png

+

../../../_images/Northflank22.png

+
+

o) If not done before, you now need to add a payment method.

+

../../../_images/Northflank23.png

+
+

p) Wait until your build completes. You will see a green cloud when done, it will take less than 15 minutes.

+

../../../_images/Northflank24.png

+
+
+

Step 4: Attach your database to your Nightscout site

+
+

a) Browse back into your project Service then Environment, click Edit.

+

../../../_images/Northflank25.png

+
+

b) Select Add variable at the end of the list.

+

../../../_images/Northflank26.png

+
+

c) Name it MONGODB_URI and paste the string you obtained at Step 0.

+

../../../_images/Northflank27.png

+
+

d) Click Update and restart bottom right.

+

../../../_images/Northflank28.png

+
+
+ +
+
+

Warning

+

If you already have a Northflank database, you cannot use this wizard. +Create a new Northflank Nightscout site with only MONGODB_URI and API_SECRET then manually copy your Heroku variables.

+
+

a) Go to your Account Dashboard - Settings and scroll down to Import.
+Select Heroku.

+../../../_images/NorthflankM01.png +
+

Note

+

If you don’t see this option, send a mail to Northflank support to request access to the feature.

+
+



+

b) Click Link Heroku.

+../../../_images/NorthflankM02.png +



+

c) Login in Heroku.

+../../../_images/NorthflankM03.png +



+

d) Click Allow.

+../../../_images/NorthflankM04.png +



+

e) Select your Nightscout Heroku app then click Continue.

+../../../_images/NorthflankM05.png +



+

f) Select your project (the one you created in Step 1.g) then click Continue.

+../../../_images/NorthflankM06.png +



+

g) Verify the branch you want to migrate, usually it’s master unless you know why you need another one.

+../../../_images/NorthflankM07.png +



+

h) Select heroku/builder-classic:22.

+../../../_images/NorthflankM08.png +



+

i) Modify your compute plan to the smallest nf-compute-10 and click Continue.

+../../../_images/NorthflankM09.png +



+

j) Wait until import completes then return to your Dashboard (top left).

+../../../_images/NorthflankM10.png +



+
+
+

To open your Nightscout site, navigate to your project Services and click the address link top right.

+../../../_images/Northflank29.png +
+

Good time to check you selected the right plan.

+

Make sure you selected the developer sandbox plan to avoid unexpected fees.

+../../../_images/NorthflankSP.png +
+
+
+
+

New Nightscout Setup

+
+

a) Your Nightscout site should open and direct you to a new profile creation.

+../../../_images/NewNS50.png +
+

b) Setup your Time zone and eventually all other fields. Do not leave any fields empty. If you don’t know which value to use, just use the default value. You can change these values later at any time.

+../../../_images/NewNS44.png +
+

c) Browse down to Authentication status and click Authenticate. Enter your API secret. Click Update.

+../../../_images/NewNS45.png +
+

d) Click Save.

+../../../_images/NewNS46.png +
+

e) If the following pop-up shows up click OK, and check status (upper right of the window).

+../../../_images/NewNS47.png +
+

f) If you need to modify your profile after this, authenticate with the lock icon (top right of the page): enter your API secret. Then click on the hamburger menu and select Profile Editor.

+../../../_images/NewNS43.png +
+
+

Privacy warning

+

Anyone with access to the URL of your Nightscout site, can view your BG and run reports of your data. It it strongly recommended that you enable security to your site once you’re done with the setup

+
+
+

g) Dexcom Share users should see data flowing in after some minutes. +xDrip+ users (including Medtronic CareLink followers) should setup the uploader as shown here. +xDrip4iOS users here. +AAPS and Loop: consult the relative documentation.

+../../../_images/NewNS48.png +
+
+

You have completed a new Nightscout site creation. You can continue here now.

+

The following section provides more information that you might not need to use now.

+
+
+
+
+
+
+

Change your Northflank Nightscout site name

+

You cannot override the default name if you don’t have a DNS.
+You can use TinyURL to get a shorter name.

+../../../_images/TinyURL.png +

You can also use a free dynamic DNS service to do this in order to have something easier to remember.

+

Keep the original Northflank URL in your uploaders and followers.

+
+
+

You have completed a new Nightscout site creation. The following section provides more information for variables edition that you might not need to use now.

+
+
+
+
+

Editing Variables in Northflank

+
+

a) Open Northflank and login with your username or with GitHub.

+../../../_images/Northflank30.png +
+

b) Select Services then your Nightscout project.

+../../../_images/Northflank31.png +
+

c) Select Environment then Edit.

+../../../_images/Northflank25.png +
+

e) You can perform various operations on your variables:

+
    +
  1. Add a new variable with + Add Variable

  2. +
  3. Edit variables values directly in the table

  4. +
  5. Delete a variable with the bin icon

  6. +
+
+

Note

+

Multiple lines values should be typed with \n separating each original line.
+Example:
+../../../_images/APNKeys.png

+
----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGBygGSM49AwEHBHkwdwIBAQQg7c8w00t5ju7N980r\nerN8N+isnJoec+ohIEuD0teRbPmgCgYIKoZIzj0DAQehRANCAAREnRISLSiFgdn4\nLbf44yIKspXKr7GpPBVshv3ShOms2qHTdAFriXXRPmbq7eAJuFrxpYOduU1dl9vo\nouciW0je\n-----END PRIVATE KEY-----
+
+
+
+

Don’t forget to Update & restart when you’re done editing.

+
+
+
+

Copy all variables from Heroku

+
+

a) Export all your Heroku variables as explained here. In a file you can call heroku.env.

+

If you’re currently deploying a new Northflank Nightscout site, select Env.

+../../../_images/Northflank36.png +

Continue to c) below.

+
+

b) If you want to modify an existing Northflank site,

+

Open Northflank and login with your username or with GitHub.

+../../../_images/Northflank30.png +
+

Select Services then your Nightscout project.

+../../../_images/Northflank31.png +
+

Select Environment then Env.

+../../../_images/Northflank39.png +
+

c) Select Import from file then the file (heroku.env) you saved in a).

+../../../_images/Northflank37.png +

Your variables should display like this:

+../../../_images/Northflank38.png +
+

d) If you’re creating a new site, return to the step you were following before importing all variables from Heroku.

+
+

e) If you were importing all variables from a running Northflank Nightscout site, select Update & restart.

+../../../_images/Northflank40.png +
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/northflank/new_user_a/index.html b/vendors/northflank/new_user_a/index.html new file mode 100644 index 00000000..8626ac39 --- /dev/null +++ b/vendors/northflank/new_user_a/index.html @@ -0,0 +1,294 @@ + + + + + + + Dexcom Bridge — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

If you already created a Nightscout project (for example if you created your database in Northflank), select it now.

+

../../../_images/Northflank32.png

+
+

a) Select Add new service or New service.

+

../../../_images/Northflank08.png

+
+

b) Select Build and deploy a Git repo. Scroll down and put a name in Service name or click Suggest random name.

+

../../../_images/Northflank09.png

+
+

c) Select your cgm-remote-monitor and the master branch.

+

../../../_images/Northflank10.png

+
+

d) In Buid options select Buildpack.

+

../../../_images/Northflank11.png

+
+

Open Advanced build settings and select heroku/builder-classic:22.

+

../../../_images/Northflank11b.png

+
+

e) Expand Variables and click Add variable.

+
+

Tip

+

If you want to copy all variables from Heroku, follow these instructions and then continue to m) below.

+
+

../../../_images/Northflank12.png

+
+

f) Setup your Nightscout core variables.

+

API_SECRET will be your Nightscout site password, it needs to be at least 12 characters long and you should NOT use spaces if you use @ or ! symbols remember you will probably need to express them using Percent encoding in your uploader and downloader apps. If you’re not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits.

+
+

Warning

+

The API_SECRET is the main password allowing full access to your Nightscout site. Make sure it’s reasonably secure (mix uppercase and lowercase letters, plus digits) and do no not share it publicly. If you think you exposed it by mistake, it is recommended that you change it.

+
+

../../../_images/Northflank13.png

+

Click Add variable each time to add another one.

+
+
+

Dexcom Bridge

+

g) If you use Dexcom bridge you need to configure these two variables with your Dexcom credentials:

+

../../../_images/Northflank14.png

+

../../../_images/Northflank15.png

+

If you’re using Dexcom Share in the US you should put US, in any other case it must be EU.
+If you don’t see it proposed at this point you’ll need to browse the list below to find it and modify it.

+

../../../_images/Northflank16.png

+

Remember to add bridge at the end of the enable variable in the list below.

+
+
+

MOST COMMON ERRORS

+

The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom’s Clarity page (check here for USA accounts and here for the others) and try logging in to your Dexcom account. If your account info isn’t valid, or you don’t see any data in your Clarity account… you need to figure out your actual credentials before moving ahead. See here for troubleshooting tips and information on your Dexcom account.

+
+
+

Password

+

Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.

+
+
+

Hint

+

You need to have at least one follower to use Dexcom Share. See here.

+
+
+

h) Select the units you’re using in DISPLAY_UNITS acceptable choices are mg/dl or mmol/L (or just mmol).

+

../../../_images/Northflank17.png

+
+

i) You can add alarms values. See here for the meaning of each one.

+

../../../_images/Northflank18.png

+
+

j) If you want to ensure that ONLY someone with permission to view your site (e.g., a token or the API_SECRET) is able to view the data, you should configure the AUTH_DEFAULT_ROLES variable in as denied.
+If you want your site to be visible to anybody leave it as readable.

+

../../../_images/Northflank19.png

+
+

k) In ENABLE, copy and paste the following words (separated by a space) so that won’t have to think about which you want now:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors

+

If you are using your Dexcom share account as a data source also add bridge at the end, after a space like this:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge

+

../../../_images/Northflank20.png

+
+

l) You can modify the variables values, check the documentation for the meaning of each one.

+
+

m) You can modify the 3 to 8 letter code to your URL.

+

../../../_images/Northflank21.png

+
+

n) Scroll down and check you’re using an nf-compute-10 plan, then click: Create Service

+

../../../_images/Northflank22a.png

+

../../../_images/Northflank22.png

+
+

o) If not done before, you now need to add a payment method.

+

../../../_images/Northflank23.png

+
+

p) Wait until your build completes. You will see a green cloud when done, it will take less than 15 minutes.

+

../../../_images/Northflank24.png

+
+
+
+
+

Step 4: Attach your database to your Nightscout site

+
+

a) Browse back into your project Service then Environment, click Edit.

+

../../../_images/Northflank25.png

+
+

b) Select Add variable at the end of the list.

+

../../../_images/Northflank26.png

+
+

c) Name it MONGODB_URI and paste the string you obtained at Step 0.

+

../../../_images/Northflank27.png

+
+

d) Click Update and restart bottom right.

+

../../../_images/Northflank28.png

+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/northflank/new_user_d/index.html b/vendors/northflank/new_user_d/index.html new file mode 100644 index 00000000..018a6991 --- /dev/null +++ b/vendors/northflank/new_user_d/index.html @@ -0,0 +1,288 @@ + + + + + + + Dexcom Bridge — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

If you already created a Nightscout project (for example if you created your database in Northflank), select it now.

+

../../../_images/Northflank32.png

+
+

a) Select Add new service or New service.

+

../../../_images/Northflank08.png

+
+

b) Select Deploy a Docker image. Scroll down and put a name in Service name or click Suggest random name.

+

../../../_images/Northflank33.png

+
+

c) In Deployment, select External image and type nightscout/cgm-remote-monitor:latest in Image path.

+

../../../_images/Northflank34.png

+
+

d) Expand Variables and click Add variable.

+

../../../_images/Northflank12.png

+
+

e) Setup your Nightscout core variables.

+
+

Tip

+

If you want to copy all variables from Heroku, follow these instructions and then continue to l) below.

+
+

API_SECRET will be your Nightscout site password, it needs to be at least 12 characters long and you should NOT use spaces if you use @ or ! symbols remember you will probably need to express them using Percent encoding in your uploader and downloader apps. If you’re not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits.

+
+

Warning

+

The API_SECRET is the main password allowing full access to your Nightscout site. Make sure it’s reasonably secure (mix uppercase and lowercase letters, plus digits) and do no not share it publicly. If you think you exposed it by mistake, it is recommended that you change it.

+
+

../../../_images/Northflank13.png

+

Click Add variable each time to add another one.

+
+
+

Dexcom Bridge

+

f) If you use Dexcom bridge you need to configure these two variables with your Dexcom credentials:

+

../../../_images/Northflank14.png

+

../../../_images/Northflank15.png

+

If you’re using Dexcom Share in the US you should put US, in any other case it must be EU.
+If you don’t see it proposed at this point you’ll need to browse the list below to find it and modify it.

+

../../../_images/Northflank16.png

+

Remember to add bridge at the end of the enable variable in the list below.

+
+
+

MOST COMMON ERRORS

+

The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom’s Clarity page (check here for USA accounts and here for the others) and try logging in to your Dexcom account. If your account info isn’t valid, or you don’t see any data in your Clarity account… you need to figure out your actual credentials before moving ahead. See here for troubleshooting tips and information on your Dexcom account.

+
+
+

Password

+

Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.

+
+
+

Hint

+

You need to have at least one follower to use Dexcom Share. See here.

+
+
+

g) Select the units you’re using in DISPLAY_UNITS acceptable choices are mg/dl or mmol/L (or just mmol).

+

../../../_images/Northflank17.png

+
+

h) You can add alarms values. See here for the meaning of each one.

+

../../../_images/Northflank18.png

+
+

i) If you want to ensure that ONLY someone with permission to view your site (e.g., a token or the API_SECRET) is able to view the data, you should configure the AUTH_DEFAULT_ROLES variable in as denied.
+If you want your site to be visible to anybody leave it as readable.

+

../../../_images/Northflank19.png

+
+

j) In ENABLE, copy and paste the following words (separated by a space) so that won’t have to think about which you want now:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors

+

If you are using your Dexcom share account as a data source also add bridge at the end, after a space like this:

+

careportal basal dbsize rawbg iob maker cob bwp cage iage sage boluscalc pushover treatmentnotify loop pump profile food openaps bage alexa override speech cors bridge

+

../../../_images/Northflank20.png

+
+

k) You can modify the variables values, check the documentation for the meaning of each one.

+
+

l) You can modify the 3 to 8 letter code to your URL.

+

../../../_images/Northflank21.png

+
+

m) Scroll down and check you’re using an nf-compute-10 plan, then click: Create Service

+

../../../_images/Northflank22a.png

+

../../../_images/Northflank22.png

+
+

n) If not done before, you now need to add a payment method.

+

../../../_images/Northflank23.png

+
+

o) Wait until your build completes. You will see a green cloud when done, it will take less than 15 minutes.

+

../../../_images/Northflank24.png

+
+
+
+
+

Step 4: Attach your database to your Nightscout site

+
+

a) Browse back into your project Service then Environment, click Edit.

+

../../../_images/Northflank25.png

+
+

b) Select Add variable at the end of the list.

+

../../../_images/Northflank26.png

+
+

c) Name it MONGODB_URI and paste the string you obtained at Step 0.

+

../../../_images/Northflank27.png

+
+

d) Click Update and restart bottom right.

+

../../../_images/Northflank28.png

+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/oracle/new_user/index.html b/vendors/oracle/new_user/index.html new file mode 100644 index 00000000..bf8e2ef3 --- /dev/null +++ b/vendors/oracle/new_user/index.html @@ -0,0 +1,191 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/railway/NightscoutVariablesRailway/index.html b/vendors/railway/NightscoutVariablesRailway/index.html new file mode 100644 index 00000000..e5ba20a4 --- /dev/null +++ b/vendors/railway/NightscoutVariablesRailway/index.html @@ -0,0 +1,192 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/railway/database/index.html b/vendors/railway/database/index.html new file mode 100644 index 00000000..eecc15a6 --- /dev/null +++ b/vendors/railway/database/index.html @@ -0,0 +1,298 @@ + + + + + + + Railway Database — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Railway Database

+
+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+
+

Danger

+

The free plan has been removed Jul 3rd for new users and Aug 1st for existing users.
+Documentation will be updated to reflect the changes when visible.

+
+
+
+
+

Railway Mongo Database

+

Railway MongoDB

+
+
+

Railway offers a Mongo database.

+

Pros:

+
    +
  • Simple to create

  • +
  • Less overhead than Atlas (more space)

  • +
  • Mongo database cost is $0.000231/GB/Minute

  • +
+

Cons:

+
    +
  • You need to carefully monitor your database size and clean it up regularly to remain within the Hobby plan 5$/month limits

  • +
  • Simple Mongo 4.4 database

  • +
+
+
+
+
+

Create a Railway account

+

If you already have a Railway account, make sure you have a developper plan: go to step g).

+
+

a) Open Railway in a new browser tab and click login. Type your email and select Email.

+../../../_images/Railway00.png +../../../_images/Railway01a.png +
+

b) Leave the browser open on this screen

+../../../_images/Railway01b.png +
+

c) Check your email (look also in the spam folder) and click on the Authorize Railway App.

+../../../_images/Railway01c.png +
+

d) Type the code you had in b).

+../../../_images/Railway01d.png +
+

e) Close this tab and return to the one you left open in b).

+../../../_images/Railway01e.png +
+

f) Click on Please agree to the new terms to keep on using Railway.

+../../../_images/Railway03.png +
+

d) Scroll down and click I agree with Railway's Terms of Service.

+../../../_images/Railway04.png +
+

e) Scroll down and click I will not deploy any of that.

+../../../_images/Railway05.png +
+

f) You should now see this. You’ve created your Railway account.

+../../../_images/Railway06a2.png +
+

g) Upgrade your account to a Developer plan. Click on the Unverified and select Remove Resource Limits.

+../../../_images/Railway06b2.png +
+
+

Danger

+

The free plan will be removed Jul 3rd for new users and Aug 1st for existing users.
+Documentation will be updated to reflect the changes when visible.

+
+

Enter your credit card information and select Subscribe to a Hobby Plan.

+../../../_images/Railway06c.png +

Your card will be billed 1$ that will be refund immediately. Bank fees won’t be refund.

+
+
+
+

Create your database

+

a) Click New Project from your Dashboard screen (top right).

+../../../_images/RailwayDB01.png +
+

b) Click Provision MongoDB

+../../../_images/RailwayDB02.png +
+

c) Select your new MongoDB project.

+../../../_images/RailwayDB03.png +
+

d) Go to the Connect page.

+../../../_images/RailwayDB04.png +
+

e) Scroll down to Available Variables, move the mouse to the end of the line showing the MONGO_URL and click the copy icon.

+../../../_images/RailwayDB05.png +
+
+

This is an important information

+

Now that you have copied the resulting MONGODB_URI string, keep it in a safe place, you will need it later.

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/railway/migrate/index.html b/vendors/railway/migrate/index.html new file mode 100644 index 00000000..601bb4c2 --- /dev/null +++ b/vendors/railway/migrate/index.html @@ -0,0 +1,242 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + +

../../../_images/UpdateNS15.png

+
    +
  • Leave the Heroku page opened and return to the Railway page.

  • +
  • If you cannot log into Heroku, select another deployment option (just above) and reuse your existing Atlas database connection string.

  • +
+
+

a) Click on Create a New project.

+

../../../_images/Railway06.png

+

If you don’t see that, top right, click + New Project.

+

../../../_images/RailwayDB01.png

+
+

b) Select Deploy from GitHub repo.

+

../../../_images/RailwayM19.png

+
+

Select Configure GitHub App.

+

../../../_images/RailwayM02.png

+
+

c) Choose Only select repositories, in the Select repositories drop-down select your own fork of cgm-remote-monitor.
+Then, at the bottom, click Install & Authorize.

+

../../../_images/Railway08.png

+
+

You should be back to Deploy from GitHub repo, select it.

+

../../../_images/RailwayM19.png

+
+

d) Now you can select your own GitHub repository.

+

../../../_images/RailwayM03.png

+
+

e) Select Add variables.

+

../../../_images/RailwayM20.png

+
+

f) The Nightscout project will deploy in the background, just ignore it: now we need to import all variables from Heroku.
+When you see this, press simultaneously the keys Ctrl and K.
+If you use a Mac and K.

+

../../../_images/RailwayM21.png

+
+

g) Select Import variables from Heroku.

+

../../../_images/RailwayM22.png

+
+

h) Click Connect Heroku account.

+

../../../_images/RailwayM23.png

+
+

Click Allow.

+

../../../_images/RailwayM24.png

+
+

i) Redo Ctrl K (or K and select Import variables from Heroku. Now you can select your Nightscout app.

+

../../../_images/RailwayM25.png

+
+

j) Wait until import completes.
+Your site will redeploy, wait until redeploy completes.

+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/railway/migration/index.html b/vendors/railway/migration/index.html new file mode 100644 index 00000000..cd317cc2 --- /dev/null +++ b/vendors/railway/migration/index.html @@ -0,0 +1,197 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+
+

Danger

+

The free plan has been removed Jul 3rd for new users and Aug 1st for existing users.
+Documentation will be updated to reflect the changes when visible.

+
+
+

Now included in the main Nightscout with Railway page!

+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/railway/new_user/index.html b/vendors/railway/new_user/index.html new file mode 100644 index 00000000..f5149a46 --- /dev/null +++ b/vendors/railway/new_user/index.html @@ -0,0 +1,1242 @@ + + + + + + + Nightscout in Railway — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout in Railway

+
+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+
+

Warning

+

The free plan has been removed Jul 3rd for new users and Aug 1st for existing users.

+
+
+
+
+

Railway.app

+

Railway

+
+
+

You can easily create a new Railway Nightscout site with a MongoDB Atlas database or a Railway MongoDB database.

+

Pros:

+
    +
  • Nightscout fits in the 5$/month Hobby account

  • +
  • Easy to deploy or migrate an existing site from Heroku

  • +
  • Simple to use and troubleshoot

  • +
  • You can host several Nightscout sites within a single Hobby account

  • +
  • Can use a native Railway MongoDB database ($)

  • +
+

Cons:

+
    +
  • The railway.app domain is blocked for safety by some companies

  • +
  • Railway network model causes issues with some follower app and devices

  • +
+
+
+
+
+

Set up a new Nightscout

+
+

Create your Railway and GitHub accounts from a computer.

+
+

Note

+

Do not change device/computer/browser during the setup process!
+If you have unexpected issues when creating your site, restart with another browser.

+
+
+
+
+

Step 0: Create a database

+
+

Note

+

Make sure you created one before starting your Nightscout web app creation with Railway. +Come back here when you have a MONGODB_URI connection string.

+
+
+

Migrating?

+

Copy the connection string from your previous platform: edit the variables and look for MONGODB_URI. +If you don’t see MONGODB_URI but see MONGO_CONNECTION (NOT MONGO_COLLECTION): use its value.

+
+
+
+
+

Step 1: Fork cgm-remote-monitor

+

Do you have a GitHub account?

+
+ +
+

Continue with Step 2.

+
+ +
+

You cannot connect Railway to GitHub if you just created your account.
+Your GitHub account needs to have been created months ago.

+../../../_images/RailwayGitHub.png

+Consider another platform.

+
+ +
+

Update your Nightscout fork

+
    +
  • Click here to log in at GitHub: https://github.com/login.

  • +
  • Enter your username or email and your password. Click Sign in

  • +
+

../../../_images/UpdateNS00.png

+
    +
  • Select your own cgm-remote-monitor project (not nightscout/cgm-remote-monitor)

  • +
+

../../../_images/UpdateNS01.png

+
    +
  • Your repository will open. If you see This branch is xxx commits behind nightscout:master you need to update.

  • +
  • Select Fetch upstream

  • +
+

../../../_images/UpdateNS01a.png

+
    +
  • Select Fetch and merge

  • +
+

../../../_images/UpdateNS01b.png

+
    +
  • After a moment, your repository should display This branch is up to date with nightscout:master

  • +
+

../../../_images/UpdateNS01c.png

+

You have now updated your GitHub cgm-remote-monitor repository.

+
+

If you ran into trouble, you can redeploy the project.

+
+
+
+
+
+
+

Step 2: Create a Railway account

+

If you already have a Railway account, make sure you have a Hobby plan: go to step g).

+
+

a) Open Railway in a new browser tab and click login. Login with GitHub.

+../../../_images/Railway00.png +../../../_images/Railway01.png +
+

b) If the following screen shows-up, select Authorize Railway App.

+../../../_images/Railway02.png +
+

c) Click on Please agree to the new terms to keep on using Railway.

+../../../_images/Railway03.png +
+

d) Scroll down and click I agree with Railway's Terms of Service.

+../../../_images/Railway04.png +
+

e) Scroll down and click I will not deploy any of that.

+../../../_images/Railway05.png +
+
+

Warning

+

The free plan has been removed Jul 3rd for new users and Aug 1st for existing users.

+
+
+

f) You should now see this. You’ve created your Railway account.
+If it still shows 200 hours, refresh your browser page.

+../../../_images/Railway06a.png +
+

g) Upgrade your account to a Hobby plan. Click on the Starter Plan information and select Remove Resource Limits.

+../../../_images/Railway06b.png +
+

Enter your credit card information and select Subscribe to a Hobby Plan.

+../../../_images/Railway06c.png +

Your card will be billed 1$ that will be refund immediately. Bank fees won’t be refund.

+

You will be billed 5$ per month.

+
+
+
+

Step 3 - Deploy Nightscout in Railway

+

Select below how you want to do this:

+
+ +
+

a) Click on Create a New project.

+

../../../_images/Railway06.png

+

If you don’t see that, top right, click + New Project.

+

../../../_images/RailwayDB01.png

+
+

b) Select Empty project.

+

../../../_images/RailwayD01.png

+
+

c) Select Add a Service.

+

../../../_images/RailwayD02.png

+
+

d) Select Docker Image.

+

../../../_images/RailwayD03.png

+
+

e) In the field Name of the Image type:

+

nightscout/cgm-remote-monitor:latest

+

and press <Enter>

+

../../../_images/RailwayD04.png

+
+

f) Select your new service.

+

../../../_images/RailwayD05.png

+
+

g) Select Add variables.

+

../../../_images/RailwayM20.png

+
+

h) Now we need to setup our Nightscout variables.
+Click on Raw Editor.

+

../../../_images/RailwayM21b.png

+

The raw editor will open, leave it like this for now.

+

../../../_images/RailwayM21c.png

+
+

i) Compile the information below.

+

File all necessary fields, click on the Validate button at the bottom of the form, if no error is seen you will have all variables displayed in the text box at the bottom, click on the Copy All button.

+

../../../_images/Railway42.png

+

Mandatory variables

+

These three variables below must have a value.

+

MONGODB_URI

+

The MongoDB Connection String to connect to your MongoDB cluster. If you don’t have this from your Mongo database, please re-read installation instructions at Nightscout database before continuing

+


+

API_SECRET

+


+

A passphrase that must be at least 12 characters long. Avoid special characters, which can cause problems in some cases

+

DISPLAY_UNITS

+
+
Preferred BG units for the site: `mg/dl` or `mmol/l` (or just `mmol`) +
+

Customizations

+

Leave default values if you don’t want to change them

+

CUSTOM_TITLE

+


+

The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer

+

THEME

+
+
Default setting for new browser views for the color theme of the CGM graph. (`default` `colors` or `colorblindfriendly`) +

ENABLE

+


+

Plugins to enable for your site. Must be a space-delimited lower-case list. Include the word bridge here if you are receiving data from the Dexcom Share service

+

SHOW_PLUGINS

+


+

Default setting for whether or not these plugins are checked (active) by default not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case

+

TIME_FORMAT

+
+
Default setting for new browser views for the time mode. (`12` or `24`) +

NIGHT_MODE

+
+
Default setting for new browser views for whether Night Mode should be enabled. (`on` or `off`) +

BOLUS_RENDER_OVER

+


+

U value over which the bolus values are rendered on the chart if the x U and Over option is selected

+
+

Dexcom Share

+

If you want Nightscout to import directly from Dexcom Share

+

BRIDGE_USER_NAME

+


+

Your Dexcom account username to receive CGM data from the Dexcom Share service. Also make sure to include bridge in your ENABLE line.

+

BRIDGE_PASSWORD

+


+

Your Dexcom account password to receive CGM data from the Dexcom Share service. Also make sure to include bridge in your ENABLE line

+

BRIDGE_SERVER

+
+
If you are bridging from the Dexcom Share service and are anywhere *outside* the US change this to EU. (`US` or `EU`) +
+

Alarms

+

You can customize alarms or leave them to default values

+

ALARM_TYPES

+
+
`simple` and/or `predict`v. Simple alarms trigger when BG crosses the various thresholds set below. Predict alarms use a formula that forecasts where the BG is going based on its trend. You will *not* get warnings when crossing the BG thresholds set below when using the predict type +

ALARM_URGENT_HIGH

+

+

Urgent High BG threshold triggers the ALARM_URGENT_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_URGENT_LOW

+

+

Urgent Low BG threshold triggers the ALARM_URGENT_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_HIGH

+

+

High BG threshold triggers the ALARM_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_LOW

+

+

Low BG threshold triggers the ALARM_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_TIMEAGO_URGENT

+

+

Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_URGENT alarm

+

ALARM_TIMEAGO_WARN

+

+

Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_WARN alarm

+ +

Now click on the Validate button below

+

+

If errors show up below, please correct them and click Validate again.

+

Click the button above.

+

+

+



+ +

+
+
+

j) Return to the Railway Raw editor. Paste the result. Click Update Variables.

+

../../../_images/Railway43.png

+
+

k) On the top left of the screen Deploy.

+

../../../_images/RailwayD06.png

+
+

l) Select the Settings tab and click Generate domain.

+

../../../_images/RailwayD07.png

+
+

m) Edit your Nightscout site name and put yours (one that is not already used).

+

../../../_images/RailwayD08.png

+
+
+ +
+


+

a) Click on the Deploy on Railway button below:

+

Deploy on Railway

+

Note: this is a private template as the community doesn’t have a Railway account.
+It doesn’t include any referral code.

+
+

b) If you see this screen, select Connect GitHub to Deploy.

+

../../../_images/Railway07a.png

+

Then select Authorize Railway App.

+

../../../_images/Railway02.png

+
+

c) Click Configure

+

../../../_images/Railway07.png

+
+

d) Click Install & Authorize

+

../../../_images/Railway08a.png

+
+

e) You will then see this page, scroll down to define the required variables for creating your Nightscout site.

+

../../../_images/Railway09.png

+
+

Mind if you see this you must delete thecgm-remote-monitor fork in GitHub and retry Deploy from a) afterwards.

+

../../../_images/Railway17.png

+
+

f) Setup your Nightscout core variables.

+
+

Migrating from Heroku

+

If you’re migrating your project from Heroku, display all variables in Heroku and copy all those with a value into Railway.
+See below how to add variables in Railway but use your Heroku variables values.

+
+

API_SECRET will be your Nightscout site password, it needs to be at least 12 characters long and you should NOT use spaces if you use @ or ! symbols remember you will probably need to express them using Percent encoding in your uploader and downloader apps. If you’re not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits.

+
+

Warning

+

The API_SECRET is the main password allowing full access to your Nightscout site. Make sure it’s reasonably secure (mix uppercase and lowercase letters, plus digits) and do no not share it publicly. If you think you exposed it by mistake, it is recommended that you change it.

+
+

../../../_images/Railway10.png

+

g) At Step 3 you created your database and came back with a MONGODB_URI string. Time has come to use it here.

+

../../../_images/Railway21.png

+
+

Dexcom Bridge

+

h) If you use Dexcom bridge you need to configure these two variables with your Dexcom credentials:

+

../../../_images/Railway33.png

+

../../../_images/Railway34.png

+

If you’re using Dexcom Share in the US you should put US, in any other case it must be EU.
+If you don’t see it proposed at this point you’ll need to browse the list below to find it and modify it.

+

../../../_images/Railway36.png

+

Remember to add bridge at the end of the enable variable in the list below.

+
+
+

MOST COMMON ERRORS

+

The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom’s Clarity page (check here for USA accounts and here for the others) and try logging in to your Dexcom account. If your account info isn’t valid, or you don’t see any data in your Clarity account… you need to figure out your actual credentials before moving ahead. See here for troubleshooting tips and information on your Dexcom account.

+
+
+

Password

+

Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.

+
+
+

Hint

+

You need to have at least one follower to use Dexcom Share. See here.

+
+
+

i) Many optional variables are already setup for you, open the caret to see them and eventually modify them (recommended).

+

../../../_images/Railway15.png

+
+

Select the units you’re using in DISPLAY_UNITS acceptable choices are mg/dl or mmol/L (or just mmol).

+

../../../_images/Railway13.png

+
+

You can update the alarms values. See here for the meaning of each one.

+

../../../_images/Railway37.png

+
+

If you want to ensure that ONLY someone with permission to view your site (e.g., a token or the API_SECRET) is able to view the data, you should configure the AUTH_DEFAULT_ROLES variable in as denied.
+If you want your site to be visible to anybody leave it as readable.

+

../../../_images/Railway11.png

+
+

A common list of enable variables is predefined, you can change them if you know why.
+It’s recommended that you leave them like this for now.

+

Just remember to add bridge at the end if your get your BG values from Dexcom Share.

+

../../../_images/Railway14.png

+
+

You can modify the variables values, check the documentation for the meaning of each one.
+Make sure you don’t make typo errors, some will crash your site (like for example LANGUAGE value in upercase).

+
+

j) You can now Deploy, and wait until it is complete.

+

../../../_images/Railway16.png

+

If you see this message, deploy didn’t complete, let’s fix this manually.

+

../../../_images/Railway41.png

+

j1) Select Settings and scroll down to Service.
+Disconnect your Source Repo with the cross at the end of the line.

+

../../../_images/RailwayT01.png

+

j2) Confirm Disconnect.

+

../../../_images/RailwayT02.png

+
+

j3) Select Connect Repo.

+

../../../_images/RailwayT03.png

+

You should be able to select your GitHub cgm-remote-monitor repository.

+

../../../_images/RailwayM03.png

+

Your Railway app will now automatically deploy.

+
+
+
+

Recommended

+

You should change your Railway site name now in order to make it easier to remember. +You can also do this later, before setting your uploaders.

+
+
+
+ +
+

a) Click on Create a New project.

+

../../../_images/Railway06.png

+

If you don’t see that, top right, click + New Project.

+

../../../_images/RailwayDB01.png

+
+

b) Select Deploy from GitHub repo.

+

../../../_images/RailwayM19.png

+
+

c) Select Configure GitHub App.

+

../../../_images/RailwayM02.png

+
+

d) Choose Only select repositories, in the Select repositories drop-down select your own fork of cgm-remote-monitor.
+Then, at the bottom, click Install & Authorize.

+

../../../_images/Railway08.png

+
+

e) You should be back to Deploy from GitHub repo, select it.

+

../../../_images/RailwayM19.png

+
+

f) Now you can select your own GitHub repository.

+

../../../_images/RailwayM03.png

+
+

g) Select Add variables.

+

../../../_images/RailwayM20.png

+
+

h) The Nightscout project will deploy in the background, just ignore it: now we need to setup our Nightscout variables.
+Click on Raw Editor.

+

../../../_images/RailwayM21b.png

+

The raw editor will open, leave it like this for now.

+

../../../_images/RailwayM21c.png

+
+

i) Compile the information below.

+

File all necessary fields, click on the Validate button at the bottom of the form, if no error is seen you will have all variables displayed in the text box at the bottom, click on the Copy All button.

+

../../../_images/Railway42.png

+

Mandatory variables

+

These three variables below must have a value.

+

MONGODB_URI

+

The MongoDB Connection String to connect to your MongoDB cluster. If you don’t have this from your Mongo database, please re-read installation instructions at Nightscout database before continuing

+


+

API_SECRET

+


+

A passphrase that must be at least 12 characters long. Avoid special characters, which can cause problems in some cases

+

DISPLAY_UNITS

+
+
Preferred BG units for the site: `mg/dl` or `mmol/l` (or just `mmol`) +
+

Customizations

+

Leave default values if you don’t want to change them

+

CUSTOM_TITLE

+


+

The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer

+

THEME

+
+
Default setting for new browser views for the color theme of the CGM graph. (`default` `colors` or `colorblindfriendly`) +

ENABLE

+


+

Plugins to enable for your site. Must be a space-delimited lower-case list. Include the word bridge here if you are receiving data from the Dexcom Share service

+

SHOW_PLUGINS

+


+

Default setting for whether or not these plugins are checked (active) by default not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case

+

TIME_FORMAT

+
+
Default setting for new browser views for the time mode. (`12` or `24`) +

NIGHT_MODE

+
+
Default setting for new browser views for whether Night Mode should be enabled. (`on` or `off`) +

BOLUS_RENDER_OVER

+


+

U value over which the bolus values are rendered on the chart if the x U and Over option is selected

+
+

Dexcom Share

+

If you want Nightscout to import directly from Dexcom Share

+

BRIDGE_USER_NAME

+


+

Your Dexcom account username to receive CGM data from the Dexcom Share service. Also make sure to include bridge in your ENABLE line.

+

BRIDGE_PASSWORD

+


+

Your Dexcom account password to receive CGM data from the Dexcom Share service. Also make sure to include bridge in your ENABLE line

+

BRIDGE_SERVER

+
+
If you are bridging from the Dexcom Share service and are anywhere *outside* the US change this to EU. (`US` or `EU`) +
+

Alarms

+

You can customize alarms or leave them to default values

+

ALARM_TYPES

+
+
`simple` and/or `predict`v. Simple alarms trigger when BG crosses the various thresholds set below. Predict alarms use a formula that forecasts where the BG is going based on its trend. You will *not* get warnings when crossing the BG thresholds set below when using the predict type +

ALARM_URGENT_HIGH

+

+

Urgent High BG threshold triggers the ALARM_URGENT_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_URGENT_LOW

+

+

Urgent Low BG threshold triggers the ALARM_URGENT_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_HIGH

+

+

High BG threshold triggers the ALARM_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_LOW

+

+

Low BG threshold triggers the ALARM_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_TIMEAGO_URGENT

+

+

Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_URGENT alarm

+

ALARM_TIMEAGO_WARN

+

+

Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_WARN alarm

+ +

Now click on the Validate button below

+

+

If errors show up below, please correct them and click Validate again.

+

Click the button above.

+

+

+



+ +

+
+
+

j) Return to the Railway Raw editor. Paste the result. Click Update Variables.

+

../../../_images/Railway43.png

+

Your site will redeploy, wait until redeploy completes.

+
+
+

Recommended

+

You should change your Railway site name now in order to make it easier to remember. +You can also do this later, before setting your uploaders.

+
+
+
+ +
+ +

../../../_images/UpdateNS15.png

+
    +
  • Leave the Heroku page opened and return to the Railway page.

  • +
  • If you cannot log into Heroku, select another deployment option (just above) and reuse your existing Atlas database connection string.

  • +
+
+

a) Click on Create a New project.

+

../../../_images/Railway06.png

+

If you don’t see that, top right, click + New Project.

+

../../../_images/RailwayDB01.png

+
+

b) Select Deploy from GitHub repo.

+

../../../_images/RailwayM19.png

+
+

Select Configure GitHub App.

+

../../../_images/RailwayM02.png

+
+

c) Choose Only select repositories, in the Select repositories drop-down select your own fork of cgm-remote-monitor.
+Then, at the bottom, click Install & Authorize.

+

../../../_images/Railway08.png

+
+

You should be back to Deploy from GitHub repo, select it.

+

../../../_images/RailwayM19.png

+
+

d) Now you can select your own GitHub repository.

+

../../../_images/RailwayM03.png

+
+

e) Select Add variables.

+

../../../_images/RailwayM20.png

+
+

f) The Nightscout project will deploy in the background, just ignore it: now we need to import all variables from Heroku.
+When you see this, press simultaneously the keys Ctrl and K.
+If you use a Mac and K.

+

../../../_images/RailwayM21.png

+
+

g) Select Import variables from Heroku.

+

../../../_images/RailwayM22.png

+
+

h) Click Connect Heroku account.

+

../../../_images/RailwayM23.png

+
+

Click Allow.

+

../../../_images/RailwayM24.png

+
+

i) Redo Ctrl K (or K and select Import variables from Heroku. Now you can select your Nightscout app.

+

../../../_images/RailwayM25.png

+
+

j) Wait until import completes.
+Your site will redeploy, wait until redeploy completes.

+
+
+
+
+

Congratulations. You created your new Nightscout site with Railway.

+

Click the site name to open Nightscout.

+../../../_images/RailwayM14.png +
+
+
+
+

New Nightscout Setup

+
+

a) Your Nightscout site should open and direct you to a new profile creation.

+../../../_images/NewNS50.png +
+

b) Setup your Time zone and eventually all other fields. Do not leave any fields empty. If you don’t know which value to use, just use the default value. You can change these values later at any time.

+../../../_images/NewNS44.png +
+

c) Browse down to Authentication status and click Authenticate. Enter your API secret. Click Update.

+../../../_images/NewNS45.png +
+

d) Click Save.

+../../../_images/NewNS46.png +
+

e) If the following pop-up shows up click OK, and check status (upper right of the window).

+../../../_images/NewNS47.png +
+

f) If you need to modify your profile after this, authenticate with the lock icon (top right of the page): enter your API secret. Then click on the hamburger menu and select Profile Editor.

+../../../_images/NewNS43.png +
+
+

Privacy warning

+

Anyone with access to the URL of your Nightscout site, can view your BG and run reports of your data. It it strongly recommended that you enable security to your site once you’re done with the setup

+
+
+

g) Dexcom Share users should see data flowing in after some minutes. +xDrip+ users (including Medtronic CareLink followers) should setup the uploader as shown here. +xDrip4iOS users here. +AAPS and Loop: consult the relative documentation.

+../../../_images/NewNS48.png +
+
+

You have completed a new Nightscout site creation. You can continue here now.

+

The following section provides more information that you might not need to use now.

+
+
+
+
+
+
+

Change your Nightscout site name

+

Railways automatically makes a name when creating your new site. It is rather difficult to remember.

+

You can change the site name but need to keep the .up.railway.app domain.

+
    +
  1. Select your Nightscout app

  2. +
  3. Go in Settings

  4. +
  5. In Domains (or Networking with Docker) go to the end of line and click the edit icon

  6. +
  7. Write your new name and check it’s available

    +

    Click Update

    +

    Your Nightscout URL will now be https://yoursitename.up.railway.app

    +
  8. +
+../../../_images/Railway38.png +
+

Change all your uploaders and follower devices to reflect the new URL once verified correct functioning of your Nightscout site.

+
+
+

You have completed a new Nightscout site creation. The following section provides more information for database migration and variables edition that you might not need to use now.

+
+
+
+
+

Editing Variables in Railway

+
+
+

Method 1 - Web interface

+

This is recommended when you only need to edit or add few variables.

+

a) Open Railway and click login. Login with GitHub.

+../../../_images/Railway00.png +../../../_images/Railway01.png +
+

b) Select your Nightscout project.

+../../../_images/RailwayM15.png +
+

c) Select your web app.

+../../../_images/RailwayM16.png +
+

d) Click on Variables.

+../../../_images/RailwayM17.png +
+

e) You can perform various operations on your variables:

+
    +
  1. Add a new variable with + New Variable

  2. +
  3. View the variable value with Show Value

  4. +
  5. Edit or delete the variable or its value with the line end menu

  6. +
+../../../_images/RailwayM18.png +
+

Note that each variable modification will redeploy your project.

+
+
+
+

Method 2 - Raw Editor

+

This is recommended when you must perform lots of changes to avoid multiple project redeploys.

+

a) Open Railway and click login. Login with GitHub.

+../../../_images/Railway00.png +../../../_images/Railway01.png +
+

b) Select your Nightscout project.

+../../../_images/RailwayM15.png +
+

c) Select your web app.

+../../../_images/RailwayM16.png +
+

d) Click on Variables.

+../../../_images/RailwayM17.png +
+

e) Click on RAW Editor top right

+../../../_images/Railway39.png +
+

f) You can access all your variables in a text editor, each line contains the variable name, the sign = then its corresponding value.

+

VARIABLE=value

+

Perform all your changes taking care of uppercase and lowercase information and click Update Variables when finished.

+../../../_images/Railway40.png +
+

Once saved your project will redeploy.
+If deploy fails, check your modifications…

+
+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/railway/new_user2/index.html b/vendors/railway/new_user2/index.html new file mode 100644 index 00000000..0023cd06 --- /dev/null +++ b/vendors/railway/new_user2/index.html @@ -0,0 +1,194 @@ + + + + + + + Update your link. — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/railway/new_user_a/index.html b/vendors/railway/new_user_a/index.html new file mode 100644 index 00000000..fea07c98 --- /dev/null +++ b/vendors/railway/new_user_a/index.html @@ -0,0 +1,483 @@ + + + + + + + Mandatory variables — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

a) Click on Create a New project.

+

../../../_images/Railway06.png

+

If you don’t see that, top right, click + New Project.

+

../../../_images/RailwayDB01.png

+
+

b) Select Deploy from GitHub repo.

+

../../../_images/RailwayM19.png

+
+

c) Select Configure GitHub App.

+

../../../_images/RailwayM02.png

+
+

d) Choose Only select repositories, in the Select repositories drop-down select your own fork of cgm-remote-monitor.
+Then, at the bottom, click Install & Authorize.

+

../../../_images/Railway08.png

+
+

e) You should be back to Deploy from GitHub repo, select it.

+

../../../_images/RailwayM19.png

+
+

f) Now you can select your own GitHub repository.

+

../../../_images/RailwayM03.png

+
+

g) Select Add variables.

+

../../../_images/RailwayM20.png

+
+

h) The Nightscout project will deploy in the background, just ignore it: now we need to setup our Nightscout variables.
+Click on Raw Editor.

+

../../../_images/RailwayM21b.png

+

The raw editor will open, leave it like this for now.

+

../../../_images/RailwayM21c.png

+
+

i) Compile the information below.

+

File all necessary fields, click on the Validate button at the bottom of the form, if no error is seen you will have all variables displayed in the text box at the bottom, click on the Copy All button.

+

../../../_images/Railway42.png

+
+

Mandatory variables

+

These three variables below must have a value.

+

MONGODB_URI

+

The MongoDB Connection String to connect to your MongoDB cluster. If you don’t have this from your Mongo database, please re-read installation instructions at Nightscout database before continuing

+


+

API_SECRET

+


+

A passphrase that must be at least 12 characters long. Avoid special characters, which can cause problems in some cases

+

DISPLAY_UNITS

+
+
Preferred BG units for the site: `mg/dl` or `mmol/l` (or just `mmol`) +
+
+
+

Customizations

+

Leave default values if you don’t want to change them

+

CUSTOM_TITLE

+


+

The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer

+

THEME

+
+
Default setting for new browser views for the color theme of the CGM graph. (`default` `colors` or `colorblindfriendly`) +

ENABLE

+


+

Plugins to enable for your site. Must be a space-delimited lower-case list. Include the word bridge here if you are receiving data from the Dexcom Share service

+

SHOW_PLUGINS

+


+

Default setting for whether or not these plugins are checked (active) by default not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case

+

TIME_FORMAT

+
+
Default setting for new browser views for the time mode. (`12` or `24`) +

NIGHT_MODE

+
+
Default setting for new browser views for whether Night Mode should be enabled. (`on` or `off`) +

BOLUS_RENDER_OVER

+


+

U value over which the bolus values are rendered on the chart if the x U and Over option is selected

+
+
+
+

Dexcom Share

+

If you want Nightscout to import directly from Dexcom Share

+

BRIDGE_USER_NAME

+


+

Your Dexcom account username to receive CGM data from the Dexcom Share service. Also make sure to include bridge in your ENABLE line.

+

BRIDGE_PASSWORD

+


+

Your Dexcom account password to receive CGM data from the Dexcom Share service. Also make sure to include bridge in your ENABLE line

+

BRIDGE_SERVER

+
+
If you are bridging from the Dexcom Share service and are anywhere *outside* the US change this to EU. (`US` or `EU`) +
+
+
+

Alarms

+

You can customize alarms or leave them to default values

+

ALARM_TYPES

+
+
`simple` and/or `predict`v. Simple alarms trigger when BG crosses the various thresholds set below. Predict alarms use a formula that forecasts where the BG is going based on its trend. You will *not* get warnings when crossing the BG thresholds set below when using the predict type +

ALARM_URGENT_HIGH

+

+

Urgent High BG threshold triggers the ALARM_URGENT_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_URGENT_LOW

+

+

Urgent Low BG threshold triggers the ALARM_URGENT_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_HIGH

+

+

High BG threshold triggers the ALARM_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_LOW

+

+

Low BG threshold triggers the ALARM_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_TIMEAGO_URGENT

+

+

Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_URGENT alarm

+

ALARM_TIMEAGO_WARN

+

+

Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_WARN alarm

+ +

Now click on the Validate button below

+

+

If errors show up below, please correct them and click Validate again.

+

Click the button above.

+

+

+



+ +

+
+
+

j) Return to the Railway Raw editor. Paste the result. Click Update Variables.

+

../../../_images/Railway43.png

+

Your site will redeploy, wait until redeploy completes.

+
+
+

Recommended

+

You should change your Railway site name now in order to make it easier to remember. +You can also do this later, before setting your uploaders.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/railway/new_user_b/index.html b/vendors/railway/new_user_b/index.html new file mode 100644 index 00000000..5e799d8d --- /dev/null +++ b/vendors/railway/new_user_b/index.html @@ -0,0 +1,295 @@ + + + + + + + — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+


+

a) Click on the Deploy on Railway button below:

+

Deploy on Railway

+

Note: this is a private template as the community doesn’t have a Railway account.
+It doesn’t include any referral code.

+
+

b) If you see this screen, select Connect GitHub to Deploy.

+

../../../_images/Railway07a.png

+

Then select Authorize Railway App.

+

../../../_images/Railway02.png

+
+

c) Click Configure

+

../../../_images/Railway07.png

+
+

d) Click Install & Authorize

+

../../../_images/Railway08a.png

+
+

e) You will then see this page, scroll down to define the required variables for creating your Nightscout site.

+

../../../_images/Railway09.png

+
+

Mind if you see this you must delete thecgm-remote-monitor fork in GitHub and retry Deploy from a) afterwards.

+

../../../_images/Railway17.png

+
+

f) Setup your Nightscout core variables.

+
+

Migrating from Heroku

+

If you’re migrating your project from Heroku, display all variables in Heroku and copy all those with a value into Railway.
+See below how to add variables in Railway but use your Heroku variables values.

+
+

API_SECRET will be your Nightscout site password, it needs to be at least 12 characters long and you should NOT use spaces if you use @ or ! symbols remember you will probably need to express them using Percent encoding in your uploader and downloader apps. If you’re not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits.

+
+

Warning

+

The API_SECRET is the main password allowing full access to your Nightscout site. Make sure it’s reasonably secure (mix uppercase and lowercase letters, plus digits) and do no not share it publicly. If you think you exposed it by mistake, it is recommended that you change it.

+
+

../../../_images/Railway10.png

+

g) At Step 3 you created your database and came back with a MONGODB_URI string. Time has come to use it here.

+

../../../_images/Railway21.png

+
+

Dexcom Bridge

+

h) If you use Dexcom bridge you need to configure these two variables with your Dexcom credentials:

+

../../../_images/Railway33.png

+

../../../_images/Railway34.png

+

If you’re using Dexcom Share in the US you should put US, in any other case it must be EU.
+If you don’t see it proposed at this point you’ll need to browse the list below to find it and modify it.

+

../../../_images/Railway36.png

+

Remember to add bridge at the end of the enable variable in the list below.

+
+
+

MOST COMMON ERRORS

+

The most common error on initial Nightscout setups is that people incorrectly use an old account or an old password. To test your username and password, go to Dexcom’s Clarity page (check here for USA accounts and here for the others) and try logging in to your Dexcom account. If your account info isn’t valid, or you don’t see any data in your Clarity account… you need to figure out your actual credentials before moving ahead. See here for troubleshooting tips and information on your Dexcom account.

+
+
+

Password

+

Some people have had problems with their bridge connecting when their Dexcom passwords are entirely numeric. If you have connection issues in that case, try changing your password to something with a mix of numbers and letters.

+
+
+

Hint

+

You need to have at least one follower to use Dexcom Share. See here.

+
+
+

i) Many optional variables are already setup for you, open the caret to see them and eventually modify them (recommended).

+

../../../_images/Railway15.png

+
+

Select the units you’re using in DISPLAY_UNITS acceptable choices are mg/dl or mmol/L (or just mmol).

+

../../../_images/Railway13.png

+
+

You can update the alarms values. See here for the meaning of each one.

+

../../../_images/Railway37.png

+
+

If you want to ensure that ONLY someone with permission to view your site (e.g., a token or the API_SECRET) is able to view the data, you should configure the AUTH_DEFAULT_ROLES variable in as denied.
+If you want your site to be visible to anybody leave it as readable.

+

../../../_images/Railway11.png

+
+

A common list of enable variables is predefined, you can change them if you know why.
+It’s recommended that you leave them like this for now.

+

Just remember to add bridge at the end if your get your BG values from Dexcom Share.

+

../../../_images/Railway14.png

+
+

You can modify the variables values, check the documentation for the meaning of each one.
+Make sure you don’t make typo errors, some will crash your site (like for example LANGUAGE value in upercase).

+
+

j) You can now Deploy, and wait until it is complete.

+

../../../_images/Railway16.png

+

If you see this message, deploy didn’t complete, let’s fix this manually.

+

../../../_images/Railway41.png

+

j1) Select Settings and scroll down to Service.
+Disconnect your Source Repo with the cross at the end of the line.

+

../../../_images/RailwayT01.png

+

j2) Confirm Disconnect.

+

../../../_images/RailwayT02.png

+
+

j3) Select Connect Repo.

+

../../../_images/RailwayT03.png

+

You should be able to select your GitHub cgm-remote-monitor repository.

+

../../../_images/RailwayM03.png

+

Your Railway app will now automatically deploy.

+
+
+
+

Recommended

+

You should change your Railway site name now in order to make it easier to remember. +You can also do this later, before setting your uploaders.

+
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/railway/new_user_d/index.html b/vendors/railway/new_user_d/index.html new file mode 100644 index 00000000..915724dc --- /dev/null +++ b/vendors/railway/new_user_d/index.html @@ -0,0 +1,486 @@ + + + + + + + Mandatory variables — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

a) Click on Create a New project.

+

../../../_images/Railway06.png

+

If you don’t see that, top right, click + New Project.

+

../../../_images/RailwayDB01.png

+
+

b) Select Empty project.

+

../../../_images/RailwayD01.png

+
+

c) Select Add a Service.

+

../../../_images/RailwayD02.png

+
+

d) Select Docker Image.

+

../../../_images/RailwayD03.png

+
+

e) In the field Name of the Image type:

+

nightscout/cgm-remote-monitor:latest

+

and press <Enter>

+

../../../_images/RailwayD04.png

+
+

f) Select your new service.

+

../../../_images/RailwayD05.png

+
+

g) Select Add variables.

+

../../../_images/RailwayM20.png

+
+

h) Now we need to setup our Nightscout variables.
+Click on Raw Editor.

+

../../../_images/RailwayM21b.png

+

The raw editor will open, leave it like this for now.

+

../../../_images/RailwayM21c.png

+
+

i) Compile the information below.

+

File all necessary fields, click on the Validate button at the bottom of the form, if no error is seen you will have all variables displayed in the text box at the bottom, click on the Copy All button.

+

../../../_images/Railway42.png

+
+

Mandatory variables

+

These three variables below must have a value.

+

MONGODB_URI

+

The MongoDB Connection String to connect to your MongoDB cluster. If you don’t have this from your Mongo database, please re-read installation instructions at Nightscout database before continuing

+


+

API_SECRET

+


+

A passphrase that must be at least 12 characters long. Avoid special characters, which can cause problems in some cases

+

DISPLAY_UNITS

+
+
Preferred BG units for the site: `mg/dl` or `mmol/l` (or just `mmol`) +
+
+
+

Customizations

+

Leave default values if you don’t want to change them

+

CUSTOM_TITLE

+


+

The display name for the Nightscout site. Appears in the upper left of the main view. Often set to the name of the CGM wearer

+

THEME

+
+
Default setting for new browser views for the color theme of the CGM graph. (`default` `colors` or `colorblindfriendly`) +

ENABLE

+


+

Plugins to enable for your site. Must be a space-delimited lower-case list. Include the word bridge here if you are receiving data from the Dexcom Share service

+

SHOW_PLUGINS

+


+

Default setting for whether or not these plugins are checked (active) by default not merely enabled. Include plugins here as in the ENABLE line; space-separated and lower-case

+

TIME_FORMAT

+
+
Default setting for new browser views for the time mode. (`12` or `24`) +

NIGHT_MODE

+
+
Default setting for new browser views for whether Night Mode should be enabled. (`on` or `off`) +

BOLUS_RENDER_OVER

+


+

U value over which the bolus values are rendered on the chart if the x U and Over option is selected

+
+
+
+

Dexcom Share

+

If you want Nightscout to import directly from Dexcom Share

+

BRIDGE_USER_NAME

+


+

Your Dexcom account username to receive CGM data from the Dexcom Share service. Also make sure to include bridge in your ENABLE line.

+

BRIDGE_PASSWORD

+


+

Your Dexcom account password to receive CGM data from the Dexcom Share service. Also make sure to include bridge in your ENABLE line

+

BRIDGE_SERVER

+
+
If you are bridging from the Dexcom Share service and are anywhere *outside* the US change this to EU. (`US` or `EU`) +
+
+
+

Alarms

+

You can customize alarms or leave them to default values

+

ALARM_TYPES

+
+
`simple` and/or `predict`v. Simple alarms trigger when BG crosses the various thresholds set below. Predict alarms use a formula that forecasts where the BG is going based on its trend. You will *not* get warnings when crossing the BG thresholds set below when using the predict type +

ALARM_URGENT_HIGH

+

+

Urgent High BG threshold triggers the ALARM_URGENT_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_URGENT_LOW

+

+

Urgent Low BG threshold triggers the ALARM_URGENT_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_HIGH

+

+

High BG threshold triggers the ALARM_HIGH alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_LOW

+

+

Low BG threshold triggers the ALARM_LOW alarm. Set in mg/dL or mmol/L as set in DISPLAY_UNITS variable

+

ALARM_TIMEAGO_URGENT

+

+

Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_URGENT alarm

+

ALARM_TIMEAGO_WARN

+

+

Default setting for new browser views for the number of minutes since the last CGM reading to trigger an ALARM_TIMEAGO_WARN alarm

+ +

Now click on the Validate button below

+

+

If errors show up below, please correct them and click Validate again.

+

Click the button above.

+

+

+



+ +

+
+
+

j) Return to the Railway Raw editor. Paste the result. Click Update Variables.

+

../../../_images/Railway43.png

+
+

k) On the top left of the screen Deploy.

+

../../../_images/RailwayD06.png

+
+

l) Select the Settings tab and click Generate domain.

+

../../../_images/RailwayD07.png

+
+

m) Edit your Nightscout site name and put yours (one that is not already used).

+

../../../_images/RailwayD08.png

+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/raspberry-pi/new_user/index.html b/vendors/raspberry-pi/new_user/index.html new file mode 100644 index 00000000..708e9aa8 --- /dev/null +++ b/vendors/raspberry-pi/new_user/index.html @@ -0,0 +1,192 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/render/new_user/index.html b/vendors/render/new_user/index.html new file mode 100644 index 00000000..5e437768 --- /dev/null +++ b/vendors/render/new_user/index.html @@ -0,0 +1,591 @@ + + + + + + + Nightscout in Render — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Nightscout in Render

+
+
+

Too complicated? Not what you’re looking for?

+

Consider a hosted Nightscout service! Check for easier solutions here.

+
+
+
+
+

Render

+

Render Free

+
+
+

You can create your Nightscout site in Render.

+

Pros:

+
    +
  • No credit card required

  • +
+

Cons:

+
    +
  • The free plan doesn’t guarantee any reliability

  • +
  • App will sleep after 15 minutes

  • +
  • Render URLs are considered unsafe by some internet providers

  • +
  • Relying on the MongoDB Atlas database

  • +
+
+
+
+
+
+

Step 0: Create a database

+
+

Render doesn’t include a database

+

Make sure you created one before starting your Nightscout web app creation with Render. +Come back here when you have a MONGODB_URI connection string.

+
+
+

Migrating?

+

Copy the connection string from your previous platform: edit the variables and look for MONGODB_URI. +If you don’t see MONGODB_URI but see MONGO_CONNECTION (NOT MONGO_COLLECTION): use its value.

+
+
+
+
+

Step 1: Create a GitHub account and fork the Nightscout project

+
+ +
+

Continue with Step 2.

+
+ +
+

Create a GitHub account

+

a) Click this link to create a GitHub account: https://github.com/

+

Enter your email and click Sign up for GitHub

+

../../../_images/NewNS00a.png

+

b) Enter a password and a username (anything you want and that is accepted, not very important).
+Type n to decline advertisement emails.

+

../../../_images/NewNS00.png

+

c) Play and solve the puzzle then click Create account

+

../../../_images/NewNS01.png

+

d) GitHub will send you a verification code. Open your mail and check your inbox (check your spam-folder if not received after a couple of minutes).

+

../../../_images/NewNS02.png

+

e) If a personalization sequence starts, click Skip personalization at the bottom.

+

../../../_images/NewNS03.png

+

f) Leave the page that opened as it is. Don’t close it.

+

../../../_images/NewNS04.png

+

You have created your GitHub account. Now fork the Nightscout project.

+
+

Fork the Nightscout project

+

a) Click here to log in at GitHub: https://github.com/login.
+Enter your username or email and your password. Click Sign in

+

../../../_images/UpdateNS00.png

+
+

If you already have a fork of cgm-remote-monitor in GitHub

+

Delete or update your current cgm-remote-monitor fork before continuing.

+
+

b) Open this link https://github.com/nightscout/cgm-remote-monitor. Click on Fork

+

../../../_images/NewNS29.png

+

Confirm with Create fork

+
+

Warning

+

Make sure you deselect Copy the master branch only.

+
+

../../../_images/NewNS51.png

+

c) Wait for a moment

+

../../../_images/NewNS30.png

+

d) You now have a copy (fork) of the Nightscout project repository in your own GitHub.

+

../../../_images/UpdateNS30.png

+
+ +
+

Update your Nightscout fork

+
    +
  • Click here to log in at GitHub: https://github.com/login.

  • +
  • Enter your username or email and your password. Click Sign in

  • +
+

../../../_images/UpdateNS00.png

+
    +
  • Select your own cgm-remote-monitor project (not nightscout/cgm-remote-monitor)

  • +
+

../../../_images/UpdateNS01.png

+
    +
  • Your repository will open. If you see This branch is xxx commits behind nightscout:master you need to update.

  • +
  • Select Fetch upstream

  • +
+

../../../_images/UpdateNS01a.png

+
    +
  • Select Fetch and merge

  • +
+

../../../_images/UpdateNS01b.png

+
    +
  • After a moment, your repository should display This branch is up to date with nightscout:master

  • +
+

../../../_images/UpdateNS01c.png

+

You have now updated your GitHub cgm-remote-monitor repository.

+
+

If you ran into trouble, you can redeploy the project.

+
+
+
+
+
+
+

Step 2: Create a Render account

+

a) Open a new browser page in Render and select GET STARTED FOR FREE

+

../../../_images/Render01.png

+

b) Sign up with GitHub

+

../../../_images/Render02.png

+

c) Authorize Render

+

../../../_images/Render03.png

+

d) COMPLETE SIGN UP with your GitHub account email

+

../../../_images/Render04.png

+

e) Check your inbox and click the confirmation link

+

../../../_images/Render05.png

+
+
+
+

Step 3 - Deploy Nightscout in Render

+

Select below how you want to do this:

+
+ +
+

Step 4: Create your Nightscout service

+
    +
  • From the dashboard, create a new Web Service.

  • +
+

../../../_images/RenderD01.png

+
    +
  • Select Deploy an existing image from a registry then Next.

  • +
+

../../../_images/RenderD02.png

+
    +
  • In the field Image URL type:

  • +
+
nightscout/cgm-remote-monitor:latest
+
+
+

Then Next.

+

../../../_images/RenderD03.png

+
    +
  • InName put the name of your Nightscout site (Render will add an extension if it’s not unique).

  • +
+

../../../_images/RenderD04.png

+
    +
  • Select the Region closer to where you live.

  • +
+

../../../_images/RenderD05.png

+
    +
  • Select the Free instance type, knowing it will fall asleep (we’ll fix that later on).

  • +
+

../../../_images/RenderD06.png

+
    +
  • Clicking the button + Add Environment Variable add the following two variables, and in the box on the right the matching value:

  • +
+
HOSTNAME	0.0.0.0
+PORT		1337
+
+
+

../../../_images/RenderD07.png

+

You now need to setup core variables for your site:

+
    +
  • Clicking the button + Add Environment Variable add the following three variables:

  • +
  • MONGODB_URI paste your database connection string from Step 0 above

  • +
  • API_SECRET will be your Nightscout site password, it needs to be at least 12 characters long and you should NOT use spaces if you use @ or ! symbols remember you will probably need to express them using Percent encoding in your uploader and downloader apps. If you’re not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits.

  • +
+
+

Warning

+

The API_SECRET is the main password allowing full access to your Nightscout site. Make sure it’s reasonably secure (mix uppercase and lowercase letters, plus digits) and do no not share it publicly. If you think you exposed it by mistake, it is recommended that you change it.

+
+
    +
  • Define your DISPLAY_UNITS

  • +
+

Acceptable choices for the units used in Nightscout are mg/dl or mmol/L (or just mmol).

+
    +
  • Once all three variables have been set, Create web Service

  • +
+

../../../_images/RenderD08.png

+
    +
  • Your Nightscout site will be deployed. Wait until the operation completes after some minutes.

  • +
+../../../_images/Render13.png +

../../../_images/Render14.png

+

Congratulations. You created your new Nightscout site with Render.

+
+
+ +
+

Step 4: Add the render.yaml template

+ +

../../../_images/UpdateNS00.png

+
    +
  • Select your own cgm-remote-monitor project.

  • +
+

../../../_images/UpdateNS01.png

+
    +
  1. Open the branches list

  2. +
  3. Type render

  4. +
  5. Select Create a branch: render from ‘master’

  6. +
+

../../../_images/NewBranch.png

+
    +
  • Select Add File - Create new file

  • +
+

../../../_images/AddFile.png

+
    +
  • Type render.yaml for the name. Leave it open like that for now.

  • +
+

../../../_images/Yaml00.png

+
    +
  • Open the render.txt template from here and edit it with a notepad app, select all, copy and paste into the GitHub page you have open from above.

  • +
+

../../../_images/Yaml01.png

+
    +
  • Scroll up the page in GitHub and select Commit changes top right.

  • +
+

../../../_images/Yaml02.png

+
    +
  • Confirm with Commit changes.

  • +
+

../../../_images/Yaml03.png

+
    +
  • Your cgm-remote-monitor project is ready for Render Blueprints deploy.

  • +
+
+

Step 5: First deploy in Render

+

a) Select Blueprints

+

../../../_images/Render06.png

+

b) Then New blueprint instance

+

../../../_images/Render07.png

+

c) Connect your cgm-remote-monitor project

+

../../../_images/Render08.png

+

d) Enter a name for your blueprint (anything simple, Nightscout is ok)

+

../../../_images/Render09.png

+

e) Click the drop down menu of Branch (1) then select render (2)

+

../../../_images/Render10.png

+

You now need to setup core variables for your site:

+

../../../_images/Render11.png

+

f) In MONGODB_URI paste your database connection string from Step 0 above

+

g) API_SECRET will be your Nightscout site password, it needs to be at least 12 characters long and you should NOT use spaces if you use @ or ! symbols remember you will probably need to express them using Percent encoding in your uploader and downloader apps. If you’re not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits.

+
+

Warning

+

The API_SECRET is the main password allowing full access to your Nightscout site. Make sure it’s reasonably secure (mix uppercase and lowercase letters, plus digits) and do no not share it publicly. If you think you exposed it by mistake, it is recommended that you change it.

+
+

h) Define your DISPLAY_UNITS
+Acceptable choices for the units used in Nightscout are mg/dl or mmol/L (or just mmol).

+
+

i) Once all three variables have been set, Apply

+

../../../_images/Render12.png

+

j) Your Nightscout site will be deployed. Wait until the operation completes after some minutes.

+../../../_images/Render13.png +

../../../_images/Render14.png

+

Congratulations. You created your new Nightscout site with Render.

+

The following step is important, don’t skip it.

+
+

Step 6: Delete the render branch

+
+

Hint

+

In order to deploy your site with a blueprint, you needed to modify your GitHub repository. +Now you want to remove this modification so that you’ll be able to update it normally.

+
+ +

../../../_images/UpdateNS00.png

+
    +
  • Select your own cgm-remote-monitor project.

  • +
+

../../../_images/UpdateNS01.png

+
    +
  • Click on branches to display all.

  • +
+

../../../_images/Render18.png

+
    +
  • Locate the render branch and click on the bin icon to delete it.

  • +
+

../../../_images/Render19.png

+

You have successfully removed the temporary modification required to deploy a new Render site.

+

../../../_images/Render20.png

+
    +
  • Your Render site will redeploy using the normal master branch of cgm-remote-monitor, wait a few minutes until the operation completes.

  • +
+
+
+
+
+
    +
  • From the menu, Dashboard, then select your web service.

  • +
+../../../_images/Render15.png +

../../../_images/Render16.png

+
    +
  • This is your new Nightscout site, click on the URL to open it

  • +
+

../../../_images/Render17.png

+
+
+
+

New Nightscout Setup

+
+

a) Your Nightscout site should open and direct you to a new profile creation.

+../../../_images/NewNS50.png +
+

b) Setup your Time zone and eventually all other fields. Do not leave any fields empty. If you don’t know which value to use, just use the default value. You can change these values later at any time.

+../../../_images/NewNS44.png +
+

c) Browse down to Authentication status and click Authenticate. Enter your API secret. Click Update.

+../../../_images/NewNS45.png +
+

d) Click Save.

+../../../_images/NewNS46.png +
+

e) If the following pop-up shows up click OK, and check status (upper right of the window).

+../../../_images/NewNS47.png +
+

f) If you need to modify your profile after this, authenticate with the lock icon (top right of the page): enter your API secret. Then click on the hamburger menu and select Profile Editor.

+../../../_images/NewNS43.png +
+
+

Privacy warning

+

Anyone with access to the URL of your Nightscout site, can view your BG and run reports of your data. It it strongly recommended that you enable security to your site once you’re done with the setup

+
+
+

g) Dexcom Share users should see data flowing in after some minutes. +xDrip+ users (including Medtronic CareLink followers) should setup the uploader as shown here. +xDrip4iOS users here. +AAPS and Loop: consult the relative documentation.

+../../../_images/NewNS48.png +
+
+

You have completed a new Nightscout site creation. You can continue here now.

+

The following section provides more information that you might not need to use now.

+
+
+
+
+
+

Editing Variables in Render

+
+
    +
  • Sign in Render with GitHub

  • +
+

../../../_images/Render02.png

+
    +
  • Select your web service

  • +
+../../../_images/Render16.png +
    +
  • Go to Environment, your variables will display

  • +
+../../../_images/Render21.png +
    +
  • You can modify variables by making the changes directly in the text boxes.
    +You can also add variables with Add environment variable.
    +When you’re done, scroll down and Save changes.

  • +
+../../../_images/Render23.png +
    +
  • Wait a few minutes for your site to redeploy. You can track the status in Events.

  • +
+../../../_images/Render24.png +
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/render/new_user_a/index.html b/vendors/render/new_user_a/index.html new file mode 100644 index 00000000..166217da --- /dev/null +++ b/vendors/render/new_user_a/index.html @@ -0,0 +1,292 @@ + + + + + + + Step 4: Add the render.yaml template — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Step 4: Add the render.yaml template

+ +

../../../_images/UpdateNS00.png

+
    +
  • Select your own cgm-remote-monitor project.

  • +
+

../../../_images/UpdateNS01.png

+
    +
  1. Open the branches list

  2. +
  3. Type render

  4. +
  5. Select Create a branch: render from ‘master’

  6. +
+

../../../_images/NewBranch.png

+
    +
  • Select Add File - Create new file

  • +
+

../../../_images/AddFile.png

+
    +
  • Type render.yaml for the name. Leave it open like that for now.

  • +
+

../../../_images/Yaml00.png

+
    +
  • Open the render.txt template from here and edit it with a notepad app, select all, copy and paste into the GitHub page you have open from above.

  • +
+

../../../_images/Yaml01.png

+
    +
  • Scroll up the page in GitHub and select Commit changes top right.

  • +
+

../../../_images/Yaml02.png

+
    +
  • Confirm with Commit changes.

  • +
+

../../../_images/Yaml03.png

+
    +
  • Your cgm-remote-monitor project is ready for Render Blueprints deploy.

  • +
+
+
+
+

Step 5: First deploy in Render

+

a) Select Blueprints

+

../../../_images/Render06.png

+

b) Then New blueprint instance

+

../../../_images/Render07.png

+

c) Connect your cgm-remote-monitor project

+

../../../_images/Render08.png

+

d) Enter a name for your blueprint (anything simple, Nightscout is ok)

+

../../../_images/Render09.png

+

e) Click the drop down menu of Branch (1) then select render (2)

+

../../../_images/Render10.png

+

You now need to setup core variables for your site:

+

../../../_images/Render11.png

+

f) In MONGODB_URI paste your database connection string from Step 0 above

+

g) API_SECRET will be your Nightscout site password, it needs to be at least 12 characters long and you should NOT use spaces if you use @ or ! symbols remember you will probably need to express them using Percent encoding in your uploader and downloader apps. If you’re not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits.

+
+

Warning

+

The API_SECRET is the main password allowing full access to your Nightscout site. Make sure it’s reasonably secure (mix uppercase and lowercase letters, plus digits) and do no not share it publicly. If you think you exposed it by mistake, it is recommended that you change it.

+
+

h) Define your DISPLAY_UNITS
+Acceptable choices for the units used in Nightscout are mg/dl or mmol/L (or just mmol).

+
+

i) Once all three variables have been set, Apply

+

../../../_images/Render12.png

+

j) Your Nightscout site will be deployed. Wait until the operation completes after some minutes.

+../../../_images/Render13.png +

../../../_images/Render14.png

+

Congratulations. You created your new Nightscout site with Render.

+

The following step is important, don’t skip it.

+
+
+
+

Step 6: Delete the render branch

+
+

Hint

+

In order to deploy your site with a blueprint, you needed to modify your GitHub repository. +Now you want to remove this modification so that you’ll be able to update it normally.

+
+ +

../../../_images/UpdateNS00.png

+
    +
  • Select your own cgm-remote-monitor project.

  • +
+

../../../_images/UpdateNS01.png

+
    +
  • Click on branches to display all.

  • +
+

../../../_images/Render18.png

+
    +
  • Locate the render branch and click on the bin icon to delete it.

  • +
+

../../../_images/Render19.png

+

You have successfully removed the temporary modification required to deploy a new Render site.

+

../../../_images/Render20.png

+
    +
  • Your Render site will redeploy using the normal master branch of cgm-remote-monitor, wait a few minutes until the operation completes.

  • +
+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/render/new_user_d/index.html b/vendors/render/new_user_d/index.html new file mode 100644 index 00000000..9ec26f15 --- /dev/null +++ b/vendors/render/new_user_d/index.html @@ -0,0 +1,253 @@ + + + + + + + Step 4: Create your Nightscout service — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Step 4: Create your Nightscout service

+
    +
  • From the dashboard, create a new Web Service.

  • +
+

../../../_images/RenderD01.png

+
    +
  • Select Deploy an existing image from a registry then Next.

  • +
+

../../../_images/RenderD02.png

+
    +
  • In the field Image URL type:

  • +
+
nightscout/cgm-remote-monitor:latest
+
+
+

Then Next.

+

../../../_images/RenderD03.png

+
    +
  • InName put the name of your Nightscout site (Render will add an extension if it’s not unique).

  • +
+

../../../_images/RenderD04.png

+
    +
  • Select the Region closer to where you live.

  • +
+

../../../_images/RenderD05.png

+
    +
  • Select the Free instance type, knowing it will fall asleep (we’ll fix that later on).

  • +
+

../../../_images/RenderD06.png

+
    +
  • Clicking the button + Add Environment Variable add the following two variables, and in the box on the right the matching value:

  • +
+
HOSTNAME	0.0.0.0
+PORT		1337
+
+
+

../../../_images/RenderD07.png

+

You now need to setup core variables for your site:

+
    +
  • Clicking the button + Add Environment Variable add the following three variables:

  • +
  • MONGODB_URI paste your database connection string from Step 0 above

  • +
  • API_SECRET will be your Nightscout site password, it needs to be at least 12 characters long and you should NOT use spaces if you use @ or ! symbols remember you will probably need to express them using Percent encoding in your uploader and downloader apps. If you’re not sure on how to do this, it is recommended to use only letters (uppercase + lowercase) and digits.

  • +
+
+

Warning

+

The API_SECRET is the main password allowing full access to your Nightscout site. Make sure it’s reasonably secure (mix uppercase and lowercase letters, plus digits) and do no not share it publicly. If you think you exposed it by mistake, it is recommended that you change it.

+
+
    +
  • Define your DISPLAY_UNITS

  • +
+

Acceptable choices for the units used in Nightscout are mg/dl or mmol/L (or just mmol).

+
    +
  • Once all three variables have been set, Create web Service

  • +
+

../../../_images/RenderD08.png

+
    +
  • Your Nightscout site will be deployed. Wait until the operation completes after some minutes.

  • +
+../../../_images/Render13.png +

../../../_images/Render14.png

+

Congratulations. You created your new Nightscout site with Render.

+
+
+ + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/serendipity/index.html b/vendors/serendipity/index.html new file mode 100644 index 00000000..1ef70e8c --- /dev/null +++ b/vendors/serendipity/index.html @@ -0,0 +1,192 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/vendors/synology/new_user/index.html b/vendors/synology/new_user/index.html new file mode 100644 index 00000000..273b581e --- /dev/null +++ b/vendors/synology/new_user/index.html @@ -0,0 +1,192 @@ + + + + + + + <no title> — Nightscout Documentation documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ + + + + + +
+
+
+ +
+ +
+

© Copyright 2024, #WeAreNotWaiting.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file