From 5ae324f482d50fe3733b187a1c3b278e8bc74ef3 Mon Sep 17 00:00:00 2001 From: leandrom-humanforce Date: Fri, 10 May 2024 09:19:52 +1000 Subject: [PATCH] update --- .../plugins/webpage-html-export/data.json | 18 +- .obsidian/workspace.json | 112 +- docs/APIs/GitHub API.html | 14 + docs/APIs/Google Calendar API.html | 105 + docs/APIs/JIRA API.html | 14 + docs/APIs/QMetry API.html | 14 + docs/AWS/AWS KMS.html | 18 + ...plementing Microsoft DevOps Solutions.html | 15 + docs/Cloud/AWS/Index.html | 88 + docs/Cloud/AWS/Services/CloudFormation.html | 21 + docs/Cloud/AWS/Services/Cognito.html | 37 + docs/Cloud/AWS/Services/DynamoDB.html | 27 + docs/Cloud/AWS/Services/Lambda.html | 56 + docs/Cloud/AWS/Tools/AWS CLI.html | 22 + docs/Cloud/AWS/Tools/CDK.html | 26 + docs/Cloud/AWS/Tools/Lambda Tools.html | 21 + docs/Cloud/AWS/Tools/LocalStack.html | 37 + docs/Cloud/AWS/Tools/Moto.html | 19 + docs/Cloud/AWS/Tools/SAM CLI.html | 21 + docs/Cloud/Azure/Index.html | 18 + docs/Development/Developer Productivity.html | 19 + .../Development Environment Setup.html | 84 + docs/DotNet/CLI/dotnet list package.html | 25 + docs/DotNet/CLI/dotnet monitor.html | 16 + docs/Email Templates/Knowledge Sharing.html | 37 + docs/Email Templates/Onboarding.html | 139 + docs/Engineering Management/1on1s.html | 44 + docs/Engineering Management/Agile.html | 21 + docs/Engineering Management/Career.html | 20 + .../Change Management.html | 26 + docs/Engineering Management/Coaching.html | 17 + docs/Engineering Management/Code Reviews.html | 16 + .../Community Of Practice.html | 65 + docs/Engineering Management/Culture.html | 19 + .../Developer Experience.html | 25 + .../Effective Meetings.html | 16 + .../Engineering Management.html | 87 + docs/Engineering Management/Goals.html | 30 + .../Health Monitor.html | 94 + .../High Performing Teams.html | 16 + docs/Engineering Management/Hiring.html | 18 + .../Incident Management.html | 16 + docs/Engineering Management/Index.html | 47 + docs/Engineering Management/Interview.html | 54 + docs/Engineering Management/Interviewer.html | 45 + docs/Engineering Management/Leadership.html | 16 + .../Manage for Better Results.html | 29 + docs/Engineering Management/Metrics.html | 19 + docs/Engineering Management/Onboarding.html | 27 + .../Psychological Safety.html | 14 + docs/Engineering Management/Reports.html | 49 + docs/Engineering Management/Salary.html | 14 + .../Software Development Strategy.html | 213 ++ .../Ways of Working.html | 32 + docs/Engineering Management/Wellbeing.html | 43 + .../Microsoft.FeatureManagement.html | 51 + docs/Goals/Continous Learning.html | 209 ++ docs/Goals/Continuous Improvement.html | 98 + docs/Goals/Knowledge Sharing.html | 135 + docs/How-to/Batch File.html | 33 + ...Build and Run a Container with Docker.html | 78 + docs/How-to/Change host file on Windows.html | 51 + docs/How-to/Create IIS Websites.html | 20 + .../Create Self-Signed Certificate.html | 102 + ...nent PowerShell Alias using Set-Alias.html | 19 + docs/How-to/HTTP Client.html | 23 + .../Install multiple NodeJS Versions.html | 23 + ...asure Method Elapsed Time with CSharp.html | 41 + docs/How-to/Modernization.html | 28 + .../Run a tool globally on Windows.html | 30 + docs/How-to/Technical Support.html | 29 + docs/Security/OWASP TOP 10.html | 17 + docs/Security/Secure Code Warriors.html | 17 + docs/Technology/Coding Exercise.html | 73 + docs/Technology/HTTP 3.html | 15 + docs/Testing/MsTest.html | 14 + docs/Testing/Playwright using .NET.html | 98 + docs/Testing/Playwright using TypeScript.html | 152 + docs/Testing/WireMockNet.html | 21 + docs/Tools/Docker CLI.html | 38 + docs/Tools/Docker Compose.html | 16 + docs/Tools/Docker Desktop.html | 89 + docs/Tools/GitHub Copilot.html | 14 + docs/Tools/Kubernetes.html | 341 ++ .../Microsoft Application Inspector.html | 22 + docs/Tools/NuGet.html | 20 + docs/Tools/Nuget CLI.html | 17 + docs/Tools/Proxy.html | 14 + docs/Tools/Redash.html | 66 + docs/Tools/SQL Lite.html | 16 + docs/Tools/Slack CLI.html | 21 + docs/Tools/Sql Server.html | 213 ++ docs/Tools/Visual Studio.html | 95 + docs/Tools/Windows Terminal.html | 36 + docs/development/devcontainers.html | 90 +- docs/development/developer-productivity.html | 51 - .../development-environment-setup.html | 116 - docs/devops/observability.html | 60 +- docs/documentation/diagramsascode.html | 54 +- docs/documentation/documentation.html | 62 +- docs/dotnet/asp.net.html | 58 +- docs/dotnet/cli/dotnet-list-package.html | 57 - docs/dotnet/cli/dotnet-monitor.html | 48 - docs/dotnet/configuration.html | 104 +- docs/dotnet/csharp.html | 54 +- docs/dotnet/deployment.html | 58 +- docs/dotnet/entityframework.html | 83 +- docs/dotnet/libraries/identityserver.html | 66 +- .../microsoft.featuremanagement.html | 83 - docs/dotnet/libraries/nukebuild.html | 68 +- docs/dotnet/libraries/playwright.html | 55 - docs/dotnet/libraries/wiremocknet.html | 53 - docs/dotnet/libraries/yarp.html | 58 +- docs/dotnet/minimalapi.html | 60 +- docs/email-templates/knowledge-sharing.html | 69 - docs/email-templates/onboarding.html | 171 - docs/frontend/angular.html | 60 +- docs/frontend/css.html | 55 +- docs/frontend/index.html | 66 +- docs/goals/continous-learning.html | 250 -- docs/goals/continuous-improvement.html | 130 - docs/goals/knowledge-sharing.html | 167 - docs/goals/quality.html | 144 +- docs/how-to/batch-file.html | 65 - docs/how-to/change-host-file-on-windows.html | 83 - docs/how-to/cli.html | 64 +- docs/how-to/create-iis-websites.html | 52 - .../create-self-signed-certificate.html | 134 - docs/how-to/docker.html | 103 - docs/how-to/git.html | 98 +- docs/how-to/google-calendar-api.html | 58 - .../install-multiple-nodejs-versions.html | 55 - ...asure-method-elapsed-time-with-csharp.html | 73 - docs/how-to/technical-support.html | 61 - docs/index.html | 72 +- docs/lib/scripts/graph-render-worker.js | 356 --- docs/lib/scripts/graph_view.js | 913 ------ docs/lib/scripts/graph_wasm.js | 3 - docs/lib/scripts/graph_wasm.wasm | Bin 23377 -> 0 bytes docs/lib/scripts/tinycolor.js | 1863 ----------- docs/lib/scripts/webpage.js | 936 ------ docs/lib/styles/obsidian-styles.css | 2753 ----------------- docs/lib/styles/plugin-styles.css | 733 ----- docs/lib/styles/snippets.css | 1 - docs/lib/styles/theme.css | 1 - docs/management/1on1s.html | 76 - docs/management/career.html | 52 - docs/management/change-management.html | 58 - docs/management/coaching.html | 49 - docs/management/community-of-practice.html | 97 - docs/management/culture.html | 51 - docs/management/effective-meetings.html | 48 - docs/management/goals.html | 62 - docs/management/health-monitor.html | 126 - docs/management/high-performing-teams.html | 48 - docs/management/hiring.html | 50 - docs/management/interview.html | 86 - docs/management/leadership.html | 48 - docs/management/management.html | 79 - docs/management/metrics.html | 59 - docs/management/onboarding.html | 59 - docs/management/psychological-safety.html | 46 - docs/management/reports.html | 81 - docs/management/salary.html | 46 - .../software-development-strategy.html | 245 -- docs/management/ways-of-working.html | 67 - docs/management/wellbeing.html | 75 - docs/performance/general.html | 68 +- docs/security/cve.html | 60 +- docs/security/hackerone.html | 66 +- docs/security/jwt.html | 80 +- docs/security/owasp-top-10.html | 49 - docs/security/secure-code-warriors.html | 49 - docs/security/security.html | 65 +- docs/technology/ai.html | 58 +- docs/technology/architecture.html | 76 +- docs/technology/aws.html | 214 -- docs/technology/azure.html | 50 - docs/technology/coding-exercise.html | 105 - docs/technology/http-3.html | 47 - docs/technology/monorepo.html | 66 +- docs/tools/cmd.html | 62 +- docs/tools/docker-desktop.html | 107 - docs/tools/firefox.html | 54 +- docs/tools/git.html | 73 +- docs/tools/ideas.html | 54 +- docs/tools/infersharp.html | 72 +- .../microsoft-application-inspector.html | 54 - docs/tools/powershell.html | 58 +- docs/tools/redis.html | 76 +- docs/tools/slngen.html | 54 +- docs/tools/sql-server.html | 234 -- docs/tools/troubleshooting.html | 90 +- docs/tools/tye.html | 214 -- docs/tools/visual-studio.html | 127 - docs/tools/vscode.html | 68 +- docs/tools/windows-terminal.html | 68 - docs/tools/windows.html | 90 +- docs/tools/winget.html | 86 +- images/Pasted image 20240510085959.png | Bin 0 -> 8710 bytes src/{AWS KMS.org => AWS/AWS KMS.md} | 6 +- src/Email Templates/Onboarding.md | 2 +- .../.obsidian/app.json | 0 .../.obsidian/appearance.json | 0 .../.obsidian/core-plugins-migration.json | 0 .../.obsidian/core-plugins.json | 0 .../.obsidian/hotkeys.json | 0 .../.obsidian/workspace.json | 0 .../1on1s.md | 0 .../Agile.md | 0 .../Career.md | 0 .../Change Management.md | 0 .../Coaching.md | 0 .../Code Reviews.md | 0 .../Community Of Practice.md | 0 .../Culture.md | 0 .../Developer Experience.md | 0 .../Effective Meetings.md | 0 .../Engineering Management.md | 0 .../Goals.md | 0 .../Health Monitor.md | 0 .../High Performing Teams.md | 0 .../Hiring.md | 2 +- .../Incident Management.md} | 0 .../Index.md | 0 .../Interview.md | 0 .../Interviewer.md | 0 .../Leadership.md | 0 .../Manage for Better Results.md | 0 .../Metrics.md | 0 .../Onboarding.md | 0 .../Psychological Safety.md | 0 .../Reports.md | 0 .../Salary.md | 0 .../Software Development Strategy.md | 0 .../Ways of Working.md | 0 .../Wellbeing.md | 0 .../HTTP Client.md} | 27 +- .../Modernization.md} | 0 src/Index.md | 9 +- src/NuGet.org | 4 - src/RU102N Redis for .NET Developers.org | 14 - src/Tools/NuGet.md | 5 +- 243 files changed, 5317 insertions(+), 14531 deletions(-) create mode 100644 docs/APIs/GitHub API.html create mode 100644 docs/APIs/Google Calendar API.html create mode 100644 docs/APIs/JIRA API.html create mode 100644 docs/APIs/QMetry API.html create mode 100644 docs/AWS/AWS KMS.html create mode 100644 docs/Certifications/AZ-400 Designing and Implementing Microsoft DevOps Solutions.html create mode 100644 docs/Cloud/AWS/Index.html create mode 100644 docs/Cloud/AWS/Services/CloudFormation.html create mode 100644 docs/Cloud/AWS/Services/Cognito.html create mode 100644 docs/Cloud/AWS/Services/DynamoDB.html create mode 100644 docs/Cloud/AWS/Services/Lambda.html create mode 100644 docs/Cloud/AWS/Tools/AWS CLI.html create mode 100644 docs/Cloud/AWS/Tools/CDK.html create mode 100644 docs/Cloud/AWS/Tools/Lambda Tools.html create mode 100644 docs/Cloud/AWS/Tools/LocalStack.html create mode 100644 docs/Cloud/AWS/Tools/Moto.html create mode 100644 docs/Cloud/AWS/Tools/SAM CLI.html create mode 100644 docs/Cloud/Azure/Index.html create mode 100644 docs/Development/Developer Productivity.html create mode 100644 docs/Development/Development Environment Setup.html create mode 100644 docs/DotNet/CLI/dotnet list package.html create mode 100644 docs/DotNet/CLI/dotnet monitor.html create mode 100644 docs/Email Templates/Knowledge Sharing.html create mode 100644 docs/Email Templates/Onboarding.html create mode 100644 docs/Engineering Management/1on1s.html create mode 100644 docs/Engineering Management/Agile.html create mode 100644 docs/Engineering Management/Career.html create mode 100644 docs/Engineering Management/Change Management.html create mode 100644 docs/Engineering Management/Coaching.html create mode 100644 docs/Engineering Management/Code Reviews.html create mode 100644 docs/Engineering Management/Community Of Practice.html create mode 100644 docs/Engineering Management/Culture.html create mode 100644 docs/Engineering Management/Developer Experience.html create mode 100644 docs/Engineering Management/Effective Meetings.html create mode 100644 docs/Engineering Management/Engineering Management.html create mode 100644 docs/Engineering Management/Goals.html create mode 100644 docs/Engineering Management/Health Monitor.html create mode 100644 docs/Engineering Management/High Performing Teams.html create mode 100644 docs/Engineering Management/Hiring.html create mode 100644 docs/Engineering Management/Incident Management.html create mode 100644 docs/Engineering Management/Index.html create mode 100644 docs/Engineering Management/Interview.html create mode 100644 docs/Engineering Management/Interviewer.html create mode 100644 docs/Engineering Management/Leadership.html create mode 100644 docs/Engineering Management/Manage for Better Results.html create mode 100644 docs/Engineering Management/Metrics.html create mode 100644 docs/Engineering Management/Onboarding.html create mode 100644 docs/Engineering Management/Psychological Safety.html create mode 100644 docs/Engineering Management/Reports.html create mode 100644 docs/Engineering Management/Salary.html create mode 100644 docs/Engineering Management/Software Development Strategy.html create mode 100644 docs/Engineering Management/Ways of Working.html create mode 100644 docs/Engineering Management/Wellbeing.html create mode 100644 docs/FeatureManagement/Microsoft.FeatureManagement.html create mode 100644 docs/Goals/Continous Learning.html create mode 100644 docs/Goals/Continuous Improvement.html create mode 100644 docs/Goals/Knowledge Sharing.html create mode 100644 docs/How-to/Batch File.html create mode 100644 docs/How-to/Build and Run a Container with Docker.html create mode 100644 docs/How-to/Change host file on Windows.html create mode 100644 docs/How-to/Create IIS Websites.html create mode 100644 docs/How-to/Create Self-Signed Certificate.html create mode 100644 docs/How-to/Creating a permanent PowerShell Alias using Set-Alias.html create mode 100644 docs/How-to/HTTP Client.html create mode 100644 docs/How-to/Install multiple NodeJS Versions.html create mode 100644 docs/How-to/Measure Method Elapsed Time with CSharp.html create mode 100644 docs/How-to/Modernization.html create mode 100644 docs/How-to/Run a tool globally on Windows.html create mode 100644 docs/How-to/Technical Support.html create mode 100644 docs/Security/OWASP TOP 10.html create mode 100644 docs/Security/Secure Code Warriors.html create mode 100644 docs/Technology/Coding Exercise.html create mode 100644 docs/Technology/HTTP 3.html create mode 100644 docs/Testing/MsTest.html create mode 100644 docs/Testing/Playwright using .NET.html create mode 100644 docs/Testing/Playwright using TypeScript.html create mode 100644 docs/Testing/WireMockNet.html create mode 100644 docs/Tools/Docker CLI.html create mode 100644 docs/Tools/Docker Compose.html create mode 100644 docs/Tools/Docker Desktop.html create mode 100644 docs/Tools/GitHub Copilot.html create mode 100644 docs/Tools/Kubernetes.html create mode 100644 docs/Tools/Microsoft Application Inspector.html create mode 100644 docs/Tools/NuGet.html create mode 100644 docs/Tools/Nuget CLI.html create mode 100644 docs/Tools/Proxy.html create mode 100644 docs/Tools/Redash.html create mode 100644 docs/Tools/SQL Lite.html create mode 100644 docs/Tools/Slack CLI.html create mode 100644 docs/Tools/Sql Server.html create mode 100644 docs/Tools/Visual Studio.html create mode 100644 docs/Tools/Windows Terminal.html delete mode 100644 docs/development/developer-productivity.html delete mode 100644 docs/development/development-environment-setup.html delete mode 100644 docs/dotnet/cli/dotnet-list-package.html delete mode 100644 docs/dotnet/cli/dotnet-monitor.html delete mode 100644 docs/dotnet/libraries/microsoft.featuremanagement.html delete mode 100644 docs/dotnet/libraries/playwright.html delete mode 100644 docs/dotnet/libraries/wiremocknet.html delete mode 100644 docs/email-templates/knowledge-sharing.html delete mode 100644 docs/email-templates/onboarding.html delete mode 100644 docs/goals/continous-learning.html delete mode 100644 docs/goals/continuous-improvement.html delete mode 100644 docs/goals/knowledge-sharing.html delete mode 100644 docs/how-to/batch-file.html delete mode 100644 docs/how-to/change-host-file-on-windows.html delete mode 100644 docs/how-to/create-iis-websites.html delete mode 100644 docs/how-to/create-self-signed-certificate.html delete mode 100644 docs/how-to/docker.html delete mode 100644 docs/how-to/google-calendar-api.html delete mode 100644 docs/how-to/install-multiple-nodejs-versions.html delete mode 100644 docs/how-to/measure-method-elapsed-time-with-csharp.html delete mode 100644 docs/how-to/technical-support.html delete mode 100644 docs/lib/scripts/graph-render-worker.js delete mode 100644 docs/lib/scripts/graph_view.js delete mode 100644 docs/lib/scripts/graph_wasm.js delete mode 100644 docs/lib/scripts/graph_wasm.wasm delete mode 100644 docs/lib/scripts/tinycolor.js delete mode 100644 docs/lib/scripts/webpage.js delete mode 100644 docs/lib/styles/obsidian-styles.css delete mode 100644 docs/lib/styles/plugin-styles.css delete mode 100644 docs/lib/styles/snippets.css delete mode 100644 docs/lib/styles/theme.css delete mode 100644 docs/management/1on1s.html delete mode 100644 docs/management/career.html delete mode 100644 docs/management/change-management.html delete mode 100644 docs/management/coaching.html delete mode 100644 docs/management/community-of-practice.html delete mode 100644 docs/management/culture.html delete mode 100644 docs/management/effective-meetings.html delete mode 100644 docs/management/goals.html delete mode 100644 docs/management/health-monitor.html delete mode 100644 docs/management/high-performing-teams.html delete mode 100644 docs/management/hiring.html delete mode 100644 docs/management/interview.html delete mode 100644 docs/management/leadership.html delete mode 100644 docs/management/management.html delete mode 100644 docs/management/metrics.html delete mode 100644 docs/management/onboarding.html delete mode 100644 docs/management/psychological-safety.html delete mode 100644 docs/management/reports.html delete mode 100644 docs/management/salary.html delete mode 100644 docs/management/software-development-strategy.html delete mode 100644 docs/management/ways-of-working.html delete mode 100644 docs/management/wellbeing.html delete mode 100644 docs/security/owasp-top-10.html delete mode 100644 docs/security/secure-code-warriors.html delete mode 100644 docs/technology/aws.html delete mode 100644 docs/technology/azure.html delete mode 100644 docs/technology/coding-exercise.html delete mode 100644 docs/technology/http-3.html delete mode 100644 docs/tools/docker-desktop.html delete mode 100644 docs/tools/microsoft-application-inspector.html delete mode 100644 docs/tools/sql-server.html delete mode 100644 docs/tools/tye.html delete mode 100644 docs/tools/visual-studio.html delete mode 100644 docs/tools/windows-terminal.html create mode 100644 images/Pasted image 20240510085959.png rename src/{AWS KMS.org => AWS/AWS KMS.md} (89%) rename src/{Management => Engineering Management}/.obsidian/app.json (100%) rename src/{Management => Engineering Management}/.obsidian/appearance.json (100%) rename src/{Management => Engineering Management}/.obsidian/core-plugins-migration.json (100%) rename src/{Management => Engineering Management}/.obsidian/core-plugins.json (100%) rename src/{Management => Engineering Management}/.obsidian/hotkeys.json (100%) rename src/{Management => Engineering Management}/.obsidian/workspace.json (100%) rename src/{Management => Engineering Management}/1on1s.md (100%) rename src/{Management => Engineering Management}/Agile.md (100%) rename src/{Management => Engineering Management}/Career.md (100%) rename src/{Management => Engineering Management}/Change Management.md (100%) rename src/{Management => Engineering Management}/Coaching.md (100%) rename src/{Management => Engineering Management}/Code Reviews.md (100%) rename src/{Management => Engineering Management}/Community Of Practice.md (100%) rename src/{Management => Engineering Management}/Culture.md (100%) rename src/{Management => Engineering Management}/Developer Experience.md (100%) rename src/{Management => Engineering Management}/Effective Meetings.md (100%) rename src/{Management => Engineering Management}/Engineering Management.md (100%) rename src/{Management => Engineering Management}/Goals.md (100%) rename src/{Management => Engineering Management}/Health Monitor.md (100%) rename src/{Management => Engineering Management}/High Performing Teams.md (100%) rename src/{Management => Engineering Management}/Hiring.md (68%) rename src/{Incident Management.org => Engineering Management/Incident Management.md} (100%) rename src/{Management => Engineering Management}/Index.md (100%) rename src/{Management => Engineering Management}/Interview.md (100%) rename src/{Management => Engineering Management}/Interviewer.md (100%) rename src/{Management => Engineering Management}/Leadership.md (100%) rename src/{Management => Engineering Management}/Manage for Better Results.md (100%) rename src/{Management => Engineering Management}/Metrics.md (100%) rename src/{Management => Engineering Management}/Onboarding.md (100%) rename src/{Management => Engineering Management}/Psychological Safety.md (100%) rename src/{Management => Engineering Management}/Reports.md (100%) rename src/{Management => Engineering Management}/Salary.md (100%) rename src/{Management => Engineering Management}/Software Development Strategy.md (100%) rename src/{Management => Engineering Management}/Ways of Working.md (100%) rename src/{Management => Engineering Management}/Wellbeing.md (100%) rename src/{HTTP Client.org => How-to/HTTP Client.md} (52%) rename src/{Modernization.org => How-to/Modernization.md} (100%) delete mode 100644 src/NuGet.org delete mode 100644 src/RU102N Redis for .NET Developers.org diff --git a/.obsidian/plugins/webpage-html-export/data.json b/.obsidian/plugins/webpage-html-export/data.json index 19e3e3316..0a6b36e2a 100644 --- a/.obsidian/plugins/webpage-html-export/data.json +++ b/.obsidian/plugins/webpage-html-export/data.json @@ -1,7 +1,7 @@ { "settingsVersion": "1.8.01", "makeOfflineCompatible": false, - "inlineAssets": false, + "inlineAssets": true, "includePluginCSS": "", "includeSvelteCSS": true, "titleProperty": "title", @@ -16,21 +16,21 @@ "allowResizingSidebars": true, "logLevel": "warning", "minifyHTML": true, - "makeNamesWebStyle": true, + "makeNamesWebStyle": false, "onlyExportModified": true, "deleteOldFiles": true, "addThemeToggle": true, "addOutline": true, "addFileNav": true, - "addSearchBar": true, - "addGraphView": true, + "addSearchBar": false, + "addGraphView": false, "addTitle": true, "addRSSFeed": true, "siteURL": "", "authorName": "", "vaultTitle": "digital-knowledge-garden", - "exportPreset": "website", - "openAfterExport": false, + "exportPreset": "documents", + "openAfterExport": true, "graphAttractionForce": 1, "graphLinkLength": 10, "graphRepulsionForce": 150, @@ -43,8 +43,10 @@ "defaultFileIcon": "lucide//file", "defaultFolderIcon": "lucide//folder", "defaultMediaIcon": "lucide//file-image", - "exportPath": "", + "exportPath": "C:\\\\Dev\\GitHub\\workbench\\digital-knowledge-garden\\docs", "filesToExport": [ - [] + [ + "src" + ] ] } \ No newline at end of file diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index b8dcb9b3b..6a0a0d116 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -179,50 +179,92 @@ "webpage-html-export:Export Vault to HTML": false } }, - "active": "4ae7314987c01415", + "floating": { + "id": "7addaee0b30a5c83", + "type": "floating", + "children": [ + { + "id": "cf1a7974493e6c55", + "type": "window", + "children": [ + { + "id": "24d7f1cd0fd21b69", + "type": "tabs", + "children": [ + { + "id": "0bd3f57d393ff55c", + "type": "leaf", + "state": { + "type": "markdown", + "state": { + "file": "src/Index.md", + "mode": "source", + "source": false + } + } + } + ] + } + ], + "direction": "vertical", + "x": 1470, + "y": 532, + "width": 900, + "height": 500, + "maximize": false, + "zoom": 0 + } + ] + }, + "active": "0bd3f57d393ff55c", "lastOpenFiles": [ - "images/Pasted image 20240510083448.png", + "docs/src/Goals/Knowledge Sharing.html", + "docs/src/Goals/Continuous Improvement.html", + "docs/src/Goals/Quality.html", + "docs/src/Goals/Continous Learning.html", + "docs/src/Goals", + "docs/src/Frontend/CSS.html", + "docs/src/Frontend/Index.html", + "docs/src/Frontend/Angular.html", + "docs/src/Frontend", + "docs/src/FeatureManagement/Microsoft.FeatureManagement.html", + "docs/src/FeatureManagement", "src/Tools/WinGet.md", - "src/Tools/Windows Terminal.md", "src/Tools/Windows.md", "src/Tools/VSCode.md", "src/Tools/Visual Studio.md", "src/Tools/Troubleshooting.md", - "images/Pasted image 20230810091642.png", - "images/Pasted image 20230731083648.png", + "src/Tools/Sql Server.md", + "src/Tools/SQL Lite.md", + "src/Tools/Slack CLI.md", + "src/Tools/Redis.md", "src/Tools/Proxy.md", + "src/Tools/Powershell.md", + "src/Tools/Nuget CLI.md", "src/Tools/NuGet.md", - "src/Tools/Slack CLI.md", - "src/Tools/Redash.md", + "src/Tools/Microsoft Application Inspector.md", + "src/Tools/Kubernetes.md", + "src/Tools/InferSharp.md", + "src/Tools/Ideas.md", + "src/Tools/GitHub Copilot.md", + "src/Tools/Git.md", + "src/Tools/Docker Desktop.md", "src/Tools/Docker Compose.md", - "src/Tools/SQL Lite.md", - "images/learning pyramid.png", - "Untitled.canvas", - "Objectives.md", - "2024-04-16.md", - "src/Untitled.md", - "src/Untitled.canvas", - "2024-04-12.md", - "src/Management/Engineering Management.md", - "images/engineering manager framework.png", - "images/what engineering managers should do.png", - "images", - "a0a584bd-c3f4-43d1-8842-d8ccc3cd2f75_3000x2250.png", - "src/Management/Health Monitor.md", - "src/Management/Engineering Management.png", - "src/Management/Interviewer.md", - "44aedbbb-d23e-4dc9-8fa6-5391fa175bea_3000x2250.webp", - "src/Testing/Playwright using TypeScript.md", - "src/Testing/Playwright using .NET.md", - "src/Testing/MsTest.md", - "src/DotNet/MinimalAPI.md", + "src/Tools/Docker CLI.md", + "src/Tools/CMD.md", "src/Testing/WireMockNet.md", - "src/FeatureManagement/Microsoft.FeatureManagement.md", - "src/FeatureManagement", - "src/Testing", - "assets", - "books/The Startup CTO Handbook.pdf", - "books/Kubernetes Learning Path.pdf", - "books/50 Things You Need to Know to Be a Top IT Pro.pdf" + "src/Testing/Playwright using TypeScript.md", + "images/Pasted image 20240510085959.png", + "docs/lib/media/favicon.png", + "docs/lib/media/pasted-image-20240510083448.png", + "docs/lib/media/pasted-image-20230731083648.png", + "docs/lib/media/pasted-image-20230810091642.png", + "docs/lib/media/learning-pyramid.png", + "docs/lib/media/what-engineering-managers-should-do.png", + "docs/lib/media/engineering-manager-framework.png", + "images/Pasted image 20240510083448.png", + "images/Pasted image 20230810091642.png", + "Untitled.canvas", + "src/Untitled.canvas" ] } \ No newline at end of file diff --git a/docs/APIs/GitHub API.html b/docs/APIs/GitHub API.html new file mode 100644 index 000000000..ba07e89e3 --- /dev/null +++ b/docs/APIs/GitHub API.html @@ -0,0 +1,14 @@ + + GitHub API + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/APIs/Google Calendar API.html b/docs/APIs/Google Calendar API.html new file mode 100644 index 000000000..77c335300 --- /dev/null +++ b/docs/APIs/Google Calendar API.html @@ -0,0 +1,105 @@ + + Google Calendar API + + + + + + + + + + + +

Google Calendar API

API Key

    +
  1. Open Credentials on Google Cloud Console
  2. +
  3. Create Project
  4. +
  5. Click on Create Credentials -> API key
  6. +
  7. Enable Google Calendar API for the project https://console.cloud.google.com/apis/api/calendar-json.googleapis.com/overview?project=our-brand-397422
  8. +

Full List of Calendars (Country & Religious)

||\ ['Australian Holidays', 'en.australian#holiday@group.v.calendar.google.com'],|
+||\ ['Austrian Holidays', 'en.austrian#holiday@group.v.calendar.google.com'],|
+||\ ['Brazilian Holidays', 'en.brazilian#holiday@group.v.calendar.google.com'],|
+||\ ['Canadian Holidays', 'en.canadian#holiday@group.v.calendar.google.com'],|
+||\ ['China Holidays', 'en.china#holiday@group.v.calendar.google.com'],|
+||\ ['Christian Holidays', 'en.christian#holiday@group.v.calendar.google.com'],|
+||\ ['Danish Holidays', 'en.danish#holiday@group.v.calendar.google.com'],|
+||\ ['Dutch Holidays', 'en.dutch#holiday@group.v.calendar.google.com'],|
+||\ ['Finnish Holidays', 'en.finnish#holiday@group.v.calendar.google.com'],|
+||\ ['French Holidays', 'en.french#holiday@group.v.calendar.google.com'],|
+||\ ['German Holidays', 'en.german#holiday@group.v.calendar.google.com'],|
+||\ ['Greek Holidays', 'en.greek#holiday@group.v.calendar.google.com'],|
+||\ ['Hong Kong (C) Holidays', 'en.hong_kong_c#holiday@group.v.calendar.google.com'],|
+||\ ['Hong Kong Holidays', 'en.hong_kong#holiday@group.v.calendar.google.com'],|
+||\ ['Indian Holidays', 'en.indian#holiday@group.v.calendar.google.com'],|
+||\ ['Indonesian Holidays', 'en.indonesian#holiday@group.v.calendar.google.com'],|
+||\ ['Iranian Holidays', 'en.iranian#holiday@group.v.calendar.google.com'],|
+||\ ['Irish Holidays', 'en.irish#holiday@group.v.calendar.google.com'],|
+||\ ['Islamic Holidays', 'en.islamic#holiday@group.v.calendar.google.com'],|
+||\ ['Italian Holidays', 'en.italian#holiday@group.v.calendar.google.com'],|
+||\ ['Japanese Holidays', 'en.japanese#holiday@group.v.calendar.google.com'],|
+||\ ['Jewish Holidays', 'en.jewish#holiday@group.v.calendar.google.com'],|
+||\ ['Malaysian Holidays', 'en.malaysia#holiday@group.v.calendar.google.com'],|
+||\ ['Mexican Holidays', 'en.mexican#holiday@group.v.calendar.google.com'],|
+||\ ['New Zealand Holidays', 'en.new_zealand#holiday@group.v.calendar.google.com'],|
+||\ ['Norwegian Holidays', 'en.norwegian#holiday@group.v.calendar.google.com'],|
+||\ ['Philippines Holidays', 'en.philippines#holiday@group.v.calendar.google.com'],|
+||\ ['Polish Holidays', 'en.polish#holiday@group.v.calendar.google.com'],|
+||\ ['Portuguese Holidays', 'en.portuguese#holiday@group.v.calendar.google.com'],|
+||\ ['Russian Holidays', 'en.russian#holiday@group.v.calendar.google.com'],|
+||\ ['Singapore Holidays', 'en.singapore#holiday@group.v.calendar.google.com'],|
+||\ ['South Africa Holidays', 'en.sa#holiday@group.v.calendar.google.com'],|
+||\ ['South Korean Holidays', 'en.south_korea#holiday@group.v.calendar.google.com'],|
+||\ ['Spain Holidays', 'en.spain#holiday@group.v.calendar.google.com'],|
+||\ ['Swedish Holidays', 'en.swedish#holiday@group.v.calendar.google.com'],|
+||\ ['Taiwan Holidays', 'en.taiwan#holiday@group.v.calendar.google.com'],|
+||\ ['Thai Holidays', 'en.thai#holiday@group.v.calendar.google.com'],|
+||\ ['UK Holidays', 'en.uk#holiday@group.v.calendar.google.com'],|
+||\ ['US Holidays', 'en.usa#holiday@group.v.calendar.google.com'],|
+||\ ['Vietnamese Holidays', 'en.vietnamese#holiday@group.v.calendar.google.com'],|
+||\ ['アイルランドの祝日', 'ja.irish#holiday@group.v.calendar.google.com'],|
+||\ ['アメリカの祝日', 'ja.usa#holiday@group.v.calendar.google.com'],|
+||\ ['イギリスの祝日', 'ja.uk#holiday@group.v.calendar.google.com'],|
+||\ ['イスラム教の祝日', 'ja.islamic#holiday@group.v.calendar.google.com'],|
+||\ ['イタリアの祝日', 'ja.italian#holiday@group.v.calendar.google.com'],|
+||\ ['インドの祝日', 'ja.indian#holiday@group.v.calendar.google.com'],|
+||\ ['インドネシアの祝日', 'ja.indonesian#holiday@group.v.calendar.google.com'],|
+||\ ['オランダの祝日', 'ja.dutch#holiday@group.v.calendar.google.com'],|
+||\ ['オーストラリアの祝日', 'ja.australian#holiday@group.v.calendar.google.com'],|
+||\ ['オーストリアの祝日', 'ja.austrian#holiday@group.v.calendar.google.com'],|
+||\ ['カナダの祝日', 'ja.canadian#holiday@group.v.calendar.google.com'],|
+||\ ['キリスト教の祝日', 'ja.christian#holiday@group.v.calendar.google.com'],|
+||\ ['ギリシャの祝日', 'ja.greek#holiday@group.v.calendar.google.com'],|
+||\ ['シンガポールの祝日', 'ja.singapore#holiday@group.v.calendar.google.com'],|
+||\ ['スウェーデンの祝日', 'ja.swedish#holiday@group.v.calendar.google.com'],|
+||\ ['スペインの祝日', 'ja.spain#holiday@group.v.calendar.google.com'],|
+||\ ['タイの祝日', 'ja.thai#holiday@group.v.calendar.google.com'],|
+||\ ['デンマークの祝日', 'ja.danish#holiday@group.v.calendar.google.com'],|
+||\ ['ドイツの祝日', 'ja.german#holiday@group.v.calendar.google.com'],|
+||\ ['ニュージーランドの祝日', 'ja.new_zealand#holiday@group.v.calendar.google.com'],|
+||\ ['ノルウェイの祝日', 'ja.norwegian#holiday@group.v.calendar.google.com'],|
+||\ ['フィリピンの祝日', 'ja.philippines#holiday@group.v.calendar.google.com'],|
+||\ ['フィンランドの祝日', 'ja.finnish#holiday@group.v.calendar.google.com'],|
+||\ ['フランスの祝日', 'ja.french#holiday@group.v.calendar.google.com'],|
+||\ ['ブラジルの祝日', 'ja.brazilian#holiday@group.v.calendar.google.com'],|
+||\ ['ベトナムの祝日', 'ja.vietnamese#holiday@group.v.calendar.google.com'],|
+||\ ['ポルトガルの祝日', 'ja.portuguese#holiday@group.v.calendar.google.com'],|
+||\ ['ポーランドの祝日', 'ja.polish#holiday@group.v.calendar.google.com'],|
+||\ ['マレーシアの祝日', 'ja.malaysia#holiday@group.v.calendar.google.com'],|
+||\ ['メキシコの祝日', 'ja.mexican#holiday@group.v.calendar.google.com'],|
+||\ ['ユダヤ教の祝日', 'ja.jewish#holiday@group.v.calendar.google.com'],|
+||\ ['ロシアの祝日', 'ja.russian#holiday@group.v.calendar.google.com'],|
+||\ ['中国の祝日', 'ja.china#holiday@group.v.calendar.google.com'],|
+||\ ['韓国の祝日', 'ja.south_korea#holiday@group.v.calendar.google.com'],|
+||\ ['南アフリカの祝日', 'ja.sa#holiday@group.v.calendar.google.com'],|
+||\ ['台湾の祝日', 'ja.taiwan#holiday@group.v.calendar.google.com'],|
+||\ ['日本の祝日', 'ja.japanese#holiday@group.v.calendar.google.com'],|
+||\ ['香港(C)の祝日', 'ja.hong_kong_c#holiday@group.v.calendar.google.com'],|
+||\ ['香港の祝日', 'ja.hong_kong#holiday@group.v.calendar.google.com'],|
+||\ ]|

\ No newline at end of file diff --git a/docs/APIs/JIRA API.html b/docs/APIs/JIRA API.html new file mode 100644 index 000000000..f846f820a --- /dev/null +++ b/docs/APIs/JIRA API.html @@ -0,0 +1,14 @@ + + JIRA API + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/APIs/QMetry API.html b/docs/APIs/QMetry API.html new file mode 100644 index 000000000..da5346338 --- /dev/null +++ b/docs/APIs/QMetry API.html @@ -0,0 +1,14 @@ + + QMetry API + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/AWS/AWS KMS.html b/docs/AWS/AWS KMS.html new file mode 100644 index 000000000..ae1678b1e --- /dev/null +++ b/docs/AWS/AWS KMS.html @@ -0,0 +1,18 @@ + + AWS KMS + + + + + + + + + + + +

AWS KMS

    +
  • aws --endpoint-url=http://localhost:52002 kms --region ap-southeast-2 create-key --key-spec RSA_2048 --key-usage SIGN_VERIFY
  • +
  • aws --endpoint-url=http://localhost:52002 kms --region ap-southeast-2 list-keys
  • +
  • aws --endpoint-url=http://localhost:52002 kms --region ap-southeast-2 get-public-key --key-id 6732c7ca-6ec9-4b96-9711-fd1c7d637c8e
  • +
\ No newline at end of file diff --git a/docs/Certifications/AZ-400 Designing and Implementing Microsoft DevOps Solutions.html b/docs/Certifications/AZ-400 Designing and Implementing Microsoft DevOps Solutions.html new file mode 100644 index 000000000..a84025f2d --- /dev/null +++ b/docs/Certifications/AZ-400 Designing and Implementing Microsoft DevOps Solutions.html @@ -0,0 +1,15 @@ + + AZ-400 Designing and Implementing Microsoft DevOps Solutions + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Cloud/AWS/Index.html b/docs/Cloud/AWS/Index.html new file mode 100644 index 000000000..7184bcc58 --- /dev/null +++ b/docs/Cloud/AWS/Index.html @@ -0,0 +1,88 @@ + + Index + + + + + + + + + + + +

Index

Tools

Installation

    +
  • +

    winget install -e --id Amazon.AWSCLI

    +
  • +
  • +

    winget install -e --id Amazon.SAM-CLI

    +
  • +
  • +

    winget install -e --id Amazon.NoSQLWorkbench

    +
  • +
  • +

    npm install -g aws-cdk

    +
  • +
  • +

    dotnet tool install -g Amazon.Lambda.Tools

    +
  • +
  • +

    npm install -g aws-cdk-local aws-cdk (ECR is a PRO feature https://github.com/localstack/localstack/issues/5382)

    +
  • +
  • +

    AWS Application Composer

    +

    Upgrade

    +
  • +
  • +

    winget upgrade -e --id Amazon.SAM-CLI

    +
  • +
  • +

    sam --version

    +
  • +
  • +

    winget upgrade -e --id Amazon.AWSCLI

    +
  • +
  • +

    aws --version

    +
  • +
  • +

    npm upgrade -g aws-cdk

    +
  • +
  • +

    cdk --version

    +
  • +
  • +

    dotnet tool update -g Amazon.Lambda.Tools

    +
  • +

Credentials

    +
  1. Run aws configure
  2. +
  3. AWS Access Key ID: test
  4. +
  5. AWS Secret Access Key: test
  6. +
  7. Default region name: ap-southeast-2
  8. +
  9. Default output format: json
  10. +
  11. Run aws configure list to verify the newly configured credentials (stored in C:\Users\{USER}\.aws\credentials)
  12. +
\ No newline at end of file diff --git a/docs/Cloud/AWS/Services/CloudFormation.html b/docs/Cloud/AWS/Services/CloudFormation.html new file mode 100644 index 000000000..6db316418 --- /dev/null +++ b/docs/Cloud/AWS/Services/CloudFormation.html @@ -0,0 +1,21 @@ + + CloudFormation + + + + + + + + + + + +

CloudFormation

Commands

    +
  • awslocal lambda list-functions
  • +
  • awslocal lambda invoke --function-name helloLambda --cli-binary-format raw-in-base64-out response.json --log-type Tail
  • +
  • awslocal lambda delete-function --function-name helloLambda
  • +
  • awslocal apigatewayv2 get-apis
  • +
\ No newline at end of file diff --git a/docs/Cloud/AWS/Services/Cognito.html b/docs/Cloud/AWS/Services/Cognito.html new file mode 100644 index 000000000..549773c0e --- /dev/null +++ b/docs/Cloud/AWS/Services/Cognito.html @@ -0,0 +1,37 @@ + + Cognito + + + + + + + + + + + +

Cognito

Tags: #Cognito

Execute POST http://localhost:52009/moto-api/seed?a=42 to ensure the resulting state will always be the same.

aws --endpoint-url=http://localhost:52009 cognito-idp create-user-pool --pool-name "LocalDev"
+
+aws --endpoint-url=http://localhost:52009 cognito-idp create-user-pool-client --user-pool-id "ap-southeast-2_2ee240fa04d40b5bbea96b2b752cb0b26dc4366b8" --client-name msnotification --generate-secret
+
+aws --endpoint-url=http://localhost:52009 cognito-idp admin-create-user --user-pool-id "ap-southeast-2_2ee240fa04d40b5bbea96b2b752cb0b26dc4366b8" --username "testuser"
+
+aws --endpoint-url=http://localhost:52009 cognito-idp admin-set-user-password --user-pool-id "ap-southeast-2_2ee240fa04d40b5bbea96b2b752cb0b26dc4366b8" --username "testuser" --password "L0c4lD3v!!!" --permanent
+
+aws --endpoint-url=http://localhost:52009 cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --auth-parameters USERNAME=testuser,PASSWORD=L0c4lD3v!!! --client-id 71hfe86y5r215dew1zcyqesh0a --region ap-southeast-2
+

Troubleshoot

aws --endpoint-url=http://localhost:52009 cognito-idp list-user-pools --max-results 20
+
+aws --endpoint-url=http://localhost:52009 cognito-idp list-user-pool-clients --user-pool-id ap-southeast-2_2ee240fa04d40b5bbea96b2b752cb0b26dc4366b8
+

To Review

Commands

    +
  • aws --endpoint-url=http://localhost:9229 cognito-idp create-user-pool-client --user-pool-id "user-pool-test" --client-name "client-test2222" --generate-secret --allowed-o-auth-flows client_credentials --explicit-auth-flows "ALLOW_USER_PASSWORD_AUTH" --allowed-o-auth-flows-user-pool-client --allowed-o-auth-flows-user-pool-client --allowed-o-auth-flows "code" "implicit" --allowed-o-auth-scopes "openid" --callback-urls "["https://example.com"]" --supported-identity-providers "["MySAMLIdP", "LoginWithAmazon"]"
  • +
  • aws --endpoint-url=http://localhost:9229 cognito-idp list-user-pool-clients --user-pool-id "user-pool-test"
  • +
  • aws --endpoint-url=http://localhost:9229 cognito-idp admin-create-user --user-pool-id "user-pool-test" --username "testuser" --temporary-password "testpassword" --user-attributes Name=email,Value=testuser@humanforce.com Name=phone_number,Value="+61455587898"
  • +
  • aws --endpoint-url=http://localhost:9229 cognito-idp admin-set-user-password --user-pool-id "user-pool-test" --username testuser --password "testpassword"--permanent
  • +
  • aws --endpoint-url=http://localhost:9229 cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --auth-parameters USERNAME=testuser,PASSWORD=testpassword --client-id 2xtkp25fbng4z7hquw2p44mzx
  • +
\ No newline at end of file diff --git a/docs/Cloud/AWS/Services/DynamoDB.html b/docs/Cloud/AWS/Services/DynamoDB.html new file mode 100644 index 000000000..7f8b06a7a --- /dev/null +++ b/docs/Cloud/AWS/Services/DynamoDB.html @@ -0,0 +1,27 @@ + + DynamoDB + + + + + + + + + + + +

DynamoDB

AWS CLI

    +
  • aws --endpoint-url=http://localhost:4566 dynamodb list-tables
  • +
  • aws --endpoint-url=http://localhost:4566 dynamodb create-table --table-name DEV_Settings_TEMP22 --attribute-definitions AttributeName=InstanceId,AttributeType=S AttributeName=SettingA,AttributeType=N --key-schema AttributeName=InstanceId,KeyType=HASH AttributeName=SettingA,KeyType=RANGE --billing-mode PAY_PER_REQUEST
  • +

NoSQL Workbench

    +
  1. Open NoSQL Workbench
  2. +
  3. Add Connection
  4. +
  5. Click "DynamoDB Local"
  6. +
  7. Hostname: localhost | Port: 8000
  8. +

Documentation

\ No newline at end of file diff --git a/docs/Cloud/AWS/Services/Lambda.html b/docs/Cloud/AWS/Services/Lambda.html new file mode 100644 index 000000000..d9ef7bef0 --- /dev/null +++ b/docs/Cloud/AWS/Services/Lambda.html @@ -0,0 +1,56 @@ + + Lambda + + + + + + + + + + + +

Lambda

    +
  • dotnet new lambda.EmptyFunction --help
  • +

Create Lambda Function

    +
  • Install DotNet Lambda templates dotnet new -i Amazon.Lambda.Templates
  • +
  • Install dotnet tool install -g Amazon.Lambda.Tools
  • +
  • List templates dotnet new --list
  • +
  • Run dotnet new serverless.AspNetCoreMinimalAPI --name MinimalApi
  • +
  • dotnet build
  • +
  • dotnet publish -c Release -o publish p:PublishReadyToRun=false
  • +
  • zip content of the .\publish\ folder (function.zip)
  • +

Create Deployment Package

    +
  1. Create Cdk folder and run cdk init app --language=csharp
  2. +
  3. configure deployment settings (CdkStack.cs)
  4. +
// The code that defines your stack goes here
+var lambda = new Function(this, "MinimalApiNet6", new FunctionProps
+{
+  Runtime = Runtime.DOTNET_6,
+  Code = Code.FromAsset("../MinimalApi/bin/Debug/net6.0"),
+  Handler = "MinimalApi",
+  FunctionName = "minimalApiNet6"
+});
+
+var api = new LambdaRestApi(this, "APIGatewayNet6", new LambdaRestApiProps
+{
+  RestApiName = "APIGatewayNet6",
+  Description = "A simple Minimal API with .NET 6",
+  Handler = lambda
+}); 
+
    +
  1. Emit the synthesized CloudFormation template cdk synth
  2. +

Test with LocalStack

    +
  1. Add Environment Variable EDGE_PORT=52005 (custom LocalStack port number)
  2. +
  3. cdklocal init app --language=csharp
  4. +
  5. Change Stack.cs file
  6. +
  7. cdklocal synth -v (this must be run where the cdk.json file is located. It creates the cdk.out folder)
  8. +
  9. cdklocal bootstrap --profile default (if you get "Unable to resolve AWS account to use." make sure the localstack service is running http://localhost:4566/health)
  10. +
  11. cdklocal deploy -v
  12. +
  13. Test endpoint using Postmanimage
  14. +

Documentation

\ No newline at end of file diff --git a/docs/Cloud/AWS/Tools/AWS CLI.html b/docs/Cloud/AWS/Tools/AWS CLI.html new file mode 100644 index 000000000..8b37dcd15 --- /dev/null +++ b/docs/Cloud/AWS/Tools/AWS CLI.html @@ -0,0 +1,22 @@ + + AWS CLI + + + + + + + + + + + +

AWS CLI

Commands

    +
  • aws --endpoint-url=http://localhost:4566 dynamodb create-table --table-name ServiceName_Setting --attribute-definitions AttributeName=TenantId,AttributeType=S --key-schema AttributeName=TenantId,KeyType=HASH --billing-mode PAY_PER_REQUEST
  • +
  • aws --endpoint-url=http://localhost:4566 sqs create-queue --queue-name sample-queue2
  • +
  • aws --endpoint-url=http://localhost:4566 kms --region ap-southeast-2 create-key --tags TagKey=Purpose,TagValue=Test --description "Development test key"
  • +
  • aws --endpoint-url=http://localhost:4566 kms encrypt --region ap-southeast-2 --key-id 1cc95196-acb1-4279-9063-a3daa3d9a20d --plaintext fileb://C:\TEMP\connectionstring.txt
  • +

Documentation

\ No newline at end of file diff --git a/docs/Cloud/AWS/Tools/CDK.html b/docs/Cloud/AWS/Tools/CDK.html new file mode 100644 index 000000000..da9dc30e8 --- /dev/null +++ b/docs/Cloud/AWS/Tools/CDK.html @@ -0,0 +1,26 @@ + + CDK + + + + + + + + + + + +

CDK

AWS CDK

Commands

    +
  • mkdir CDK
  • +
  • CD CDK
  • +
  • cdk init app --language csharp
  • +
  • dotnet build src compile this app
  • +
  • cdk deploy deploy this stack to your default AWS account/region
  • +
  • cdk diff compare deployed stack with current state
  • +
  • cdk synth emits the synthesized CloudFormation template
  • +

The cdk.json file tells the CDK Toolkit how to execute your app.


Documentation

\ No newline at end of file diff --git a/docs/Cloud/AWS/Tools/Lambda Tools.html b/docs/Cloud/AWS/Tools/Lambda Tools.html new file mode 100644 index 000000000..2914dae54 --- /dev/null +++ b/docs/Cloud/AWS/Tools/Lambda Tools.html @@ -0,0 +1,21 @@ + + Lambda Tools + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Cloud/AWS/Tools/LocalStack.html b/docs/Cloud/AWS/Tools/LocalStack.html new file mode 100644 index 000000000..7d3da833f --- /dev/null +++ b/docs/Cloud/AWS/Tools/LocalStack.html @@ -0,0 +1,37 @@ + + LocalStack + + + + + + + + + + + +

LocalStack

Installation

    +
  1. Run winget install -e --id Python.Python.3
  2. +
  3. Install pip py -m ensurepip --upgrade
  4. +
  5. Install Docker winget install -e --id Docker.DockerDesktop
  6. +
  7. Go to -> "start" and type "Manage App Execution Aliases". Go to it and turn off "Python"
  8. +
  9. Install LocalStack Cockpit
  10. +
  11. Install localstack-cli pip install localstack and check version `localstack --version``
  12. +
  13. Browse http://localhost:4566/ and http://localhost:4566/health to test the setup
  14. +

Usage: aws --endpoint-url=http://localhost:4566 sqs create-queue --queue-name myQueue

Documentation

Environment Variables

AWS_DEFAULT_REGION=ap-southeast-2
+SERVICES=s3,sns,kms,sqs,lambda,dynamodb,iam,serverless,ecr,sts,ssm,logs
+DYNAMODB_SHARE_DB=1
+PERSIST_ALL=1
+USE_SINGLE_REGION=true
+LAMBDA_EXECUTOR=docker
+LAMBDA_REMOTE_DOCKER=true
+LAMBDA_REMOVE_CONTAINERS=true
+DEBUG=1
+DATA_DIR=/tmp/localstack/data
+LOCALSTACK_HOSTNAME=localhost
+LOCALSTACK_API_KEY=[Insert PRO Version Key]
+
\ No newline at end of file diff --git a/docs/Cloud/AWS/Tools/Moto.html b/docs/Cloud/AWS/Tools/Moto.html new file mode 100644 index 000000000..cf5c5036f --- /dev/null +++ b/docs/Cloud/AWS/Tools/Moto.html @@ -0,0 +1,19 @@ + + Moto + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Cloud/AWS/Tools/SAM CLI.html b/docs/Cloud/AWS/Tools/SAM CLI.html new file mode 100644 index 000000000..729c420e1 --- /dev/null +++ b/docs/Cloud/AWS/Tools/SAM CLI.html @@ -0,0 +1,21 @@ + + SAM CLI + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Cloud/Azure/Index.html b/docs/Cloud/Azure/Index.html new file mode 100644 index 000000000..dc8a72933 --- /dev/null +++ b/docs/Cloud/Azure/Index.html @@ -0,0 +1,18 @@ + + Index + + + + + + + + + + + +

Index

    +
  • +

    Tools

    +
  • +

winget install -e --id Microsoft.AzureCLI

\ No newline at end of file diff --git a/docs/Development/Developer Productivity.html b/docs/Development/Developer Productivity.html new file mode 100644 index 000000000..640b0b4d7 --- /dev/null +++ b/docs/Development/Developer Productivity.html @@ -0,0 +1,19 @@ + + Developer Productivity + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Development/Development Environment Setup.html b/docs/Development/Development Environment Setup.html new file mode 100644 index 000000000..f8e2e1afd --- /dev/null +++ b/docs/Development/Development Environment Setup.html @@ -0,0 +1,84 @@ + + Development Environment Setup + + + + + + + + + + + +

Development Environment Setup

Essentials

Using a WinGet Configuration file, you can consolidate manual machine setup and project onboarding to a single command that is reliable and repeatable.

| :memo: | TODO: Migrate this to Winget Configuration |

Browsers

winget install -e --id Microsoft.Edge.Dev
+winget install -e --id BraveSoftware.BraveBrowser
+winget install -e --id Microsoft.Edge
+winget install -e --id Google.Chrome.Dev
+winget install -e --id Mozilla.Firefox.DeveloperEdition
+winget install -e --id Opera.Opera
+

Dev Tools

https://learn.microsoft.com/en-nz/azure/developer/dev-tunnels/
+winget install -e --id Microsoft.NuGet
+winget install -e --id Postman.Postman
+winget install -e --id Docker.DockerDesktop
+winget install -e --id Datalust.Seq
+winget install -e --id Microsoft.DeploymentToolkit
+winget install -e --id Microsoft.webpicmd
+winget install --name RedisInsight
+winget install -e --id Microsoft.PowerAutomateDesktop
+winget install -e --id Gauge.Gauge
+

Development Utilities

dotnet tool install -g Microsoft.Tye --version "0.11.0-alpha.22111.1"
+winget install -e --id Dapr.CLI --silent
+winget install -e --id Microsoft.RemoteDesktopClient
+winget install -e --id ScooterSoftware.BeyondCompare4
+winget install -e --id LINQPad.LINQPad.7
+winget install -e --id Microsoft.XMLNotepad
+winget install -e --id Notepad++.Notepad++
+winget install -e --id WinMerge.WinMerge
+winget install -e --name Sysinternals
+winget install -e --id Microsoft.WindowsTerminal
+winget install -e --id Telerik.Fiddler.Everywhere
+winget install -e --id WiresharkFoundation.Wireshark
+winget install -e --id=Amazon.NoSQLWorkbench 
+winget install DevToys
+

Misc

winget install "Files App"
+winget install -e --id 7zip.7zip
+winget install -e --id Microsoft.PowerToys
+winget install -e --id VideoLAN.VLC
+winget install -e --id ShareX.ShareX
+winget install -e --id Grammarly.ForOffice
+winget install -e --id Grammarly.ForWindows
+winget install -e --id OBSProject.OBSStudio
+winget install -e --id JGraph.Draw
+winget install -e --id GIMP.GIMP
+winget install -e --id JAMSoftware.TreeSize.Free
+winget install -e --id Logseq.Logseq
+winget install -e --id Twilio.Authy
+
\ No newline at end of file diff --git a/docs/DotNet/CLI/dotnet list package.html b/docs/DotNet/CLI/dotnet list package.html new file mode 100644 index 000000000..5b5d7aef7 --- /dev/null +++ b/docs/DotNet/CLI/dotnet list package.html @@ -0,0 +1,25 @@ + + dotnet list package + + + + + + + + + + + +

Parameters

    +
  • +

    dotnet list package command in the .NET Core CLI tools to fetch installed packages for a given solution or project. Use it like so from the Windows command line:

    +

    dotnet list "C:\Source\MySolution\MySolution.sln" package

    +

    It works on both .NET Framework and .NET Core projects.

    +

    Note: For this command to work, the solution must use the new NuGet PackageReference format for referencing NuGet packages.

    +

    Migration is as easy as right-clicking packages.config, and clicking Migrate packages.config to PackageReference..., then restoring packages by building the solution.

    +
  • +
\ No newline at end of file diff --git a/docs/DotNet/CLI/dotnet monitor.html b/docs/DotNet/CLI/dotnet monitor.html new file mode 100644 index 000000000..9766ca4bb --- /dev/null +++ b/docs/DotNet/CLI/dotnet monitor.html @@ -0,0 +1,16 @@ + + dotnet monitor + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Email Templates/Knowledge Sharing.html b/docs/Email Templates/Knowledge Sharing.html new file mode 100644 index 000000000..d3f2ffd99 --- /dev/null +++ b/docs/Email Templates/Knowledge Sharing.html @@ -0,0 +1,37 @@ + + Knowledge Sharing + + + + + + + + + + + +

Email 1 (2 weeks prior to launch)

Hi team,

I’m excited to share that we’re giving each of you access to Stack Overflow for Teams, a secure and private place for you to share and find knowledge related to our technology and company. Instead of getting pinged through chat or email for information causing distractions, we’ll be able to work more asynchronously by storing our team knowledge in one central location for any of us to access at any time.

To help you get familiar, you can watch the following short videos:

How to ask and answer a question

How to write an Article

How to create a Collection

You can also check out this user guide on how to use Stack Overflow for Teams.

We’ll be releasing this company-wide on ___ so be on the lookout for an invite!

In the meantime, start thinking about the most common questions you get asked - we’ll be asking you to transfer that knowledge into our brand new Stack Overflow for Team when we launch. More to come about this exciting addition to our tools tech stack!

Please let me know if you have any questions.

Email 2 (1 week prior to launch)

Hi there,

As I’ve mentioned, we’re counting down the days to launch for Stack Overflow for Teams, and I’m asking you to take 30 minutes between now and then to gather some of the most frequently asked questions that you hear on chat or in email and jot them down. These questions might sound like:

How do I find...?

What is the process for…?

Who is responsible for... ?

Does anyone know about…?

Does anyone know where…?

When we launch next week, I’ll be asking you to share those questions - and the answers in our Team to get us started.

Thanks!

Email 3 (Launch Day)

Hi there,

Each of you should have just received an invite to Stack Overflow for Teams / Each of you now has access to our own Stack Overflow for Teams.

As requested, please take some time today to ask and answer a question. Here’s how to do that:

Start a new question draft
+
+Use the question as the title
+
+Draft the question in total in the body
+
+Click “Answer my own question” at the bottom of the page
+
+Include your answer
+
+Hit save
+

What if my question has already been asked/answered?

When you type your question in the title bar, you will see if any other related questions have been asked. If you notice this, click on the question that is populated and check to see if it has been answered. If not, please do so! Notice that you could add more context? Go ahead and add that!

What if I don’t know of any common questions?

There are bound to be at least a few questions that our chat channels or you personally get asked on a somewhat regular basis. Check back through your chat and email messages if you’re struggling to come up with something.

What else can I do within Teams?

Have a question that you don’t know the answer to? Write it up, and let’s get you some answers!
+
+Upvote good questions and answers and use emojis to show your enthusiasm. 
+
+Create an Article. Longer-form content like project documentation, how-to guides, etc. can live in our Team, too - just copy and paste something that you already know exists, and everyone else will be able to access it.
+

Email 4 (2 days post-launch)

Hi team,

Congrats! We’ve managed to ask _ questions, provide ___ answers, and write ____ Articles. This is just the beginning - and we’re already off to a great start!

What can you do next to make sure that our knowledge community thrives?

Make sure that you are asking questions in our Team.
+
+Follow and create tags to stay on top of new information.
+
+When you see someone asking questions in Slack/Microsoft Teams, use the integration to suggest that they ask the question in our Team instead.
+
+Continue to transport documents into Articles.
+

I’ll continue to keep you all updated on how our Team is growing on a regular basis, and in the meantime, if you have any questions, please feel free to contact me.

Thank you!

\ No newline at end of file diff --git a/docs/Email Templates/Onboarding.html b/docs/Email Templates/Onboarding.html new file mode 100644 index 000000000..ae94fda3d --- /dev/null +++ b/docs/Email Templates/Onboarding.html @@ -0,0 +1,139 @@ + + Onboarding + + + + + + + + + + + +

Onboarding

    +
  • +

    src/Engineering Management/Onboarding Templates

    +
  • +
  • +
  • +

    Before Starting

    +
  • +
  • +

    Hi [new team member],

    +
  • +
  • +

    I wanted to take a moment to welcome you to our team and to confirm your start date of Monday. We are glad to have you on board and we hope that you will find this to be a positive and productive experience.

    +
  • +
  • +

    I am confident that your skills and experience will be a valuable addition to our group, and I look forward to working with you. If you have any questions or concerns leading up to your start date, please don't hesitate to reach out. I am here to help make your transition as smooth as possible.

    +
  • +
  • +

    Best,
    +[Your Name]

    +
  • +
  • +
  • +

    Day 1

    +
  • +
  • +

    Hi [new team member],

    +

    Welcome to your first day on the team! I'm excited to have you here and I'm looking forward to getting to know you better.

    +

    To help you get started, here are a few things you'll need to know:

    +
  • +
  • +

    Your computer login is [username] and your temporary password is [password]. Please make sure to change your password as soon as you can.

    +
  • +
  • +

    Our team typically starts the day at 9:00 AM, with a stand-up meeting at 9:30 AM. This is a short meeting where everyone shares what they're working on for the day.

    +
  • +
  • +

    Your team leader is [team leader name] and they will be your primary point of contact. Feel free to reach out to them with any questions you have.

    +
  • +
  • +

    We have a slack channel for the team where we communicate throughout the day. Make sure to join and introduce yourself to the team!

    +
  • +
  • +

    I have put together an onboarding plan for your first few weeks with us to help you get up to speed.

    +
  • +
  • +
  • +

    Again, welcome to the team! I'm looking forward to working with you.

    +

    Best,
    +[Your Name]

    +
  • +
  • +
  • +

    Introducing a new team member

    +
  • +
  • +
  • +

    Hi team,

    +
  • +
  • +

    I am excited to introduce [new team member] who will be joining us on the team! [New team member] brings with them a wealth of experience in [industry/area of expertise] and I have no doubt that they will be a valuable asset to our group.

    +
  • +
  • +

    Please join me in welcoming [new team member] to the team. I know that they are looking forward to getting to know everyone and getting started on their new role.

    +
  • +
  • +

    Best,
    +[Your Name]

    +
  • +
  • +
  • +

    Starting a Community Of Practice

    +
  • +
  • +
  • +

    Dear [Colleagues],

    +

    I hope this email finds you well. I wanted to reach out to you about an idea I have been thinking about for a while - starting a community of practice (CoP) centered around [focus of CoP].

    +

    I believe that this CoP has the potential to bring together a group of individuals who are passionate about [focus of CoP] and provide a space for us to share our knowledge and experiences, collaborate on projects, and support each other in our professional development.

    +

    I envision the CoP meeting [frequency] and hosting events or activities that facilitate learning and collaboration. Some potential benefits of participating in the CoP include:

    +
  • +
  • +

    Staying up-to-date on the latest developments in [focus of CoP]

    +
  • +
  • +

    Connecting with like-minded professionals

    +
  • +
  • +

    Sharing best practices and ideas

    +
  • +
  • +

    Collaborating on projects and initiatives

    +
  • +
  • +

    Providing support and guidance to one another

    +

    I would love to hear your thoughts on this idea and whether you might be interested in joining the CoP. Please let me know if you have any questions or if there is anything else I can provide to help convince you of the value of this opportunity.

    +

    Thank you for considering this request.

    +

    Best,
    +[Your Name]

    +
  • +
  • +
  • +

    CoP Invite

    +
  • +
  • +
  • +

    Dear [CoP Members],

    +

    I hope this email finds you well. I am writing to invite you to the next meeting of our community of practice (CoP) focused on [focus of CoP].

    +

    The meeting will take place on [date] at [time] and will be held via [online platform or in-person location]. The agenda for the meeting is as follows:

    +
  • +
  • +

    [Agenda item 1]

    +
  • +
  • +

    [Agenda item 2]

    +
  • +
  • +

    [Agenda item 3]

    +
  • +
  • +

    [etc.]

    +

    I encourage you to come prepared to share any updates, ideas, or successes related to [focus of CoP] and to actively participate in the discussion.

    +

    I look forward to seeing you at the meeting and continuing to collaborate as a community.

    +

    Best,
    +[Your Name]

    +
  • +
\ No newline at end of file diff --git a/docs/Engineering Management/1on1s.html b/docs/Engineering Management/1on1s.html new file mode 100644 index 000000000..138733c06 --- /dev/null +++ b/docs/Engineering Management/1on1s.html @@ -0,0 +1,44 @@ + + 1on1s + + + + + + + + + + + +

1on1s

Performance

    +
  1. What was your biggest highlight or proudest achievement in the past 6 months?
  2. +
  3. What were the main objectives that you wanted to accomplish?
  4. +
  5. Do you feel recognised for your good work?
  6. +
  7. Do you feel like you are using your strengths to their best abilities in your role?
  8. +
  9. Is there anything you’ve worked on that you don’t like doing?
  10. +
  11. How do you feel about communication within the team? Are there any areas or processes you think can be improved on?
  12. +

Roadblocks and challenges

    +
  1. What was your greatest challenge or concern in the past 6 months?
  2. +
  3. Do you think it was resolved to your satisfaction, or can more be done?
  4. +
  5. What did you learn from overcoming the challenge(s)?
  6. +
  7. Do you feel like you have enough resources to support you in your role?
  8. +
  9. Do you anticipate any upcoming challenges in the next 6 months?
  10. +

Happiness

    +
  1. What is your current Happiness Score between 0-10, and why?
  2. +
  3. Is there anything that is making you feel frustrated or upset in your role?
  4. +
  5. How has your work/life balance been, and are you seeking any additional support in this area?
  6. +

Learning and development

    +
  1. Is there anything you’d like to work on that you’re not currently doing?
  2. +
  3. What’s one new skill you’d like to improve on over the next 6 months?
  4. +
  5. Are you satisfied with the current upskill opportunities provided, or do you have a specific course in mind that’s not currently available to you?
  6. +

Management

    +
  1. What can I do as your manager to support you in achieving your goals?
  2. +
  3. Do you think I’ve been responsive and helpful enough to your questions and requests?
  4. +
  5. Do you like my management style? If not, what management style do you think you would best respond to?
  6. +

Moving forward

    +
  1. What are your goals for the rest of the year?
  2. +
  3. How can we measure the success of those goals?
  4. +
  5. Let’s plan out three key action steps we can focus on for the rest of the year.
  6. +
  7. Is there anything else that you’d like to discuss
  8. +
\ No newline at end of file diff --git a/docs/Engineering Management/Agile.html b/docs/Engineering Management/Agile.html new file mode 100644 index 000000000..4e897c3d5 --- /dev/null +++ b/docs/Engineering Management/Agile.html @@ -0,0 +1,21 @@ + + Agile + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Career.html b/docs/Engineering Management/Career.html new file mode 100644 index 000000000..07b90c127 --- /dev/null +++ b/docs/Engineering Management/Career.html @@ -0,0 +1,20 @@ + + Career + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Change Management.html b/docs/Engineering Management/Change Management.html new file mode 100644 index 000000000..edc40e346 --- /dev/null +++ b/docs/Engineering Management/Change Management.html @@ -0,0 +1,26 @@ + + Change Management + + + + + + + + + + + +

Change Management

ADKAR Model

The ADKAR model is an outcome-oriented change management method that aims to limit resistance to organizational change. It is based on five building blocks that bring about successful change, and each letter in the ADKAR acronym represents a different step in the change management process. The five steps are:

    +
  1. Awareness: This involves understanding the need for change and becoming aware of the implications of not changing. Leaders need to create awareness of the need for change among people who will be impacted by it.
  2. +
  3. Desire: Once people are aware of the need for change, they need to be motivated to make it happen. Leaders need to create a desire for change in individuals by explaining why it is essential and what benefits it will bring.
  4. +
  5. Knowledge: In this step, people need to be provided with the right information and knowledge about the change that is happening. Leaders should provide training and instruction to individuals on how to make the change happen.
  6. +
  7. Ability: Individuals need to possess the skills and resources necessary to make the change happen. Leaders need to provide the necessary resources and support to ensure that individuals can execute the change.
  8. +
  9. Reinforcement: In the final step, individuals need to be supported in maintaining the change. Leaders should continue to provide reinforcement to ensure that the change sticks and becomes a permanent part of the organization.
  10. +

The ADKAR model is a widely used framework for managing organizational change. It provides a structured approach to change management that helps to minimize resistance and create a successful transition.

What is the CLARC framework?

The CLARC framework is a change management model that helps people managers navigate change effectively. CLARC stands for:

    +
  • C: Communicate clearly
  • +
  • L: Lead with empathy
  • +
  • A: Align to the vision
  • +
  • R: Respect the individual
  • +
  • C: Create momentum
  • +

This framework is based on the ADKAR model, which describes the stages an individual goes through during change: Awareness, Desire, Knowledge, Ability, Reinforcement. By fulfilling each of the CLARC roles, people managers can have a positive impact on an individual's journey through each stage of the ADKAR mode.

\ No newline at end of file diff --git a/docs/Engineering Management/Coaching.html b/docs/Engineering Management/Coaching.html new file mode 100644 index 000000000..f7be26b3d --- /dev/null +++ b/docs/Engineering Management/Coaching.html @@ -0,0 +1,17 @@ + + Coaching + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Code Reviews.html b/docs/Engineering Management/Code Reviews.html new file mode 100644 index 000000000..09867ef2c --- /dev/null +++ b/docs/Engineering Management/Code Reviews.html @@ -0,0 +1,16 @@ + + Code Reviews + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Community Of Practice.html b/docs/Engineering Management/Community Of Practice.html new file mode 100644 index 000000000..51e92f4b0 --- /dev/null +++ b/docs/Engineering Management/Community Of Practice.html @@ -0,0 +1,65 @@ + + Community Of Practice + + + + + + + + + + + +

Community Of Practice

Communities of practice are groups of people who share a concern or a
+passion for something they do and learn how to do it better as they
+interact regularly.

Three characteristics are crucial:

    +
  • Domain
  • +
  • Community
  • +
  • Practice
  • +

The domain. A community of practice is not
+merely a club of friends or a network of connections between people. It
+has an identity defined by a shared domain of interest. Membership
+therefore implies a commitment to the domain, and therefore a shared
+competence that distinguishes members from other people. (You could
+belong to the same network as someone and never know it.) The domain is
+not necessarily something recognized as “expertise” outside the
+community. A youth gang may have developed all sorts of ways of dealing
+with their domain: surviving on the street and maintaining some kind of
+identity they can live with. They value their collective competence and
+learn from each other, even though few people outside the group may
+value or even recognize their expertise.

The community. In pursuing their interest in
+their domain, members engage in joint activities and discussions, help
+each other, and share information. They build relationships that enable
+them to learn from each other; they care about their standing with each
+other. A website in itself is not a community of practice. Having the
+same job or the same title does not make for a community of practice
+unless members interact and learn together. The claims processors in a
+large insurance company or students in American high schools may have
+much in common, yet unless they interact and learn together, they do not
+form a community of practice. But members of a community of practice do
+not necessarily work together on a daily basis. The Impressionists, for
+instance, used to meet in cafes and studios to discuss the style of
+painting they were inventing together. These interactions were essential
+to making them a community of practice even though they often painted
+alone.

The practice. A community of practice is not
+merely a community of interest–people who like certain kinds of movies,
+for instance. Members of a community of practice are practitioners. They
+develop a shared repertoire of resources: experiences, stories, tools,
+ways of addressing recurring problems—in short a shared practice. This
+takes time and sustained interaction. A good conversation with a
+stranger on an airplane may give you all sorts of interesting insights,
+but it does not in itself make for a community of practice. The
+development of a shared practice may be more or less self-conscious. The
+“windshield wipers” engineers at an auto manufacturer make a concerted
+effort to collect and document the tricks and lessons they have learned
+into a knowledge base. By contrast, nurses who meet regularly for lunch
+in a hospital cafeteria may not realize that their lunch discussions are
+one of their main sources of knowledge about how to care for patients.
+Still, in the course of all these conversations, they have developed a
+set of stories and cases that have become a shared repertoire for their
+practice.

It is the combination of these three elements that constitutes
+a community of practice. And it is by developing these three elements
+in parallel that one cultivates such a community.

image_1672704213276_0.png

\ No newline at end of file diff --git a/docs/Engineering Management/Culture.html b/docs/Engineering Management/Culture.html new file mode 100644 index 000000000..18045e978 --- /dev/null +++ b/docs/Engineering Management/Culture.html @@ -0,0 +1,19 @@ + + Culture + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Developer Experience.html b/docs/Engineering Management/Developer Experience.html new file mode 100644 index 000000000..59525602c --- /dev/null +++ b/docs/Engineering Management/Developer Experience.html @@ -0,0 +1,25 @@ + + Developer Experience + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Effective Meetings.html b/docs/Engineering Management/Effective Meetings.html new file mode 100644 index 000000000..f9a736ff7 --- /dev/null +++ b/docs/Engineering Management/Effective Meetings.html @@ -0,0 +1,16 @@ + + Effective Meetings + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Engineering Management.html b/docs/Engineering Management/Engineering Management.html new file mode 100644 index 000000000..76c02b855 --- /dev/null +++ b/docs/Engineering Management/Engineering Management.html @@ -0,0 +1,87 @@ + + Engineering Management + + + + + + + + + + + +

Tech Lead vs Engineering Manager

what engineering managers should do.png

engineering manager framework.png

It is very common for companies to mix the Tech Lead and Engineering Manager roles. Although both roles have some overlap, their focus is different: the Tech Lead is in charge of the System while the Engineering Manager is in charge of the People.

If the team is small and/or the leader has a lot of experience as Engineering Manager and Tech Lead, the same person might perform both roles. But as the system and team grow in size and complexity, there might be an opportunity to have different people for each role.

The following is a non-exhaustive list that exemplifies some of the different responsibilities of each role:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Tech Lead (System)Engineering Manager (People)
Technical Excellence and InnovationCareer Planning, Promotions and Coaching
Architecture and System IntegrationHeadcount Planning and Hiring
Tech Mentoring, Adoption and AlignmentTeam Planning and Delivery
Technical Spikes and Experiments​Objectives, Performance and Feedback
Code Reviews and FeedbackOne on Ones
System Design Presentations​Participation in Technical Decisions
Technical Capacity Planning​Cascading Communications​
Production Issues Escalation​Team Building Activities and Culture​
System SLAs, Metrics & Monitoring​Team Protection and Happiness​
Platform Direction, Patterns and PracticesTeam Productivity and Metrics​
Alignment with other Tech Leads​Alignment with other Dev Managers​
Hands-On Coding 30% to 70% of the TimeHands-On Coding 0% to 30% of the Time
System Roadmap (shared)​System Roadmap (shared)​
Development Process (shared)​Development Process (shared)​
Team Visibility and Recognition (shared)Team Visibility and Recognition (shared)​
Ability to Act as Engineering Manager when RequiredAbility to Act as Tech Lead when Required

The last point on each role highlights the fact that the lists are not mutually exclusive, and therefore many of the points from one side are also important on the other side too. An Engineering Manager that can't understand the technical challenges that the team is facing won't be successful at the role, the same is true for a Tech Lead that doesn't understand the career paths of the engineers in the team.

Having said that, although it is important for an Engineering Manager to be able act as a Tech Lead and vice versa, it also critical for them to focus and excel at the right things. Although there is a clear overlap and an opportunity for collaboration, both positions must know well who is responsible for what to avoid conflicts and misunderstandings.

\ No newline at end of file diff --git a/docs/Engineering Management/Goals.html b/docs/Engineering Management/Goals.html new file mode 100644 index 000000000..6735c2b77 --- /dev/null +++ b/docs/Engineering Management/Goals.html @@ -0,0 +1,30 @@ + + Goals + + + + + + + + + + + +

Objectives

OKRs

Definition

OKR stands for Objectives and Key Results. OKRs help break up big, audacious missions into actionable goals and milestones.

    +
  • Objectives (The “What”): An objective is what you want to do. It describes our mission-supporting goal.
  • +
  • Key Results (The “How”): Objectives must be paired with a roadmap that will help you know whether or not you’re on the path to meeting your goals.
  • +
\ No newline at end of file diff --git a/docs/Engineering Management/Health Monitor.html b/docs/Engineering Management/Health Monitor.html new file mode 100644 index 000000000..3b9a08460 --- /dev/null +++ b/docs/Engineering Management/Health Monitor.html @@ -0,0 +1,94 @@ + + Health Monitor + + + + + + + + + + + +

Health Monitor

Employee

    +
  • I know what is expected of me at work.
  • +
  • I have the materials and equipment I need to do my work right.
  • +
  • At work, I have the opportunity to do what I do best every day.
  • +
  • In the last seven days, I have received recognition or praise for doing good work.
  • +
  • My supervisor, or someone at work, seems to care about me as a person.
  • +
  • There is someone at work who encourages my development.
  • +
  • At work, my opinions seem to count.
  • +
  • The mission or purpose of my company makes me feel my job is important.
  • +
  • My associates or fellow employees are committed to doing quality work.
  • +
  • I have a best friend at work.
  • +
  • In the last six months, someone at work has talked to me about my progress.
  • +
  • This last year, I have had opportunities at work to learn and grow.
  • +

Manager

    +
  • I would recommend my manager to others.
  • +
  • My manager assigns stretch opportunities to help me develop in my career.
  • +
  • My manager communicates clear goals for our team.
  • +
  • My manager gives me actionable feedback on a regular basis.
  • +
  • My manager provides the autonomy I need to do my job (i.e., does not "micro-manage" by getting involved in details that should be handled at other levels).
  • +
  • My manager consistently shows consideration for me as a person.
  • +
  • My manager keeps the team focused on priorities, even when it’s difficult (e.g., declining or deprioritizing other projects).
  • +
  • My manager regularly shares relevant information from their manager and senior leadership.
  • +
  • My manager has had a meaningful discussion with me about my career development in the past six months.
  • +
  • My manager has the technical expertise (e.g., technical judgment in Tech, selling in Sales, accounting in Finance) required to effectively manage me.
  • +
  • The actions of my manager show they value the perspective I bring to the team, even if it is different from their own.
  • +
  • My manager makes tough decisions effectively (e.g., decisions involving multiple teams, competing priorities).
  • +
  • My manager effectively collaborates across boundaries (e.g., team, organizational).
  • +
  • What would you recommend your manager keep doing?
  • +
  • What would you have your manager change?
  • +

Psychological Safety

    +
  • If you make a mistake on this team, it is often held against you.
  • +
  • Members of this team are able to bring up problems and tough issues.
  • +
  • People on this team sometimes reject others for being different.
  • +
  • It is safe to take a risk on this team.
  • +
  • It is difficult to ask other members of this team for help.
  • +
  • No one on this team would deliberately act in a way that undermines my efforts.
  • +
  • Working with members of this team, my unique skills and talents are valued and utilized.
  • +

Stress

We’ve all been working under a lot of stress this past year. I wanted to gauge how the team is feeling, and see if there’s anything I can do to help mitigate feelings of burnout. Please answer these questions and send your responses back to me before the end of the day tomorrow. Feel free to provide more context in any of your answers. And please be honest — the goal here is for me to find out how you’re really doing, not to punish anyone for feeling unproductive or overwhelmed. Everything you say will be kept confidential.

Over the past week…

    +
  • How overwhelmed did you feel, on a scale of 1 to 5? (1 is lowest, 5 is highest)
  • +
  • How many days did you work later than you should?
  • +
  • How many days did you answer emails after hours?
  • +
  • How effective did you feel, on a scale of 1 to 5?
  • +
  • How productive did you feel, on a scale of 1 to 5?
  • +
  • How much fun did you have, on a scale of 1 to 5?
  • +

Service Team

Team leadership

    +
  • There is a team lead who is responsible for team performance, communication and process ownership.
  • +
  • The team lead actively monitors work, identifies and successfully advocates improvements in process, and communicates opportunities both inside and outside of the team.
  • +

Balanced team

    +
  • The team has the right specialist skills and experience.
  • +
  • The team is empowered to make decisions and escalate where appropriate.
  • +
  • The team share stories, collaborate on tricky problems and share lessons learned.
  • +
  • Individual service excellence is recognized.
  • +
  • Team schedules and rosters are set and agreed with an even distribution of work across the team.
  • +
  • There is a smooth onboarding process for new team members.
  • +

Service mandate

    +
  • The services offered by the team are defined and documented. The scope of the team’s work is clear.
  • +
  • Ownership and accountabilities for individuals and leads are defined.
  • +
  • The service mandate has been communicated and agreed by key stakeholders, with agreed-upon success metrics that are well-defined and actively monitored.
  • +

Service levels

    +
  • Service levels for all areas of the teams’ service mandate are defined, agreed and visible to key stakeholders, including customers.
  • +
  • All service levels are current, applicable and there is queue management, categorization, prioritization & escalation in place to meet SLAs.
  • +
  • The team operates at a good velocity with recognized consequences for not meeting SLAs.
  • +

Customer centricity

    +
  • You understand what your customers need and have the necessary information about the customer to resolve their issues.
  • +
  • You are skilled at understanding, empathizing and resolving requests with an effective customer feedback loop in place which drives improvements to build trust and
    +improve your service offering.
  • +
  • Your service offering balances quality with velocity.
  • +
  • Customers can self serve and your team has a mechanism or cycle in place to detect, correct and prevent problem management.
  • +

Tools and processes

    +
  • The team has the necessary tool set that is well designed and optimized towards delivering the services offered by your team.
  • +
  • Processes are well documented, and have defined workflows and owners.
  • +
  • There is a well defined and followed hand-over process to operationalize new services and handle rootcause analysis.
  • +

Effective partnership

    +
  • Your vendors and partners are known, key contracts are documented and there is a trusting relationship(s) in place.
  • +
  • There are established operational level agreements (OLAs) for down-level teams and partners.
  • +
  • Partner contracts are current and their OLAs allow your team to uphold your commitments and retain ownership of the customer request.
  • +

Reporting and analytics

    +
  • You are capturing feedback and your performance reporting is available, visible and helping your team improve established service levels.
  • +
  • KPIs are realistic, focused on the correct metrics and you are meeting your KPIs.
  • +
  • Your cost to serve is known and a focus area for the team to improve on.
  • +
\ No newline at end of file diff --git a/docs/Engineering Management/High Performing Teams.html b/docs/Engineering Management/High Performing Teams.html new file mode 100644 index 000000000..c12d17581 --- /dev/null +++ b/docs/Engineering Management/High Performing Teams.html @@ -0,0 +1,16 @@ + + High Performing Teams + + + + + + + + + + + +

High Performing Teams

    +
  • “../assets/image_1667451270542_0.png” could not be found.
  • +
\ No newline at end of file diff --git a/docs/Engineering Management/Hiring.html b/docs/Engineering Management/Hiring.html new file mode 100644 index 000000000..b4e15b40c --- /dev/null +++ b/docs/Engineering Management/Hiring.html @@ -0,0 +1,18 @@ + + Hiring + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Incident Management.html b/docs/Engineering Management/Incident Management.html new file mode 100644 index 000000000..5cf405fc0 --- /dev/null +++ b/docs/Engineering Management/Incident Management.html @@ -0,0 +1,16 @@ + + Incident Management + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Index.html b/docs/Engineering Management/Index.html new file mode 100644 index 000000000..2a5896bf3 --- /dev/null +++ b/docs/Engineering Management/Index.html @@ -0,0 +1,47 @@ + + Index + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Interview.html b/docs/Engineering Management/Interview.html new file mode 100644 index 000000000..2764d9f10 --- /dev/null +++ b/docs/Engineering Management/Interview.html @@ -0,0 +1,54 @@ + + Interview + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Interviewer.html b/docs/Engineering Management/Interviewer.html new file mode 100644 index 000000000..b6e7e1e3b --- /dev/null +++ b/docs/Engineering Management/Interviewer.html @@ -0,0 +1,45 @@ + + Interviewer + + + + + + + + + + + +

Interviewer

As an interviewer, your role is to assess the qualifications, skills, and suitability of candidates for a particular position. You want to ensure that you find the best fit for the role and the organization. Here are some key points to consider from an interviewer's perspective:

    +
  1. +

    Prepare and plan: Before the interview, thoroughly review the candidate's resume and any other relevant materials. Identify the key qualifications, skills, and experiences you are looking for in a candidate. Prepare a list of interview questions that will help you assess these qualities.

    +
  2. +
  3. +

    Create a welcoming environment: Start the interview by introducing yourself and making the candidate feel comfortable. Set a positive tone and establish rapport to encourage open and honest communication.

    +
  4. +
  5. +

    Ask behavioral and situational questions: Use a mix of behavioral and situational questions to evaluate the candidate's past experiences and how they handle specific situations. These questions can provide insights into their problem-solving abilities, decision-making skills, and alignment with the company's values.

    +
  6. +
  7. +

    Listen actively: Pay attention to the candidate's responses and actively listen to what they are saying. Take notes to help you remember important details and follow-up questions. This will show the candidate that you are engaged and interested in their answers.

    +
  8. +
  9. +

    Assess cultural fit: Evaluate whether the candidate aligns with the company's culture and values. Ask questions that delve into their work style, preferred team dynamics, and how they handle challenges or conflicts. This will help you determine if they will fit well within the existing team.

    +
  10. +
  11. +

    Provide clear information: Offer a clear overview of the role, responsibilities, and expectations. Answer any questions the candidate may have about the position or the company. This will help them understand if the role aligns with their career goals and aspirations.

    +
  12. +
  13. +

    Evaluate soft skills: Assess the candidate's soft skills, such as communication, teamwork, problem-solving, and adaptability. These skills are often crucial for success in a role and can contribute to a harmonious work environment.

    +
  14. +
  15. +

    Allow time for candidate questions: Provide an opportunity for the candidate to ask questions about the role, the company, or any other relevant topics. This demonstrates their interest and initiative, and also provides valuable insights into their level of research and understanding.

    +
  16. +
  17. +

    Take notes and compare candidates: After the interview, take detailed notes on each candidate's responses, strengths, weaknesses, and overall impression. This will help you compare candidates and make an informed decision.

    +
  18. +
  19. +

    Provide feedback and follow-up: Once the interview process is complete, provide feedback to the candidates, whether they were successful or not. This helps maintain a positive impression of the company and shows respect for the candidate's time and effort.

    +
  20. +

Remember, the goal of the interview is to find the best candidate for the role. By following these guidelines, you can conduct an effective interview that helps you make an informed hiring decision.

\ No newline at end of file diff --git a/docs/Engineering Management/Leadership.html b/docs/Engineering Management/Leadership.html new file mode 100644 index 000000000..be158b614 --- /dev/null +++ b/docs/Engineering Management/Leadership.html @@ -0,0 +1,16 @@ + + Leadership + + + + + + + + + + + +

Leadership

    +
  • “../assets/image_1667451208006_0.png” could not be found.
  • +
\ No newline at end of file diff --git a/docs/Engineering Management/Manage for Better Results.html b/docs/Engineering Management/Manage for Better Results.html new file mode 100644 index 000000000..a29ae1c49 --- /dev/null +++ b/docs/Engineering Management/Manage for Better Results.html @@ -0,0 +1,29 @@ + + Manage for Better Results + + + + + + + + + + + +

Manage for Better Results

Commitment is all about purpose (servant leadership)
+Compliance about the paycheck (positional power)
+Believe it's possible and lead by example
+Avoid taking over (coaching / asking questions / let the team figure it out)
+Let the team fail safely with a safety net
+Keep Morale high
+Accountability sits with the team

Having a clear picture of success to provide Clarity and Focus (compass)

Individual Results

    +
  • Set clear expectations with individuals and write them down to remember make it clearer
  • +
  • Gain agreement and commitment
  • +
  • Align personal goals with the team and organization goals
  • +
  • HAVE 1:1s regularly (enable the team / goal check / pulse check)
  • +

Team Results

    +
  • Clarify Team Roles
  • +
  • Smart goals and Metrics (Specific, Measurable, Achievable, Relevant, Time-bound)
    +Specific: Goals should be clear and well-defined. They should answer the questions of who, what, where, when, and why. Being specific helps to avoid ambiguity and provides a clear direction.
  • +

Measurable: Goals should have specific criteria or metrics that can be used to track progress and determine when the goal has been achieved. Measurable goals provide a way to objectively assess success and make adjustments if necessary.

Achievable: Goals should be realistic and attainable. It's important to set goals that are challenging but still within reach. Setting unattainable goals can lead to frustration and demotivation.

Relevant: Goals should be aligned with broader objectives and have a meaningful impact. They should be relevant to the individual or organization's overall vision and mission. Relevance ensures that goals are worth pursuing and contribute to overall success.

Time-bound: Goals should have a specific timeframe or deadline for completion. Setting a timeline helps to create a sense of urgency and provides a clear target to work towards. It also helps with planning and prioritization.

\ No newline at end of file diff --git a/docs/Engineering Management/Metrics.html b/docs/Engineering Management/Metrics.html new file mode 100644 index 000000000..45ea329b2 --- /dev/null +++ b/docs/Engineering Management/Metrics.html @@ -0,0 +1,19 @@ + + Metrics + + + + + + + + + + + +

Metrics

Agile

Engineering

\ No newline at end of file diff --git a/docs/Engineering Management/Onboarding.html b/docs/Engineering Management/Onboarding.html new file mode 100644 index 000000000..47566e35d --- /dev/null +++ b/docs/Engineering Management/Onboarding.html @@ -0,0 +1,27 @@ + + Onboarding + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Psychological Safety.html b/docs/Engineering Management/Psychological Safety.html new file mode 100644 index 000000000..c7a8a139e --- /dev/null +++ b/docs/Engineering Management/Psychological Safety.html @@ -0,0 +1,14 @@ + + Psychological Safety + + + + + + + + + + + +

Psychological Safety

image

\ No newline at end of file diff --git a/docs/Engineering Management/Reports.html b/docs/Engineering Management/Reports.html new file mode 100644 index 000000000..37c89c514 --- /dev/null +++ b/docs/Engineering Management/Reports.html @@ -0,0 +1,49 @@ + + Reports + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Salary.html b/docs/Engineering Management/Salary.html new file mode 100644 index 000000000..a5ead1b9f --- /dev/null +++ b/docs/Engineering Management/Salary.html @@ -0,0 +1,14 @@ + + Salary + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Engineering Management/Software Development Strategy.html b/docs/Engineering Management/Software Development Strategy.html new file mode 100644 index 000000000..41812e392 --- /dev/null +++ b/docs/Engineering Management/Software Development Strategy.html @@ -0,0 +1,213 @@ + + Software Development Strategy + + + + + + + + + + + +

Software Development Strategy

Introduction

This document is a set of upfront decisions that allows the team to come up with an effective set of dos, don’ts and how's regarding
+the future application design, development and deployment, and move consistently through each step of a development project.

General

    +
  • Use GitHub folder structure (src, doc, test, build, tool)
  • +
  • Use sqlproj project file for SQL databases
  • +
  • Use the latest .NET LTS version. See .NET Roadmap
  • +

Guidelines

Tools, Frameworks and Libraries

Tools

Logging

Always use Structured Logging, which makes it easier to store and query log-events.
+https://datatracker.ietf.org/doc/html/rfc7807

Health Checks

A health check API is a separate REST service that is implemented within a microservice component that quickly returns the operational status of the service and an indication of its ability to connect to downstream dependent services.
+Example: myservice.com/health

Caching

A distributed cache is a cache shared by multiple app servers, typically maintained as an external service to the app servers that access it. A distributed cache can improve the performance and scalability of an application, especially when the application is hosted by a cloud service or a server farm.

When cached data is distributed, the data:

- Is coherent (consistent) across requests to multiple servers.
+- Survives server restarts and app deployments.
+- Doesn't use local memory.
+

API Versioning

Versioning is an important aspect of any mature web service. Microsoft has published REST API guidelines that require that all compliant services must support explicit versioning. This ensures that clients can rely on services to be stable over time, while still enabling service changes and new features. Detailed information about the recommended guidance can be found in the Microsoft REST Guidelines for versioning.

Code

// Define a 'version set' that applies to an API group
+var versionSet = app.NewApiVersionSet()
+                    .HasApiVersion(1.0)
+                    .HasApiVersion(2.0)
+                    .ReportApiVersions()
+                    .Build();
+
+app.MapGet("{instanceId}/endpoint", [Authorize] async (IMediator mediator, [FromHeader] string authorization, Guid instanceId, CancellationToken cancellationToken) => await mediator.Send(new RequestV1() { InstanceId = instanceId }, cancellationToken))
+   .WithApiVersionSet(versionSet)
+   .MapToApiVersion(1.0);
+
+app.MapGet("{instanceId}/endpoint", [Authorize] async (IMediator mediator, [FromHeader] string authorization, Guid instanceId, CancellationToken cancellationToken) => await mediator.Send(new RequestV2() { InstanceId = instanceId }, cancellationToken))
+   .WithApiVersionSet(versionSet)
+   .MapToApiVersion(2.0);
+

Rate Limiting

Linting

Linting is essentially a form of static code analysis. It analyzes the code you wrote against some rules for stylistic or programmatic errors. Think of it as a tool that flags suspicious usage in software.

A linter can help you save a lot of time by:

    +
  • +

    Preventing broken code from being pushed

    +
  • +
  • +

    Helping establish coding best practices

    +
  • +
  • +

    Building guidelines for code layout and format

    +
  • +
  • +

    Helping code reviews be a lot smoother

    +
  • +
  • +

    Flagging bugs in your code from syntax errors

    +

    Given the useful nature of linting tools, you would ideally want to run a linter before any code reviews happen on every single piece of code that is pushed to your repository. This definitely helps you write better, more readable, and more stable code.

    +
  • +

Super Linter

You first want to pull the latest Docker container down from DockerHub with this command:

docker pull github/super-linter:latest

To run this container you then run the following:

docker run -e RUN_LOCAL=true -e USE_FIND_ALGORITHM=true -v /project/directory:/tmp/lint github/super-linter

Notice a couple of things here:

    +
  • We run it with the RUN_LOCAL flag to bypass some of the GitHub Actions checks. This automatically sets VALIDATE_ALL_CODEBASE to true.
  • +
  • We map our local codebase to /tmp/lint so that the linter can pick up the code.
  • +
  • The way we set environment variables is of course different, but the overall process of running the GitHub Super Linter remains the same.
  • +

Rules Catalog

Code Quality Rules

<PropertyGroup>
+<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
+</PropertyGroup>
+

Best Practices

\ No newline at end of file diff --git a/docs/Engineering Management/Ways of Working.html b/docs/Engineering Management/Ways of Working.html new file mode 100644 index 000000000..e8597a1bd --- /dev/null +++ b/docs/Engineering Management/Ways of Working.html @@ -0,0 +1,32 @@ + + Ways of Working + + + + + + + + + + + +

Ways of Working

Project Planning

Capacity Planning

A great resource to help with Public Holidays is Google Calendar API

Definition of Ready (DOR)

    +
  • Independent (of all others).
  • +
  • Negotiable (not a specific contract for features).
  • +
  • Valuable (or vertical).
  • +
  • Estimable (to a good approximation).
  • +
  • Small (so as to fit within an iteration).
  • +
  • Testable (in principle, even if there isn’t a test for it yet).
  • +

Definition of Done (DOD)

The Definition of Done creates transparency by providing everyone a shared understanding of what work was completed.

    +
  • Unit tests are passing.
  • +
  • Automation tests are passing.
  • +
  • Documentation is updated.
  • +
  • The change is code reviewed via a pull request.
  • +
  • Code is merged into the main branch.
  • +
  • Testing is done by Testers.
  • +
\ No newline at end of file diff --git a/docs/Engineering Management/Wellbeing.html b/docs/Engineering Management/Wellbeing.html new file mode 100644 index 000000000..c6e29cde2 --- /dev/null +++ b/docs/Engineering Management/Wellbeing.html @@ -0,0 +1,43 @@ + + Wellbeing + + + + + + + + + + + +

Wellbeing

Happiness

\ No newline at end of file diff --git a/docs/FeatureManagement/Microsoft.FeatureManagement.html b/docs/FeatureManagement/Microsoft.FeatureManagement.html new file mode 100644 index 000000000..084de677c --- /dev/null +++ b/docs/FeatureManagement/Microsoft.FeatureManagement.html @@ -0,0 +1,51 @@ + + Microsoft.FeatureManagement + + + + + + + + + + + +

Objective

To implement a Feature Management solution that allows us to change application behaviour without changing code.

AWS AppConfig

AWS AppConfig is a capability of AWS Systems Manager, to create, manage, and quickly deploy application configurations. A configuration is a collection of settings that influence the behavior of the application.

The Amazon.Extensions.Configuration.SystemsManager simplifies using AWS AppConfig as a source for configuration information for .NET applications.

Microsoft.FeatureManagement

Microsoft.FeatureManagement provides standardized APIs for enabling feature flags within applications. This library secures a consistent experience when developing applications that use patterns such as beta access, rollout, dark deployments, and more.

Configuration Sample

"FeatureFlags": {
+        "featureA": false,
+        "featureB": true,
+        "featureC": false,
+        "featureD": {
+            "EnabledFor": [
+                {
+                    "Name": "Microsoft.Targeting",
+                    "Parameters": {
+                        "Audience": {
+                            "Users": [
+                                "{tenantId}:{userId}",
+                                "{tenantId}:{userId2}"
+                            ],
+                            "Groups": [
+                                {
+                                    "Name": "{tenantId}",
+                                    "RolloutPercentage": 0
+                                },
+                                {
+
+                                    "Name": "{tenantId2}",
+                                    "RolloutPercentage": 50
+                                },
+                                {
+
+                                    "Name": "{tenantId3}",
+                                    "RolloutPercentage": 100
+                                }
+                            ],
+                            "DefaultRolloutPercentage": 0
+                        }
+                    }
+                }
+            ]
+        }
+    }
+
\ No newline at end of file diff --git a/docs/Goals/Continous Learning.html b/docs/Goals/Continous Learning.html new file mode 100644 index 000000000..56e033ced --- /dev/null +++ b/docs/Goals/Continous Learning.html @@ -0,0 +1,209 @@ + + Continous Learning + + + + + + + + + + + +

Continous Learning

This a list of ideas to make learning a part the routine.

learning pyramid.png

Career Roadmap

Soft Skills

Videos

TBA

\ No newline at end of file diff --git a/docs/Goals/Continuous Improvement.html b/docs/Goals/Continuous Improvement.html new file mode 100644 index 000000000..f2d3b5de0 --- /dev/null +++ b/docs/Goals/Continuous Improvement.html @@ -0,0 +1,98 @@ + + Continuous Improvement + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Goals/Knowledge Sharing.html b/docs/Goals/Knowledge Sharing.html new file mode 100644 index 000000000..188dcb45b --- /dev/null +++ b/docs/Goals/Knowledge Sharing.html @@ -0,0 +1,135 @@ + + Knowledge Sharing + + + + + + + + + + + +

Knowledge Sharing

What

Share knowledge

Why

Sharing knowledge is crucial for software development teams to be successful in delivering high-quality software, improving team collaboration and efficiency, and staying up-to-date with new trends and technologies.

    +
  • Collaboration: Software development is rarely a solitary activity. Teamwork and collaboration are critical to the success of any software project. Sharing knowledge allows team members to work together more effectively and to leverage each other's strengths.
  • +
  • Efficiency: Sharing knowledge allows developers to avoid reinventing the wheel. They can build on the work of others, reuse code, and avoid common mistakes, which can save time and resources.
  • +
  • Quality: Sharing knowledge can help improve the quality of software. Developers can share best practices, techniques, and tools that can help ensure that software is well-designed, secure, and reliable.
  • +
  • Continuous Learning: The field of software development is constantly evolving. Sharing knowledge helps developers stay up-to-date with the latest developments, trends, and technologies. It also helps them learn from each other's experiences and mistakes.
  • +

Examples

How

    +
  • Document infrastructure, architecture, technical analysis and designs.
  • +
  • Provide how-to guides, tutorials, and runbooks.
  • +
  • Establish guidelines for contributors and code reviews.
  • +
  • Create and update documentation regularly.
  • +
  • Consolidate conflicting information in documentation.
  • +

Presentation Agenda

I. Introduction

    +
  • +

    Purpose of the presentation

    +
  • +
  • +

    Overview of knowledge sharing in software development

    +

    II. The Importance of Knowledge Sharing

    +
  • +
  • +

    Benefits of knowledge sharing for the team and organization

    +

    III. Strategies for Knowledge Sharing

    +
  • +
  • +

    Best practices for knowledge sharing

    +
  • +
  • +

    Examples of successful knowledge sharing practices

    +

    IV. Overcoming Challenges to Knowledge Sharing

    +
  • +
  • +

    Common challenges to knowledge sharing

    +
  • +
  • +

    Solutions for overcoming these challenges

    +

    V. Documenting Knowledge

    +
  • +
  • +

    Importance of documenting knowledge

    +
  • +
  • +

    Types of knowledge that should be documented

    +

    VI. Collaborative Learning

    +
  • +
  • +

    Benefits of collaborative learning

    +
  • +
  • +

    Ways to encourage collaborative learning

    +

    VII. Knowledge Sharing Tools

    +
  • +
  • +

    Tools that can be used for knowledge sharing

    +
  • +
  • +

    Examples of how these tools can be used effectively

    +

    VIII. Conclusion

    +
  • +
  • +

    Summary of key points

    +
  • +
  • +

    Importance of knowledge sharing in software development

    +
  • +
  • +

    Call to action for implementing knowledge sharing practices

    +

    IX. Questions and Answers

    +
  • +
  • +

    Open floor for questions and discussion

    +

    X. Closing

    +
  • +
  • +

    Final thoughts

    +
  • +
  • +

    Thank audience for their time and attention

    +
  • +
\ No newline at end of file diff --git a/docs/How-to/Batch File.html b/docs/How-to/Batch File.html new file mode 100644 index 000000000..97bf3771f --- /dev/null +++ b/docs/How-to/Batch File.html @@ -0,0 +1,33 @@ + + Batch File + + + + + + + + + + + +

Batch File

Example with Angular

    +
  • AngularParallelBuild.bat
  • +
  start AngularBuild.bat C:\Dev\App1
+  start AngularBuild.bat C:\Dev\App2
+  start AngularBuild.bat C:\Dev\App3
+  start AngularBuild.bat C:\Dev\App3
+
    +
  • AngularBuild.bat
  • +
  cd %1  
+  ECHO Removing node_modules folder  
+  RMDIR /s /q node_modules  
+  ECHO Building Angular App  
+  call npm cache clean -f  
+  call npm install  
+  call npm ci  
+  call ng build  
+  ECHO Build Finished  
+
\ No newline at end of file diff --git a/docs/How-to/Build and Run a Container with Docker.html b/docs/How-to/Build and Run a Container with Docker.html new file mode 100644 index 000000000..019d387ff --- /dev/null +++ b/docs/How-to/Build and Run a Container with Docker.html @@ -0,0 +1,78 @@ + + Build and Run a Container with Docker + + + + + + + + + + + +

Build and Run a Container with Docker

    +
  1. Navigate to the folder where the Dockerfile is stored
  2. +
  3. Run docker build -t angular-container:1.0 .
  4. +
  5. Search ImageID by running docker images
  6. +
  7. Run docker run -p 80:80 469b3a773ed7
  8. +

Images

Tags

\ No newline at end of file diff --git a/docs/How-to/Change host file on Windows.html b/docs/How-to/Change host file on Windows.html new file mode 100644 index 000000000..9ff7ba683 --- /dev/null +++ b/docs/How-to/Change host file on Windows.html @@ -0,0 +1,51 @@ + + Change host file on Windows + + + + + + + + + + + +

Change host file on Windows


+$HostFile = 'C:\Windows\System32\drivers\etc\hosts'
+
+# Create a backup copy of the Hosts file
+$dateFormat = (Get-Date).ToString('dd-MM-yyyy hh-mm-ss')
+$FileCopy = $HostFile + '.' + $dateFormat  + '.copy'
+Copy-Item $HostFile -Destination $FileCopy
+
+$Bindings = Get-IISSiteBinding "websitename.com"
+
+# Get the contents of the Hosts file
+$File = Get-Content $HostFile
+
+# write the Entries to hosts file, if it doesn't exist.
+foreach ($Binding in $Bindings) 
+{
+$HostFileEntry = $Binding.bindingInformation
+$HostFileEntry = $HostFileEntry -replace "\*:443:", ""
+
+Write-Host "Checking existing HOST file entries for $HostFileEntry..."
+
+#Set a Flag
+$EntryExists = $false
+
+if ($File -contains "127.0.0.1 `t $HostFileEntry") 
+{
+  Write-Host "Host File Entry for $HostFileEntry already exists."
+  $EntryExists = $true
+}
+#Add Entry to Host File
+if (!$EntryExists) 
+{
+  Write-host "Adding Host File Entry for $HostFileEntry"
+  Add-content -path $HostFile -value "127.0.0.1 `t $HostFileEntry"
+}
+}
+
+
\ No newline at end of file diff --git a/docs/How-to/Create IIS Websites.html b/docs/How-to/Create IIS Websites.html new file mode 100644 index 000000000..c625e7d9d --- /dev/null +++ b/docs/How-to/Create IIS Websites.html @@ -0,0 +1,20 @@ + + Create IIS Websites + + + + + + + + + + + +

Create IIS Websites

+

Powershell 7+ is required

+
    +
  1. Run Install-Module -Name IISAdministration -Scope AllUsers -AllowClobber
  2. +
  3. Run New-IISSite -Name 'website_name' -PhysicalPath 'C:\Inetpub\wwwroot' -BindingInformation "*:443:hostname1.com" -Protocol https -SslFlag "Sni" -CertificateThumbPrint "[Insert Thumbprint]" -CertStoreLocation "Cert:\LocalMachine\My" -Force
  4. +
  5. Run New-IISSiteBinding -Name "website_name" -BindingInformation "*:443:hostname2.com" -Protocol https -SslFlag "Sni" -CertificateThumbPrint "[Insert Thumbprint]" -CertStoreLocation "Cert:\LocalMachine\My" -Force
  6. +
\ No newline at end of file diff --git a/docs/How-to/Create Self-Signed Certificate.html b/docs/How-to/Create Self-Signed Certificate.html new file mode 100644 index 000000000..2b62e58ef --- /dev/null +++ b/docs/How-to/Create Self-Signed Certificate.html @@ -0,0 +1,102 @@ + + Create Self-Signed Certificate + + + + + + + + + + + +

Create Self-Signed Certificate

+

Note
+This process requires WSL2 and Ubuntu. Read here for installation steps.

+
    +
  1. Open a command prompt window
  2. +
  3. Run ubuntu
  4. +
  5. Create certificate.cnf
  6. +
[req]
+default_bits= 2048
+default_keyfile= keyfile.pem
+distinguished_name= req_distinguished_name
+attributes= req_attributes
+prompt= no
+output_password= mypass
+req_extensions= v3_req
+
+[v3_req]
+basicConstraints= CA:FALSE
+keyUsage= nonRepudiation, digitalSignature, keyEncipherment
+subjectAltName = @alt_names
+
+[alt_names]
+DNS.1   = local.company.dev
+DNS.2   = support.company.dev
+DNS.3   = test.company.dev
+DNS.4   = automation.company.dev
+
+[req_distinguished_name ]
+C= AU
+ST= QLD
+L= Brisbane
+O= company Local
+OU= Technology
+CN= *.company.dev
+emailAddress=leandro@company.com
+
+[req_attributes]
+challengePassword= C0mp4ny
+
    +
  1. openssl req -new -newkey rsa:2048 -nodes -keyout ca.key -out ca.csr -config certificate.cnf
  2. +
  3. openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr -config certificate.cnf
  4. +
  5. openssl req -x509 -new -key ca.key -out ca.crt -days 36500 -config certificate.cnf
  6. +
  7. openssl x509 -req -days 36500 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extensions v3_req -extfile certificate.cnf
  8. +
  9. openssl verify -CAfile ca.crt -verify_hostname local.company.dev server.crt
  10. +

PFX Export

Required to be visible on IIS, which needs a private key associated to the certificate.

    +
  1. openssl pkcs12 -export -out ca.pfx -inkey ca.key -in ca.crt -passout pass:C0mp4ny
  2. +
  3. openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt -passout pass:C0mp4ny
  4. +

Import into Windows Certificate Store

    +
  1. Import-PfxCertificate -FilePath C:\Dev\SSL\ca.pfx -Password (ConvertTo-SecureString -String 'C0mp4ny' -AsPlainText -Force) -CertStoreLocation Cert:\LocalMachine\Root
  2. +
  3. Import-PfxCertificate -FilePath C:\Dev\SSL\server.pfx -Password (ConvertTo-SecureString -String 'C0mp4ny' -AsPlainText -Force) -CertStoreLocation Cert:\LocalMachine\My
  4. +

Firefox

Trust the Certificate Authority on #Firefox: Settings -> Privacy & Security -> View Certificates -> Authorities -> import ca.crt

Configure Certificate in ASP.NET

Configure Certificate in Angular

Manage Certificate Private keys

    +
  1. Go to Windows -> type "run" -> mmc
  2. +
  3. Once the mmc window is up -> Add Snap-in -> Add certificate -> Local Computer
  4. +
  5. Go to Personal -> Certificate -> Select the certificate
  6. +
  7. Right Click Certificate -> All tasks -> Manage Private keys
  8. +

Notes:

    +
  • Private key must be exportable when installing the certificate
  • +
  • In Windows 10 1809, it seems that the Manage Private Keys option is available only to certificates in the Personal store. The workaround is to drag and drop the certificate there, add permissions as needed and drag it back to where you need it.
  • +

Difference between CRT and PFX files

A .crt (or .cer or .cert) file usually contains a single X.509 encoded digital certificate, which is what is typically used for SSL/TLS encryption on websites. A .pfx (personal exchange format) file, on the other hand, is a password-protected data file that contains a private key, public key, and typically a chain of digital certificates. The main difference between the two is that a .pfx file contains both the private key and the public key, while a .crt file contains only the public key. Additionally, a .pfx file can include multiple certificates, while a .crt file typically only contains one.

Notes

    +
  • CRT file does not contain the private key
  • +
  • KEY file contains the private key
  • +
  • PFX file contains the private key, but it's protected by a password (eg. C0mp4ny)
  • +

Using CloudFlare as CA

    +
  1. Go to https://dash.cloudflare.com
  2. +
  3. Create a Website
  4. +
  5. Run Ubuntu
  6. +
  7. Run openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr
  8. +
  9. When prompted Common Name, make sure you use a wildcard address *.mydomain.dev
  10. +
  11. Run ls and check if server.csr is listed
  12. +
  13. Run cat server.csr
  14. +
  15. Copy the CSR content
  16. +
  17. Go to CloudFare -> Website -> SSL/TLS -> Origin Server -> Create Certificate
  18. +
  19. Select "Use my private key and CSR"
  20. +
  21. Copy content from step 8
  22. +
  23. Click Create
  24. +
  25. Select PEM Format
  26. +
  27. Copy content into a notepad and save as newsslcertificate.crt
  28. +
  29. Generate PFX openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt -passout pass:P4ssW0rd
  30. +
\ No newline at end of file diff --git a/docs/How-to/Creating a permanent PowerShell Alias using Set-Alias.html b/docs/How-to/Creating a permanent PowerShell Alias using Set-Alias.html new file mode 100644 index 000000000..6f30a2f57 --- /dev/null +++ b/docs/How-to/Creating a permanent PowerShell Alias using Set-Alias.html @@ -0,0 +1,19 @@ + + Creating a permanent PowerShell Alias using Set-Alias + + + + + + + + + + + +

Creating a permanent PowerShell Alias using Set-Alias

To create a permanent PowerShell Alias using the Set-Alias cmdlet, you should add it to your PowerShell profile, which ensures that the alias is available every time you launch PowerShell.

    +
  1. Open the PowerShell profile file in Notepad: notepad $profile
  2. +
  3. Add the following line to create a permanent alias: Set-Alias -Name aliasname -Value command
  4. +
  5. Save your changes and close Notepad.
  6. +
  7. To ensure that your profile is loaded, run the command: . $profile
  8. +
\ No newline at end of file diff --git a/docs/How-to/HTTP Client.html b/docs/How-to/HTTP Client.html new file mode 100644 index 000000000..5413e9d10 --- /dev/null +++ b/docs/How-to/HTTP Client.html @@ -0,0 +1,23 @@ + + HTTP Client + + + + + + + + + + + +

HTTP Client

Program.cs

services.AddHttpClient("MyClient", client =>
+            {
+                client.DefaultRequestHeaders.Add("authToken", "token123");
+            }).AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(300)));
+

Option 1 - Inject IHttpClientFactory

var  httpClient = _httpClientFactory.CreateClient("MyClient");
+

Option 2 - Create Instance

var httpClient = new HttpClient();
+
+responseJson = await httpClient.GetStringAsync($"https://domain.com/endpoint");
+var instance = JsonSerializer.Deserialize<ObjectDeserialized>(responseJson)!;
+
\ No newline at end of file diff --git a/docs/How-to/Install multiple NodeJS Versions.html b/docs/How-to/Install multiple NodeJS Versions.html new file mode 100644 index 000000000..a9ecdb21a --- /dev/null +++ b/docs/How-to/Install multiple NodeJS Versions.html @@ -0,0 +1,23 @@ + + Install multiple NodeJS Versions + + + + + + + + + + + +

Install multiple NodeJS Versions

+

Warning
+Each time a new NodeJS version is installed, tools like Angular must be re-installed.

+
    +
  1. winget install -e --id CoreyButler.NVMforWindows
  2. +
  3. Restart Windows Terminal
  4. +
  5. Execute nvm --version to verify if your installation
  6. +
  7. Execute nvm install latest
  8. +
  9. Execute nvm use latest
  10. +

NVM Commands: nvm help

\ No newline at end of file diff --git a/docs/How-to/Measure Method Elapsed Time with CSharp.html b/docs/How-to/Measure Method Elapsed Time with CSharp.html new file mode 100644 index 000000000..40188785b --- /dev/null +++ b/docs/How-to/Measure Method Elapsed Time with CSharp.html @@ -0,0 +1,41 @@ + + Measure Method Elapsed Time with CSharp + + + + + + + + + + + +

Measure Method Elapsed Time with CSharp

Class

using System;
+using System.Diagnostics;
+
+[AttributeUsage(AttributeTargets.Method)]
+public class StopWatchAttribute: Attribute
+{
+    public virtual void OnEntry()
+    {
+        Stopwatch stopwatch = new Stopwatch();
+        stopwatch.Start();
+
+        AppDomain.CurrentDomain.ProcessExit += (sender, args) =>
+        {
+            stopwatch.Stop();
+            Console.WriteLine($"Elapsed Time: {stopwatch.ElapsedMilliseconds} ms");
+        };
+    }
+}
+

How to use it

public class MyClass
+{
+    [StopWatch]
+    public static void MyMethod()
+    {
+        // Code to be measured.
+        System.Threading.Thread.Sleep(500);
+    }
+}
+
\ No newline at end of file diff --git a/docs/How-to/Modernization.html b/docs/How-to/Modernization.html new file mode 100644 index 000000000..8d992b8f7 --- /dev/null +++ b/docs/How-to/Modernization.html @@ -0,0 +1,28 @@ + + Modernization + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/How-to/Run a tool globally on Windows.html b/docs/How-to/Run a tool globally on Windows.html new file mode 100644 index 000000000..bdac971c0 --- /dev/null +++ b/docs/How-to/Run a tool globally on Windows.html @@ -0,0 +1,30 @@ + + Run a tool globally on Windows + + + + + + + + + + + +

Run a tool globally on Windows

To add a folder to the PATH environment variable:

    +
  1. In Windows File Explorer, navigate to the folder containing the EXE.
  2. +
  3. Copy the full path to the folder from the address bar.
  4. +
  5. Open the Start menu, search for "Environment Variables", and select "Edit the system environment variables".
  6. +
  7. Click the "Environment Variables" button.
  8. +
  9. Under "System Variables", scroll down and select "Path", then click "Edit".
  10. +
  11. Click "New", paste the path to the folder containing the EXE, and click "OK" on all open windows.
  12. +
  13. Open a command prompt window and type the name of the EXE. It should run from any folder because the folder is included in the PATH environment variable.
  14. +

The folder must be under C:\Program Files\local-dev-cli, then you can run localdev (localdev.exe) from anywhere

//Make the tool accesible globally
+string folderPathToAdd = @"C:\Program Files\local-dev-cli";
+string pathVariable = Environment.GetEnvironmentVariable("Path", EnvironmentVariableTarget.Machine) ?? "";
+if (!pathVariable.Contains(folderPathToAdd))
+{
+	pathVariable = $@"{folderPathToAdd};{pathVariable}";
+	Environment.SetEnvironmentVariable("Path", pathVariable, EnvironmentVariableTarget.Machine);
+}
+
\ No newline at end of file diff --git a/docs/How-to/Technical Support.html b/docs/How-to/Technical Support.html new file mode 100644 index 000000000..75b96b619 --- /dev/null +++ b/docs/How-to/Technical Support.html @@ -0,0 +1,29 @@ + + Technical Support + + + + + + + + + + + +

Share Secrets

Quick Assist

Give the security code to the person you’re helping and tell them to follow these steps:

    +
  1. Open the Start menu go to Windows Accessories -> Quick Assist or type Quick Assist in the search bar and select the Quick Assist app to launch it.
  2. +
  3. Accept the privacy policy, if prompted.
  4. +
  5. Enter the code provided in Code from assistant and click Share screen.
  6. +
  7. Verify that the person trying to help you is who you expected and accept the request.
  8. +
  9. Wait for your devices to connect.
  10. +

Problem Step Recorder (PSR)

    +
  1. Click on your Windows Start search menu
  2. +
  3. Type “PSR” and then click on psr.exe in the search results.
  4. +
  5. Open the application
  6. +
  7. Start the recording from the login page until you reach the page where you can see the error message/problem occurred.
  8. +
  9. Once you reach the last page, ensure your home page before you stop the recording to ensure that you have captured the last page where we encountered the error message.
  10. +
  11. In the Save As dialog box, type a name for the file, and then click Save. Then it will be created as a zip file. Please send the zip file attached to this email
    +You may look online for more suitable steps for your computer if the above steps will not work.
    +Please let me know if you need any further assistance, I would be happy to help and assist further.
  12. +
\ No newline at end of file diff --git a/docs/Security/OWASP TOP 10.html b/docs/Security/OWASP TOP 10.html new file mode 100644 index 000000000..75dcb3506 --- /dev/null +++ b/docs/Security/OWASP TOP 10.html @@ -0,0 +1,17 @@ + + OWASP TOP 10 + + + + + + + + + + + +

OWASP TOP 10

\ No newline at end of file diff --git a/docs/Security/Secure Code Warriors.html b/docs/Security/Secure Code Warriors.html new file mode 100644 index 000000000..d1a63001c --- /dev/null +++ b/docs/Security/Secure Code Warriors.html @@ -0,0 +1,17 @@ + + Secure Code Warriors + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Technology/Coding Exercise.html b/docs/Technology/Coding Exercise.html new file mode 100644 index 000000000..5bd785a98 --- /dev/null +++ b/docs/Technology/Coding Exercise.html @@ -0,0 +1,73 @@ + + Coding Exercise + + + + + + + + + + + +

Objective

Assess your natural approach to coding and engineering best practices.

Pre-Requisites

    +
  1. Test the API Authentication.
  2. +
  3. Run the Code with your favorite IDE.
  4. +

Process

    +
  1. Refactor the code following SOLID principles.
  2. +
  3. Test the code.
  4. +
  5. Make the code production-ready.
  6. +

Code

public class Program
+{
+    static void Main(string[] args)
+    {
+        Task.Run(async () =>
+        {
+            //Get Repositories
+            await GetDetails("https://dev.azure.com/AcmeInc/ff86f2fb-5c3a-49e2-a677-c9b95d6baaef/_apis/tfvc/branches?includeParent=1&includeChildren=1&includeDeleted=1&includeLinks=1&api-version=6.0");
+            //Get Commits
+            await GetDetails("https://dev.azure.com/AcmeInc/ff86f2fb-5c3a-49e2-a677-c9b95d6baaef/_apis/git/repositories/4563efa9-da5d-4f54-b609-18db14479f48/commits?api-version=6.0");
+            //Get Pull Requests
+            await GetDetails("https://dev.azure.com/AcmeInc/ff86f2fb-5c3a-49e2-a677-c9b95d6baaef/_apis/git/repositories/4563efa9-da5d-4f54-b609-18db14479f48/pullrequests?searchCriteria.status=completed||searchCriteria.status=open?api-version=5.1");
+        }).Wait();
+    }
+
+
+    public static async Task GetDetails(string url)
+    {
+        try
+        {
+            var personalaccesstoken = "bGVtb25hY29AYWxsaWFuei1hc3Npc3RhbmNlLmNvbS5hdTpuZXczZ3ludmRpdWJpdno0djNoc2E1enpqMmF3ZGtvbzQ3ZnZxMzZ4aWJxb2x5Y203NnNx";
+
+            using (HttpClient client = new HttpClient())
+            {
+                client.DefaultRequestHeaders.Accept.Add(
+                    new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
+
+                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", personalaccesstoken);
+
+                using (HttpResponseMessage response = await client.GetAsync(url))
+                {
+                    response.EnsureSuccessStatusCode();
+
+                    var resultJson = await response.Content.ReadAsStringAsync();
+                    Console.WriteLine(resultJson);
+                }
+            }
+        }
+        catch (Exception ex)
+        {
+            Console.WriteLine(ex.ToString());
+        }
+    }
+}
+

API Authentication

\ No newline at end of file diff --git a/docs/Technology/HTTP 3.html b/docs/Technology/HTTP 3.html new file mode 100644 index 000000000..fca247c57 --- /dev/null +++ b/docs/Technology/HTTP 3.html @@ -0,0 +1,15 @@ + + HTTP 3 + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Testing/MsTest.html b/docs/Testing/MsTest.html new file mode 100644 index 000000000..0111eb784 --- /dev/null +++ b/docs/Testing/MsTest.html @@ -0,0 +1,14 @@ + + MsTest + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Testing/Playwright using .NET.html b/docs/Testing/Playwright using .NET.html new file mode 100644 index 000000000..687a924cf --- /dev/null +++ b/docs/Testing/Playwright using .NET.html @@ -0,0 +1,98 @@ + + Playwright using .NET + + + + + + + + + + + +

Quick Start Guide

    +
  1. Add Microsoft.Playwright package to the .NET application
  2. +
  3. Compile the application in Debug mode
  4. +
  5. Open Powershell
  6. +
  7. Run npm install @playwright/test
  8. +
  9. Run npx playwright install
  10. +
  11. Run `cd bin\Debug\net6.0\
  12. +
  13. Record the steps by running ./playwright.ps1 codegen wikipedia.org
  14. +
  15. Copy the steps into the .NET Application
  16. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
dddddddd
------
dddddd
\ No newline at end of file diff --git a/docs/Testing/Playwright using TypeScript.html b/docs/Testing/Playwright using TypeScript.html new file mode 100644 index 000000000..2ab6a8bff --- /dev/null +++ b/docs/Testing/Playwright using TypeScript.html @@ -0,0 +1,152 @@ + + Playwright using TypeScript + + + + + + + + + + + +

Playwright using TypeScript

Prerequisites

Installation

Run from your project's root directory

   npm init playwright@latest (if new project)
+

√ Do you want to use TypeScript or JavaScript? · TypeScript
+√ Where to put your end-to-end tests? · tests
+√ Add a GitHub Actions workflow? (y/N) · true
+√ Install Playwright browsers (can be done manually via npx playwright install)? (Y/n) · true

npm i -D playwright@latest (if existing project)
+npm i -D @cucumber/cucumber@latest
+npm i -D playwright-bdd@latest
+

Running the Example Test

By default tests will be run on all 3 browsers, chromium, firefox and webkit using 3 workers. This can be configured in the playwright.config file. Tests are run in headless mode meaning no browser will open up when running the tests. Results of the tests and test logs will be shown in the terminal.

npx playwright test
+

To open last HTML report run:

npx playwright show-report

Playwright Configuration

Add the following to `playwright.config.ts in the project root:

import { defineConfig, devices } from '@playwright/test';
+import { defineBddConfig } from 'playwright-bdd';
+
+const testDir = defineBddConfig({
+  paths: ['features/**/*.feature'],
+  require: ['steps/**/*.ts'],
+});
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+
+export default defineConfig({
+  testDir,
+  /* Run tests in files in parallel */
+  fullyParallel: true,
+  /* Fail the build on CI if you accidentally left test.only in the source code. */
+  forbidOnly: !!process.env.CI,
+  /* Retry on CI only */
+  retries: process.env.CI ? 2 : 0,
+  /* Opt out of parallel tests on CI. */
+  workers: process.env.CI ? 1 : undefined,
+  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+  reporter: 'html',
+  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+  use: {
+    /* Base URL to use in actions like `await page.goto('/')`. */
+    // baseURL: 'http://127.0.0.1:3000',
+    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+    trace: 'on-first-retry',
+    /*Show brownser*/
+    headless: false
+  },
+  /* Configure projects for major browsers */
+  projects: [
+    {
+      name: 'chromium',
+      use: { ...devices['Desktop Chrome'] },
+    },
+    {
+      name: 'firefox',
+      use: { ...devices['Desktop Firefox'] },
+    },  
+    {
+      name: 'webkit',
+      use: { ...devices['Desktop Safari'] },
+    },
+    /* Test against mobile viewports. */
+    // {
+    //   name: 'Mobile Chrome',
+    //   use: { ...devices['Pixel 5'] },
+    // },
+    // {
+    //   name: 'Mobile Safari',
+    //   use: { ...devices['iPhone 12'] },
+    // },
+    /* Test against branded browsers. */
+    // {
+    //   name: 'Microsoft Edge',
+    //   use: { ...devices['Desktop Edge'], channel: 'msedge' },
+    // },
+    // {
+    //   name: 'Google Chrome',
+    //   use: { ...devices['Desktop Chrome'], channel: 'chrome' },
+    // },
+  ],
+
+  /* Run your local dev server before starting the tests */
+  // webServer: {
+  //   command: 'npm run start',
+  //   url: 'http://127.0.0.1:3000',
+  //   reuseExistingServer: !process.env.CI,
+  // },
+
+});
+

Create BDD Test

Feature: Playwright site
+  
+    Scenario: Check title
+        Given I open url "https://playwright.dev"
+        When I click link "Get started"
+        Then I see in title "Playwright"
+

Run npx bddgen to generate Step Definition Code Snippet

Copy snippet into steps/test.ts

import { createBdd } from 'playwright-bdd';
+
+const { Given, When, Then } = createBdd();
+
+// 1. Missing step definition for "features\test.feature:4:9"
+Given('I open url {string}', async ({}, arg) => {
+  // ...
+});
+
+// 2. Missing step definition for "features\test.feature:5:9"
+When('I click link {string}', async ({}, arg) => {
+  // ...
+});
+
+// 3. Missing step definition for "features\test.feature:6:9"
+Then('I see in title {string}', async ({}, arg) => {
+  // ...
+});
+

Add import { expect } from '@playwright/test'; to steps/test.ts

Record Playwright Test

Copy code into Step definition

import { createBdd } from 'playwright-bdd';
+import { expect } from '@playwright/test';  
+
+const { Given, When, Then } = createBdd();
+
+Given('I open url {string}', async ({ page }, url) => {
+    await page.goto(url);
+});
+
+When('I click link {string}', async ({ page }, name) => {
+    await page.getByRole('link', { name }).click();
+});
+
+Then('I see in title {string}', async ({ page }, keyword) => {
+    await expect(page).toHaveTitle(new RegExp(keyword));
+});
+

Run Tests

Run npx bddgen to generate step definition template under .features-gen\features\ folder (each time feature file changes this is required)

Run all tests

npx playwright test
+

Run only tagged tests

npx playwright test --grep "@login"
+

Run with UI Mode (for troubleshooting)

npx playwright test --ui
+
\ No newline at end of file diff --git a/docs/Testing/WireMockNet.html b/docs/Testing/WireMockNet.html new file mode 100644 index 000000000..efdc8c9af --- /dev/null +++ b/docs/Testing/WireMockNet.html @@ -0,0 +1,21 @@ + + WireMockNet + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Tools/Docker CLI.html b/docs/Tools/Docker CLI.html new file mode 100644 index 000000000..04ce3ee78 --- /dev/null +++ b/docs/Tools/Docker CLI.html @@ -0,0 +1,38 @@ + + Docker CLI + + + + + + + + + + + +

Docker CLI

    +
  • Display containers' resource usage statistics docker stats --all --no-stream
  • +
  • Stop running containers docker kill $(docker ps -q)
  • +
  • Remove all containers docker rm $(docker ps -a -q)
  • +
  • Remove all images docker rmi $(docker images -q)
  • +

docker init Example of selecting ASP.NET

The following example shows the prompts that appear after selecting ASP.NET and example input. The ASP.NET template also creates a README.Docker.md file with additional information about building and deploying your application.

? What application platform does your project use? ASP.NET
+? What's the name of your solution's main project? myapp
+? What version of .NET do you want to use? 6.0
+? What local port do you want to use to access your server? 8000
+
+CREATED: .dockerignore
+CREATED: Dockerfile
+CREATED: compose.yaml
+CREATED: README.Docker.md
+
+✔ Your Docker files are ready!
+
+Take a moment to review them and tailor them to your application.
+
+When you're ready, start your application by running: docker compose up --build
+
+Your application will be available at http://localhost:8000
+

Tags

\ No newline at end of file diff --git a/docs/Tools/Docker Compose.html b/docs/Tools/Docker Compose.html new file mode 100644 index 000000000..3bc4ebc4a --- /dev/null +++ b/docs/Tools/Docker Compose.html @@ -0,0 +1,16 @@ + + Docker Compose + + + + + + + + + + + +

Docker Compose

Start-BitsTransfer -Source "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-windows-x86_64.exe" -Destination $Env:ProgramFiles\Docker\docker-compose.exe

docker-compose --version

docker-compose up 
+
\ No newline at end of file diff --git a/docs/Tools/Docker Desktop.html b/docs/Tools/Docker Desktop.html new file mode 100644 index 000000000..c5cea88ec --- /dev/null +++ b/docs/Tools/Docker Desktop.html @@ -0,0 +1,89 @@ + + Docker Desktop + + + + + + + + + + + +

Docker Desktop

Intro

Docker Desktop for Windows provides a development environment for building, shipping, and running dockerized apps. By enabling the WSL 2 based engine, you can run both Linux and Windows containers in Docker Desktop on the same machine.

Configuration

+

Warning
+This process requires reboot

+
    +
  1. Run Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
  2. +
  3. Run Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
  4. +
  5. Run winget install -e --id Docker.DockerDesktop
  6. +
  7. Run `winget install -e --id Docker.DockerCLI
  8. +
  9. Click Settings
  10. +
  11. Tick the “Start Docker Desktop when you log in“ option
  12. +
  13. Run systeminfo | find "System Type" to check if your system is x64 (if so, download wsl_update_x64.msi)
  14. +
  15. Run wsl --set-default-version 2
  16. +
  17. Run wsl --install -d Ubuntu (This is optional - Docker will configure docker-desktop-data as the default distro)
  18. +
  19. Create a default UNIX user account
  20. +
  21. Check WSL2 Settings
  22. +

Reinstall Distribution

wsl --list
+wsl --unregister Ubuntu
+wsl --list
+wsl --install -d Ubuntu
+

WSL Process

image

Configure WSL2

    +
  1. Run wsl --shutdown
  2. +
  3. Run notepad "$env:USERPROFILE/.wslconfig"
  4. +
[wsl2]
+memory=5GB   
+processors=1 
+

See all configuration options

Build and Run a Container

    +
  1. Navigate to the folder where the Dockerfile is stored
  2. +
  3. Run docker build -t angular-container:1.0 .
  4. +
  5. Search ImageID by running docker images
  6. +
  7. Run docker run -p 80:80 469b3a773ed7
  8. +

Dockerfile example

FROM node:lts as node
+
+RUN npm install -g @angular/cli
+
+WORKDIR /usr/src/app
+COPY src/TeamHub.UI/ ./my-app/
+
+WORKDIR /usr/src/app/my-app
+RUN npm install
+RUN npm run build
+
+FROM nginx:alpine
+COPY --from=node /usr/src/app/my-app/dist/team-hub.ui /usr/share/nginx/html
+

Images

docker pull jagregory/cognito-local:latest
+docker pull localstack/localstack:latest
+docker pull amazon/dynamodb-local:latest
+docker pull redis:latest
+docker pull mcr.microsoft.com/mssql/server:2022-latest
+docker pull datalust/seq:latest
+docker pull motoserver/moto:latest
+docker pull jijiechen/papercut:latest
+

Commands

    +
  • Display containers' resource usage statistics docker stats --all --no-stream
  • +
  • Stop running containers docker kill $(docker ps -q)
  • +
  • Remove all containers docker rm $(docker ps -a -q)
  • +
  • Remove all images docker rmi $(docker images -q)
  • +
\ No newline at end of file diff --git a/docs/Tools/GitHub Copilot.html b/docs/Tools/GitHub Copilot.html new file mode 100644 index 000000000..8b3bf8627 --- /dev/null +++ b/docs/Tools/GitHub Copilot.html @@ -0,0 +1,14 @@ + + GitHub Copilot + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Tools/Kubernetes.html b/docs/Tools/Kubernetes.html new file mode 100644 index 000000000..e471f3931 --- /dev/null +++ b/docs/Tools/Kubernetes.html @@ -0,0 +1,341 @@ + + Kubernetes + + + + + + + + + + + +

Kubernetes

winget install Kubernetes.kubectl

    +
  • Clusters -> Nodes -> PODs -> 1 or more containers
  • +
  • Controllers (Job / CronJob)
  • +
  • Worker
  • +
  • Ingress Controller (Nginx)
  • +

Update Kube File

aws eks update-kubeconfig --name au-sandbox --region ap-southeast-2

Kubernetes API

kubectl api-resources

Namespaces

kubectl create namespace leandrom
+kubectl delete namespace leandrom
+kubectl get namespaces

POD

https://kubernetes.io/docs/concepts/workloads/pods/
+kubectl apply -n leandrom -f hello-world.yml
+kubectl apply -f hello-world.yml
+kubectl get pods -n leandrom
+kubectl describe pod hello-world -n leandrom
+kubectl logs hello-world -n leandrom
+kubectl delete pod hello-world -n leandrom

hello-world.yml

apiVersion: v1
+kind: Pod
+metadata:
+  name: hello-world
+  namespace: leandrom
+spec:
+  restartPolicy: Always
+  containers:
+    - name: main
+      image: busybox
+      command: ['sh', '-c', 'echo $MESSAGE && sleep 10 && echo Bye!']
+      env:
+        - name: MESSAGE
+          value: "Hello env vars!"
+

Restart Policy

The spec of a Pod has a restartPolicy field with possible values Always, OnFailure, and Never. The default value is Always.

Controllers

Jobs

kubectl get job -n leandrom
+kubectl delete job hellojob -n leandrom

apiVersion: batch/v1
+kind: Job
+metadata:
+  name: hellojob
+  namespace: leandrom
+spec:
+  completions: 20
+  parallelism: 2
+  template:
+    metadata:
+      name: hello-job
+    spec:
+      containers:
+        - name: main
+          image: busybox
+          command: ['sh', '-c', 'echo $MESSAGE && sleep 10 && echo Bye!']
+          env:
+            - name: MESSAGE
+              value: "Hello env vars!"
+      restartPolicy: OnFailure
+

Cron Jobs

apiVersion: batch/v1
+kind: CronJob
+metadata:
+  name: hellocron
+  namespace: leandrom
+spec:
+  schedule: "* * * * *"
+  jobTemplate:
+    spec:
+      template:
+        spec:
+          containers:
+          - name: main
+            image: busybox
+            command: ['sh', '-c', 'echo $MESSAGE && sleep 10 && echo Bye!']
+            env:
+              - name: MESSAGE
+                value: "Hello env vars!"
+          restartPolicy: OnFailure
+

Export/Import Resources

kubectl get namespace leandrom -o yaml
+kubectl get pod debian -n leandrom -o yaml
+kubectl apply -f namespace.yaml
+kubectl apply -f pod.yaml

POD Controllers

Kubernetes provides 4 types of long running pod controllers:

    +
  • Deployments - Make sure n pods of the same type are running at any time. More ephemeral. They can share volumes. Best for stateless applications like APIs, microservices, webservers.
  • +
  • Statefulsets - Same as deployments but the network name of the pods are consistent and usually don’t share volumes (but might for coordination). Best for stateful applications like databases.
  • +
  • Daemonsets - Make sure one pod runs on every host.
  • +
  • Replicaset - Light implementation of pod replication that tries to keep a number of pods active at the same time, used by Deployments with improved features. Do not use directly.
  • +

Deployment

httpd.yml

apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: httpd
+  namespace: leandrom
+  labels:
+    app: httpd_app
+spec:
+  replicas: 4
+  selector:
+      matchLabels:
+        mypod: httpd_pod
+  template:
+    metadata:
+      labels:
+        mypod: httpd_pod
+    spec:
+      containers:
+        - name: main
+          image: httpd:latest
+          ports:
+            - containerPort: 80
+

kubectl apply -f httpd.yml
+kubectl get deployment -n leandrom
+kubectl get pods -n leandrom
+kubectl delete pod httpd-68d6cfbc7d-4f7hg -n leandrom
+kubectl edit deployment httpd -n leandrom
+kubectl describe deployment -n leandrom
+kubectl describe pod httpd-68d6cfbc7d-tcw75 -n leandrom (to get POD Internal IP Address)

Services

Each pod in a deployment has its own IP, however due to the dynamic nature of the clusters, pods can change along with their IPs so we can’t just rely on any static configuration. Fortunately Kubernetes has this covered by the Service resource.

A Kubernetes service is like a routing solution inside the cluster. It exposes all the pods belonging to a deployment, statefulset or daemonset under a static IP and DNS name and it is immediately updated if pods change. Services identify the member pods by labels.

Kubernetes also has an internal DNS server and every service receives a unique name in the form:

<servicename>.<namespace>.svc.cluster.local

kubectl get service -n leandrom
+kubectl describe svc helloworld -n leandrom

---
+apiVersion: v1
+kind: Service
+metadata:
+  name: helloworld
+  namespace: leandrom
+spec:
+  type: ClusterIP
+  selector:
+    mypod: httpd_pod
+  ports:
+    - port: 80
+      targetPort: 80
+

kubectl run debian --image debian -n leandrom -- sleep infinity
+kubectl exec -ti debian -n leandrom -- bash
+apt-get update
+apt-get install -y curl
+curl helloworld.leandrom.svc.cluster.local

Ingress

---
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name: helloworld
+  namespace: leandrom
+  annotations:
+    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
+    nginx.ingress.kubernetes.io/rewrite-target: "/"
+spec:
+  ingressClassName: sandbox-nlb
+  rules:
+  - host: helloworld.sandbox.au.humanforce.com
+    http:
+      paths:
+      - backend:
+          service:
+            name: helloworld
+            port:
+              number: 80
+        path: /leandrom
+        pathType: Prefix
+

kubectl get pods -n leandrom
+kubectl exec -ti httpd-68d6cfbc7d-nmhg8 -n leandrom -- bash
+# echo '<html><body><h1>Hello World Leo!</h1></body></html>' > htdocs/index.html # cat htdocs/index.html

POD Example

apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: httpd
+  namespace: leandrom
+  labels:
+    app: httpd_app
+spec:
+  replicas: 1
+  selector:
+      matchLabels:
+        mypod: httpd_pod
+  template:
+    metadata:
+      labels:
+        mypod: httpd_pod
+    spec:
+      containers:
+        - name: main
+          image: httpd:latest
+          ports:
+            - containerPort: 80
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: helloworld
+  namespace: leandrom
+spec:
+  type: ClusterIP
+  selector:
+    mypod: httpd_pod
+  ports:
+    - port: 80
+      targetPort: 80
+---
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name: helloworld
+  namespace: leandrom
+  annotations:
+    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
+    nginx.ingress.kubernetes.io/rewrite-target: "/"
+spec:
+  ingressClassName: sandbox-nlb
+  rules:
+  - host: helloworld.sandbox.au.humanforce.com
+    http:
+      paths:
+      - backend:
+          service:
+            name: helloworld
+            port:
+              number: 80
+        path: /leandrom
+        pathType: Prefix
+

Secrets

Secrets are resources holding a collection of key-value pairs. The most simple way to think about it is like a file with key-value pairs. Secrets can be clear or may be configured as opaque for a bit of obfuscation. More specialised secrets can be configured with third party backing solutions (i.e. Hashicorp Vault). The main objective of a secret is to be used as source for environment variables (but might be mounted as a file as well).

kubectl get secrets -n leandrom
+kubectl apply -f secrets.yml
+kubectl describe secret safe -n leandrom
+kubectl get secret safe -n leandrom -o yaml
+kubectl get secret safe -n leandrom -o jsonpath='{.data}' (this will show base64 encoded values)

secrets.yml

apiVersion: v1
+kind: Secret
+metadata:
+  name: safe
+  namespace: leandrom
+type: Opaque
+stringData:
+  user: leandrom
+  pass: "12345"
+

Consuming the secret

---
+apiVersion: v1
+kind: Pod
+metadata:
+  name: hello
+  namespace: guimo
+spec:
+  containers:
+    - name: main
+      image: busybox
+      command: ['sh', '-c', 'echo Hello $USER && sleep 10 && echo Bye!']
+      env:
+        - name: USER
+          valueFrom:
+            secretKeyRef:
+              name: safe
+              key: user
+

kubectl apply -f secrets.yml
+kubectl logs hello -n leandrom
+kubectl describe pod hello -n leandrom (environment variables don't show the secrets)

Configmaps

ConfigMaps are used to keep your application code separate from your configuration. Configmaps are very similar to Secrets, indeed a configmap can do almost anything you can do with a secret and even more, however the configmap is never encrypted and not designed to store secret information like passwords or certificates.

Same as a secret, a configmap is a key value store with the difference a configmap value can be multiline and describe a whole file. You can use it to define env vars but the main purpose is allowing you to define a configuration you would like to be applied at pod startup by mounting those files in the pod.

For this example, we will replace the index.html from the httpd service we are running for a new file that comes from the configmap. To do this, we are going to use the httpd.yaml file we created in the last session. First make a copy of the httpd.yaml to configmap.yaml (just for safekeeping)

cp httpd.yml configmap.yml
+add the below

---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: httpd
+  namespace: guimo
+data:
+  index.html: |
+    <html><body><h1>This file comes from my configmap</h1></body></html>
+

kubectl apply -f configmap.yml -n leandrom
+kubectl describe configmap httpd -n leandrom

So we have a configmap, now we need to mount this to the container. Edit your configmap.yaml file in the Deployment definition so it looks like this:

apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: httpd
+  namespace: leandrom
+  labels:
+    app: httpd_app
+spec:
+  replicas: 1
+  selector:
+      matchLabels:
+        mypod: httpd_pod
+  template:
+    metadata:
+      labels:
+        mypod: httpd_pod
+    spec:
+      containers:
+        - name: main
+          image: httpd:latest
+          ports:
+            - containerPort: 80
+          volumeMounts:
+          - name: index-config
+            mountPath: /usr/local/apache2/htdocs
+      volumes:
+        - name: index-config
+          configMap:
+            name: httpd
+

kubectl apply -f configmap.yml -n leandrom
+curl https://helloworld.sandbox.au.humanforce.com/leandrom

Mounting persistent volumes

As mentioned before, Persistent volumes are used to keep data generated by a service. Just don’t get confused by the term “persistent”, given the dynamic nature of cloud resources, we can spawn a volume for a couple hours then terminate them once we are done. By doing this we are never constrained to the host node restrictions.

For example, a host node may have a 50GB disk, but we need to uncompress a file of about 100GB size, then we can spawn a 100GB volume, attach to the pod, run our process then release the volume.

Kubernetes uses two levels of abstraction of the underlying file storage to mount filesystems to the pod.

    +
  • Persistent Volume (pv) - Describes the resource in its most basic level backed by a real resource like an EBS volume, an EFS/NFS storage and similar. When a PV is created, a real volume is created in the cloud.
    +
  • +
  • Persistent Volume Claim (pvc) - Is a request of storage space. When a PVC is created, the cluster will look for PVs with matching attributes and reserve the requested space if available. PVCs are then attached to pods via volumeMounts. Kubernetes can detach and reattach a PV and PVC to the appropriate nodes following the pod that requires them.
    +
  • +

Our clusters are configured with a dynamic provisioning that will automatically create a PV when a PVC is created, but it is possible to create the PV if you prefer a more fine grained control.

kubectl get storageclass

ebs-gp2         ebs.csi.aws.com         Delete          WaitForFirstConsumer   true  
+gp2 (default)   kubernetes.io/aws-ebs   Delete          WaitForFirstConsumer   false 
+

volume.yml

apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: bigdisk
+  namespace: leandrom
+spec:
+  accessModes:
+    - ReadWriteOnce
+  storageClassName: ebs-gp2
+  resources:
+    requests:
+      storage: 30Gi
+

kubectl apply -f volume.yml

## Init Containers

The idea of an init container is to execute some startup commands using public images without having to embed those commands into the main container image. As they work like regular pods, it is possible to mount shared filesystems or empty folders so they can write the command outputs for coordination; and as they are guaranteed to execute sequentially it is easy to coordinate the outputs as next step inputs.

volumes.yml

kubectl delete pod volumes -n leandrom
+kubectl apply -f volumes.yml

apiVersion: v1
+kind: Pod
+metadata:
+  name: volumes
+  namespace: leandrom
+spec:
+  securityContext:
+    runAsUser: 1000
+    runAsGroup: 1000
+    fsGroup: 1000
+  initContainers:
+    - name: download
+      image: curlimages/curl:latest
+      command: ['sh', '-c', "curl google.com -o /write/google.html"]
+      volumeMounts:
+        - mountPath: /write
+          name: shared-volume
+  containers:
+    - name: app
+      image: busybox:1.28
+      command: ['sh', '-c', 'cat /read/google.html']
+      volumeMounts:
+        - mountPath: /read
+          name: shared-volume
+  volumes:
+    - name: shared-volume
+      emptyDir:
+        sizeLimit: 100Mi
+
\ No newline at end of file diff --git a/docs/Tools/Microsoft Application Inspector.html b/docs/Tools/Microsoft Application Inspector.html new file mode 100644 index 000000000..225b8fc4f --- /dev/null +++ b/docs/Tools/Microsoft Application Inspector.html @@ -0,0 +1,22 @@ + + Microsoft Application Inspector + + + + + + + + + + + +

References

    +
  • Microsoft Application Inspector is a software source code characterization tool that helps identify coding features of first or third party software components based on well-known library/API calls and is helpful in Security and non-security use cases
  • +
  • “../assets/image_1667865747494_0.png” could not be found.
  • +
  • Additionally, it includes a confidence indicator (and filter) as well as the ability to drill down to the code file area where the match was found.
    +
    “../assets/image_1667865786921_0.png” could not be found.
  • +
\ No newline at end of file diff --git a/docs/Tools/NuGet.html b/docs/Tools/NuGet.html new file mode 100644 index 000000000..4f5d13e92 --- /dev/null +++ b/docs/Tools/NuGet.html @@ -0,0 +1,20 @@ + + NuGet + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Tools/Nuget CLI.html b/docs/Tools/Nuget CLI.html new file mode 100644 index 000000000..7d5d59d49 --- /dev/null +++ b/docs/Tools/Nuget CLI.html @@ -0,0 +1,17 @@ + + Nuget CLI + + + + + + + + + + + +

Nuget CLI

Installation

winget install -e --id Microsoft.NuGet

Feed

dotnet nuget add source https://api.nuget.org/v3/index.json -n nuget.org
+

Commands

You can list the local caches with this command:

nuget locals all -list
+

You can clear all caches with this command:

nuget locals all -clear
+
\ No newline at end of file diff --git a/docs/Tools/Proxy.html b/docs/Tools/Proxy.html new file mode 100644 index 000000000..342ccfefd --- /dev/null +++ b/docs/Tools/Proxy.html @@ -0,0 +1,14 @@ + + Proxy + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/Tools/Redash.html b/docs/Tools/Redash.html new file mode 100644 index 000000000..e7ffa051c --- /dev/null +++ b/docs/Tools/Redash.html @@ -0,0 +1,66 @@ + + Redash + + + + + + + + + + + +

Redash

Create docker-compose.yml

version: '3'
+
+services:
+  server:
+    image: redash/redash:latest
+    ports:
+      - 5000:5000
+    environment:
+      REDASH_LOG_LEVEL: "INFO"
+      REDASH_REDIS_URL: "redis://redis:6379/0"
+      REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
+      REDASH_RATELIMIT_ENABLED: "false"
+      REDASH_MAIL_DEFAULT_SENDER: "redash@example.com"
+      REDASH_MAIL_SERVER: "email"
+      REDASH_MAIL_PORT: 1025
+      REDASH_ENFORCE_CSRF: "true"
+      REDASH_GUNICORN_TIMEOUT: 60
+    depends_on:
+      - postgres
+      - redis
+      - email
+  
+  redis:
+    image: redis:7-alpine
+    restart: unless-stopped
+
+  postgres:
+    image: pgautoupgrade/pgautoupgrade:15-alpine3.8
+    ports:
+      - "5432:5432"
+    # The following turns the DB into less durable, but gains significant performance improvements for the tests run (x3
+    # improvement on my personal machine). We should consider moving this into a dedicated Docker Compose configuration for
+    # tests.
+    command: "postgres -c fsync=off -c full_page_writes=off -c synchronous_commit=OFF"
+    restart: unless-stopped
+    environment:
+      POSTGRES_HOST_AUTH_METHOD: "trust"
+
+  email:
+      image: maildev/maildev
+      ports:
+        - "1080:1080"
+        - "1025:1025"
+      restart: unless-stopped
+
    +
  • Run docker-compose up -d
  • +
  • Create tables docker-compose run --rm server create_db
  • +
  • Create database for tests docker-compose run --rm postgres psql -h postgres -U postgres -c "create database tests"
  • +
  • Test setup http://localhost:5000
  • +
\ No newline at end of file diff --git a/docs/Tools/SQL Lite.html b/docs/Tools/SQL Lite.html new file mode 100644 index 000000000..24f402299 --- /dev/null +++ b/docs/Tools/SQL Lite.html @@ -0,0 +1,16 @@ + + SQL Lite + + + + + + + + + + + +

SQL Lite

Winget Package
+winget install sqlitestudio.pl.SQLiteStudio

EF Core Package
+Microsoft.EntityFrameworkCore.Sqlite

"Data Source=mydatabase.db"

\ No newline at end of file diff --git a/docs/Tools/Slack CLI.html b/docs/Tools/Slack CLI.html new file mode 100644 index 000000000..d7cec3413 --- /dev/null +++ b/docs/Tools/Slack CLI.html @@ -0,0 +1,21 @@ + + Slack CLI + + + + + + + + + + + +

Slack CLI

Installation

    +
  1. Open Powershell Terminal
  2. +
  3. irm https://downloads.slack-edge.com/slack-cli/install-windows.ps1 | iex
  4. +
  5. slack login
  6. +
  7. Run /slackauthticket 5MzFjNmU3ThlMzQtZ0MTI1NDMzAyOWJLThlGUAtZjgxZkZi0 in any slack window
  8. +
  9. Authorize
    +Pasted image 20230731083648.png
  10. +
\ No newline at end of file diff --git a/docs/Tools/Sql Server.html b/docs/Tools/Sql Server.html new file mode 100644 index 000000000..6d0309e21 --- /dev/null +++ b/docs/Tools/Sql Server.html @@ -0,0 +1,213 @@ + + Sql Server + + + + + + + + + + + +

Sql Server

Installation

Local Server Instance

winget install -e --id Microsoft.SQLServer.2019.Express
+winget install -e --id Microsoft.SQLServer.2019.Developer --override '/QUIET /IACCEPTSQLSERVERLICENSETERMS /CONFIGURATIONFILE="C:\Dev\SQLConfigurationFile.ini"'
+

SQLConfigurationFile.ini

; Microsoft SQL Server Configuration file  
+[OPTIONS]  
+; Specifies a Setup work flow, like INSTALL, UNINSTALL, or UPGRADE.  
+; This is a required parameter.  
+ACTION="Install"  
+; Specifies features to install, uninstall, or upgrade.  
+; The list of top-level features include SQL, AS, RS, IS, and Tools.  
+; The SQL feature will install the database engine, replication, and full-text.  
+; The Tools feature will install Management Tools, Books online,   
+; SQL Server Data Tools, and other shared components.  
+FEATURES=SQL,Tools
+INSTANCENAME=SQL2019Dev
+SQLSYSADMINACCOUNTS="[Domain]\[Username]"
+SECURITYMODE=SQL
+SAPWD="S4P4ssw0rd"
+

Docker Image

docker pull mcr.microsoft.com/mssql/server:2019-latest
+docker pull mcr.microsoft.com/mssql/server:2022-latest
+

SQL Server Management Studio

winget install -e --id Microsoft.SQLServerManagementStudio
+winget upgrade -e --id Microsoft.SQLServerManagementStudio
+

Sqlcmd Tools

winget install -e --id Microsoft.Sqlcmd
+winget upgrade -e --id Microsoft.Sqlcmd
+

SQL Performance

Resources

Retries

Enable transient error resiliency by adding EnableRetryOnFailure to the UseSqlServer call on ASP.NET

Useful Commands

sp_helptext

Useful Queries

Backup


+--Windows
+BACKUP DATABASE [DbName] TO
+DISK = N'C:\Dev\Database\DbName.bak'
+WITH COMPRESSION, STATS = 10
+GO
+
+--Linux
+BACKUP DATABASE [DbName] TO
+DISK = N'/var/opt/mssql/data/DbName.bak'
+WITH COMPRESSION, STATS = 10
+GO
+

Paging

--https://learn.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql
+SELECT *
+FROM Employee
+ORDER BY EmployeeId
+OFFSET 20 ROWS
+FETCH NEXT 5 ROWS ONLY 
+

Restore

USE master;
+GO
+
+ALTER DATABASE [DbName]
+SET SINGLE_USER
+WITH ROLLBACK IMMEDIATE;
+GO
+
+RESTORE DATABASE [DbName]
+FROM DISK = N'C:\Dev\Database\DbName.bak'
+WITH RECOVERY
+GO
+
+RESTORE DATABASE [DbName]
+FROM DISK = N'C:\Dev\Database\DbName.bak'
+WITH MOVE 'DbName' TO 'C:\Dev\Database\DbName.mdf',
+   MOVE 'DbName_log' TO 'C:\Dev\Database\DbName_log.ldf',
+RECOVERY, REPLACE
+GO
+
+RESTORE DATABASE Local
+FROM DISK = N'/var/opt/mssql/data/Local.bak'
+WITH MOVE 'Database' TO '/var/opt/mssql/data/Local.mdf',
+     MOVE 'Database_Log' TO '/var/opt/mssql/log/Local.ldf',
+RECOVERY, REPLACE
+GO
+

Get all linked tables by FK

SELECT
+OBJECT_NAME(fkeys.constraint_object_id) foreign_key_name,
+OBJECT_NAME(fkeys.parent_object_id) referencing_table_name,
+COL_NAME(fkeys.parent_object_id, fkeys.parent_column_id) referencing_column_name,
+OBJECT_SCHEMA_NAME(fkeys.parent_object_id) referencing_schema_name,
+OBJECT_NAME (fkeys.referenced_object_id) referenced_table_name,
+COL_NAME(
+fkeys.referenced_object_id,
+fkeys.referenced_column_id
+) referenced_column_name,
+OBJECT_SCHEMA_NAME(fkeys.referenced_object_id) referenced_schema_name
+FROM
+sys.foreign_key_columns AS fkeys
+ORDER BY referenced_table_name
+

View the compatibility level of a database

USE AdventureWorks2019;  
+GO  
+SELECT compatibility_level  
+FROM sys.databases WHERE name = 'AdventureWorks2019';  
+GO
+

List all tables that are linked by foreign keys

SELECT 
+    FK_Table = FK.TABLE_NAME,
+    FK_Column = CU.COLUMN_NAME,
+    PK_Table = PK.TABLE_NAME,
+    PK_Column = PT.COLUMN_NAME,
+    Constraint_Name = C.CONSTRAINT_NAME
+FROM 
+    INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
+INNER JOIN 
+    INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK 
+        ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
+INNER JOIN 
+    INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK 
+        ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
+INNER JOIN 
+    INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU 
+        ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
+INNER JOIN 
+    (
+    SELECT 
+        i1.TABLE_NAME, 
+        i2.COLUMN_NAME
+    FROM 
+        INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
+    INNER JOIN 
+        INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 
+        ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
+    WHERE 
+        i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
+    ) PT 
+    ON PT.TABLE_NAME = PK.TABLE_NAME
+

List tables with no records

SELECT
+  t.NAME AS TableName,
+  p.rows AS RowCounts
+FROM
+  sys.tables t
+  INNER JOIN sys.partitions p ON t.object_id = p.OBJECT_ID
+WHERE
+  t.NAME NOT LIKE 'dt%'
+  AND t.is_ms_shipped = 0
+  AND p.rows = 0
+GROUP BY
+  t.Name,
+  p.Rows
+ORDER BY
+  t.Name
+

List all DB objects in a Database

SELECT name,*
+FROM [DBName].sys.all_objects
+WHERE upper(name) LIKE upper('%someName%')
+ORDER BY type_desc
+

Data Size

SELECT  CAST(SUM(TotalSize) AS varchar(255)) + ' bytes'
+FROM(
+		SELECT (DATALENGTH(Column) + 
+				DATALENGTH(Column) + 
+				DATALENGTH(Column) + 
+				DATALENGTH(Column) + 
+				DATALENGTH(Column)) AS TotalSize 
+		FROM TableName 
+) t
+

Encryption by Password

1 - Create Symmetric Key (one-off)

Encryption keys are generated by running the CREATE SYMMETRIC KEY command.

CREATE SYMMETRIC KEY [SymKey_SomeID] WITH ALGORITHM = AES_256,
+KEY_SOURCE = 'KEY_SOURCE_STRING',
+IDENTITY_VALUE = 'IDENTITY_VALUE_STRING' ENCRYPTION BY PASSWORD = 'eLtGc5woM&S$n5'
+
+-- View the newly created encryption
+SELECT * 
+FROM sys.symmetric_keys
+
+-- View the actual key data. At its lowest level, a 256 bit AES key is comprised of 256 bits (32 bytes) of data.
+SELECT * 
+FROM sys.key_encryptions
+

2 - Open Symmetric Key

A symmetric encryption key must be opened using the OPEN SYMMETRIC KEY command before it can be used.

OPEN SYMMETRIC KEY [SymKey_SomeID] 
+DECRYPTION BY PASSWORD = 'eLtGc5woM&S$n5'
+

3 - Encrypt Data

Data can be encrypted using the SQL function ENCRYPTBYKEY.

The authenticator value is used as an additional piece of data against which the encryption will be validated. If the same context (including authenticator) is not provided again when decrypting, then decryption will fail.

The following SQL statement demonstrates encrypting a string using a GUID value as an authenticator:

DECLARE @keyId UNIQUEIDENTIFIER = (SELECT key_guid FROM sys.symmetric_keys WHERE name='SymKey_SomeID')
+DECLARE @auth VARCHAR(40) = '7AECFD07-4643-41FC-B17C-472AD71699E7'
+DECLARE @str VARCHAR(50) = 'Super secret string data'
+SELECT ENCRYPTBYKEY(@keyId, @str, 1, @auth)
+

4 - Decrypt Data

DECLARE @encryptedData VARBINARY(200) = 0x00983DD06D6B6AC67A112F2A8866927A020000005A05FE279810FC3A75B27979324C9C81EBCE0D65AD8E2312ACBC5E23A49F135FFE44453511432DDF7C68D764865DE75C12F692E50B0B6EC5F3FD2C0E4C2C68DE5EEB8F773DA407DA32D6C79C5EF6F0BA
+DECLARE @auth VARCHAR(40) = '7AECFD07-4643-41FC-B17C-472AD71699E7'
+SELECT CONVERT(VARCHAR(100), DECRYPTBYKEY(@encryptedData, 1, @auth))
+

Troubleshooting


Error: 'Agent XPs' component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'Agent XPs' by using sp_configure. For more information about enabling 'Agent XPs', see "Surface Area Configuration" in SQL Server Books Online. (Microsoft.SqlServer.Management.MaintenancePlanWizard)

Solution:

sp_configure 'show advanced options', 1;  
+GO  
+RECONFIGURE;  
+GO  
+sp_configure 'Agent XPs', 1;  
+GO  
+RECONFIGURE  
+GO
+

Error: SQLServerAgent is not currently running so it cannot be notified of this action. (Microsoft SQL Server, Error: 22022)

Solution: Open SQL Server Configuration Manager and enable SQL Server Agent Service


Error: Cannot execute as the database principal because the principal ‘dbo’ does not exist, this type of principal cannot be impersonated, or you do not have permission. (Microsoft SQL Server, Error: 15517)

Solution:

USE [AdventureWorks]
+GO
+ALTER AUTHORIZATION ON DATABASE::[AdventureWorks] TO [sa]
+GO
+

\ No newline at end of file diff --git a/docs/Tools/Visual Studio.html b/docs/Tools/Visual Studio.html new file mode 100644 index 000000000..75cebaf65 --- /dev/null +++ b/docs/Tools/Visual Studio.html @@ -0,0 +1,95 @@ + + Visual Studio + + + + + + + + + + + +

Visual Studio

<<<<<<< HEAD

Installation

>>>>>>> e89b33083bcb8beb793b776dec7c4eab0dce39bd
+ winget install -e --id Microsoft.VisualStudio.2019.Professional
+ winget install -e --id Microsoft.VisualStudio.2022.Enterprise
+ winget install -e --id Microsoft.VisualStudio.2022.TestController
+ winget install -e --id Microsoft.VisualStudio.2022.TestAgent
+ winget install -e --id Microsoft.VisualStudio.2022.TeamExplorer
+ winget install -e --id Microsoft.VisualStudio.2022.Professional
+ winget install -e --id Microsoft.VisualStudio.2022.Enterprise
+ winget install -e --id Microsoft.VisualStudio.2022.Community
+ winget install -e --id Microsoft.VisualStudio.2022.BuildTools
+

Extensions


+#Credits: https://gist.github.com/ScottHutchinson/b22339c3d3688da5c9b477281e258400
+#$PackageName = "AmazonWebServices.AWSToolkitforVisualStudio2022"
+#$PackageName = "GitHub.copilotvs"
+#$PackageName = "SteveCadwallader.CodeMaid"
+#$PackageName = "SteveCadwallader.CodeMaidVS2022"
+#$PackageName = "ironcev.sharpen"
+#$PackageName = "SonarSource.SonarLintforVisualStudio2022"
+#$PackageName = "DevExpress.CodeRushforVS2022"
+#$PackageName = "MLNET.notebook"
+#$PackageName = "VisualStudioProductTeam.ProjectSystemTools2022"
+$PackageName = "snyk-security.snyk-vulnerability-scanner-vs-2022"
+
+$ErrorActionPreference = "Stop"
+
+$baseProtocol = "https:"
+$baseHostName = "marketplace.visualstudio.com"
+
+$Uri = "$($baseProtocol)//$($baseHostName)/items?itemName=$($PackageName)"
+$VsixLocation = "$($env:Temp)\$([guid]::NewGuid()).vsix"
+
+$VSInstallDir = "C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service"
+
+if (-Not $VSInstallDir) {
+Write-Error "Visual Studio InstallDir registry key missing"
+Exit 1
+}
+
+Write-Host "Grabbing VSIX extension at $($Uri)"
+$HTML = Invoke-WebRequest -Uri $Uri -UseBasicParsing -SessionVariable session
+
+Write-Host "Attempting to download $($PackageName)..."
+$anchor = $HTML.Links |
+Where-Object { $_.class -eq 'install-button-container' } |
+Select-Object -ExpandProperty href
+
+if (-Not $anchor) {
+Write-Error "Could not find download anchor tag on the Visual Studio Extensions page"
+Exit 1
+}
+Write-Host "Anchor is $($anchor)"
+$href = "$($baseProtocol)//$($baseHostName)$($anchor)"
+Write-Host "Href is $($href)"
+Invoke-WebRequest $href -OutFile $VsixLocation -WebSession $session
+
+if (-Not (Test-Path $VsixLocation)) {
+Write-Error "Downloaded VSIX file could not be located"
+Exit 1
+}
+Write-Host "VSInstallDir is $($VSInstallDir)"
+Write-Host "VsixLocation is $($VsixLocation)"
+Write-Host "Installing $($PackageName)..."
+Start-Process -Filepath "$($VSInstallDir)\VSIXInstaller" -ArgumentList "/q /a $($VsixLocation)" -Wait
+
+Write-Host "Cleanup..."
+rm $VsixLocation
+
+Write-Host "Installation of $($PackageName) complete!"
+

Features

\ No newline at end of file diff --git a/docs/Tools/Windows Terminal.html b/docs/Tools/Windows Terminal.html new file mode 100644 index 000000000..01b143adc --- /dev/null +++ b/docs/Tools/Windows Terminal.html @@ -0,0 +1,36 @@ + + Windows Terminal + + + + + + + + + + + +

Windows Terminal

Installation

    +
  1. Install Caskaydia Cove Nerd Font Complete Regular.otf
  2. +
  3. Run winget install --id Microsoft.WindowsTerminal
  4. +
  5. Run winget install --id Microsoft.PowerShell
  6. +
  7. Run winget install --id JanDeDobbeleer.OhMyPosh
  8. +
  9. Run Install-Module PSReadLine -AllowPrerelease -Force
  10. +
  11. Run notepad $PROFILE
  12. +
  13. Add these lines
  14. +
oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH\jandedobbeleer.omp.json" | Invoke-Expression
+Import-Module PSReadLine
+Set-PSReadLineOption -PredictionSource History  
+Set-PSReadLineOption -PredictionViewStyle ListView  
+Set-PSReadLineOption -EditMode Windows
+
    +
  1. Restart command prompt window
  2. +
  3. Go to Settings -> Profile -> Appearance
  4. +
  5. Check "Show all fonts"
  6. +
  7. Choose the CaskaydiaCove Nerd Font
  8. +
\ No newline at end of file diff --git a/docs/development/devcontainers.html b/docs/development/devcontainers.html index 11c1e905e..bf96e81d3 100644 --- a/docs/development/devcontainers.html +++ b/docs/development/devcontainers.html @@ -1,83 +1,51 @@ - - - + DevContainers - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
DevContainers
    -
  • + + + + + + + +

    Training

      +
      1. -
      2. Check if Docker is installed by running docker version
      3. +
      4. Check if Build and Run a Container with Docker is installed by running docker version
    • -
    • +
      1. -
      2. Install VSCode and its extensions
      3. +
      4. Install VSCode and its extensions
    • -
    • +
    • winget install -e --id Microsoft.VisualStudioCode  
       code --install-extension ms-vscode-remote.remote-containers  
       code --install-extension ms-python.python
       
    • -
    • +
      1. -
      2. Click
        "../assets/image_1667341230993_0.png" is not created yet. Click to create.
        located at the bottom left of the screen
      3. +
      4. Click
        “../assets/image_1667341230993_0.png” could not be found.
        located at the bottom left of the screen
      5. Search for "Add Dev Container Configuration Files" and follow the steps
      6. Once the setup is finished, the following 2 files will appear
    • -
    • -
    • +
    • +
      1. -
      2. Click
        "../assets/image_1667341230993_0.png" is not created yet. Click to create.
        and write "Reopen in container"
      3. -
      4. VSCode will restart and you will see this
        "../assets/image_1667430653209_0.png" is not created yet. Click to create.
      5. +
      6. Click
        “../assets/image_1667341230993_0.png” could not be found.
        and write "Reopen in container"
      7. +
      8. VSCode will restart and you will see this
        “../assets/image_1667430653209_0.png” could not be found.
    • -

    Training

    \ No newline at end of file +
\ No newline at end of file diff --git a/docs/development/developer-productivity.html b/docs/development/developer-productivity.html deleted file mode 100644 index 238ea1adc..000000000 --- a/docs/development/developer-productivity.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - Developer Productivity - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/docs/development/development-environment-setup.html b/docs/development/development-environment-setup.html deleted file mode 100644 index 5078ecb5a..000000000 --- a/docs/development/development-environment-setup.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - Development Environment Setup - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Development Environment Setup

Essentials

Using a WinGet Configuration file, you can consolidate manual machine setup and project onboarding to a single command that is reliable and repeatable.

| :memo: | TODO: Migrate this to Winget Configuration |

Tools

Browsers

winget install -e --id Microsoft.Edge.Dev
-winget install -e --id BraveSoftware.BraveBrowser
-winget install -e --id Microsoft.Edge
-winget install -e --id Google.Chrome.Dev
-winget install -e --id Mozilla.Firefox.DeveloperEdition
-winget install -e --id Opera.Opera
-

Dev Tools

https://learn.microsoft.com/en-nz/azure/developer/dev-tunnels/
-winget install -e --id Microsoft.NuGet
-winget install -e --id Postman.Postman
-winget install -e --id Docker.DockerDesktop
-winget install -e --id Datalust.Seq
-winget install -e --id Microsoft.DeploymentToolkit
-winget install -e --id Microsoft.webpicmd
-winget install --name RedisInsight
-winget install -e --id Microsoft.PowerAutomateDesktop
-winget install -e --id Gauge.Gauge
-

Development Utilities

dotnet tool install -g Microsoft.Tye --version "0.11.0-alpha.22111.1"
-winget install -e --id Dapr.CLI --silent
-winget install -e --id Microsoft.RemoteDesktopClient
-winget install -e --id ScooterSoftware.BeyondCompare4
-winget install -e --id LINQPad.LINQPad.7
-winget install -e --id Microsoft.XMLNotepad
-winget install -e --id Notepad++.Notepad++
-winget install -e --id WinMerge.WinMerge
-winget install -e --name Sysinternals
-winget install -e --id Microsoft.WindowsTerminal
-winget install -e --id Telerik.Fiddler.Everywhere
-winget install -e --id WiresharkFoundation.Wireshark
-winget install -e --id=Amazon.NoSQLWorkbench 
-winget install DevToys
-

Misc

winget install "Files App"
-winget install -e --id 7zip.7zip
-winget install -e --id Microsoft.PowerToys
-winget install -e --id VideoLAN.VLC
-winget install -e --id ShareX.ShareX
-winget install -e --id Grammarly.ForOffice
-winget install -e --id Grammarly.ForWindows
-winget install -e --id OBSProject.OBSStudio
-winget install -e --id JGraph.Draw
-winget install -e --id GIMP.GIMP
-winget install -e --id JAMSoftware.TreeSize.Free
-winget install -e --id Logseq.Logseq
-winget install -e --id Twilio.Authy
-
\ No newline at end of file diff --git a/docs/devops/observability.html b/docs/devops/observability.html index 31cc024d9..f7728209c 100644 --- a/docs/devops/observability.html +++ b/docs/devops/observability.html @@ -1,49 +1,17 @@ - - - + Observability - - - - + + - - - - - - - - - - - - - - - - - - - - - - -

Prerequisites

Perpetually free New Relic account, 100 GB/month of free data ingest, 1 free full access user, unlimited free basic users

Reference Material

\ No newline at end of file + + + + + + + +

Prerequisites

Perpetually free New Relic account, 100 GB/month of free data ingest, 1 free full access user, unlimited free basic users

\ No newline at end of file diff --git a/docs/documentation/diagramsascode.html b/docs/documentation/diagramsascode.html index 5fe0baf4c..9a8c4d1d1 100644 --- a/docs/documentation/diagramsascode.html +++ b/docs/documentation/diagramsascode.html @@ -1,46 +1,14 @@ - - - + DiagramsAsCode - - - - + + - - - - - - - - - - - - - - - - - - - - - - -

Sequence Diagram

ClassAClassBMethod1()response1Method2()response2ClassAClassB
\ No newline at end of file + + + + + + + +

Sequence Diagram

ClassBClassAClassBClassAMethod1()response1Method2()response2
\ No newline at end of file diff --git a/docs/documentation/documentation.html b/docs/documentation/documentation.html index 5c8515169..3c9c5e86c 100644 --- a/docs/documentation/documentation.html +++ b/docs/documentation/documentation.html @@ -1,56 +1,24 @@ - - - + Documentation - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
Documentation
    -
  • + + + + + + + +
    \ No newline at end of file +
\ No newline at end of file diff --git a/docs/dotnet/asp.net.html b/docs/dotnet/asp.net.html index 6386ea994..7a3164b01 100644 --- a/docs/dotnet/asp.net.html +++ b/docs/dotnet/asp.net.html @@ -1,52 +1,20 @@ - - - + ASP.NET - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
ASP.NET
    -
  • https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services
    + + + + + + + +
    \ No newline at end of file +
\ No newline at end of file diff --git a/docs/dotnet/cli/dotnet-list-package.html b/docs/dotnet/cli/dotnet-list-package.html deleted file mode 100644 index 6f18b6c38..000000000 --- a/docs/dotnet/cli/dotnet-list-package.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - dotnet list package - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
  • -

    dotnet list package command in the .NET Core CLI tools to fetch installed packages for a given solution or project. Use it like so from the Windows command line:

    -

    dotnet list "C:\Source\MySolution\MySolution.sln" package

    -

    It works on both .NET Framework and .NET Core projects.

    -

    Note: For this command to work, the solution must use the new NuGet PackageReference format for referencing NuGet packages.

    -

    Migration is as easy as right-clicking packages.config, and clicking Migrate packages.config to PackageReference..., then restoring packages by building the solution.

    -
  • -

Parameters

\ No newline at end of file diff --git a/docs/dotnet/cli/dotnet-monitor.html b/docs/dotnet/cli/dotnet-monitor.html deleted file mode 100644 index 548450bfb..000000000 --- a/docs/dotnet/cli/dotnet-monitor.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - dotnet monitor - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/docs/dotnet/configuration.html b/docs/dotnet/configuration.html index fb01d8550..a40bc6e88 100644 --- a/docs/dotnet/configuration.html +++ b/docs/dotnet/configuration.html @@ -1,49 +1,22 @@ - - - + Configuration - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
Configuration

Packages

Implementation

Singleton

using Microsoft.Extensions.Configuration;
+		
+		
+		
+		
+		
+		
+		
+		

Configuration

Implementation

Singleton

using Microsoft.Extensions.Configuration;
 
 public static class ConfigurationManager
 {
@@ -65,11 +38,11 @@
         }
     }
 }
-

Usage

ConfigurationManager.Configuration["SomeConfig"]

Code Sample

.NET Console App

 var configuration = new ConfigurationBuilder()
+

Usage

ConfigurationManager.Configuration["SomeConfig"]

Code Sample

.NET Console App

 var configuration = new ConfigurationBuilder()
                                         .SetBasePath(AppContext.BaseDirectory)
                                         .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                                         .Build();
-

ASP.NET

private static ConfigurationManager GetConfiguration(ConfigurationManager configurationManager)
+

ASP.NET

private static ConfigurationManager GetConfiguration(ConfigurationManager configurationManager)
 {
     configurationManager
                  .SetBasePath(AppContext.BaseDirectory)
@@ -80,12 +53,12 @@
 
     return configurationManager;
 }
-

Add Configuration File to csproj

<ItemGroup>
+

Add Configuration File to csproj

<ItemGroup>
     <None Update="appsettings.json">
         <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
 </ItemGroup>
-

Cross-Platform Support

The : separator doesn't work with environment variable hierarchical keys on all platforms. __, the double underscore, is supported by all platforms.

+

Cross-Platform Support

The : separator doesn't work with environment variable hierarchical keys on all platforms. __, the double underscore, is supported by all platforms.

@@ -96,7 +69,7 @@ -
:warning: WARNINGAppPrefix:ModuleConfiguration:Infrastructure:Redis:Port would need to be translated to AppPrefix__ModuleConfiguration__Infrastructure__Redis__Port

Set Environment Variable

+

Set Environment Variable

@@ -107,11 +80,11 @@ -
:warning: WARNINGWhen creating/removing Environment Variables, Visual Studio MUST be restarted to pick up the changes.
    -
  • setx Lambda__ModuleConfiguration__Infrastructure__Cognito__ValidIssuer "SOME VALUE" /M
  • -
  • setx Lambda__ModuleConfiguration__Infrastructure__Cognito__ClientId "SOME VALUE" /M
  • -
  • setx ASPNETCORE_ENVIRONMENT "Development" /M or setx ASPNETCORE_ENVIRONMENT "Staging" /M or setx ASPNETCORE_ENVIRONMENT "Production" /M
  • -

Safe storage of app secrets in development

    +
    +
  • setx Lambda__ModuleConfiguration__Infrastructure__Cognito__ValidIssuer "SOME VALUE" /M
  • +
  • setx Lambda__ModuleConfiguration__Infrastructure__Cognito__ClientId "SOME VALUE" /M
  • +
  • setx ASPNETCORE_ENVIRONMENT "Development" /M or setx ASPNETCORE_ENVIRONMENT "Staging" /M or setx ASPNETCORE_ENVIRONMENT "Production" /M
  • +

Safe storage of app secrets in development

  1. Add a reference to the Microsoft.Extensions.Configuration.UserSecrets package
  2. Navigate to your .NET project folder
  3. Run dotnet user-secrets init (one-off per project)
  4. @@ -119,18 +92,13 @@
  5. Read the value in your application
var configuration = new ConfigurationBuilder().AddUserSecrets("[ID obtained from step 3]").Build();
 var value = configuration["Segment:SomeConfig"];
-

Values are stored on C:\Users\<username>\AppData\Roaming\Microsoft\UserSecrets

Documentation

Troubleshooting

    -
  • Issue: ASP.NET Core: AddEnvironmentVariables doesn't load variables
  • -
  • Cause: You probably just declared your Environment Variables hence Visual Studio does not see them.
  • -
  • Resolution: Restart your Visual Studio.
  • -
\ No newline at end of file +

Values are stored on C:\Users\<username>\AppData\Roaming\Microsoft\UserSecrets

Troubleshooting

    +
  • Issue: ASP.NET Core: AddEnvironmentVariables doesn't load variables
  • +
  • Cause: You probably just declared your Environment Variables hence Visual Studio does not see them.
  • +
  • Resolution: Restart your Visual Studio.
  • +
\ No newline at end of file diff --git a/docs/dotnet/csharp.html b/docs/dotnet/csharp.html index f63ac73ea..1a1ddcbc8 100644 --- a/docs/dotnet/csharp.html +++ b/docs/dotnet/csharp.html @@ -1,46 +1,14 @@ - - - + CSharp - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file + + + + + + + +
\ No newline at end of file diff --git a/docs/dotnet/deployment.html b/docs/dotnet/deployment.html index 37860ccf3..a37961334 100644 --- a/docs/dotnet/deployment.html +++ b/docs/dotnet/deployment.html @@ -1,48 +1,16 @@ - - - + Deployment - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file + + + + + + + +
\ No newline at end of file diff --git a/docs/dotnet/entityframework.html b/docs/dotnet/entityframework.html index 48c57757e..5a4df76ac 100644 --- a/docs/dotnet/entityframework.html +++ b/docs/dotnet/entityframework.html @@ -1,65 +1,39 @@ - - - + EntityFramework - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
EntityFramework

EF CLI

Commands

    -
  • Install: dotnet tool install --global dotnet-ef
  • -
  • Update: dotnet tool update --global dotnet-ef
  • -

Create/Update Model (Database First)

    + + + + + + + +

    EntityFramework

    EF CLI

    Commands

      +
    • Install: dotnet tool install --global dotnet-ef
    • +
    • Update: dotnet tool update --global dotnet-ef
    • +

    Create/Update Model (Database First)

    1. .csproj file must reference the following nuget packages: -
        -
      • Microsoft.EntityFrameworkCore.Design
      • -
      • Microsoft.EntityFrameworkCore.SqlServer
      • +
          +
        • Microsoft.EntityFrameworkCore.Design
        • +
        • Microsoft.EntityFrameworkCore.SqlServer
        • +
        • Microsoft.EntityFrameworkCore.Sqlite
        -
      • Navigate to the folder where you want to store the model
      • -
      • Update EF Model Classes dotnet ef dbcontext scaffold "Server=localhost;Database=DbName;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -o Database -f --project C:\Dev\Something.csproj
      • -

    Connection String

dotnet ef dbcontext scaffold "Server=localhost;Database=DbName;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -o Database -f --project C:\Dev\Something.csproj

dotnet ef dbcontext scaffold "DataSource='C:\ScrumTeamSqlLite3.db" Microsoft.EntityFrameworkCore.Sqlite -o Database -f --project C:\Dev\Something.csproj

Connection String

Search for DbContext.cs class

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
 {
     var connectionString = "Persist Security Info=False;User ID=*****;Password=*****;Initial Catalog=AdventureWorks;Server=MySqlServer";
     optionsBuilder.UseSqlServer(connectionString);
 }
-

Logging

This will allow us to see the SQL Queries being executed

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+

Logging

This will allow us to see the SQL Queries being executed

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
 {
     var connectionString = "Persist Security Info=False;User ID=*****;Password=*****;Initial Catalog=AdventureWorks;Server=MySqlServer";
     optionsBuilder.LogTo(Console.Write, LogLevel.Trace)
@@ -67,9 +41,4 @@
                   .EnableDetailedErrors()
                   .UseSqlServer(connectionString);
 }
-
\ No newline at end of file + \ No newline at end of file diff --git a/docs/dotnet/libraries/identityserver.html b/docs/dotnet/libraries/identityserver.html index 4444ee67d..49f1b76cb 100644 --- a/docs/dotnet/libraries/identityserver.html +++ b/docs/dotnet/libraries/identityserver.html @@ -1,54 +1,22 @@ - - - + IdentityServer - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
IdentityServer

Examples

    + + + + + + + +
    \ No newline at end of file +

Reference Material

\ No newline at end of file diff --git a/docs/dotnet/libraries/microsoft.featuremanagement.html b/docs/dotnet/libraries/microsoft.featuremanagement.html deleted file mode 100644 index f76e8cb14..000000000 --- a/docs/dotnet/libraries/microsoft.featuremanagement.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - Microsoft.FeatureManagement - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Objective

To implement a Feature Management solution that allows us to change application behaviour without changing code.

AWS AppConfig

AWS AppConfig is a capability of AWS Systems Manager, to create, manage, and quickly deploy application configurations. A configuration is a collection of settings that influence the behavior of the application.

The Amazon.Extensions.Configuration.SystemsManager simplifies using AWS AppConfig as a source for configuration information for .NET applications.

Microsoft.FeatureManagement

Microsoft.FeatureManagement provides standardized APIs for enabling feature flags within applications. This library secures a consistent experience when developing applications that use patterns such as beta access, rollout, dark deployments, and more.

Configuration Sample

"FeatureFlags": {
-        "featureA": false,
-        "featureB": true,
-        "featureC": false,
-        "featureD": {
-            "EnabledFor": [
-                {
-                    "Name": "Microsoft.Targeting",
-                    "Parameters": {
-                        "Audience": {
-                            "Users": [
-                                "{tenantId}:{userId}",
-                                "{tenantId}:{userId2}"
-                            ],
-                            "Groups": [
-                                {
-                                    "Name": "{tenantId}",
-                                    "RolloutPercentage": 0
-                                },
-                                {
-
-                                    "Name": "{tenantId2}",
-                                    "RolloutPercentage": 50
-                                },
-                                {
-
-                                    "Name": "{tenantId3}",
-                                    "RolloutPercentage": 100
-                                }
-                            ],
-                            "DefaultRolloutPercentage": 0
-                        }
-                    }
-                }
-            ]
-        }
-    }
-
\ No newline at end of file diff --git a/docs/dotnet/libraries/nukebuild.html b/docs/dotnet/libraries/nukebuild.html index d9679b6d5..ad7f7a197 100644 --- a/docs/dotnet/libraries/nukebuild.html +++ b/docs/dotnet/libraries/nukebuild.html @@ -1,60 +1,33 @@ - - - + NukeBuild - - - - + + - - - - - - - - - - - - - - - - - - - - - - -

Nuke Build Setup

Installation

    + + + + + + + +

    Nuke Build Setup

    Installation

    1. Run dotnet tool install Nuke.GlobalTool --global
    2. Run nuke :setup
    3. -

    image

      -
    • +

image

    +
  • Documentation

  • -
  • +
  • Cli-tools Support

  • -
  • +
  • See Example

  • -
  • +
  • Run dotnet run --plan from build folder to see Execution Plan

  • -
  • +
  • Run dotnet run --Param1 "value" --Param2 "value" --Param3 "value"

Notes:

    @@ -64,9 +37,4 @@
  1. Update Solution Name in the .nuke/parameters.json file
  2. Create the version.json file under each component that must be versioned (required for GitVersioning to calculate the semantic version number)
  3. Create deployment_list.json file (required for the pipeline to know which components should be packed for deployment)
  4. -
\ No newline at end of file +

https://github.com/OctopusDeploy/OctoVersion

\ No newline at end of file diff --git a/docs/dotnet/libraries/playwright.html b/docs/dotnet/libraries/playwright.html deleted file mode 100644 index ce6c5563c..000000000 --- a/docs/dotnet/libraries/playwright.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - Playwright - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Quick Start Guide

    -
  1. Add Microsoft.Playwright package to the .NET application
  2. -
  3. Compile the application in Debug mode
  4. -
  5. Record the steps by running pwsh bin\Debug\net6.0\playwright.ps1 codegen wikipedia.org
  6. -
  7. Copy the steps into the .NET Application
  8. -

Resources

\ No newline at end of file diff --git a/docs/dotnet/libraries/wiremocknet.html b/docs/dotnet/libraries/wiremocknet.html deleted file mode 100644 index 5b9000bce..000000000 --- a/docs/dotnet/libraries/wiremocknet.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - WireMockNet - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/docs/dotnet/libraries/yarp.html b/docs/dotnet/libraries/yarp.html index 1516f8d5c..a7e88a043 100644 --- a/docs/dotnet/libraries/yarp.html +++ b/docs/dotnet/libraries/yarp.html @@ -1,48 +1,16 @@ - - - + YARP - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file + + + + + + + +
\ No newline at end of file diff --git a/docs/dotnet/minimalapi.html b/docs/dotnet/minimalapi.html index 2c61404ff..f350944ec 100644 --- a/docs/dotnet/minimalapi.html +++ b/docs/dotnet/minimalapi.html @@ -1,49 +1,17 @@ - - - + MinimalAPI - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file + + + + + + + +
\ No newline at end of file diff --git a/docs/email-templates/knowledge-sharing.html b/docs/email-templates/knowledge-sharing.html deleted file mode 100644 index 0bb807a2a..000000000 --- a/docs/email-templates/knowledge-sharing.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - Knowledge Sharing - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Email 1 (2 weeks prior to launch)

Hi team,

I’m excited to share that we’re giving each of you access to Stack Overflow for Teams, a secure and private place for you to share and find knowledge related to our technology and company. Instead of getting pinged through chat or email for information causing distractions, we’ll be able to work more asynchronously by storing our team knowledge in one central location for any of us to access at any time.

To help you get familiar, you can watch the following short videos:

How to ask and answer a question

How to write an Article

How to create a Collection

You can also check out this user guide on how to use Stack Overflow for Teams.

We’ll be releasing this company-wide on ___ so be on the lookout for an invite!

In the meantime, start thinking about the most common questions you get asked - we’ll be asking you to transfer that knowledge into our brand new Stack Overflow for Team when we launch. More to come about this exciting addition to our tools tech stack!

Please let me know if you have any questions.

Email 2 (1 week prior to launch)

Hi there,

As I’ve mentioned, we’re counting down the days to launch for Stack Overflow for Teams, and I’m asking you to take 30 minutes between now and then to gather some of the most frequently asked questions that you hear on chat or in email and jot them down. These questions might sound like:

How do I find...?

What is the process for…?

Who is responsible for... ?

Does anyone know about…?

Does anyone know where…?

When we launch next week, I’ll be asking you to share those questions - and the answers in our Team to get us started.

Thanks!

Email 3 (Launch Day)

Hi there,

Each of you should have just received an invite to Stack Overflow for Teams / Each of you now has access to our own Stack Overflow for Teams.

As requested, please take some time today to ask and answer a question. Here’s how to do that:

Start a new question draft
-
-Use the question as the title
-
-Draft the question in total in the body
-
-Click “Answer my own question” at the bottom of the page
-
-Include your answer
-
-Hit save
-

What if my question has already been asked/answered?

When you type your question in the title bar, you will see if any other related questions have been asked. If you notice this, click on the question that is populated and check to see if it has been answered. If not, please do so! Notice that you could add more context? Go ahead and add that!

What if I don’t know of any common questions?

There are bound to be at least a few questions that our chat channels or you personally get asked on a somewhat regular basis. Check back through your chat and email messages if you’re struggling to come up with something.

What else can I do within Teams?

Have a question that you don’t know the answer to? Write it up, and let’s get you some answers!
-
-Upvote good questions and answers and use emojis to show your enthusiasm. 
-
-Create an Article. Longer-form content like project documentation, how-to guides, etc. can live in our Team, too - just copy and paste something that you already know exists, and everyone else will be able to access it.
-

Email 4 (2 days post-launch)

Hi team,

Congrats! We’ve managed to ask _ questions, provide ___ answers, and write ____ Articles. This is just the beginning - and we’re already off to a great start!

What can you do next to make sure that our knowledge community thrives?

Make sure that you are asking questions in our Team.
-
-Follow and create tags to stay on top of new information.
-
-When you see someone asking questions in Slack/Microsoft Teams, use the integration to suggest that they ask the question in our Team instead.
-
-Continue to transport documents into Articles.
-

I’ll continue to keep you all updated on how our Team is growing on a regular basis, and in the meantime, if you have any questions, please feel free to contact me.

Thank you!

\ No newline at end of file diff --git a/docs/email-templates/onboarding.html b/docs/email-templates/onboarding.html deleted file mode 100644 index 40e09aadc..000000000 --- a/docs/email-templates/onboarding.html +++ /dev/null @@ -1,171 +0,0 @@ - - - - Onboarding - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Onboarding
    -
  • -

    Management/Onboarding Templates

    -
  • -
  • -
  • -

    Before Starting

    -
  • -
  • -

    Hi [new team member],

    -
  • -
  • -

    I wanted to take a moment to welcome you to our team and to confirm your start date of Monday. We are glad to have you on board and we hope that you will find this to be a positive and productive experience.

    -
  • -
  • -

    I am confident that your skills and experience will be a valuable addition to our group, and I look forward to working with you. If you have any questions or concerns leading up to your start date, please don't hesitate to reach out. I am here to help make your transition as smooth as possible.

    -
  • -
  • -

    Best,
    -[Your Name]

    -
  • -
  • -
  • -

    Day 1

    -
  • -
  • -

    Hi [new team member],

    -

    Welcome to your first day on the team! I'm excited to have you here and I'm looking forward to getting to know you better.

    -

    To help you get started, here are a few things you'll need to know:

    -
  • -
  • -

    Your computer login is [username] and your temporary password is [password]. Please make sure to change your password as soon as you can.

    -
  • -
  • -

    Our team typically starts the day at 9:00 AM, with a stand-up meeting at 9:30 AM. This is a short meeting where everyone shares what they're working on for the day.

    -
  • -
  • -

    Your team leader is [team leader name] and they will be your primary point of contact. Feel free to reach out to them with any questions you have.

    -
  • -
  • -

    We have a slack channel for the team where we communicate throughout the day. Make sure to join and introduce yourself to the team!

    -
  • -
  • -

    I have put together an onboarding plan for your first few weeks with us to help you get up to speed.

    -
  • -
  • -
  • -

    Again, welcome to the team! I'm looking forward to working with you.

    -

    Best,
    -[Your Name]

    -
  • -
  • -
  • -

    Introducing a new team member

    -
  • -
  • -
  • -

    Hi team,

    -
  • -
  • -

    I am excited to introduce [new team member] who will be joining us on the team! [New team member] brings with them a wealth of experience in [industry/area of expertise] and I have no doubt that they will be a valuable asset to our group.

    -
  • -
  • -

    Please join me in welcoming [new team member] to the team. I know that they are looking forward to getting to know everyone and getting started on their new role.

    -
  • -
  • -

    Best,
    -[Your Name]

    -
  • -
  • -
  • -

    Starting a Community Of Practice

    -
  • -
  • -
  • -

    Dear [Colleagues],

    -

    I hope this email finds you well. I wanted to reach out to you about an idea I have been thinking about for a while - starting a community of practice (CoP) centered around [focus of CoP].

    -

    I believe that this CoP has the potential to bring together a group of individuals who are passionate about [focus of CoP] and provide a space for us to share our knowledge and experiences, collaborate on projects, and support each other in our professional development.

    -

    I envision the CoP meeting [frequency] and hosting events or activities that facilitate learning and collaboration. Some potential benefits of participating in the CoP include:

    -
  • -
  • -

    Staying up-to-date on the latest developments in [focus of CoP]

    -
  • -
  • -

    Connecting with like-minded professionals

    -
  • -
  • -

    Sharing best practices and ideas

    -
  • -
  • -

    Collaborating on projects and initiatives

    -
  • -
  • -

    Providing support and guidance to one another

    -

    I would love to hear your thoughts on this idea and whether you might be interested in joining the CoP. Please let me know if you have any questions or if there is anything else I can provide to help convince you of the value of this opportunity.

    -

    Thank you for considering this request.

    -

    Best,
    -[Your Name]

    -
  • -
  • -
  • -

    CoP Invite

    -
  • -
  • -
  • -

    Dear [CoP Members],

    -

    I hope this email finds you well. I am writing to invite you to the next meeting of our community of practice (CoP) focused on [focus of CoP].

    -

    The meeting will take place on [date] at [time] and will be held via [online platform or in-person location]. The agenda for the meeting is as follows:

    -
  • -
  • -

    [Agenda item 1]

    -
  • -
  • -

    [Agenda item 2]

    -
  • -
  • -

    [Agenda item 3]

    -
  • -
  • -

    [etc.]

    -

    I encourage you to come prepared to share any updates, ideas, or successes related to [focus of CoP] and to actively participate in the discussion.

    -

    I look forward to seeing you at the meeting and continuing to collaborate as a community.

    -

    Best,
    -[Your Name]

    -
  • -
\ No newline at end of file diff --git a/docs/frontend/angular.html b/docs/frontend/angular.html index 5cf88fa70..ee44c81dd 100644 --- a/docs/frontend/angular.html +++ b/docs/frontend/angular.html @@ -1,47 +1,20 @@ - - - + Angular - - - - + + - - - - - - - - - - - - - - - - - - - - - - -

Training

Introduction to Angular: Codelab | Video

Tools

    -
  1. Angular
  2. + + + + + + + +

    Training

    Introduction to Angular: Codelab | Video

    Tools

      +
    1. Angular
    2. Install Angular Language Service for VS Code code --install-extension angular.ng-template
    3. -

    Create a new Angular App

      +

    Create a new Angular App

    1. Run ng new NewApp.UI --strict false
    2. Would you like to add Angular routing? Yes
    3. Which stylesheet format would you like to use? CSS
    4. @@ -105,9 +78,4 @@ 1. Run `npm install -g @angular/cli@13.3.10` or `npm install -g @angular/cli@latest` 2. Run `ng --version` -
    \ No newline at end of file +
\ No newline at end of file diff --git a/docs/frontend/css.html b/docs/frontend/css.html index 3f42134a5..287c19ea2 100644 --- a/docs/frontend/css.html +++ b/docs/frontend/css.html @@ -1,46 +1,15 @@ - - - + CSS - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file + + + + + + + +
\ No newline at end of file diff --git a/docs/frontend/index.html b/docs/frontend/index.html index 58d9c097f..cc49b1fe2 100644 --- a/docs/frontend/index.html +++ b/docs/frontend/index.html @@ -1,52 +1,20 @@ - - - + Index - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file + + + + + + + +
\ No newline at end of file diff --git a/docs/goals/continous-learning.html b/docs/goals/continous-learning.html deleted file mode 100644 index f48391a03..000000000 --- a/docs/goals/continous-learning.html +++ /dev/null @@ -1,250 +0,0 @@ - - - - Continous Learning - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Continous Learning

This a list of ideas to make learning a part the routine.
-

"../../assets/image_1672704712173_0.png" is not created yet. Click to create.

Career Roadmap

Training

Blog Posts

Videos

TBA

Training

General

Cloud

Backend

Frontend

Cloud

Frontend

Misc

Books

Books suggested by the community

Paperback

Online

\ No newline at end of file diff --git a/docs/goals/continuous-improvement.html b/docs/goals/continuous-improvement.html deleted file mode 100644 index 6b4f70e8f..000000000 --- a/docs/goals/continuous-improvement.html +++ /dev/null @@ -1,130 +0,0 @@ - - - - Continuous Improvement - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/docs/goals/knowledge-sharing.html b/docs/goals/knowledge-sharing.html deleted file mode 100644 index 1259b0c1e..000000000 --- a/docs/goals/knowledge-sharing.html +++ /dev/null @@ -1,167 +0,0 @@ - - - - Knowledge Sharing - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Knowledge Sharing

What

Share knowledge

Why

Sharing knowledge is crucial for software development teams to be successful in delivering high-quality software, improving team collaboration and efficiency, and staying up-to-date with new trends and technologies.

    -
  • Collaboration: Software development is rarely a solitary activity. Teamwork and collaboration are critical to the success of any software project. Sharing knowledge allows team members to work together more effectively and to leverage each other's strengths.
  • -
  • Efficiency: Sharing knowledge allows developers to avoid reinventing the wheel. They can build on the work of others, reuse code, and avoid common mistakes, which can save time and resources.
  • -
  • Quality: Sharing knowledge can help improve the quality of software. Developers can share best practices, techniques, and tools that can help ensure that software is well-designed, secure, and reliable.
  • -
  • Continuous Learning: The field of software development is constantly evolving. Sharing knowledge helps developers stay up-to-date with the latest developments, trends, and technologies. It also helps them learn from each other's experiences and mistakes.
  • -

Examples

How

    -
  • Document infrastructure, architecture, technical analysis and designs.
  • -
  • Provide how-to guides, tutorials, and runbooks.
  • -
  • Establish guidelines for contributors and code reviews.
  • -
  • Create and update documentation regularly.
  • -
  • Consolidate conflicting information in documentation.
  • -

Presentation Agenda

I. Introduction

    -
  • -

    Purpose of the presentation

    -
  • -
  • -

    Overview of knowledge sharing in software development

    -

    II. The Importance of Knowledge Sharing

    -
  • -
  • -

    Benefits of knowledge sharing for the team and organization

    -

    III. Strategies for Knowledge Sharing

    -
  • -
  • -

    Best practices for knowledge sharing

    -
  • -
  • -

    Examples of successful knowledge sharing practices

    -

    IV. Overcoming Challenges to Knowledge Sharing

    -
  • -
  • -

    Common challenges to knowledge sharing

    -
  • -
  • -

    Solutions for overcoming these challenges

    -

    V. Documenting Knowledge

    -
  • -
  • -

    Importance of documenting knowledge

    -
  • -
  • -

    Types of knowledge that should be documented

    -

    VI. Collaborative Learning

    -
  • -
  • -

    Benefits of collaborative learning

    -
  • -
  • -

    Ways to encourage collaborative learning

    -

    VII. Knowledge Sharing Tools

    -
  • -
  • -

    Tools that can be used for knowledge sharing

    -
  • -
  • -

    Examples of how these tools can be used effectively

    -

    VIII. Conclusion

    -
  • -
  • -

    Summary of key points

    -
  • -
  • -

    Importance of knowledge sharing in software development

    -
  • -
  • -

    Call to action for implementing knowledge sharing practices

    -

    IX. Questions and Answers

    -
  • -
  • -

    Open floor for questions and discussion

    -

    X. Closing

    -
  • -
  • -

    Final thoughts

    -
  • -
  • -

    Thank audience for their time and attention

    -
  • -

Documentation and Knowledge Sharing

\ No newline at end of file diff --git a/docs/goals/quality.html b/docs/goals/quality.html index 659b67e41..c83b38d1c 100644 --- a/docs/goals/quality.html +++ b/docs/goals/quality.html @@ -1,114 +1,82 @@ - - - + Quality - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
    -
  • + + + + + + + +

    Quality

    Goal-Oriented Ideas

      -
    • +

    Goal-Oriented Ideas

    Code Reviews

    Code Quality

    \ No newline at end of file +
\ No newline at end of file diff --git a/docs/how-to/batch-file.html b/docs/how-to/batch-file.html deleted file mode 100644 index 10af3ee2d..000000000 --- a/docs/how-to/batch-file.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - Batch File - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Batch File

Example with Angular

    -
  • AngularParallelBuild.bat
  • -
  start AngularBuild.bat C:\Dev\App1
-  start AngularBuild.bat C:\Dev\App2
-  start AngularBuild.bat C:\Dev\App3
-  start AngularBuild.bat C:\Dev\App3
-
    -
  • AngularBuild.bat
  • -
  cd %1  
-  ECHO Removing node_modules folder  
-  RMDIR /s /q node_modules  
-  ECHO Building Angular App  
-  call npm cache clean -f  
-  call npm install  
-  call npm ci  
-  call ng build  
-  ECHO Build Finished  
-
\ No newline at end of file diff --git a/docs/how-to/change-host-file-on-windows.html b/docs/how-to/change-host-file-on-windows.html deleted file mode 100644 index 1affc3059..000000000 --- a/docs/how-to/change-host-file-on-windows.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - Change host file on Windows - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Change host file on Windows

-$HostFile = 'C:\Windows\System32\drivers\etc\hosts'
-
-# Create a backup copy of the Hosts file
-$dateFormat = (Get-Date).ToString('dd-MM-yyyy hh-mm-ss')
-$FileCopy = $HostFile + '.' + $dateFormat  + '.copy'
-Copy-Item $HostFile -Destination $FileCopy
-
-$Bindings = Get-IISSiteBinding "websitename.com"
-
-# Get the contents of the Hosts file
-$File = Get-Content $HostFile
-
-# write the Entries to hosts file, if it doesn't exist.
-foreach ($Binding in $Bindings) 
-{
-$HostFileEntry = $Binding.bindingInformation
-$HostFileEntry = $HostFileEntry -replace "\*:443:", ""
-
-Write-Host "Checking existing HOST file entries for $HostFileEntry..."
-
-#Set a Flag
-$EntryExists = $false
-
-if ($File -contains "127.0.0.1 `t $HostFileEntry") 
-{
-  Write-Host "Host File Entry for $HostFileEntry already exists."
-  $EntryExists = $true
-}
-#Add Entry to Host File
-if (!$EntryExists) 
-{
-  Write-host "Adding Host File Entry for $HostFileEntry"
-  Add-content -path $HostFile -value "127.0.0.1 `t $HostFileEntry"
-}
-}
-
-
\ No newline at end of file diff --git a/docs/how-to/cli.html b/docs/how-to/cli.html index 6e60240d5..951c5f6dc 100644 --- a/docs/how-to/cli.html +++ b/docs/how-to/cli.html @@ -1,48 +1,21 @@ - - - + CLI - - - - + + - - - - - - - - - - - - - - - - - - - - - - -

Documentation

Package

Code Example

var userIdArgument = new Option<Guid>(name: "--userId", description: "User ID", getDefaultValue: () => Guid.Empty);
+		
+		
+		
+		
+		
+		
+		
+		

Documentation

Code Example

var userIdArgument = new Option<Guid>(name: "--userId", description: "User ID", getDefaultValue: () => Guid.Empty);
 var passwordArgument = new Option<string>("--password", "New Password");
 
 var rootCommand = new RootCommand();
@@ -58,9 +31,4 @@
 rootCommand.SetHandler(ConsoleAppRunner, userIdArgument, passwordArgument);
 
 await rootCommand.InvokeAsync(args);
-

Publish CLI Tool

TBA

\ No newline at end of file +

Publish CLI Tool

TBA

\ No newline at end of file diff --git a/docs/how-to/create-iis-websites.html b/docs/how-to/create-iis-websites.html deleted file mode 100644 index 2182140b1..000000000 --- a/docs/how-to/create-iis-websites.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - Create IIS Websites - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Create IIS Websites
-

Powershell 7+ is required

-
    -
  1. Run Install-Module -Name IISAdministration -Scope AllUsers -AllowClobber
  2. -
  3. Run New-IISSite -Name 'website_name' -PhysicalPath 'C:\Inetpub\wwwroot' -BindingInformation "*:443:hostname1.com" -Protocol https -SslFlag "Sni" -CertificateThumbPrint "[Insert Thumbprint]" -CertStoreLocation "Cert:\LocalMachine\My" -Force
  4. -
  5. Run New-IISSiteBinding -Name "website_name" -BindingInformation "*:443:hostname2.com" -Protocol https -SslFlag "Sni" -CertificateThumbPrint "[Insert Thumbprint]" -CertStoreLocation "Cert:\LocalMachine\My" -Force
  6. -
\ No newline at end of file diff --git a/docs/how-to/create-self-signed-certificate.html b/docs/how-to/create-self-signed-certificate.html deleted file mode 100644 index 84b45de8a..000000000 --- a/docs/how-to/create-self-signed-certificate.html +++ /dev/null @@ -1,134 +0,0 @@ - - - - Create Self-Signed Certificate - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Create Self-Signed Certificate
-

Note
-This process requires WSL2 and Ubuntu. Read here for installation steps.

-
    -
  1. Open a command prompt window
  2. -
  3. Run ubuntu
  4. -
  5. Create certificate.cnf
  6. -
[req]
-default_bits= 2048
-default_keyfile= keyfile.pem
-distinguished_name= req_distinguished_name
-attributes= req_attributes
-prompt= no
-output_password= mypass
-req_extensions= v3_req
-
-[v3_req]
-basicConstraints= CA:FALSE
-keyUsage= nonRepudiation, digitalSignature, keyEncipherment
-subjectAltName = @alt_names
-
-[alt_names]
-DNS.1   = local.company.dev
-DNS.2   = support.company.dev
-DNS.3   = test.company.dev
-DNS.4   = automation.company.dev
-
-[req_distinguished_name ]
-C= AU
-ST= QLD
-L= Brisbane
-O= company Local
-OU= Technology
-CN= *.company.dev
-emailAddress=leandro@company.com
-
-[req_attributes]
-challengePassword= C0mp4ny
-
    -
  1. openssl req -new -newkey rsa:2048 -nodes -keyout ca.key -out ca.csr -config certificate.cnf
  2. -
  3. openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr -config certificate.cnf
  4. -
  5. openssl req -x509 -new -key ca.key -out ca.crt -days 36500 -config certificate.cnf
  6. -
  7. openssl x509 -req -days 36500 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extensions v3_req -extfile certificate.cnf
  8. -
  9. openssl verify -CAfile ca.crt -verify_hostname local.company.dev server.crt
  10. -

PFX Export

Required to be visible on IIS, which needs a private key associated to the certificate.

    -
  1. openssl pkcs12 -export -out ca.pfx -inkey ca.key -in ca.crt -passout pass:C0mp4ny
  2. -
  3. openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt -passout pass:C0mp4ny
  4. -

Import into Windows Certificate Store

    -
  1. Import-PfxCertificate -FilePath C:\Dev\SSL\ca.pfx -Password (ConvertTo-SecureString -String 'C0mp4ny' -AsPlainText -Force) -CertStoreLocation Cert:\LocalMachine\Root
  2. -
  3. Import-PfxCertificate -FilePath C:\Dev\SSL\server.pfx -Password (ConvertTo-SecureString -String 'C0mp4ny' -AsPlainText -Force) -CertStoreLocation Cert:\LocalMachine\My
  4. -

Firefox

Trust the Certificate Authority on #Firefox: Settings -> Privacy & Security -> View Certificates -> Authorities -> import ca.crt

Configure Certificate in ASP.NET

Configure Certificate in Angular

Manage Certificate Private keys

    -
  1. Go to Windows -> type "run" -> mmc
  2. -
  3. Once the mmc window is up -> Add Snap-in -> Add certificate -> Local Computer
  4. -
  5. Go to Personal -> Certificate -> Select the certificate
  6. -
  7. Right Click Certificate -> All tasks -> Manage Private keys
  8. -

Notes:

    -
  • Private key must be exportable when installing the certificate
  • -
  • In Windows 10 1809, it seems that the Manage Private Keys option is available only to certificates in the Personal store. The workaround is to drag and drop the certificate there, add permissions as needed and drag it back to where you need it.
  • -

Documentation

Difference between CRT and PFX files

A .crt (or .cer or .cert) file usually contains a single X.509 encoded digital certificate, which is what is typically used for SSL/TLS encryption on websites. A .pfx (personal exchange format) file, on the other hand, is a password-protected data file that contains a private key, public key, and typically a chain of digital certificates. The main difference between the two is that a .pfx file contains both the private key and the public key, while a .crt file contains only the public key. Additionally, a .pfx file can include multiple certificates, while a .crt file typically only contains one.

Notes

    -
  • CRT file does not contain the private key
  • -
  • KEY file contains the private key
  • -
  • PFX file contains the private key, but it's protected by a password (eg. C0mp4ny)
  • -

Using CloudFlare as CA

    -
  1. Go to https://dash.cloudflare.com
  2. -
  3. Create a Website
  4. -
  5. Run Ubuntu
  6. -
  7. Run openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr
  8. -
  9. When prompted Common Name, make sure you use a wildcard address *.mydomain.dev
  10. -
  11. Run ls and check if server.csr is listed
  12. -
  13. Run cat server.csr
  14. -
  15. Copy the CSR content
  16. -
  17. Go to CloudFare -> Website -> SSL/TLS -> Origin Server -> Create Certificate
  18. -
  19. Select "Use my private key and CSR"
  20. -
  21. Copy content from step 8
  22. -
  23. Click Create
  24. -
  25. Select PEM Format
  26. -
  27. Copy content into a notepad and save as newsslcertificate.crt
  28. -
  29. Generate PFX openssl pkcs12 -export -out server.pfx -inkey server.key -in server.crt -passout pass:P4ssW0rd
  30. -
\ No newline at end of file diff --git a/docs/how-to/docker.html b/docs/how-to/docker.html deleted file mode 100644 index c74812bdf..000000000 --- a/docs/how-to/docker.html +++ /dev/null @@ -1,103 +0,0 @@ - - - - Docker - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Docker

Installation

Build and Run a Container

    -
  1. Navigate to the folder where the Dockerfile is stored
  2. -
  3. Run docker build -t angular-container:1.0 .
  4. -
  5. Search ImageID by running docker images
  6. -
  7. Run docker run -p 80:80 469b3a773ed7
  8. -

Images

Commands

    -
  • Display containers' resource usage statistics docker stats --all --no-stream
  • -
  • Stop running containers docker kill $(docker ps -q)
  • -
  • Remove all containers docker rm $(docker ps -a -q)
  • -
  • Remove all images docker rmi $(docker images -q)
  • -
    -
  • -

    Security

    -:PROPERTIES:
    -:heading: 2
    -:END:
  • -
\ No newline at end of file diff --git a/docs/how-to/git.html b/docs/how-to/git.html index c3cfc2565..4607dfbdb 100644 --- a/docs/how-to/git.html +++ b/docs/how-to/git.html @@ -1,86 +1,56 @@ - - - + Git - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
Git

Clean Repository

git clean -fdx is a command used in Git to remove untracked files and directories from the working tree.

    -
  • -f flag stands for "force", which allows the command to execute without prompting the user for confirmation.
  • -
  • -d flag is used to also remove untracked directories.
  • -
  • -x flag is used to also remove ignored files.
  • -

Git Clone with Submodules

git clone git@github.com:leandromonaco/leandromonaco.github.io.git C:\Dev\Repo --recurse-submodules

Basic Git Commands

git checkout main
+		
+		
+		
+		
+		
+		
+		
+		

Git

Clean Repository

git clean -fdx is a command used in Git to remove untracked files and directories from the working tree.

    +
  • -f flag stands for "force", which allows the command to execute without prompting the user for confirmation.
  • +
  • -d flag is used to also remove untracked directories.
  • +
  • -x flag is used to also remove ignored files.
  • +

Git Clone with Submodules

git clone git@github.com:leandromonaco/leandromonaco.github.io.git C:\Dev\Repo --recurse-submodules

Start a new change

git checkout main
 git fetch
 git pull
 git branch branch_name
 git checkout branch_name
-git push --set-upstream origin branch_name
---Make code changes, stage and commit them
+

Commit Changes

git status --short
+git add myfile.txt
+git commit -m "Made changes to myfile.txt"
+

Push changes

git push --set-upstream origin branch_name
 git push
-

Reset author for ALL commits

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD
+

Reset author for ALL commits

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD
 git push --force --tags origin 'refs/heads/main'
-

Change last commit message

Run git commit --amend -m "New and correct message"

Delete the most recent commit

without destroying the work you've done: git reset --soft HEAD~1
-destroying the work you've done: git reset --hard HEAD~1

Fix .gitignore issues

    +

Change last commit message

Run git commit --amend -m "New and correct message"

Delete the most recent commit

without destroying the work you've done: git reset --soft HEAD~1
+destroying the work you've done: git reset --hard HEAD~1

Fix .gitignore issues

  1. Run git rm -r --cached . to unstage and remove the path to your files from the Git index.
  2. Execute git add . to re-add all your files back (only the correct files will be updated).
  3. Execute git commit -m ".gitignore is now working" to commit all your files back into the Git index.
  4. -

Configuration

Read All Configuration

git config --local -l
+

Configuration

Read All Configuration

git config --local -l
 git config --global -l
-

Read specific values

git config --global user.name
+

Read specific values

git config --global user.name
 git config --global user.email
 

Make sure that local git config does not override the global configuration

git config --local user.name
 git config --local user.email
-

Change values

git config --global user.name [username]
+

Change values

git config --global user.name [username]
 git config --global user.email [email address]
-

Removing sensitive data from a repository

Removing sensitive data from a repository

Example

  1. winget install -e --id Oracle.JavaRuntimeEnvironment
  2. java -jar bfg.jar --delete-folders ReleasePlanning
  3. git push --force
  4. -
    -
  • if dealing with protected commits add --no-blob-protection parameter
  • -
  • -

Troubleshooting

set GIT_TRACE=1
+
    +
  • if dealing with protected commits add --no-blob-protection parameter
  • +
  • +

Troubleshooting

set GIT_TRACE=1
 set GIT_CURL_VERBOSE=1
-
\ No newline at end of file + \ No newline at end of file diff --git a/docs/how-to/google-calendar-api.html b/docs/how-to/google-calendar-api.html deleted file mode 100644 index 9d4232606..000000000 --- a/docs/how-to/google-calendar-api.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - Google Calendar API - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/docs/how-to/install-multiple-nodejs-versions.html b/docs/how-to/install-multiple-nodejs-versions.html deleted file mode 100644 index a5aa08b46..000000000 --- a/docs/how-to/install-multiple-nodejs-versions.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - Install multiple NodeJS Versions - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Install multiple NodeJS Versions
-

Warning
-Each time a new NodeJS version is installed, tools like Angular must be re-installed.

-
    -
  1. winget install -e --id CoreyButler.NVMforWindows
  2. -
  3. Restart Windows Terminal
  4. -
  5. Execute nvm --version to verify if your installation
  6. -
  7. Execute nvm install latest
  8. -
  9. Execute nvm use latest
  10. -

NVM Commands: nvm help

\ No newline at end of file diff --git a/docs/how-to/measure-method-elapsed-time-with-csharp.html b/docs/how-to/measure-method-elapsed-time-with-csharp.html deleted file mode 100644 index 28742a5aa..000000000 --- a/docs/how-to/measure-method-elapsed-time-with-csharp.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - Measure Method Elapsed Time with CSharp - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Measure Method Elapsed Time with CSharp

Class

using System;
-using System.Diagnostics;
-
-[AttributeUsage(AttributeTargets.Method)]
-public class StopWatchAttribute: Attribute
-{
-    public virtual void OnEntry()
-    {
-        Stopwatch stopwatch = new Stopwatch();
-        stopwatch.Start();
-
-        AppDomain.CurrentDomain.ProcessExit += (sender, args) =>
-        {
-            stopwatch.Stop();
-            Console.WriteLine($"Elapsed Time: {stopwatch.ElapsedMilliseconds} ms");
-        };
-    }
-}
-

How to use it

public class MyClass
-{
-    [StopWatch]
-    public static void MyMethod()
-    {
-        // Code to be measured.
-        System.Threading.Thread.Sleep(500);
-    }
-}
-
\ No newline at end of file diff --git a/docs/how-to/technical-support.html b/docs/how-to/technical-support.html deleted file mode 100644 index 24fe5fb0b..000000000 --- a/docs/how-to/technical-support.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - Technical Support - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Share Secrets

Quick Assist

Give the security code to the person you’re helping and tell them to follow these steps:

    -
  1. Open the Start menu go to Windows Accessories -> Quick Assist or type Quick Assist in the search bar and select the Quick Assist app to launch it.
  2. -
  3. Accept the privacy policy, if prompted.
  4. -
  5. Enter the code provided in Code from assistant and click Share screen.
  6. -
  7. Verify that the person trying to help you is who you expected and accept the request.
  8. -
  9. Wait for your devices to connect.
  10. -

Problem Step Recorder (PSR)

    -
  1. Click on your Windows Start search menu
  2. -
  3. Type “PSR” and then click on psr.exe in the search results.
  4. -
  5. Open the application
  6. -
  7. Start the recording from the login page until you reach the page where you can see the error message/problem occurred.
  8. -
  9. Once you reach the last page, ensure your home page before you stop the recording to ensure that you have captured the last page where we encountered the error message.
  10. -
  11. In the Save As dialog box, type a name for the file, and then click Save. Then it will be created as a zip file. Please send the zip file attached to this email
    -You may look online for more suitable steps for your computer if the above steps will not work.
    -Please let me know if you need any further assistance, I would be happy to help and assist further.
  12. -
\ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 99247b0ca..1fc8ef379 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,51 +1,27 @@ - - - + Index - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
Index

Welcome to my Digital Knowledge Garden 🌱

"The more I learn, the more I realize how much I don't know" -Aristotle

This project was inspired by this blog post

Toolkit

Sources

\ No newline at end of file + + + + + + + +

Index

Welcome to my Digital Knowledge Garden 🌱

"The more I learn, the more I realize how much I don't know" -Aristotle

This project was inspired by this blog post

Toolkit

Publish

    +
  1. Delete all files in digital-knowledge-garden\docs
  2. +
  3. Export src as HTML Documents (self-contained)Pasted image 20240510083448.pngPasted image 20240510085959.png
  4. +
  5. Copy docs\src to docs
  6. +
  7. Push Git changes
  8. +
  9. A GitHub Action will be triggered to publish https://leandromonaco.github.io/digital-knowledge-garden
  10. +

Sources

\ No newline at end of file diff --git a/docs/lib/scripts/graph-render-worker.js b/docs/lib/scripts/graph-render-worker.js deleted file mode 100644 index df3e4c319..000000000 --- a/docs/lib/scripts/graph-render-worker.js +++ /dev/null @@ -1,356 +0,0 @@ -// Import Pixi.js library -if( 'function' === typeof importScripts) -{ - importScripts('https://d157l7jdn8e5sf.cloudfront.net/v7.2.0/webworker.js', './tinycolor.js'); - - addEventListener('message', onMessage); - - let app; - let container; - let graphics; - let labelText; - - isDrawing = false; - - let linkCount = 0; - let linkSources = []; - let linkTargets = []; - let nodeCount = 0; - let radii = []; - let labels = []; - let cameraOffset = {x: 0, y: 0}; - let positions = new Float32Array(0); - let linkLength = 0; - let edgePruning = 0; - let colors = - { - background: 0x232323, - link: 0xAAAAAA, - node: 0xCCCCCC, - outline: 0xAAAAAA, - text: 0xFFFFFF, - accent: 0x4023AA - } - - let hoveredNode = -1; - let lastHoveredNode = -1; - let grabbedNode = -1; - let updateAttached = false; - let attachedToGrabbed = []; - let activeNode = -1; - let attachedToActive = []; - - let cameraScale = 1; - let cameraScaleRoot = 1; - - function toScreenSpace(x, y, floor = true) - { - if (floor) - { - return {x: Math.floor((x * cameraScale) + cameraOffset.x), y: Math.floor((y * cameraScale) + cameraOffset.y)}; - } - else - { - return {x: (x * cameraScale) + cameraOffset.x, y: (y * cameraScale) + cameraOffset.y}; - } - } - - function vecToScreenSpace({x, y}, floor = true) - { - return toScreenSpace(x, y, floor); - } - - function toWorldspace(x, y) - { - return {x: (x - cameraOffset.x) / cameraScale, y: (y - cameraOffset.y) / cameraScale}; - } - - function vecToWorldspace({x, y}) - { - return toWorldspace(x, y); - } - - function setCameraCenterWorldspace({x, y}) - { - cameraOffset.x = (canvas.width / 2) - (x * cameraScale); - cameraOffset.y = (canvas.height / 2) - (y * cameraScale); - } - - function getCameraCenterWorldspace() - { - return toWorldspace(canvas.width / 2, canvas.height / 2); - } - - function getNodeScreenRadius(radius) - { - return radius * cameraScaleRoot; - } - - function getNodeWorldspaceRadius(radius) - { - return radius / cameraScaleRoot; - } - - function getPosition(index) - { - return {x: positions[index * 2], y: positions[index * 2 + 1]}; - } - - function mixColors(hexStart, hexEnd, factor) - { - return tinycolor.mix(tinycolor(hexStart.toString(16)), tinycolor(hexEnd.toString(16)), factor).toHexNumber() - } - - function darkenColor(hexColor, factor) - { - return tinycolor(hexColor.toString(16)).darken(factor).toHexNumber(); - } - - function lightenColor(hexColor, factor) - { - return tinycolor(hexColor.toString(16)).lighten(factor).toHexNumber(); - } - - function invertColor(hex, bw) - { - hex = hex.toString(16); // force conversion - - if (hex.indexOf('#') === 0) { - hex = hex.slice(1); - } - // convert 3-digit hex to 6-digits. - if (hex.length === 3) { - hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; - } - if (hex.length !== 6) { - throw new Error('Invalid HEX color.'); - } - var r = parseInt(hex.slice(0, 2), 16), - g = parseInt(hex.slice(2, 4), 16), - b = parseInt(hex.slice(4, 6), 16); - if (bw) { - // https://stackoverflow.com/a/3943023/112731 - return (r * 0.299 + g * 0.587 + b * 0.114) > 186 - ? '#000000' - : '#FFFFFF'; - } - // invert color components - r = (255 - r).toString(16); - g = (255 - g).toString(16); - b = (255 - b).toString(16); - // pad each with zeros and return - return "#" + padZero(r) + padZero(g) + padZero(b); - } - - let hoverFade = 0; - let hoverFadeSpeed = 0.2; - - function draw() - { - graphics.clear(); - - let topLines = []; - if (updateAttached) - { - attachedToGrabbed = []; - // hoverFade = 0; - } - - if (hoveredNode != -1 || grabbedNode != -1) - { - hoverFade = Math.min(1, hoverFade + hoverFadeSpeed); - } - else - { - hoverFade = Math.max(0, hoverFade - hoverFadeSpeed); - } - - graphics.lineStyle(1, mixColors(colors.link, colors.background, hoverFade * 50), 0.7); - - for (let i = 0; i < linkCount; i++) - { - let target = linkTargets[i]; - let source = linkSources[i]; - - if (hoveredNode == source || hoveredNode == target || ((lastHoveredNode == source || lastHoveredNode == target) && hoverFade != 0)) - { - if (updateAttached && hoveredNode == source) - attachedToGrabbed.push(target); - - else if (updateAttached && hoveredNode == target) - attachedToGrabbed.push(source); - - topLines.push(i); - } - - let startWorld = getPosition(source); - let endWorld = getPosition(target); - - let start = vecToScreenSpace(startWorld); - let end = vecToScreenSpace(endWorld); - - let dist = Math.sqrt(Math.pow(startWorld.x - endWorld.x, 2) + Math.pow(startWorld.y - endWorld.y, 2)); - - if (dist < (radii[source] + radii[target]) * edgePruning) - { - graphics.moveTo(start.x, start.y); - graphics.lineTo(end.x, end.y); - } - } - - let opacity = 1 - (hoverFade * 0.5); - graphics.beginFill(mixColors(colors.node, colors.background, hoverFade * 50), opacity); - graphics.lineStyle(0, 0xffffff); - for (let i = 0; i < nodeCount; i++) - { - if (hoveredNode == i || (lastHoveredNode == i && hoverFade != 0) || (hoveredNode != -1 && attachedToGrabbed.includes(i))) continue; - - let pos = vecToScreenSpace(getPosition(i)); - - graphics.drawCircle(pos.x, pos.y, getNodeScreenRadius(radii[i])); - } - - graphics.endFill(); - - - opacity = hoverFade * 0.7; - graphics.lineStyle(1, mixColors(mixColors(colors.link, colors.accent, hoverFade * 100), colors.background, 20), opacity); - - for (let i = 0; i < topLines.length; i++) - { - let target = linkTargets[topLines[i]]; - let source = linkSources[topLines[i]]; - - // draw lines on top when hovered - let start = vecToScreenSpace(getPosition(source)); - let end = vecToScreenSpace(getPosition(target)); - - - graphics.moveTo(start.x, start.y); - graphics.lineTo(end.x, end.y); - } - - if(hoveredNode != -1 || (lastHoveredNode != -1 && hoverFade != 0)) - { - graphics.beginFill(mixColors(colors.node, colors.accent, hoverFade * 20), 0.9); - graphics.lineStyle(0, 0xffffff); - for (let i = 0; i < attachedToGrabbed.length; i++) - { - let point = attachedToGrabbed[i]; - - let pos = vecToScreenSpace(getPosition(point)); - - graphics.drawCircle(pos.x, pos.y, getNodeScreenRadius(radii[point])); - } - graphics.endFill(); - - let index = hoveredNode != -1 ? hoveredNode : lastHoveredNode; - - let pos = vecToScreenSpace(getPosition(index)); - graphics.beginFill(mixColors(colors.node, colors.accent, hoverFade * 100), 1); - graphics.lineStyle(hoverFade, mixColors(invertColor(colors.background, true), colors.accent, 50)); - graphics.drawCircle(pos.x, pos.y, getNodeScreenRadius(radii[index])); - graphics.endFill(); - - labelText.text = labels[index]; - let nodePos = vecToScreenSpace(getPosition(index)); - labelText.x = nodePos.x - labelText.width/2; - labelText.y = nodePos.y + getNodeScreenRadius(radii[index]) + hoverFade * 5 + 15; - } - - updateAttached = false; - - if (hoveredNode == -1) - { - labelText.text = ""; - } - else - { - - } - - graphics.lineStyle(2, colors.accent); - // draw the active node - if (activeNode != -1) - { - let pos = vecToScreenSpace(getPosition(activeNode)); - graphics.drawCircle(pos.x, pos.y, getNodeScreenRadius(radii[activeNode]) + 4); - } - } - - function onMessage(event) - { - if(event.data.type == "draw") - { - positions = new Float32Array(event.data.positions); - draw(); - } - else if(event.data.type == "update_camera") - { - cameraOffset = event.data.cameraOffset; - cameraScale = event.data.cameraScale; - cameraScaleRoot = Math.sqrt(cameraScale); - } - else if(event.data.type == "update_interaction") - { - if(hoveredNode != event.data.hoveredNode && event.data.hoveredNode != -1) updateAttached = true; - if(grabbedNode != event.data.grabbedNode && event.data.hoveredNode != -1) updateAttached = true; - - if(event.data.hoveredNode == -1) lastHoveredNode = hoveredNode; - else lastHoveredNode = -1; - - hoveredNode = event.data.hoveredNode; - grabbedNode = event.data.grabbedNode; - } - else if(event.data.type == "resize") - { - app.renderer.resize(event.data.width, event.data.height); - } - else if(event.data.type == "set_active") - { - activeNode = event.data.active; - } - else if(event.data.type == "update_colors") - { - colors = event.data.colors; - - if(labelText) - { - labelText.style.fill = invertColor(colors.background, true); - } - } - else if(event.data.type == "init") - { - // Extract data from message - linkCount = event.data.linkCount; - linkSources = event.data.linkSources; - linkTargets = event.data.linkTargets; - nodeCount = event.data.nodeCount; - radii = event.data.radii; - labels = event.data.labels; - linkLength = event.data.linkLength; - edgePruning = event.data.edgePruning; - - app = new PIXI.Application({... event.data.options, antialias: true, resolution: 2, backgroundAlpha: 0, transparent: true}); - container = new PIXI.Container(); - graphics = new PIXI.Graphics(); - app.stage.addChild(container); - container.addChild(graphics); - - labelText = new PIXI.Text("", {fontFamily : 'Arial', fontSize: 16, fontWeight: "bold", fill : invertColor(colors.background, true), align : 'center', anchor: 0.5}); - app.stage.addChild(labelText); - - } - else - { - console.log("Unknown message type sent to graph worker: " + event.data.type); - } - } -} - - - - - - - diff --git a/docs/lib/scripts/graph_view.js b/docs/lib/scripts/graph_view.js deleted file mode 100644 index f6683f3a5..000000000 --- a/docs/lib/scripts/graph_view.js +++ /dev/null @@ -1,913 +0,0 @@ -// -------------------------- GRAPH VIEW -------------------------- -var running = false; -let batchFraction = 1; -let minBatchFraction = 0.3; -repulsionForce /= batchFraction; -let dt = 1; -let targetFPS = 40; -let startingCameraScale = undefined; -let startingCameraOffset = undefined; - -let mousePositionWorld = { x: undefined, y: undefined }; -let mousePositionScreen = { x: undefined, y: undefined }; -let scrollVelocity = 0; -let lastMousePos = { x: 0, y: 0 }; -let averageFPS = targetFPS; - -let mouseInside = false; -let graphExpanded = false; -let leftButtonDown = false; -let rightButtonDown = false; -let middleButtonDown = false; -let panning = false; - -const pixiApp = new PIXI.Application(); -var renderWorker = undefined; - - -class GraphAssembly -{ - static nodeCount = 0; - static linkCount = 0; - static hoveredNode = -1; - - static #positionsPtr = 0; - static #positionsByteLength = 0; - static #radiiPtr = 0; - static #linkSourcesPtr = 0; - static #linkTargetsPtr = 0; - - static linkSources = new Int32Array(0); - static linkTargets = new Int32Array(0); - static radii = new Float32Array(0); - static maxRadius = 0; - static averageRadius = 0; - static minRadius = 0; - - /** - * @param {{nodeCount: number, linkCount:number, radii: number[], labels: string[], paths: string[], linkSources: number[], linkTargets: number[], linkCounts: number[]}} nodes - */ - static init(nodes) - { - GraphAssembly.nodeCount = nodes.nodeCount; - GraphAssembly.linkCount = nodes.linkCount; - - // create arrays for the data - let positions = new Float32Array(GraphAssembly.nodeCount * 2); - GraphAssembly.radii = new Float32Array(nodes.radii); - GraphAssembly.linkSources = new Int32Array(nodes.linkSources); - GraphAssembly.linkTargets = new Int32Array(nodes.linkTargets); - - // allocate memory on the heap - GraphAssembly.#positionsPtr = Module._malloc(positions.byteLength); - GraphAssembly.#positionsByteLength = positions.byteLength; - GraphAssembly.#radiiPtr = Module._malloc(GraphAssembly.radii.byteLength); - GraphAssembly.#linkSourcesPtr = Module._malloc(GraphAssembly.linkSources.byteLength); - GraphAssembly.#linkTargetsPtr = Module._malloc(GraphAssembly.linkTargets.byteLength); - - GraphAssembly.maxRadius = GraphAssembly.radii.reduce((a, b) => Math.max(a, b)); - GraphAssembly.averageRadius = GraphAssembly.radii.reduce((a, b) => a + b) / GraphAssembly.radii.length; - GraphAssembly.minRadius = GraphAssembly.radii.reduce((a, b) => Math.min(a, b)); - - positions = this.loadState(); - - // copy the data to the heap - Module.HEAP32.set(new Int32Array(positions.buffer), GraphAssembly.#positionsPtr / positions.BYTES_PER_ELEMENT); - Module.HEAP32.set(new Int32Array(GraphAssembly.radii.buffer), GraphAssembly.#radiiPtr / GraphAssembly.radii.BYTES_PER_ELEMENT); - Module.HEAP32.set(new Int32Array(GraphAssembly.linkSources.buffer), GraphAssembly.#linkSourcesPtr / GraphAssembly.linkSources.BYTES_PER_ELEMENT); - Module.HEAP32.set(new Int32Array(GraphAssembly.linkTargets.buffer), GraphAssembly.#linkTargetsPtr / GraphAssembly.linkTargets.BYTES_PER_ELEMENT); - - Module._Init( - GraphAssembly.#positionsPtr, - GraphAssembly.#radiiPtr, - GraphAssembly.#linkSourcesPtr, - GraphAssembly.#linkTargetsPtr, - GraphAssembly.nodeCount, - GraphAssembly.linkCount, - batchFraction, - dt, - attractionForce, - linkLength, - repulsionForce, - centralForce - ); - } - - /** - * @returns {Float32Array} - */ - static get positions() - { - return Module.HEAP32.buffer.slice(GraphAssembly.#positionsPtr, GraphAssembly.#positionsPtr + GraphAssembly.#positionsByteLength); - } - - /** - * @param {GraphRenderWorker} renderWorker - * */ - static saveState(renderWorker) - { - localStorage.setItem("positions", JSON.stringify(new Float32Array(GraphAssembly.positions))); - localStorage.setItem("cameraOffset", JSON.stringify(renderWorker.cameraOffset)); - localStorage.setItem("cameraScale", JSON.stringify(renderWorker.cameraScale)); - } - - /** - * @returns {Float32Array} - * */ - static loadState() - { - let positionsLoad = localStorage.getItem("positions"); - let positions = null; - if(positionsLoad) positions = new Float32Array(Object.values(JSON.parse(positionsLoad))); - if (!positions || !positionsLoad || positions.length != GraphAssembly.nodeCount * 2) - { - positions = new Float32Array(GraphAssembly.nodeCount * 2); - let spawnRadius = (GraphAssembly.averageRadius * Math.sqrt(GraphAssembly.nodeCount)) * 2; - for (let i = 0; i < GraphAssembly.nodeCount; i++) - { - let distance = (1 - GraphAssembly.radii[i] / GraphAssembly.maxRadius) * spawnRadius; - positions[i * 2] = Math.cos(i/GraphAssembly.nodeCount * 7.41 * 2 * Math.PI) * distance; - positions[i * 2 + 1] = Math.sin(i/GraphAssembly.nodeCount * 7.41 * 2 * Math.PI) * distance; - } - } - - startingCameraOffset = JSON.parse(localStorage.getItem("cameraOffset")); - startingCameraScale = JSON.parse(localStorage.getItem("cameraScale")); - - return positions; - } - - /** - * @param {{x: number, y: number}} mousePosition - * @param {number} grabbedNode - */ - static update(mousePosition, grabbedNode, cameraScale) - { - GraphAssembly.hoveredNode = Module._Update(mousePosition.x, mousePosition.y, grabbedNode, cameraScale); - } - - static free() - { - Module._free(GraphAssembly.#positionsPtr); - Module._free(GraphAssembly.#radiiPtr); - Module._free(GraphAssembly.#linkSourcesPtr); - Module._free(GraphAssembly.#linkTargetsPtr); - Module._FreeMemory(); - } - - /** - * @param {number} value - */ - static set batchFraction(value) - { - Module._SetBatchFractionSize(value); - } - - /** - * @param {number} value - */ - static set attractionForce(value) - { - Module._SetAttractionForce(value); - } - - /** - * @param {number} value - */ - static set repulsionForce(value) - { - Module._SetRepulsionForce(value); - } - - /** - * @param {number} value - */ - static set centralForce(value) - { - Module._SetCentralForce(value); - } - - /** - * @param {number} value - */ - static set linkLength(value) - { - Module._SetLinkLength(value); - } - - /** - * @param {number} value - */ - static set dt(value) - { - Module._SetDt(value); - } -} - -class GraphRenderWorker -{ - #cameraOffset - #cameraScale - #hoveredNode - #grabbedNode - #colors - #width - #height - - - constructor() - { - this.canvas = document.querySelector("#graph-canvas"); - - this.view = this.canvas.transferControlToOffscreen(); - - this.worker = new Worker(new URL("./graph-render-worker.js", import.meta.url)); - - this.#cameraOffset = {x: 0, y: 0}; - this.#cameraScale = 1; - this.#hoveredNode = -1; - this.#grabbedNode = -1; - this.#colors = - { - background: 0x000000, - link: 0x000000, - node: 0x000000, - outline: 0x000000, - text: 0x000000, - accent: 0x000000, - } - this.#width = 0; - this.#height = 0; - - this.cameraOffset = {x: this.canvas.width / 2, y: this.canvas.height / 2}; - this.cameraScale = 1; - this.hoveredNode = -1; - this.grabbedNode = -1; - this.resampleColors(); - - this.#pixiInit(); - - this.width = this.canvas.width; - this.height = this.canvas.height; - - this.autoResizeCanvas(); - - if (startingCameraOffset && startingCameraScale) - { - this.cameraOffset = startingCameraOffset; - this.cameraScale = startingCameraScale; - } - else - { - this.centerCamera(); - } - } - - #pixiInit() - { - let { width, height } = this.view; - - this.worker.postMessage( - { - type: 'init', - linkCount: GraphAssembly.linkCount, - linkSources: GraphAssembly.linkSources, - linkTargets: GraphAssembly.linkTargets, - nodeCount: GraphAssembly.nodeCount, - radii: GraphAssembly.radii, - labels: nodes.labels, - linkLength: linkLength, - edgePruning: edgePruning, - options: { width: width, height: height, view: this.view }, - }, [this.view]); - } - - resampleColors() - { - function sampleColor(variable) - { - let testEl = document.createElement('div'); - testEl.style.setProperty('display', 'none'); - testEl.style.setProperty('color', 'var(' + variable + ')'); - document.body.appendChild(testEl); - - let col = getComputedStyle(testEl).color; - let opacity = getComputedStyle(testEl).opacity; - - testEl.remove(); - - function toColorObject(str) - { - var match = str.match(/rgb?\((\d+),\s*(\d+),\s*(\d+)\)/); - return match ? { - red: parseInt(match[1]), - green: parseInt(match[2]), - blue: parseInt(match[3]), - alpha: 1 - } : null - } - - var color = toColorObject(col), alpha = parseFloat(opacity); - return isNaN(alpha) && (alpha = 1), - color ? { - a: alpha * color.alpha, - rgb: color.red << 16 | color.green << 8 | color.blue - } : { - a: alpha, - rgb: 8947848 - } - }; - - this.colors = - { - background: sampleColor('--background-secondary').rgb, - link: sampleColor('--graph-line').rgb, - node: sampleColor('--graph-node').rgb, - outline: sampleColor('--graph-line').rgb, - text: sampleColor('--graph-text').rgb, - accent: sampleColor('--interactive-accent').rgb, - }; - } - - draw(_positions) - { - this.worker.postMessage( - { - type: 'draw', - positions: _positions, - }, [_positions]); - } - - resizeCanvas(width, height) - { - this.worker.postMessage( - { - type: "resize", - width: width, - height: height, - }); - - this.#width = width; - this.#height = height; - } - - autoResizeCanvas() - { - this.resizeCanvas(this.canvas.offsetWidth, this.canvas.offsetHeight); - } - - centerCamera() - { - this.cameraOffset = { x: this.width / 2, y: this.height / 2 }; - } - - #pixiSetInteraction(hoveredNodeIndex, grabbedNodeIndex) - { - let obj = - { - type: "update_interaction", - hoveredNode: hoveredNodeIndex, - grabbedNode: grabbedNodeIndex, - } - - this.worker.postMessage(obj); - } - - #pixiSetCamera(cameraOffset, cameraScale) - { - this.worker.postMessage( - { - type: "update_camera", - cameraOffset: cameraOffset, - cameraScale: cameraScale, - }); - } - - #pixiSetColors(colors) - { - this.worker.postMessage( - { - type: "update_colors", - colors: colors, - }); - - } - - set cameraOffset(offset) - { - this.#cameraOffset = offset; - this.#pixiSetCamera(offset, this.cameraScale); - } - - set cameraScale(scale) - { - this.#cameraScale = scale; - this.#pixiSetCamera(this.cameraOffset, scale); - } - - get cameraOffset() - { - return this.#cameraOffset; - } - - get cameraScale() - { - return this.#cameraScale; - } - - /** - * @param {number} node - */ - set hoveredNode(node) - { - this.#hoveredNode = node; - this.#pixiSetInteraction(node, this.#grabbedNode); - } - - /** - * @param {number} node - */ - set grabbedNode(node) - { - this.#grabbedNode = node; - this.#pixiSetInteraction(this.#hoveredNode, node); - } - - /** - * @param {number} node - */ - set activeNode(node) - { - this.worker.postMessage( - { - type: 'set_active', - active: node, - }); - } - - get hoveredNode() - { - return this.#hoveredNode; - } - - get grabbedNode() - { - return this.#grabbedNode; - } - - /** - * @param {{ background: number; link: number; node: number; outline: number; text: number; accent: number; }} colors - */ - set colors(colors) - { - this.#colors = colors; - this.#pixiSetColors(colors); - } - - get colors() - { - return this.#colors; - } - - set width(width) - { - this.#width = width; - this.resizeCanvas(width, this.#height); - } - - set height(height) - { - this.#height = height; - this.resizeCanvas(this.#width, height); - } - - get height() - { - return this.#height; - } - - get width() - { - return this.#width; - } - - /** - * @param {number} x - * @param {number} y - * @param {boolean} floor - * @returns {{x: number; y: number;}} - */ - toScreenSpace(x, y, floor = true) - { - if (floor) - { - return {x: Math.floor((x * this.cameraScale) + this.cameraOffset.x), y: Math.floor((y * this.cameraScale) + this.cameraOffset.y)}; - } - else - { - return {x: (x * this.cameraScale) + this.cameraOffset.x, y: (y * this.cameraScale) + this.cameraOffset.y}; - } - } - - /** - * @param {{x: number; y: number;}} vector - * @param {boolean} floor - * @returns {{x: number; y: number;}} - */ - vecToScreenSpace(vector, floor = true) - { - return this.toScreenSpace(vector.x, vector.y, floor); - } - - /** - * @param {number} x - * @param {number} y - * @returns {{x: number; y: number;}} - */ - toWorldspace(x, y) - { - return {x: (x - this.cameraOffset.x) / this.cameraScale, y: (y - this.cameraOffset.y) / this.cameraScale}; - } - - /** - * @param {{x: number; y: number;}} vector - * @returns {{x: number; y: number;}} - */ - vecToWorldspace(vector) - { - return this.toWorldspace(vector.x, vector.y); - } - - setCameraCenterWorldspace({x, y}) - { - this.cameraOffset = {x: (this.width / 2) - (x * this.cameraScale), y: (this.height / 2) - (y * this.cameraScale)}; - } - - getCameraCenterWorldspace() - { - return this.toWorldspace(this.width / 2, this.height / 2); - } -} - -async function initializeGraphView() -{ - if(running) return; - running = true; - - console.log("Module Ready"); - GraphAssembly.init(nodes); - - renderWorker = new GraphRenderWorker(); - window.renderWorker = renderWorker; - - initializeGraphEvents(); - - pixiApp.ticker.maxFPS = targetFPS; - pixiApp.ticker.add(updateGraph); - - setActiveDocument(getURLPath()); - - setInterval(() => - { - function isHidden(el) { - var style = window.getComputedStyle(el); - return (style.display === 'none') - } - - try - { - var hidden = (isHidden(document.querySelector(".graph-view-placeholder")) || isHidden(document.querySelector(".sidebar:has(.graph-view-placeholder)"))); - } - catch(e) - { - return; - } - - if(running && hidden) - { - running = false; - } - else if (!running && !hidden) - { - running = true; - renderWorker.autoResizeCanvas(); - renderWorker.centerCamera(); - } - - }, 1000); -} - -function updateGraph() -{ - if(!running) return; - - GraphAssembly.update(mousePositionWorld, renderWorker.grabbedNode, renderWorker.cameraScale); - - if (GraphAssembly.hoveredNode != renderWorker.hoveredNode) - { - renderWorker.hoveredNode = GraphAssembly.hoveredNode; - renderWorker.canvas.style.cursor = GraphAssembly.hoveredNode == -1 ? "default" : "pointer"; - } - - renderWorker.draw(GraphAssembly.positions); - - averageFPS = averageFPS * 0.95 + pixiApp.ticker.FPS * 0.05; - - if (averageFPS < targetFPS * 0.9 && batchFraction > minBatchFraction) - { - batchFraction = Math.max(batchFraction - 0.5 * 1/targetFPS, minBatchFraction); - GraphAssembly.batchFraction = batchFraction; - GraphAssembly.repulsionForce = repulsionForce / batchFraction; - } - - if (scrollVelocity != 0) - { - let cameraCenter = renderWorker.getCameraCenterWorldspace(); - - if (Math.abs(scrollVelocity) < 0.001) - { - scrollVelocity = 0; - } - - renderWorker.cameraScale = Math.max(Math.min(renderWorker.cameraScale + scrollVelocity * renderWorker.cameraScale, 10.0), 0.1); - - if(renderWorker.cameraScale != 0.1 && renderWorker.cameraScale != 10 && scrollVelocity > 0 && mousePositionWorld.x != undefined && mousePositionWorld.y != undefined) - { - // zoom towards cursor position - let mouseDiff = {x: mousePositionWorld.x - cameraCenter.x, y: mousePositionWorld.y - cameraCenter.y}; - var movePos = {x: cameraCenter.x + mouseDiff.x * scrollVelocity, y: cameraCenter.y + mouseDiff.y * scrollVelocity}; - renderWorker.setCameraCenterWorldspace(movePos); - } - else renderWorker.setCameraCenterWorldspace(cameraCenter); - - scrollVelocity *= 0.6; - } -} - -function initializeGraphEvents() -{ - window.addEventListener('beforeunload', () => - { - running = false; - GraphAssembly.free(); - }); - - let lastCanvasWidth = renderWorker.canvas.width; - window.addEventListener('resize', () => - { - if(graphExpanded) - { - renderWorker.autoResizeCanvas(); - renderWorker.centerCamera(); - } - else - { - if (renderWorker.canvas.width != lastCanvasWidth) - { - renderWorker.autoResizeCanvas(); - renderWorker.centerCamera(); - } - } - }); - - // Get the mouse position relative to the canvas. - function getMousePos(canvas, event) - { - var rect = canvas.getBoundingClientRect(); - var clientX = event.clientX; - var clientY = event.clientY; - - return { - x: clientX - rect.left, - y: clientY - rect.top - }; - } - - function handleMouseMove(event) - { - mousePositionScreen = getMousePos(renderWorker.canvas, event); - mousePositionWorld = renderWorker.vecToWorldspace(mousePositionScreen); - - if (lastMousePos.x == 0 && lastMousePos.y == 0) - { - lastMousePos = { x: event.clientX, y: event.clientY }; - return; - } - - let delta = { x: lastMousePos.x - event.clientX, y: lastMousePos.y - event.clientY }; - - if (leftButtonDown && renderWorker.hoveredNode != -1) - { - renderWorker.grabbedNode = renderWorker.hoveredNode; - } - - if (middleButtonDown || (leftButtonDown && renderWorker.hoveredNode == -1)) - { - let camOffset = renderWorker.cameraOffset; - renderWorker.cameraOffset = { x: camOffset.x - delta.x, y: camOffset.y - delta.y }; - panning = true; - } - else - { - panning = false; - } - - lastMousePos = { x: event.clientX, y: event.clientY }; - } - - renderWorker.canvas.addEventListener("mouseenter", () => mouseInside = true); - renderWorker.canvas.addEventListener("mouseleave", () => mouseInside = false); - - document.querySelectorAll("body").forEach(element => - { - element.addEventListener("mousemove", event => - { - event.stopPropagation(); - - if(mouseInside) return; - - if (panning || renderWorker.grabbedNode != -1) { - handleMouseMove(event); - } - }); - }); - - document.getElementById("graph-canvas").addEventListener("mousemove", event => - { - handleMouseMove(event); - }); - - - document.getElementById("graph-canvas").addEventListener("mousedown", event => - { - event.stopPropagation(); - - if (event.button == 0) leftButtonDown = true; - if (event.button == 1) middleButtonDown = true; - if (event.button == 2) rightButtonDown = true; - }); - - async function navigateToNode(nodeIndex) - { - if (!graphExpanded) GraphAssembly.saveState(renderWorker); - else toggleExpandedGraph(); - - let url = nodes.paths[nodeIndex]; - if(window.location.pathname.endsWith(nodes.paths[nodeIndex])) return; - await loadDocument(url); - } - - document.body.addEventListener("mouseup", event => - { - event.stopPropagation(); - - if (event.button == 0) leftButtonDown = false; - if (event.button == 1) middleButtonDown = false; - if (event.button == 2) rightButtonDown = false; - - // we must have just clicked on a node without dragging it - if (!panning && renderWorker.grabbedNode == -1 && renderWorker.hoveredNode != -1) - { - navigateToNode(renderWorker.hoveredNode); - } - - renderWorker.grabbedNode = -1; - }); - - // also mouse up if mouse leaves canvas - document.getElementById("graph-canvas").addEventListener("mouseleave", event => - { - event.stopPropagation(); - - if (renderWorker.grabbedNode == -1 && !(middleButtonDown || leftButtonDown)) - { - mousePositionScreen = { x: undefined, y: undefined }; - mousePositionWorld = { x: undefined, y: undefined }; - } - }); - - document.getElementById("graph-canvas").addEventListener("wheel", function(e) - { - e.preventDefault(); - e.stopPropagation(); - - let startingScrollVelocity = 0.08; - - let delta = e.deltaY; - if (delta > 0) - { - if(scrollVelocity >= -startingScrollVelocity) - { - scrollVelocity = -startingScrollVelocity; - } - - scrollVelocity *= 1.3; - } - else - { - if(scrollVelocity <= startingScrollVelocity) - { - scrollVelocity = startingScrollVelocity; - } - - scrollVelocity *= 1.3; - } - }); - - // touch controls - document.getElementById("graph-canvas").addEventListener("touchstart", function(e) - { - e.preventDefault(); - e.stopPropagation(); - - if (e.touches.length == 1) - { - lastMousePos = { x: e.touches[0].clientX, y: e.touches[0].clientY }; - - leftButtonDown = true; - } - else if (e.touches.length == 2) - { - middleButtonDown = true; - } - }); - - document.getElementById("graph-canvas").addEventListener("touchmove", function(e) - { - handleMouseMove(e.touches[0]); - }); - - document.addEventListener("touchend", function(e) - { - e.preventDefault(); - e.stopPropagation(); - - if (e.touches.length == 0) - { - leftButtonDown = false; - middleButtonDown = false; - - if (!panning && renderWorker.grabbedNode == -1 && renderWorker.hoveredNode != -1) - { - navigateToNode(renderWorker.hoveredNode); - } - - renderWorker.grabbedNode = -1; - } - else if (e.touches.length == 1) - { - middleButtonDown = false; - } - }); - - document.querySelector(".theme-toggle-input")?.addEventListener("change", event => - { - renderWorker.resampleColors(); - }); - - function toggleExpandedGraph() - { - let container = document.querySelector(".graph-view-container"); - let initialWidth = container.clientWidth; - let initialHeight = container.clientHeight; - - // scale and fade out animation: - container.classList.add("scale-down"); - let fadeOutAnimation = container.animate({ opacity: 0 }, {duration: 100, easing: "ease-in", fill: "forwards"}); - fadeOutAnimation.addEventListener("finish", function() - { - container.classList.toggle("expanded"); - - renderWorker.autoResizeCanvas(); - renderWorker.centerCamera(); - - let finalWidth = container.clientWidth; - let finalHeight = container.clientHeight; - renderWorker.cameraScale *= ((finalWidth / initialWidth) + (finalHeight / initialHeight)) / 2; - - container.classList.remove("scale-down"); - container.classList.add("scale-up"); - - updateGraph(); - - let fadeInAnimation = container.animate({ opacity: 1 }, {duration: 200, easing: "ease-out", fill: "forwards"}); - fadeInAnimation.addEventListener("finish", function() - { - container.classList.remove("scale-up"); - }); - }); - - graphExpanded = !graphExpanded; - } - - document.querySelector(".graph-expand.graph-icon")?.addEventListener("click", event => - { - event.preventDefault(); - event.stopPropagation(); - - toggleExpandedGraph(); - }); -} - -Module['onRuntimeInitialized'] = initializeGraphView; -setTimeout(() => Module['onRuntimeInitialized'](), 300); diff --git a/docs/lib/scripts/graph_wasm.js b/docs/lib/scripts/graph_wasm.js deleted file mode 100644 index e3a86bb72..000000000 --- a/docs/lib/scripts/graph_wasm.js +++ /dev/null @@ -1,3 +0,0 @@ - -// Wasm glue -var Module=typeof Module!="undefined"?Module:{};var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_NODE){var fs=require("fs");var nodePath=require("path");if(ENVIRONMENT_IS_WORKER){scriptDirectory=nodePath.dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=(filename,binary)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return fs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}return ret};readAsync=(filename,onload,onerror)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);fs.readFile(filename,function(err,data){if(err)onerror(err);else onload(data.buffer)})};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);if(typeof module!="undefined"){module["exports"]=Module}process.on("uncaughtException",function(ex){if(ex!=="unwind"&&!(ex instanceof ExitStatus)&&!(ex.context instanceof ExitStatus)){throw ex}});var nodeMajor=process.versions.node.split(".")[0];if(nodeMajor<15){process.on("unhandledRejection",function(reason){throw reason})}quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=title=>document.title=title}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;var HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateMemoryViews(){var b=wasmMemory.buffer;Module["HEAP8"]=HEAP8=new Int8Array(b);Module["HEAP16"]=HEAP16=new Int16Array(b);Module["HEAP32"]=HEAP32=new Int32Array(b);Module["HEAPU8"]=HEAPU8=new Uint8Array(b);Module["HEAPU16"]=HEAPU16=new Uint16Array(b);Module["HEAPU32"]=HEAPU32=new Uint32Array(b);Module["HEAPF32"]=HEAPF32=new Float32Array(b);Module["HEAPF64"]=HEAPF64=new Float64Array(b)}var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -sASSERTIONS for more info.";var e=new WebAssembly.RuntimeError(what);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}function isFileURI(filename){return filename.startsWith("file://")}var wasmBinaryFile;wasmBinaryFile="graph_wasm.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}catch(err){abort(err)}}function getBinaryPromise(binaryFile){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"&&!isFileURI(binaryFile)){return fetch(binaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+binaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(binaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(binaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(binaryFile)})}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then(function(binary){return WebAssembly.instantiate(binary,imports)}).then(function(instance){return instance}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)})})}else{return instantiateArrayBuffer(binaryFile,imports,callback)}}function createWasm(){var info={"a":wasmImports};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["f"];updateMemoryViews();wasmTable=Module["asm"]["r"];addOnInit(Module["asm"]["g"]);removeRunDependency("wasm-instantiate");return exports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult);return{}}var tempDouble;var tempI64;var ASM_CONSTS={2304:$0=>{console.log(UTF8ToString($0))}};function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}function callRuntimeCallbacks(callbacks){while(callbacks.length>0){callbacks.shift()(Module)}}function getValue(ptr,type="i8"){if(type.endsWith("*"))type="*";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];case"*":return HEAPU32[ptr>>2];default:abort("invalid type for getValue: "+type)}}function setValue(ptr,value,type="i8"){if(type.endsWith("*"))type="*";switch(type){case"i1":HEAP8[ptr>>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math.abs(tempDouble)>=1?tempDouble>0?(Math.min(+Math.floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;case"*":HEAPU32[ptr>>2]=value;break;default:abort("invalid type for setValue: "+type)}}function _abort(){abort("")}var readEmAsmArgsArray=[];function readEmAsmArgs(sigPtr,buf){readEmAsmArgsArray.length=0;var ch;buf>>=2;while(ch=HEAPU8[sigPtr++]){buf+=ch!=105&buf;readEmAsmArgsArray.push(ch==105?HEAP32[buf]:HEAPF64[buf++>>1]);++buf}return readEmAsmArgsArray}function runEmAsmFunction(code,sigPtr,argbuf){var args=readEmAsmArgs(sigPtr,argbuf);return ASM_CONSTS[code].apply(null,args)}function _emscripten_asm_const_int(code,sigPtr,argbuf){return runEmAsmFunction(code,sigPtr,argbuf)}function _emscripten_date_now(){return Date.now()}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function getHeapMax(){return 2147483648}function emscripten_realloc_buffer(size){var b=wasmMemory.buffer;try{wasmMemory.grow(size-b.byteLength+65535>>>16);updateMemoryViews();return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.length;requestedSize=requestedSize>>>0;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}let alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}function getCFunc(ident){var func=Module["_"+ident];return func}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function stringToUTF8OnStack(str){var size=lengthBytesUTF8(str)+1;var ret=stackAlloc(size);stringToUTF8(str,ret,size);return ret}var UTF8Decoder=typeof TextDecoder!="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heapOrArray,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":str=>{var ret=0;if(str!==null&&str!==undefined&&str!==0){ret=stringToUTF8OnStack(str)}return ret},"array":arr=>{var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string"){return UTF8ToString(ret)}if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;itype==="number"||type==="boolean");var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return function(){return ccall(ident,returnType,argTypes,arguments,opts)}}var wasmImports={"b":_abort,"e":_emscripten_asm_const_int,"d":_emscripten_date_now,"c":_emscripten_memcpy_big,"a":_emscripten_resize_heap};var asm=createWasm();var ___wasm_call_ctors=function(){return(___wasm_call_ctors=Module["asm"]["g"]).apply(null,arguments)};var _SetBatchFractionSize=Module["_SetBatchFractionSize"]=function(){return(_SetBatchFractionSize=Module["_SetBatchFractionSize"]=Module["asm"]["h"]).apply(null,arguments)};var _SetAttractionForce=Module["_SetAttractionForce"]=function(){return(_SetAttractionForce=Module["_SetAttractionForce"]=Module["asm"]["i"]).apply(null,arguments)};var _SetLinkLength=Module["_SetLinkLength"]=function(){return(_SetLinkLength=Module["_SetLinkLength"]=Module["asm"]["j"]).apply(null,arguments)};var _SetRepulsionForce=Module["_SetRepulsionForce"]=function(){return(_SetRepulsionForce=Module["_SetRepulsionForce"]=Module["asm"]["k"]).apply(null,arguments)};var _SetCentralForce=Module["_SetCentralForce"]=function(){return(_SetCentralForce=Module["_SetCentralForce"]=Module["asm"]["l"]).apply(null,arguments)};var _SetDt=Module["_SetDt"]=function(){return(_SetDt=Module["_SetDt"]=Module["asm"]["m"]).apply(null,arguments)};var _Init=Module["_Init"]=function(){return(_Init=Module["_Init"]=Module["asm"]["n"]).apply(null,arguments)};var _Update=Module["_Update"]=function(){return(_Update=Module["_Update"]=Module["asm"]["o"]).apply(null,arguments)};var _SetPosition=Module["_SetPosition"]=function(){return(_SetPosition=Module["_SetPosition"]=Module["asm"]["p"]).apply(null,arguments)};var _FreeMemory=Module["_FreeMemory"]=function(){return(_FreeMemory=Module["_FreeMemory"]=Module["asm"]["q"]).apply(null,arguments)};var ___errno_location=function(){return(___errno_location=Module["asm"]["__errno_location"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["s"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["t"]).apply(null,arguments)};var stackSave=function(){return(stackSave=Module["asm"]["u"]).apply(null,arguments)};var stackRestore=function(){return(stackRestore=Module["asm"]["v"]).apply(null,arguments)};var stackAlloc=function(){return(stackAlloc=Module["asm"]["w"]).apply(null,arguments)};var ___cxa_is_pointer_type=function(){return(___cxa_is_pointer_type=Module["asm"]["__cxa_is_pointer_type"]).apply(null,arguments)};Module["cwrap"]=cwrap;Module["setValue"]=setValue;Module["getValue"]=getValue;var calledRun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(){if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); diff --git a/docs/lib/scripts/graph_wasm.wasm b/docs/lib/scripts/graph_wasm.wasm deleted file mode 100644 index e94bee22df7e2e277d34b3887496c68fdf3827ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23377 zcmb`P4Uk^ddEd{y@ArG(clX`ZYPHfz=-eyW5g?oeV}Tu#-6M=7#FrC$Y$qK90)xXY z238U>sgZUGgs6?%8nK#S4>OTvCwPcyDDfn2{2?Vx6FMOs(%MrxAuX99PBL*4#UY8? z605)ebME`@t`KgTi9Yt;d+zyqp6CC3oadaoZr_2ACeFF!<7;kB7LtWqD+>#{Bn$4= zMnWk*7S%P#;V+;4=$)s&7AdnnC_~F4=)_%sS|rR zY=2z3xt8op_A!fn$!)I5&)Z#eaMWb)D{zOVf0? z(Wuqx^;Y7NW^ZJ)Vt-Oc_4|_H;aVd}7SqMWwBCfgaOR0>*0^>wxifXiN8E7o!y-9_x;J;?rq6O-6hFAZhLaCyEwVeU6jnb3zPlye!%sTgRYj`?=DCVxlPH( z+~uvY#Dydqdi%ETTeETFTQ}!h*Z5*f`{*wwQ@@iXjfHf^yKB16yU?5~QZCiGZK*4g z@W6cGX7d{FlaS0)BMFuHYr2U~eQGtR9=VGjkzDtx1}44YDf=;muOZo8li!CG6zWSCgBUC{EOsN2jtX4FO2y*-THLb~X^A9xEzhx4jrEUqFJdZA+`nzcL>xySpwtJL)x8UxVXE z;A0h5A@TjXg9)?tc9ShZY zVY%Nl3VL_9!tll_3hX+Zl^C$DzEXBYrDxxytCdp}=ol@J6I%rzrY-nzc~khn)Yb5b zyo&ItscD2y1nq{{*LhG>TLq2UKMjgR5;Hg#MdH%;MiEr4Kv8WailDDV5j~$5MU)$g zfT-ZrN0Gqr28f_9roFoXbBQTX^F2|O(Myz)LvrE8(b+sn7ou7hm5}hda_C^;3}K%K zr@jI#nT%kJvNf|@GXrf+K~?IUMy+Ok6auErs3n7(J=>5iapA4}Zyx$ck<1;!Dgoc* z;9U42lvgxiG&cHlr@I10>T7G>NN4mnYNySrdawZgApHxYj2@@dFwE0O1Fh8bTv$&Z z$)UO6xNhD(d61bjP=`Fhh$J!sRfFrUE(3>6vT@W`Eie_T^Rq<*=+K}@%%W%j%z)$| z{qB=1;x!)qHH(r7m`SlDl}2GA)I^*SOS16%DF0+=lDWc#1@9(dX_kF8Nh&;C;#}|| z4!k9Kg`c!5%&@sC?~!M3gRBaOF&T^%wYlq}{h=zwTSpSN0n@7vwx#b0ZjWqf?x5Ng zRaqpgvkgA0!P?j$;gG_9YhRT|pkOwK5?`Imt>dx0COlEp>(YSE$1qQzGULy^NwToT zg~fEPsBLvN?aK8GTn&q-tMWbq;#njPH|CJyB3FJ~TO^acY=cjrSQGR$3VU^Xr)p=D z>zE$W)WE$ut}QjthpI8CewyP5V3p&8V~KA5hF!E`Q0Flb-XY@o_IrDwoqMH@=lnB1A!m5FF1 zDcflFUoHHO)W^45ccfe6-L@U+ws^OFN4h=Up-5Bl?(!Y!RZuoF zmrDdQijS)|l_3BBdm1#tAMZjP+eP z-W}-^x_9A|NiQStT-cFb&oeG+D;J*LL$f6OT!Jm%ZnsOieV@92m+R5{i}aq-d#dqX z5HC*vlNw!alkv9D{slDg`6QhQ&a2|{$t*u#bhEzJTNiy0V!b}N8&MtZTwd2@PjJ`6 zO2VLUi`EcX%7P}PU|TvR5i@;ZBOx}Zpkv$8?N~7;!i*&(3VJfL3(-4npyZrc z*pz$g6tGnBqhbf#D!pawo>3Hmz=CoxK#FIwA%m-VCqJb&j@kNoi-c;JOcV%OW6n9N73@)*kGED&JopdwzR zYHvNueI_d{Y8t*fgvbln2p3K*;9$6BK#!T{wUQT2bPi64A!Zg2TlH2M*U392wDlOb2M<=5}2!kOVF?TaQfR;-L{24{4vZCBF-TRISGo3{hQ4 z2O7dw`XCKLu{dA%7&+Lm>5$eFA~e}G$;&z}pJEmpuwIs(vg&>WMjxzud_%w%%=h~y zh!-#8^Gez0u*^hTnOP}Z`I4MLCF3Yw4CN$~L^Bv)wh!hqyUe(bQYh+E9zcezHYb{p z$pl%Js%|=kvO#?WP%v2KfEcjbY0$;8V1>FUQq4Nb*n(N?J#byF$S@HfF@<6Xs7C}? zm>+FHRd&mkwYf{_+29*`G5A4e;om@0t7U#h;xo0D%0tXR$8qe*3Y!D7Q~o1zmdlDG zrG6L)VNTiz66wiOC`F2Y<`%X}e^mGMXw113497gwY~^GImZjenBWYsaPuR;MVsRX9 z)8$cJg}P6S?_7{qcw~I%;tBk~VpUIz<30K-{c0W3ffghdCBe?r1*-K$GkRSBms4k$S%CPmIx4dBDhkUW=g`; z@=w<04tyDUT+tBU8-_Nl;&oji-2fpB2iI#M;DuetJ<01(qT$gutf^1uWsNZ7FsVAr zOfliJxdiR&H<5*ka}`J8T+t~RWa1-+_RVX%`l>9Ml&ctUT*O%Z7ADgdBTveNd?|w13|aWrTBRu+{TZ^Ad?4U+;f2u%LEXO= zaa5Us2y^zhQq)Q=-#lLuUZ%iqk*18XS2!wlsE2JzVmtu3p)oIJ0(b5v$?sTWNRrr5 zJVxSf*{`Ovfq=dmeseT@Qb^%F1StX13C(#eeSGCQE(q!dQ4I#`M5R^rSYgCUIbx+h zBEgC&<{<3}uW85p;?T_9Vh=hz&(Ia|s|v8VNcNGlJ|)l}aFn@#j>Lr1*A-piTq3bJ z<+e-lBxGO))L06jRHcg5ED|BoT49w~kPnmzyW=vM_RhR`EV5 z`J%u}lE5&aWDUagxm=NHy-X3;B>Dlb`YB=oIR<2~AZ`X&11zI8ctaw1(0~coW(~>G z98%`hg8aaIP(DTio6lRRZeqTX_at*wty!d+(Td#!njMPaB)L;?plAaO$=6`eX)=*F z=?drC_fD}Nt5Zf+<%U9C{zmD3$sQgQvxmSC7ee-i1CkzK-L$ekVw(WuBJs0IhvBCd6M=szM2wd$vl)YzBrIL zA48=1c%rpR8Ld@fw1x{pCUIr1*tDPORZ5CfFE&8Y7qyVIQoRB4y6a!W|C(|Xga`%r4SyAJDrrP0@Ql$YK(fXk+ z8*%%k^%Il4wuE6sv}b1huysegWA!bKpgFW?GnFkEHh11&`@rNxxo|Ms2Qx@hl(vuY zY#A$@@?xz2f*Do9ur`*oX+s!}=|Zdu8S$zpk7O3z83vZcL;0FJ#Rk{_tF4GY5|XY( z%P4JpzF(ku0=r8EmqM8(UumEqE57G zuo9hCYA9H-`(?hth+#ohjexf8{#Ha2PWD_hDI|b}7IRi3n%WUfC6-!-rIxT{8}qTI z`B9cO!ct5_7&J;OQK!E#&$=0i^s!_wmazmJR%40q^;|5m4lJ?6ods|umN4cemR2Q< z%99lcPkH~CE@J6p<_Po1?YT%o7&0DBY>6=taf{`|OcW|MGwx{VD&%UdB1@66UhF9a z>9S8J{0txoO*WW^|1ok4rG>}OGEWx;}@FFPk=iQlu1{9-yo9u>RAKTRMBiwpB% z@symO!8x2Yvw{f1G%pf%-86U->W9KR(p{preX-9B5nDekwdXa);;>KqEM zShId7gI+_W>}Qb(;OyCH+a_PpUO`?k*Y!s^~fW4$m5N# zE=$POpa0d{-~82-d(&2zu6|W+zm{>2CUbGcy>rEgg9^PkTXLGog%$j{F3r3_%3Qm0 zwp-n>4OPtY*|Y9p_F9#JSzJ85c-3Jd)AHf$e{hGjLEG3_ebiTXUUl>l(v;Of!{LXE zs_hP{dh^GqSQ|W^b`RziX;8nj#l@M!grC*2ZyNjv=*I5sOdeKMxvTdKYM*9S?_2fs z!&>UEm`Q&Ym52L1zJAs{VjcAhzH?Ry%34|T6x6)G>vqPnsiRNfJ0JTy+uqYcqR)@% zet)OkBSk&ey32)!{*G035>7iMb%;LL41DI%ys5rSd1PGifX@`QM=>L(k<8pPFiRV^ zwMTR1ReVL;IIMWsI7Jm7`VL@HA|ZB(=~I_S^D14|4ZG^HuCCnNGcez~XNn4462|$; zQRR^cU_l#~`V|#?4+55yxRL=gQL&i2P-9+LnRsNU`;li>N$!zzMOWFG^u^HUpG1U- zL_og6JBDO$7faiMtj3_y;=;p^oC1Z}d3EA)BKH*tU8za$Sp8}MUW@95Zb+eRw%?A4 zpm*C*=Bc^RCXpZuhfkL^%PVBhvD4v&PyO;YowBD3z7nezDsJD+fd#KSVZCu+?<5IO zy2sp`mLysmZFh-vZA*eQ``PW4jSK06=@D%OBBu^i=I`5mfgUO zb%W`VwySF@Pr+3dlwr!Xynf3r!WFIF>KsHFOrRLr+a+&Fdtk(lq!N$adY=f^D|80m zhM7syC*G3#^dGj$ZL&3_0n4}fa7gm?866P9v#Du{QG?AzOEx88r=PKyyTHpOBtFqL z+Q0Zcma(>LPD@5DGTVzKc7qDqC;j&RCTP!?)QW~8j0v{FMfgN>XxYlSiWhONR-7JG zqV+WCptfvvrunxtYj3YB2bBg}tmv?)Cb=GVFiq;1&xA6fC{eba|2?f)R$F+zG4r40 zy|S|JvAavK=6r9C!X|FfL6>^(gcsawZ@i$!9^ zqOO*--NIfXARguzE1OzSrj6v6+}u!J9V`C~jSbg_hK9!KdQNMVu`y0FkBwE?=7+xU z>r`$Gjb&rhfd#ejU)`>5tFs1fTv(aOw=l7okgaKE%YR`a)?%pX6rOCT)!FVx4l{lY z-04Uw2M@&i@!<=Y&d$32(+?!BGv0q7DC(^3Kd6VX{)07IlZ7UG9xTK;sMCOR($(-C z*qXsJYzR{=wiH|ODH0k71M(J7U{_c>09&6DgBFJ+Zr`%ATU&PyzdvvLtvjnn^R2#Z z=4#7(*fgPQi~~M0R1ZP=Y~BrNJ}lLnK!&Tv5!N(7O#_g4kEg=6?rglD8ExH(OWf+~ z(GXG)J7!zalU}3|SVUfpJ#p&xklieZS3vu9W1gIgPEiei7ZSWt~fxSkjLtemd zd5_JE9Q9ycn7W1NJ&gJ0tZtet+69o^9id8x5-#+d1U!=kPQ?x`5qv}&D<7jnR7{h7 zF>5Eb>Eud0;M6o0Wh@)%E7qnl2Y$>%bNJR_78VX*7Y41l zoDRcULK!OJ$l8BK?^RDTP^I89sI1TVwx-P8EcOC^Ny}Su0`P>c%3C=&*X`6|=kCrAvWr8|b2Fdb=STu6Sda%G=5C8z%T4wxaJn;_r$jlWiz(sinVtlJN zR2o!Mgkk;+m*Lw z<52ON4bxzlhG$EkI_iH=OgdjfDQw6XMLt}dGB0wV*YG`F)O-)n*0eFZ46~-qqjND9 zBlpdG7#8v}XHzTRNWk(e5*i|484`=OGok#e1vmukzVr62VXT0gwv{)Z7&WXL#P7b1pD4()IO%hr-!>UI={n#j6FTk00EpLr0=BLuI;0(nbr?mhY;zvB z&-Nw?+Mg)$cf0b>ZOmlI4{=;dT0f`5O$@oe7z=;sw2z8y89XZuq?-7!y6GG`Yy%+fN#CG5B`PpzX&zGxZL=8jivW62WsN|T+jchxO=5=sZ$GP`goe8%O?wz|+tB3p- z#bD`#JX?u?+}FPJ8KdEj-~HWiawR>e5acp~PK~tzb{*{+jX?$%6=AtH+59)%h=HRv zy<+sViHzxaCdX3eTbNl5`N^ydKkRD+-+t?(4;EV_)1^Oqxv~gG?B>YfAL1SAZe0)) zW`4_4h2UK(zxiavsAOu2nvM!uWx-zN06`g7ePd3i^0tFcxEtJFvludzv}lF(v!Qj5 zY{gnX7QX3r<&%(sI;xp8qXjKpXn_nR2-rZ1E2ChO^xZ@GCIbELL9A828RX-rBKzTl zX`rW$1^Ao2pZA;Y7VFSAZ4O%e5qq=*FN5g#n&`lG4G8GkvBK@1BT9T$qj02X`bo^L zUmIf++STVmdcR)_M(IPA!7QFhK{JPGv{s$aVg><+VWbq@(2h2jLpQTbt;^(Csc|U++@Ng{iLtoQ?R?D7S}KW+}q@9yExpA zVAf(CSdy2TH*+<%h@k}~tzrPC0(#oaVbE0-XuLZyEmhsDZ1>7^d2^52<95@vlX=1L8)5ARb$y8zE5)bt0;5L1xEZQ3VF@(%#R;G9qe7ci5c1T~ zfc`XDM#2I3rZVO$#J9DIDSe#E)mBr0K4Q(} z;Rr51=DRvB_Awhn5+0M!0vO#uWX?eC`^<+ipSDm*5y$|Q-TSBrE6_DoXmD}`0EvV~ zILR7*%dtj758HsZCRXDoQ7E@pGsKmmAuY3fRs+Bjk)5}a4#RaJ?(el)kLP*mvc139 zIJp-@wfsgDVOH}SgF70#n2e*N`C~DHI@_^%mnIr?x zHa=S*kX2rB3LhsSar_CF7bAY(r$-)-NfCeJ3`1)_tdlKj`qAqqi*DWoI!zh!Hi0NB z23~Z9l$yE9c-ngs|N;2Mp<=i$@43Jx*7)5E5>L9)*rmJdDl;K0q`utOasw;kp9bmI;Cy2pkuw8vS6? za1ukK5nuywhz%_?+JGKxI2bnLWjJJ}g-0V0Q@YT>o#wUDlupg$1)?bik0&vjQBaa{ z)2ykuB~$8)&z!)X3Mpnqi_gfot}8<;nw_Ib11=B4>|t}G<00J-4;1p{qcPGF8&Rk> zg~PL}bc)4M)G4!bBPQDD(2JTPs!x@(ekI(_4D+XDOO$thAmbchx!fGJxi-3l|0H@E2 zOB*q)+>}U+@Gehckvd$@I+Ch20HbYWf**Md2k*6BCl|vMNxV>HjkRSc>`B5boD5SmHbtTmWS8tKD;fI$6ES(dhUI~V(_WG%QE9?faz>wZz|S?= zk(3YKk9hahqO$YyqffDE#!*Us?yf%QZD$cO@pUN*8RlULE^oHo0b=L1t*+*H>W>lM*!>}LbKtjErZ+VQEj zxWfHKY41uqiD5hZRAd)N+}3V0Bf=Cuf+)Eoy(Vt3lUk&UtMiUbrYga8q|_V9vMb)~l{guX zBbBu=A{2NBNRq^@(=Hq=IK^>Zg-Ze-Vs_f`(jdgWnBn8;SYVhpZ) z^oL>8@e~|S0(+5|k6Is3HPVl#JF0F2-F)*GN8}7aIpRc!W5=@u^Z+WiXW3Eo%|_6dc$ z5X?aa9qL@BTen8F6&lsXFHTUrQD$+hiIEz(ytK~j^>Mol&e~T>p z_bIAF7Hx*}QkZ--DKKi=H!FAnQ` z7v@!F2JXtP5IN4~4$hh_vYEq2eas2kus2k20d@oH)_;NP|X1SDdiOmhq+)l(@;h8x& zRmq-AFldo=70wvM?|qqmuc>7wNX4w%HM~09dy5_I)pvq??cu`Z`m7QS5%Fy33K^Jg zu?(vvUZHN{2!p~B0R@IglKM3SzMxD2D7w$2F}b;3zDMtc=Mz-PT_N= z0ICtbq}mo+SHl-|52gGp8WMuBouxu`FM(@guN|KI1DGsknB>}!0;AP zf0P#&*yZtpjRyMSU6p{kqoBT%c%U7QzuwVj2`=PF?sS=jLZw(q!#b^F9`D`&c zSdm|?75U_|@Tb3ESzKJmo+6@s2C=YRb67HvNr3}})L_rfrDFIiMKzijkiG$hh))fj z2|WAL4=Cwhf5)5dVJtoirkHMFcEkO zxWiU)SZ%Ib`id&O?B@6tJmF}YGjv!R_3^_0;?Tc!_Tc>7*S<{Iunr;47xdbkrQXRB zL}yN&PSZm=C+3kgjLy0s!obd|*>tl=I3iR* z`Y-e3llXA#v2s%Na#G;^LxhbR!gogOt3IH~&Rh6AABmQIb(td1{1kY@7sfp$Rjy@; zqH}zSjA^8|-!-@&S=Gzq#h4$HJyHjc7i;{QrDMee)GSW_6PTrf{Mx``zL{aFpq|Ty z$;@jN>wA7H7VTFFiJ0QV@(m$S8Tx3}@;}8;jDPx66j&muiS zH2Y%YaT185Vya2N^yyg96ARtV3{>&G$B-i0Ipn!Oi-#Ra&!@W+y@Ah$o1Y~kM z1#6*2V{pc=JHgO>f$Iush{c$*O*cTr<~pd2N-~=7)5$%PIaPtH}kEFdF0E zp_nhSA ze0`~?FFW1(3a5*dUAXLe;KBgaz4~2sIwYp!+q$G%Nu>kDE6EDuq_sfW9^Z2YN$)o< zznI`x-tdGyaJ}_maUJ&?XSsWlyKO1IwTWMC!0m;VDXno_Z;}dHt!8Zlyp~nE1>5~w z;NHJQ1Nyfph27q$k8Pk<58TCIA$`ufrNS)}>sAn(Cj=qbvdiFhVpMbWsZpIZ^ecOM zlUa{M8^_T3oeTweH|3%KqB-Pq;|I=Sj|LNAB{Dqe; z{hd=k|KX#Z_1(Xo{@}+>w{QBuZ=E{vud|OAH-CHDJ@n*nU;Om1pPIgW!`{7L{;TPm zhd%M258e1{r+)2^{^gkuZuzU}7dGzuv8#Ue-<^8OeJV^JKQnzn=MS%Z?MF_Ya`xxU zbi6wEh25Y2`%m2Z7t@dY=(j)g^v^#%ePTA<{L7#F*7O(Ow&Usd-u#v6Z@xbJfgS$O zrklU-KlVp&{g2a^JpGy5fA2T`bo##CMfcI)_?_uL4-Ztn`RJca|KX7n&;LyA_oi># z^WMLC`6GWk-TI4P`M^~5>(hVv&j0=0op1Z*^yLqKY0qbeUOY9My^{U24}4>KOK5-l zyJ!FBsk_`I7klrgJ~;J&yJYHv7f*eV`%9)CxOnOTPtorE`)<4Kjt~2L?)~r`{;mW5 z-un;wd++qO-FyE%A3or&zw4eke{kRakK94&et+QJ`}f~|o@)2(yT{#i&zApS=2|ZkCMFRX4j}M8)=_HEK2Z$-fQUZ`iQGg>QGW zq5gxtZ@KWC`Q^-2T7=`)<4I(508|xaF1uKYrIoZ#noA_uX*|Lb&%D zHC=2v_sNEHuX0^o{|egPz3;$*)eThtH1)s8|2NdX@3wsh?s#MUGv}@U&RcG|@7}xa zIe5qZl`Yi2=l>Z0_2*UER=8IAFBsJMPm$AW;i1ic{dt}O)e}5c){_*GxFo%LzL&w9 t19zQ|MB~W``qS9&J^0Q6!|1|&kn*oLF*hUG*nOSEDJWGeD9^3y{{;|SKN0`{ diff --git a/docs/lib/scripts/tinycolor.js b/docs/lib/scripts/tinycolor.js deleted file mode 100644 index dd2cbedcf..000000000 --- a/docs/lib/scripts/tinycolor.js +++ /dev/null @@ -1,1863 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.tinycolor = factory()); -})(this, (function () { 'use strict'; - - function _typeof(obj) { - "@babel/helpers - typeof"; - - return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { - return typeof obj; - } : function (obj) { - return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }, _typeof(obj); - } - - // https://github.com/bgrins/TinyColor - // Brian Grinstead, MIT License - - var trimLeft = /^\s+/; - var trimRight = /\s+$/; - function tinycolor(color, opts) { - color = color ? color : ""; - opts = opts || {}; - - // If input is already a tinycolor, return itself - if (color instanceof tinycolor) { - return color; - } - // If we are called as a function, call using new instead - if (!(this instanceof tinycolor)) { - return new tinycolor(color, opts); - } - var rgb = inputToRGB(color); - this._originalInput = color, this._r = rgb.r, this._g = rgb.g, this._b = rgb.b, this._a = rgb.a, this._roundA = Math.round(100 * this._a) / 100, this._format = opts.format || rgb.format; - this._gradientType = opts.gradientType; - - // Don't let the range of [0,255] come back in [0,1]. - // Potentially lose a little bit of precision here, but will fix issues where - // .5 gets interpreted as half of the total, instead of half of 1 - // If it was supposed to be 128, this was already taken care of by `inputToRgb` - if (this._r < 1) this._r = Math.round(this._r); - if (this._g < 1) this._g = Math.round(this._g); - if (this._b < 1) this._b = Math.round(this._b); - this._ok = rgb.ok; - } - tinycolor.prototype = { - isDark: function isDark() { - return this.getBrightness() < 128; - }, - isLight: function isLight() { - return !this.isDark(); - }, - isValid: function isValid() { - return this._ok; - }, - getOriginalInput: function getOriginalInput() { - return this._originalInput; - }, - getFormat: function getFormat() { - return this._format; - }, - getAlpha: function getAlpha() { - return this._a; - }, - getBrightness: function getBrightness() { - //http://www.w3.org/TR/AERT#color-contrast - var rgb = this.toRgb(); - return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000; - }, - getLuminance: function getLuminance() { - //http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef - var rgb = this.toRgb(); - var RsRGB, GsRGB, BsRGB, R, G, B; - RsRGB = rgb.r / 255; - GsRGB = rgb.g / 255; - BsRGB = rgb.b / 255; - if (RsRGB <= 0.03928) R = RsRGB / 12.92;else R = Math.pow((RsRGB + 0.055) / 1.055, 2.4); - if (GsRGB <= 0.03928) G = GsRGB / 12.92;else G = Math.pow((GsRGB + 0.055) / 1.055, 2.4); - if (BsRGB <= 0.03928) B = BsRGB / 12.92;else B = Math.pow((BsRGB + 0.055) / 1.055, 2.4); - return 0.2126 * R + 0.7152 * G + 0.0722 * B; - }, - setAlpha: function setAlpha(value) { - this._a = boundAlpha(value); - this._roundA = Math.round(100 * this._a) / 100; - return this; - }, - toHsv: function toHsv() { - var hsv = rgbToHsv(this._r, this._g, this._b); - return { - h: hsv.h * 360, - s: hsv.s, - v: hsv.v, - a: this._a - }; - }, - toHsvString: function toHsvString() { - var hsv = rgbToHsv(this._r, this._g, this._b); - var h = Math.round(hsv.h * 360), - s = Math.round(hsv.s * 100), - v = Math.round(hsv.v * 100); - return this._a == 1 ? "hsv(" + h + ", " + s + "%, " + v + "%)" : "hsva(" + h + ", " + s + "%, " + v + "%, " + this._roundA + ")"; - }, - toHsl: function toHsl() { - var hsl = rgbToHsl(this._r, this._g, this._b); - return { - h: hsl.h * 360, - s: hsl.s, - l: hsl.l, - a: this._a - }; - }, - toHslString: function toHslString() { - var hsl = rgbToHsl(this._r, this._g, this._b); - var h = Math.round(hsl.h * 360), - s = Math.round(hsl.s * 100), - l = Math.round(hsl.l * 100); - return this._a == 1 ? "hsl(" + h + ", " + s + "%, " + l + "%)" : "hsla(" + h + ", " + s + "%, " + l + "%, " + this._roundA + ")"; - }, - toHex: function toHex(allow3Char) { - return rgbToHex(this._r, this._g, this._b, allow3Char); - }, - toHexString: function toHexString(allow3Char) { - return "#" + this.toHex(allow3Char); - }, - toHexNumber: function toHexNumber() { - return Number("0x" + this.toHex()); - }, - toHex8: function toHex8(allow4Char) { - return rgbaToHex(this._r, this._g, this._b, this._a, allow4Char); - }, - toHex8String: function toHex8String(allow4Char) { - return "#" + this.toHex8(allow4Char); - }, - toRgb: function toRgb() { - return { - r: Math.round(this._r), - g: Math.round(this._g), - b: Math.round(this._b), - a: this._a - }; - }, - toRgbString: function toRgbString() { - return this._a == 1 ? "rgb(" + Math.round(this._r) + ", " + Math.round(this._g) + ", " + Math.round(this._b) + ")" : "rgba(" + Math.round(this._r) + ", " + Math.round(this._g) + ", " + Math.round(this._b) + ", " + this._roundA + ")"; - }, - toPercentageRgb: function toPercentageRgb() { - return { - r: Math.round(bound01(this._r, 255) * 100) + "%", - g: Math.round(bound01(this._g, 255) * 100) + "%", - b: Math.round(bound01(this._b, 255) * 100) + "%", - a: this._a - }; - }, - toPercentageRgbString: function toPercentageRgbString() { - return this._a == 1 ? "rgb(" + Math.round(bound01(this._r, 255) * 100) + "%, " + Math.round(bound01(this._g, 255) * 100) + "%, " + Math.round(bound01(this._b, 255) * 100) + "%)" : "rgba(" + Math.round(bound01(this._r, 255) * 100) + "%, " + Math.round(bound01(this._g, 255) * 100) + "%, " + Math.round(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")"; - }, - toName: function toName() { - if (this._a === 0) { - return "transparent"; - } - if (this._a < 1) { - return false; - } - return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false; - }, - toFilter: function toFilter(secondColor) { - var hex8String = "#" + rgbaToArgbHex(this._r, this._g, this._b, this._a); - var secondHex8String = hex8String; - var gradientType = this._gradientType ? "GradientType = 1, " : ""; - if (secondColor) { - var s = tinycolor(secondColor); - secondHex8String = "#" + rgbaToArgbHex(s._r, s._g, s._b, s._a); - } - return "progid:DXImageTransform.Microsoft.gradient(" + gradientType + "startColorstr=" + hex8String + ",endColorstr=" + secondHex8String + ")"; - }, - toString: function toString(format) { - var formatSet = !!format; - format = format || this._format; - var formattedString = false; - var hasAlpha = this._a < 1 && this._a >= 0; - var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "hex4" || format === "hex8" || format === "name"); - if (needsAlphaFormat) { - // Special case for "transparent", all other non-alpha formats - // will return rgba when there is transparency. - if (format === "name" && this._a === 0) { - return this.toName(); - } - return this.toRgbString(); - } - if (format === "rgb") { - formattedString = this.toRgbString(); - } - if (format === "prgb") { - formattedString = this.toPercentageRgbString(); - } - if (format === "hex" || format === "hex6") { - formattedString = this.toHexString(); - } - if (format === "hex3") { - formattedString = this.toHexString(true); - } - if (format === "hex4") { - formattedString = this.toHex8String(true); - } - if (format === "hex8") { - formattedString = this.toHex8String(); - } - if (format === "name") { - formattedString = this.toName(); - } - if (format === "hsl") { - formattedString = this.toHslString(); - } - if (format === "hsv") { - formattedString = this.toHsvString(); - } - return formattedString || this.toHexString(); - }, - clone: function clone() { - return tinycolor(this.toString()); - }, - _applyModification: function _applyModification(fn, args) { - var color = fn.apply(null, [this].concat([].slice.call(args))); - this._r = color._r; - this._g = color._g; - this._b = color._b; - this.setAlpha(color._a); - return this; - }, - lighten: function lighten() { - return this._applyModification(_lighten, arguments); - }, - brighten: function brighten() { - return this._applyModification(_brighten, arguments); - }, - darken: function darken() { - return this._applyModification(_darken, arguments); - }, - desaturate: function desaturate() { - return this._applyModification(_desaturate, arguments); - }, - saturate: function saturate() { - return this._applyModification(_saturate, arguments); - }, - greyscale: function greyscale() { - return this._applyModification(_greyscale, arguments); - }, - spin: function spin() { - return this._applyModification(_spin, arguments); - }, - _applyCombination: function _applyCombination(fn, args) { - return fn.apply(null, [this].concat([].slice.call(args))); - }, - analogous: function analogous() { - return this._applyCombination(_analogous, arguments); - }, - complement: function complement() { - return this._applyCombination(_complement, arguments); - }, - monochromatic: function monochromatic() { - return this._applyCombination(_monochromatic, arguments); - }, - splitcomplement: function splitcomplement() { - return this._applyCombination(_splitcomplement, arguments); - }, - // Disabled until https://github.com/bgrins/TinyColor/issues/254 - // polyad: function (number) { - // return this._applyCombination(polyad, [number]); - // }, - triad: function triad() { - return this._applyCombination(polyad, [3]); - }, - tetrad: function tetrad() { - return this._applyCombination(polyad, [4]); - } - }; - - // If input is an object, force 1 into "1.0" to handle ratios properly - // String input requires "1.0" as input, so 1 will be treated as 1 - tinycolor.fromRatio = function (color, opts) { - if (_typeof(color) == "object") { - var newColor = {}; - for (var i in color) { - if (color.hasOwnProperty(i)) { - if (i === "a") { - newColor[i] = color[i]; - } else { - newColor[i] = convertToPercentage(color[i]); - } - } - } - color = newColor; - } - return tinycolor(color, opts); - }; - - // Given a string or object, convert that input to RGB - // Possible string inputs: - // - // "red" - // "#f00" or "f00" - // "#ff0000" or "ff0000" - // "#ff000000" or "ff000000" - // "rgb 255 0 0" or "rgb (255, 0, 0)" - // "rgb 1.0 0 0" or "rgb (1, 0, 0)" - // "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1" - // "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1" - // "hsl(0, 100%, 50%)" or "hsl 0 100% 50%" - // "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1" - // "hsv(0, 100%, 100%)" or "hsv 0 100% 100%" - // - function inputToRGB(color) { - var rgb = { - r: 0, - g: 0, - b: 0 - }; - var a = 1; - var s = null; - var v = null; - var l = null; - var ok = false; - var format = false; - if (typeof color == "string") { - color = stringInputToObject(color); - } - if (_typeof(color) == "object") { - if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) { - rgb = rgbToRgb(color.r, color.g, color.b); - ok = true; - format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb"; - } else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) { - s = convertToPercentage(color.s); - v = convertToPercentage(color.v); - rgb = hsvToRgb(color.h, s, v); - ok = true; - format = "hsv"; - } else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) { - s = convertToPercentage(color.s); - l = convertToPercentage(color.l); - rgb = hslToRgb(color.h, s, l); - ok = true; - format = "hsl"; - } - if (color.hasOwnProperty("a")) { - a = color.a; - } - } - a = boundAlpha(a); - return { - ok: ok, - format: color.format || format, - r: Math.min(255, Math.max(rgb.r, 0)), - g: Math.min(255, Math.max(rgb.g, 0)), - b: Math.min(255, Math.max(rgb.b, 0)), - a: a - }; - } - - // Conversion Functions - // -------------------- - - // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from: - // - - // `rgbToRgb` - // Handle bounds / percentage checking to conform to CSS color spec - // - // *Assumes:* r, g, b in [0, 255] or [0, 1] - // *Returns:* { r, g, b } in [0, 255] - function rgbToRgb(r, g, b) { - return { - r: bound01(r, 255) * 255, - g: bound01(g, 255) * 255, - b: bound01(b, 255) * 255 - }; - } - - // `rgbToHsl` - // Converts an RGB color value to HSL. - // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1] - // *Returns:* { h, s, l } in [0,1] - function rgbToHsl(r, g, b) { - r = bound01(r, 255); - g = bound01(g, 255); - b = bound01(b, 255); - var max = Math.max(r, g, b), - min = Math.min(r, g, b); - var h, - s, - l = (max + min) / 2; - if (max == min) { - h = s = 0; // achromatic - } else { - var d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - case g: - h = (b - r) / d + 2; - break; - case b: - h = (r - g) / d + 4; - break; - } - h /= 6; - } - return { - h: h, - s: s, - l: l - }; - } - - // `hslToRgb` - // Converts an HSL color value to RGB. - // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100] - // *Returns:* { r, g, b } in the set [0, 255] - function hslToRgb(h, s, l) { - var r, g, b; - h = bound01(h, 360); - s = bound01(s, 100); - l = bound01(l, 100); - function hue2rgb(p, q, t) { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t; - if (t < 1 / 2) return q; - if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; - return p; - } - if (s === 0) { - r = g = b = l; // achromatic - } else { - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - r = hue2rgb(p, q, h + 1 / 3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1 / 3); - } - return { - r: r * 255, - g: g * 255, - b: b * 255 - }; - } - - // `rgbToHsv` - // Converts an RGB color value to HSV - // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1] - // *Returns:* { h, s, v } in [0,1] - function rgbToHsv(r, g, b) { - r = bound01(r, 255); - g = bound01(g, 255); - b = bound01(b, 255); - var max = Math.max(r, g, b), - min = Math.min(r, g, b); - var h, - s, - v = max; - var d = max - min; - s = max === 0 ? 0 : d / max; - if (max == min) { - h = 0; // achromatic - } else { - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - case g: - h = (b - r) / d + 2; - break; - case b: - h = (r - g) / d + 4; - break; - } - h /= 6; - } - return { - h: h, - s: s, - v: v - }; - } - - // `hsvToRgb` - // Converts an HSV color value to RGB. - // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100] - // *Returns:* { r, g, b } in the set [0, 255] - function hsvToRgb(h, s, v) { - h = bound01(h, 360) * 6; - s = bound01(s, 100); - v = bound01(v, 100); - var i = Math.floor(h), - f = h - i, - p = v * (1 - s), - q = v * (1 - f * s), - t = v * (1 - (1 - f) * s), - mod = i % 6, - r = [v, q, p, p, t, v][mod], - g = [t, v, v, q, p, p][mod], - b = [p, p, t, v, v, q][mod]; - return { - r: r * 255, - g: g * 255, - b: b * 255 - }; - } - - // `rgbToHex` - // Converts an RGB color to hex - // Assumes r, g, and b are contained in the set [0, 255] - // Returns a 3 or 6 character hex - function rgbToHex(r, g, b, allow3Char) { - var hex = [pad2(Math.round(r).toString(16)), pad2(Math.round(g).toString(16)), pad2(Math.round(b).toString(16))]; - - // Return a 3 character hex if possible - if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) { - return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0); - } - return hex.join(""); - } - - // `rgbaToHex` - // Converts an RGBA color plus alpha transparency to hex - // Assumes r, g, b are contained in the set [0, 255] and - // a in [0, 1]. Returns a 4 or 8 character rgba hex - function rgbaToHex(r, g, b, a, allow4Char) { - var hex = [pad2(Math.round(r).toString(16)), pad2(Math.round(g).toString(16)), pad2(Math.round(b).toString(16)), pad2(convertDecimalToHex(a))]; - - // Return a 4 character hex if possible - if (allow4Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1) && hex[3].charAt(0) == hex[3].charAt(1)) { - return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0) + hex[3].charAt(0); - } - return hex.join(""); - } - - // `rgbaToArgbHex` - // Converts an RGBA color to an ARGB Hex8 string - // Rarely used, but required for "toFilter()" - function rgbaToArgbHex(r, g, b, a) { - var hex = [pad2(convertDecimalToHex(a)), pad2(Math.round(r).toString(16)), pad2(Math.round(g).toString(16)), pad2(Math.round(b).toString(16))]; - return hex.join(""); - } - - // `equals` - // Can be called with any tinycolor input - tinycolor.equals = function (color1, color2) { - if (!color1 || !color2) return false; - return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString(); - }; - tinycolor.random = function () { - return tinycolor.fromRatio({ - r: Math.random(), - g: Math.random(), - b: Math.random() - }); - }; - - // Modification Functions - // ---------------------- - // Thanks to less.js for some of the basics here - // - - function _desaturate(color, amount) { - amount = amount === 0 ? 0 : amount || 10; - var hsl = tinycolor(color).toHsl(); - hsl.s -= amount / 100; - hsl.s = clamp01(hsl.s); - return tinycolor(hsl); - } - function _saturate(color, amount) { - amount = amount === 0 ? 0 : amount || 10; - var hsl = tinycolor(color).toHsl(); - hsl.s += amount / 100; - hsl.s = clamp01(hsl.s); - return tinycolor(hsl); - } - function _greyscale(color) { - return tinycolor(color).desaturate(100); - } - function _lighten(color, amount) { - amount = amount === 0 ? 0 : amount || 10; - var hsl = tinycolor(color).toHsl(); - hsl.l += amount / 100; - hsl.l = clamp01(hsl.l); - return tinycolor(hsl); - } - function _brighten(color, amount) { - amount = amount === 0 ? 0 : amount || 10; - var rgb = tinycolor(color).toRgb(); - rgb.r = Math.max(0, Math.min(255, rgb.r - Math.round(255 * -(amount / 100)))); - rgb.g = Math.max(0, Math.min(255, rgb.g - Math.round(255 * -(amount / 100)))); - rgb.b = Math.max(0, Math.min(255, rgb.b - Math.round(255 * -(amount / 100)))); - return tinycolor(rgb); - } - function _darken(color, amount) { - amount = amount === 0 ? 0 : amount || 10; - var hsl = tinycolor(color).toHsl(); - hsl.l -= amount / 100; - hsl.l = clamp01(hsl.l); - return tinycolor(hsl); - } - - // Spin takes a positive or negative amount within [-360, 360] indicating the change of hue. - // Values outside of this range will be wrapped into this range. - function _spin(color, amount) { - var hsl = tinycolor(color).toHsl(); - var hue = (hsl.h + amount) % 360; - hsl.h = hue < 0 ? 360 + hue : hue; - return tinycolor(hsl); - } - - // Combination Functions - // --------------------- - // Thanks to jQuery xColor for some of the ideas behind these - // - - function _complement(color) { - var hsl = tinycolor(color).toHsl(); - hsl.h = (hsl.h + 180) % 360; - return tinycolor(hsl); - } - function polyad(color, number) { - if (isNaN(number) || number <= 0) { - throw new Error("Argument to polyad must be a positive number"); - } - var hsl = tinycolor(color).toHsl(); - var result = [tinycolor(color)]; - var step = 360 / number; - for (var i = 1; i < number; i++) { - result.push(tinycolor({ - h: (hsl.h + i * step) % 360, - s: hsl.s, - l: hsl.l - })); - } - return result; - } - function _splitcomplement(color) { - var hsl = tinycolor(color).toHsl(); - var h = hsl.h; - return [tinycolor(color), tinycolor({ - h: (h + 72) % 360, - s: hsl.s, - l: hsl.l - }), tinycolor({ - h: (h + 216) % 360, - s: hsl.s, - l: hsl.l - })]; - } - function _analogous(color, results, slices) { - results = results || 6; - slices = slices || 30; - var hsl = tinycolor(color).toHsl(); - var part = 360 / slices; - var ret = [tinycolor(color)]; - for (hsl.h = (hsl.h - (part * results >> 1) + 720) % 360; --results;) { - hsl.h = (hsl.h + part) % 360; - ret.push(tinycolor(hsl)); - } - return ret; - } - function _monochromatic(color, results) { - results = results || 6; - var hsv = tinycolor(color).toHsv(); - var h = hsv.h, - s = hsv.s, - v = hsv.v; - var ret = []; - var modification = 1 / results; - while (results--) { - ret.push(tinycolor({ - h: h, - s: s, - v: v - })); - v = (v + modification) % 1; - } - return ret; - } - - - - // Utility Functions - // --------------------- - - tinycolor.mix = function (color1, color2, amount) { - amount = amount === 0 ? 0 : amount || 50; - var rgb1 = tinycolor(color1).toRgb(); - var rgb2 = tinycolor(color2).toRgb(); - var p = amount / 100; - var rgba = { - r: (rgb2.r - rgb1.r) * p + rgb1.r, - g: (rgb2.g - rgb1.g) * p + rgb1.g, - b: (rgb2.b - rgb1.b) * p + rgb1.b, - a: (rgb2.a - rgb1.a) * p + rgb1.a - }; - return tinycolor(rgba); - }; - - // Readability Functions - // --------------------- - // false - // tinycolor.isReadable("#000", "#111",{level:"AA",size:"large"}) => false - tinycolor.isReadable = function (color1, color2, wcag2) { - var readability = tinycolor.readability(color1, color2); - var wcag2Parms, out; - out = false; - wcag2Parms = validateWCAG2Parms(wcag2); - switch (wcag2Parms.level + wcag2Parms.size) { - case "AAsmall": - case "AAAlarge": - out = readability >= 4.5; - break; - case "AAlarge": - out = readability >= 3; - break; - case "AAAsmall": - out = readability >= 7; - break; - } - return out; - }; - - // `mostReadable` - // Given a base color and a list of possible foreground or background - // colors for that base, returns the most readable color. - // Optionally returns Black or White if the most readable color is unreadable. - // *Example* - // tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:false}).toHexString(); // "#112255" - // tinycolor.mostReadable(tinycolor.mostReadable("#123", ["#124", "#125"],{includeFallbackColors:true}).toHexString(); // "#ffffff" - // tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"large"}).toHexString(); // "#faf3f3" - // tinycolor.mostReadable("#a8015a", ["#faf3f3"],{includeFallbackColors:true,level:"AAA",size:"small"}).toHexString(); // "#ffffff" - tinycolor.mostReadable = function (baseColor, colorList, args) { - var bestColor = null; - var bestScore = 0; - var readability; - var includeFallbackColors, level, size; - args = args || {}; - includeFallbackColors = args.includeFallbackColors; - level = args.level; - size = args.size; - for (var i = 0; i < colorList.length; i++) { - readability = tinycolor.readability(baseColor, colorList[i]); - if (readability > bestScore) { - bestScore = readability; - bestColor = tinycolor(colorList[i]); - } - } - if (tinycolor.isReadable(baseColor, bestColor, { - level: level, - size: size - }) || !includeFallbackColors) { - return bestColor; - } else { - args.includeFallbackColors = false; - return tinycolor.mostReadable(baseColor, ["#fff", "#000"], args); - } - }; - - // Big List of Colors - // ------------------ - // - var names = tinycolor.names = { - aliceblue: "f0f8ff", - antiquewhite: "faebd7", - aqua: "0ff", - aquamarine: "7fffd4", - azure: "f0ffff", - beige: "f5f5dc", - bisque: "ffe4c4", - black: "000", - blanchedalmond: "ffebcd", - blue: "00f", - blueviolet: "8a2be2", - brown: "a52a2a", - burlywood: "deb887", - burntsienna: "ea7e5d", - cadetblue: "5f9ea0", - chartreuse: "7fff00", - chocolate: "d2691e", - coral: "ff7f50", - cornflowerblue: "6495ed", - cornsilk: "fff8dc", - crimson: "dc143c", - cyan: "0ff", - darkblue: "00008b", - darkcyan: "008b8b", - darkgoldenrod: "b8860b", - darkgray: "a9a9a9", - darkgreen: "006400", - darkgrey: "a9a9a9", - darkkhaki: "bdb76b", - darkmagenta: "8b008b", - darkolivegreen: "556b2f", - darkorange: "ff8c00", - darkorchid: "9932cc", - darkred: "8b0000", - darksalmon: "e9967a", - darkseagreen: "8fbc8f", - darkslateblue: "483d8b", - darkslategray: "2f4f4f", - darkslategrey: "2f4f4f", - darkturquoise: "00ced1", - darkviolet: "9400d3", - deeppink: "ff1493", - deepskyblue: "00bfff", - dimgray: "696969", - dimgrey: "696969", - dodgerblue: "1e90ff", - firebrick: "b22222", - floralwhite: "fffaf0", - forestgreen: "228b22", - fuchsia: "f0f", - gainsboro: "dcdcdc", - ghostwhite: "f8f8ff", - gold: "ffd700", - goldenrod: "daa520", - gray: "808080", - green: "008000", - greenyellow: "adff2f", - grey: "808080", - honeydew: "f0fff0", - hotpink: "ff69b4", - indianred: "cd5c5c", - indigo: "4b0082", - ivory: "fffff0", - khaki: "f0e68c", - lavender: "e6e6fa", - lavenderblush: "fff0f5", - lawngreen: "7cfc00", - lemonchiffon: "fffacd", - lightblue: "add8e6", - lightcoral: "f08080", - lightcyan: "e0ffff", - lightgoldenrodyellow: "fafad2", - lightgray: "d3d3d3", - lightgreen: "90ee90", - lightgrey: "d3d3d3", - lightpink: "ffb6c1", - lightsalmon: "ffa07a", - lightseagreen: "20b2aa", - lightskyblue: "87cefa", - lightslategray: "789", - lightslategrey: "789", - lightsteelblue: "b0c4de", - lightyellow: "ffffe0", - lime: "0f0", - limegreen: "32cd32", - linen: "faf0e6", - magenta: "f0f", - maroon: "800000", - mediumaquamarine: "66cdaa", - mediumblue: "0000cd", - mediumorchid: "ba55d3", - mediumpurple: "9370db", - mediumseagreen: "3cb371", - mediumslateblue: "7b68ee", - mediumspringgreen: "00fa9a", - mediumturquoise: "48d1cc", - mediumvioletred: "c71585", - midnightblue: "191970", - mintcream: "f5fffa", - mistyrose: "ffe4e1", - moccasin: "ffe4b5", - navajowhite: "ffdead", - navy: "000080", - oldlace: "fdf5e6", - olive: "808000", - olivedrab: "6b8e23", - orange: "ffa500", - orangered: "ff4500", - orchid: "da70d6", - palegoldenrod: "eee8aa", - palegreen: "98fb98", - paleturquoise: "afeeee", - palevioletred: "db7093", - papayawhip: "ffefd5", - peachpuff: "ffdab9", - peru: "cd853f", - pink: "ffc0cb", - plum: "dda0dd", - powderblue: "b0e0e6", - purple: "800080", - rebeccapurple: "663399", - red: "f00", - rosybrown: "bc8f8f", - royalblue: "4169e1", - saddlebrown: "8b4513", - salmon: "fa8072", - sandybrown: "f4a460", - seagreen: "2e8b57", - seashell: "fff5ee", - sienna: "a0522d", - silver: "c0c0c0", - skyblue: "87ceeb", - slateblue: "6a5acd", - slategray: "708090", - slategrey: "708090", - snow: "fffafa", - springgreen: "00ff7f", - steelblue: "4682b4", - tan: "d2b48c", - teal: "008080", - thistle: "d8bfd8", - tomato: "ff6347", - turquoise: "40e0d0", - violet: "ee82ee", - wheat: "f5deb3", - white: "fff", - whitesmoke: "f5f5f5", - yellow: "ff0", - yellowgreen: "9acd32" - }; - - // Make it easy to access colors via `hexNames[hex]` - var hexNames = tinycolor.hexNames = flip(names); - - // Utilities - // --------- - - // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }` - function flip(o) { - var flipped = {}; - for (var i in o) { - if (o.hasOwnProperty(i)) { - flipped[o[i]] = i; - } - } - return flipped; - } - - // Return a valid alpha value [0,1] with all invalid values being set to 1 - function boundAlpha(a) { - a = parseFloat(a); - if (isNaN(a) || a < 0 || a > 1) { - a = 1; - } - return a; - } - - // Take input from [0, n] and return it as [0, 1] - function bound01(n, max) { - if (isOnePointZero(n)) n = "100%"; - var processPercent = isPercentage(n); - n = Math.min(max, Math.max(0, parseFloat(n))); - - // Automatically convert percentage into number - if (processPercent) { - n = parseInt(n * max, 10) / 100; - } - - // Handle floating point rounding errors - if (Math.abs(n - max) < 0.000001) { - return 1; - } - - // Convert into [0, 1] range if it isn't already - return n % max / parseFloat(max); - } - - // Force a number between 0 and 1 - function clamp01(val) { - return Math.min(1, Math.max(0, val)); - } - - // Parse a base-16 hex value into a base-10 integer - function parseIntFromHex(val) { - return parseInt(val, 16); - } - - // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1 - // - function isOnePointZero(n) { - return typeof n == "string" && n.indexOf(".") != -1 && parseFloat(n) === 1; - } - - // Check to see if string passed in is a percentage - function isPercentage(n) { - return typeof n === "string" && n.indexOf("%") != -1; - } - - // Force a hex value to have 2 characters - function pad2(c) { - return c.length == 1 ? "0" + c : "" + c; - } - - // Replace a decimal with it's percentage value - function convertToPercentage(n) { - if (n <= 1) { - n = n * 100 + "%"; - } - return n; - } - - // Converts a decimal to a hex value - function convertDecimalToHex(d) { - return Math.round(parseFloat(d) * 255).toString(16); - } - // Converts a hex value to a decimal - function convertHexToDecimal(h) { - return parseIntFromHex(h) / 255; - } - var matchers = function () { - // - var CSS_INTEGER = "[-\\+]?\\d+%?"; - - // - var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?"; - - // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome. - var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")"; - - // Actual matching. - // Parentheses and commas are optional, but not required. - // Whitespace can take the place of commas or opening paren - var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; - var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?"; - return { - CSS_UNIT: new RegExp(CSS_UNIT), - rgb: new RegExp("rgb" + PERMISSIVE_MATCH3), - rgba: new RegExp("rgba" + PERMISSIVE_MATCH4), - hsl: new RegExp("hsl" + PERMISSIVE_MATCH3), - hsla: new RegExp("hsla" + PERMISSIVE_MATCH4), - hsv: new RegExp("hsv" + PERMISSIVE_MATCH3), - hsva: new RegExp("hsva" + PERMISSIVE_MATCH4), - hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, - hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/, - hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, - hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/ - }; - }(); - - // `isValidCSSUnit` - // Take in a single string / number and check to see if it looks like a CSS unit - // (see `matchers` above for definition). - function isValidCSSUnit(color) { - return !!matchers.CSS_UNIT.exec(color); - } - - // `stringInputToObject` - // Permissive string parsing. Take in a number of formats, and output an object - // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}` - function stringInputToObject(color) { - color = color.replace(trimLeft, "").replace(trimRight, "").toLowerCase(); - var named = false; - if (names[color]) { - color = names[color]; - named = true; - } else if (color == "transparent") { - return { - r: 0, - g: 0, - b: 0, - a: 0, - format: "name" - }; - } - - // Try to match string input using regular expressions. - // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360] - // Just return an object and let the conversion functions handle that. - // This way the result will be the same whether the tinycolor is initialized with string or object. - var match; - if (match = matchers.rgb.exec(color)) { - return { - r: match[1], - g: match[2], - b: match[3] - }; - } - if (match = matchers.rgba.exec(color)) { - return { - r: match[1], - g: match[2], - b: match[3], - a: match[4] - }; - } - if (match = matchers.hsl.exec(color)) { - return { - h: match[1], - s: match[2], - l: match[3] - }; - } - if (match = matchers.hsla.exec(color)) { - return { - h: match[1], - s: match[2], - l: match[3], - a: match[4] - }; - } - if (match = matchers.hsv.exec(color)) { - return { - h: match[1], - s: match[2], - v: match[3] - }; - } - if (match = matchers.hsva.exec(color)) { - return { - h: match[1], - s: match[2], - v: match[3], - a: match[4] - }; - } - if (match = matchers.hex8.exec(color)) { - return { - r: parseIntFromHex(match[1]), - g: parseIntFromHex(match[2]), - b: parseIntFromHex(match[3]), - a: convertHexToDecimal(match[4]), - format: named ? "name" : "hex8" - }; - } - if (match = matchers.hex6.exec(color)) { - return { - r: parseIntFromHex(match[1]), - g: parseIntFromHex(match[2]), - b: parseIntFromHex(match[3]), - format: named ? "name" : "hex" - }; - } - if (match = matchers.hex4.exec(color)) { - return { - r: parseIntFromHex(match[1] + "" + match[1]), - g: parseIntFromHex(match[2] + "" + match[2]), - b: parseIntFromHex(match[3] + "" + match[3]), - a: convertHexToDecimal(match[4] + "" + match[4]), - format: named ? "name" : "hex8" - }; - } - if (match = matchers.hex3.exec(color)) { - return { - r: parseIntFromHex(match[1] + "" + match[1]), - g: parseIntFromHex(match[2] + "" + match[2]), - b: parseIntFromHex(match[3] + "" + match[3]), - format: named ? "name" : "hex" - }; - } - return false; - } - function validateWCAG2Parms(parms) { - // return valid WCAG2 parms for isReadable. - // If input parms are invalid, return {"level":"AA", "size":"small"} - var level, size; - parms = parms || { - level: "AA", - size: "small" - }; - level = (parms.level || "AA").toUpperCase(); - size = (parms.size || "small").toLowerCase(); - if (level !== "AA" && level !== "AAA") { - level = "AA"; - } - if (size !== "small" && size !== "large") { - size = "small"; - } - return { - level: level, - size: size - }; - } - - return tinycolor; - -})); - - -// w3color.js - -/* w3color.js ver.1.18 by w3schools.com (Do not remove this line)*/ - - -function w3color(color, elmnt) { - if (!(this instanceof w3color)) { return new w3color(color, elmnt); } - if (typeof color == "object") { return color; } - this.attachValues(toColorObject(color)); - if (elmnt) { elmnt.style.backgroundColor = this.toRgbString(); } -} - -w3color.prototype = { - toRgbString: function () { - return "rgb(" + this.red + ", " + this.green + ", " + this.blue + ")"; - }, - toRgbaString: function () { - return "rgba(" + this.red + ", " + this.green + ", " + this.blue + ", " + this.opacity + ")"; - }, - toHwbString: function () { - return "hwb(" + this.hue + ", " + Math.round(this.whiteness * 100) + "%, " + Math.round(this.blackness * 100) + "%)"; - }, - toHwbStringDecimal: function () { - return "hwb(" + this.hue + ", " + this.whiteness + ", " + this.blackness + ")"; - }, - toHwbaString: function () { - return "hwba(" + this.hue + ", " + Math.round(this.whiteness * 100) + "%, " + Math.round(this.blackness * 100) + "%, " + this.opacity + ")"; - }, - toHslString: function () { - return "hsl(" + this.hue + ", " + Math.round(this.sat * 100) + "%, " + Math.round(this.lightness * 100) + "%)"; - }, - toHslStringDecimal: function () { - return "hsl(" + this.hue + ", " + this.sat + ", " + this.lightness + ")"; - }, - toHslaString: function () { - return "hsla(" + this.hue + ", " + Math.round(this.sat * 100) + "%, " + Math.round(this.lightness * 100) + "%, " + this.opacity + ")"; - }, - toCmykString: function () { - return "cmyk(" + Math.round(this.cyan * 100) + "%, " + Math.round(this.magenta * 100) + "%, " + Math.round(this.yellow * 100) + "%, " + Math.round(this.black * 100) + "%)"; - }, - toCmykStringDecimal: function () { - return "cmyk(" + this.cyan + ", " + this.magenta + ", " + this.yellow + ", " + this.black + ")"; - }, - toNcolString: function () { - return this.ncol + ", " + Math.round(this.whiteness * 100) + "%, " + Math.round(this.blackness * 100) + "%"; - }, - toNcolStringDecimal: function () { - return this.ncol + ", " + this.whiteness + ", " + this.blackness; - }, - toNcolaString: function () { - return this.ncol + ", " + Math.round(this.whiteness * 100) + "%, " + Math.round(this.blackness * 100) + "%, " + this.opacity; - }, - toName: function () { - var r, g, b, colorhexs = getColorArr('hexs'); - for (i = 0; i < colorhexs.length; i++) { - r = parseInt(colorhexs[i].substr(0, 2), 16); - g = parseInt(colorhexs[i].substr(2, 2), 16); - b = parseInt(colorhexs[i].substr(4, 2), 16); - if (this.red == r && this.green == g && this.blue == b) { - return getColorArr('names')[i]; - } - } - return ""; - }, - toHexString: function () { - var r = toHex(this.red); - var g = toHex(this.green); - var b = toHex(this.blue); - return "#" + r + g + b; - }, - toRgb: function () { - return { r: this.red, g: this.green, b: this.blue, a: this.opacity }; - }, - toHsl: function () { - return { h: this.hue, s: this.sat, l: this.lightness, a: this.opacity }; - }, - toHwb: function () { - return { h: this.hue, w: this.whiteness, b: this.blackness, a: this.opacity }; - }, - toCmyk: function () { - return { c: this.cyan, m: this.magenta, y: this.yellow, k: this.black, a: this.opacity }; - }, - toNcol: function () { - return { ncol: this.ncol, w: this.whiteness, b: this.blackness, a: this.opacity }; - }, - isDark: function (n) { - var m = (n || 128); - return (((this.red * 299 + this.green * 587 + this.blue * 114) / 1000) < m); - }, - saturate: function (n) { - var x, rgb, color; - x = (n / 100 || 0.1); - this.sat += x; - if (this.sat > 1) { this.sat = 1; } - rgb = hslToRgb(this.hue, this.sat, this.lightness); - color = colorObject(rgb, this.opacity, this.hue, this.sat); - this.attachValues(color); - }, - desaturate: function (n) { - var x, rgb, color; - x = (n / 100 || 0.1); - this.sat -= x; - if (this.sat < 0) { this.sat = 0; } - rgb = hslToRgb(this.hue, this.sat, this.lightness); - color = colorObject(rgb, this.opacity, this.hue, this.sat); - this.attachValues(color); - }, - lighter: function (n) { - var x, rgb, color; - x = (n / 100 || 0.1); - this.lightness += x; - if (this.lightness > 1) { this.lightness = 1; } - rgb = hslToRgb(this.hue, this.sat, this.lightness); - color = colorObject(rgb, this.opacity, this.hue, this.sat); - this.attachValues(color); - }, - darker: function (n) { - var x, rgb, color; - x = (n / 100 || 0.1); - this.lightness -= x; - if (this.lightness < 0) { this.lightness = 0; } - rgb = hslToRgb(this.hue, this.sat, this.lightness); - color = colorObject(rgb, this.opacity, this.hue, this.sat); - this.attachValues(color); - }, - attachValues: function (color) { - this.red = color.red; - this.green = color.green; - this.blue = color.blue; - this.hue = color.hue; - this.sat = color.sat; - this.lightness = color.lightness; - this.whiteness = color.whiteness; - this.blackness = color.blackness; - this.cyan = color.cyan; - this.magenta = color.magenta; - this.yellow = color.yellow; - this.black = color.black; - this.ncol = color.ncol; - this.opacity = color.opacity; - this.valid = color.valid; - } -}; - -function toColorObject(c) { - var x, y, typ, arr = [], arrlength, i, opacity, match, a, hue, sat, rgb, colornames = [], colorhexs = []; - c = w3trim(c.toLowerCase()); - x = c.substr(0, 1).toUpperCase(); - y = c.substr(1); - a = 1; - if ((x == "R" || x == "Y" || x == "G" || x == "C" || x == "B" || x == "M" || x == "W") && !isNaN(y)) { - if (c.length == 6 && c.indexOf(",") == -1) { - } else { - c = "ncol(" + c + ")"; - } - } - if (c.length != 3 && c.length != 6 && !isNaN(c)) { c = "ncol(" + c + ")"; } - if (c.indexOf(",") > 0 && c.indexOf("(") == -1) { c = "ncol(" + c + ")"; } - if (c.substr(0, 3) == "rgb" || c.substr(0, 3) == "hsl" || c.substr(0, 3) == "hwb" || c.substr(0, 4) == "ncol" || c.substr(0, 4) == "cmyk") { - if (c.substr(0, 4) == "ncol") { - if (c.split(",").length == 4 && c.indexOf("ncola") == -1) { - c = c.replace("ncol", "ncola"); - } - typ = "ncol"; - c = c.substr(4); - } else if (c.substr(0, 4) == "cmyk") { - typ = "cmyk"; - c = c.substr(4); - } else { - typ = c.substr(0, 3); - c = c.substr(3); - } - arrlength = 3; - opacity = false; - if (c.substr(0, 1).toLowerCase() == "a") { - arrlength = 4; - opacity = true; - c = c.substr(1); - } else if (typ == "cmyk") { - arrlength = 4; - if (c.split(",").length == 5) { - arrlength = 5; - opacity = true; - } - } - c = c.replace("(", ""); - c = c.replace(")", ""); - arr = c.split(","); - if (typ == "rgb") { - if (arr.length != arrlength) { - return emptyObject(); - } - for (i = 0; i < arrlength; i++) { - if (arr[i] == "" || arr[i] == " ") { arr[i] = "0"; } - if (arr[i].indexOf("%") > -1) { - arr[i] = arr[i].replace("%", ""); - arr[i] = Number(arr[i] / 100); - if (i < 3) { arr[i] = Math.round(arr[i] * 255); } - } - if (isNaN(arr[i])) { return emptyObject(); } - if (parseInt(arr[i]) > 255) { arr[i] = 255; } - if (i < 3) { arr[i] = parseInt(arr[i]); } - if (i == 3 && Number(arr[i]) > 1) { arr[i] = 1; } - } - rgb = { r: arr[0], g: arr[1], b: arr[2] }; - if (opacity == true) { a = Number(arr[3]); } - } - if (typ == "hsl" || typ == "hwb" || typ == "ncol") { - while (arr.length < arrlength) { arr.push("0"); } - if (typ == "hsl" || typ == "hwb") { - if (parseInt(arr[0]) >= 360) { arr[0] = 0; } - } - for (i = 1; i < arrlength; i++) { - if (arr[i].indexOf("%") > -1) { - arr[i] = arr[i].replace("%", ""); - arr[i] = Number(arr[i]); - if (isNaN(arr[i])) { return emptyObject(); } - arr[i] = arr[i] / 100; - } else { - arr[i] = Number(arr[i]); - } - if (Number(arr[i]) > 1) { arr[i] = 1; } - if (Number(arr[i]) < 0) { arr[i] = 0; } - } - if (typ == "hsl") { rgb = hslToRgb(arr[0], arr[1], arr[2]); hue = Number(arr[0]); sat = Number(arr[1]); } - if (typ == "hwb") { rgb = hwbToRgb(arr[0], arr[1], arr[2]); } - if (typ == "ncol") { rgb = ncolToRgb(arr[0], arr[1], arr[2]); } - if (opacity == true) { a = Number(arr[3]); } - } - if (typ == "cmyk") { - while (arr.length < arrlength) { arr.push("0"); } - for (i = 0; i < arrlength; i++) { - if (arr[i].indexOf("%") > -1) { - arr[i] = arr[i].replace("%", ""); - arr[i] = Number(arr[i]); - if (isNaN(arr[i])) { return emptyObject(); } - arr[i] = arr[i] / 100; - } else { - arr[i] = Number(arr[i]); - } - if (Number(arr[i]) > 1) { arr[i] = 1; } - if (Number(arr[i]) < 0) { arr[i] = 0; } - } - rgb = cmykToRgb(arr[0], arr[1], arr[2], arr[3]); - if (opacity == true) { a = Number(arr[4]); } - } - } else if (c.substr(0, 3) == "ncs") { - rgb = ncsToRgb(c); - } else { - match = false; - colornames = getColorArr('names'); - for (i = 0; i < colornames.length; i++) { - if (c.toLowerCase() == colornames[i].toLowerCase()) { - colorhexs = getColorArr('hexs'); - match = true; - rgb = { - r: parseInt(colorhexs[i].substr(0, 2), 16), - g: parseInt(colorhexs[i].substr(2, 2), 16), - b: parseInt(colorhexs[i].substr(4, 2), 16) - }; - break; - } - } - if (match == false) { - c = c.replace("#", ""); - if (c.length == 3) { c = c.substr(0, 1) + c.substr(0, 1) + c.substr(1, 1) + c.substr(1, 1) + c.substr(2, 1) + c.substr(2, 1); } - for (i = 0; i < c.length; i++) { - if (!isHex(c.substr(i, 1))) { return emptyObject(); } - } - arr[0] = parseInt(c.substr(0, 2), 16); - arr[1] = parseInt(c.substr(2, 2), 16); - arr[2] = parseInt(c.substr(4, 2), 16); - for (i = 0; i < 3; i++) { - if (isNaN(arr[i])) { return emptyObject(); } - } - rgb = { - r: arr[0], - g: arr[1], - b: arr[2] - }; - } - } - return colorObject(rgb, a, hue, sat); -} - -function colorObject(rgb, a, h, s) { - var hsl, hwb, cmyk, ncol, color, hue, sat; - if (!rgb) { return emptyObject(); } - if (a === null) { a = 1; } - hsl = rgbToHsl(rgb.r, rgb.g, rgb.b); - hwb = rgbToHwb(rgb.r, rgb.g, rgb.b); - cmyk = rgbToCmyk(rgb.r, rgb.g, rgb.b); - hue = (h || hsl.h); - sat = (s || hsl.s); - ncol = hueToNcol(hue); - color = { - red: rgb.r, - green: rgb.g, - blue: rgb.b, - hue: hue, - sat: sat, - lightness: hsl.l, - whiteness: hwb.w, - blackness: hwb.b, - cyan: cmyk.c, - magenta: cmyk.m, - yellow: cmyk.y, - black: cmyk.k, - ncol: ncol, - opacity: a, - valid: true - }; - color = roundDecimals(color); - return color; -} - -function emptyObject() { - return { - red: 0, - green: 0, - blue: 0, - hue: 0, - sat: 0, - lightness: 0, - whiteness: 0, - blackness: 0, - cyan: 0, - magenta: 0, - yellow: 0, - black: 0, - ncol: "R", - opacity: 1, - valid: false - }; -} - -function getColorArr(x) { - if (x == "names") { return ['AliceBlue', 'AntiqueWhite', 'Aqua', 'Aquamarine', 'Azure', 'Beige', 'Bisque', 'Black', 'BlanchedAlmond', 'Blue', 'BlueViolet', 'Brown', 'BurlyWood', 'CadetBlue', 'Chartreuse', 'Chocolate', 'Coral', 'CornflowerBlue', 'Cornsilk', 'Crimson', 'Cyan', 'DarkBlue', 'DarkCyan', 'DarkGoldenRod', 'DarkGray', 'DarkGrey', 'DarkGreen', 'DarkKhaki', 'DarkMagenta', 'DarkOliveGreen', 'DarkOrange', 'DarkOrchid', 'DarkRed', 'DarkSalmon', 'DarkSeaGreen', 'DarkSlateBlue', 'DarkSlateGray', 'DarkSlateGrey', 'DarkTurquoise', 'DarkViolet', 'DeepPink', 'DeepSkyBlue', 'DimGray', 'DimGrey', 'DodgerBlue', 'FireBrick', 'FloralWhite', 'ForestGreen', 'Fuchsia', 'Gainsboro', 'GhostWhite', 'Gold', 'GoldenRod', 'Gray', 'Grey', 'Green', 'GreenYellow', 'HoneyDew', 'HotPink', 'IndianRed', 'Indigo', 'Ivory', 'Khaki', 'Lavender', 'LavenderBlush', 'LawnGreen', 'LemonChiffon', 'LightBlue', 'LightCoral', 'LightCyan', 'LightGoldenRodYellow', 'LightGray', 'LightGrey', 'LightGreen', 'LightPink', 'LightSalmon', 'LightSeaGreen', 'LightSkyBlue', 'LightSlateGray', 'LightSlateGrey', 'LightSteelBlue', 'LightYellow', 'Lime', 'LimeGreen', 'Linen', 'Magenta', 'Maroon', 'MediumAquaMarine', 'MediumBlue', 'MediumOrchid', 'MediumPurple', 'MediumSeaGreen', 'MediumSlateBlue', 'MediumSpringGreen', 'MediumTurquoise', 'MediumVioletRed', 'MidnightBlue', 'MintCream', 'MistyRose', 'Moccasin', 'NavajoWhite', 'Navy', 'OldLace', 'Olive', 'OliveDrab', 'Orange', 'OrangeRed', 'Orchid', 'PaleGoldenRod', 'PaleGreen', 'PaleTurquoise', 'PaleVioletRed', 'PapayaWhip', 'PeachPuff', 'Peru', 'Pink', 'Plum', 'PowderBlue', 'Purple', 'RebeccaPurple', 'Red', 'RosyBrown', 'RoyalBlue', 'SaddleBrown', 'Salmon', 'SandyBrown', 'SeaGreen', 'SeaShell', 'Sienna', 'Silver', 'SkyBlue', 'SlateBlue', 'SlateGray', 'SlateGrey', 'Snow', 'SpringGreen', 'SteelBlue', 'Tan', 'Teal', 'Thistle', 'Tomato', 'Turquoise', 'Violet', 'Wheat', 'White', 'WhiteSmoke', 'Yellow', 'YellowGreen']; } - if (x == "hexs") { return ['f0f8ff', 'faebd7', '00ffff', '7fffd4', 'f0ffff', 'f5f5dc', 'ffe4c4', '000000', 'ffebcd', '0000ff', '8a2be2', 'a52a2a', 'deb887', '5f9ea0', '7fff00', 'd2691e', 'ff7f50', '6495ed', 'fff8dc', 'dc143c', '00ffff', '00008b', '008b8b', 'b8860b', 'a9a9a9', 'a9a9a9', '006400', 'bdb76b', '8b008b', '556b2f', 'ff8c00', '9932cc', '8b0000', 'e9967a', '8fbc8f', '483d8b', '2f4f4f', '2f4f4f', '00ced1', '9400d3', 'ff1493', '00bfff', '696969', '696969', '1e90ff', 'b22222', 'fffaf0', '228b22', 'ff00ff', 'dcdcdc', 'f8f8ff', 'ffd700', 'daa520', '808080', '808080', '008000', 'adff2f', 'f0fff0', 'ff69b4', 'cd5c5c', '4b0082', 'fffff0', 'f0e68c', 'e6e6fa', 'fff0f5', '7cfc00', 'fffacd', 'add8e6', 'f08080', 'e0ffff', 'fafad2', 'd3d3d3', 'd3d3d3', '90ee90', 'ffb6c1', 'ffa07a', '20b2aa', '87cefa', '778899', '778899', 'b0c4de', 'ffffe0', '00ff00', '32cd32', 'faf0e6', 'ff00ff', '800000', '66cdaa', '0000cd', 'ba55d3', '9370db', '3cb371', '7b68ee', '00fa9a', '48d1cc', 'c71585', '191970', 'f5fffa', 'ffe4e1', 'ffe4b5', 'ffdead', '000080', 'fdf5e6', '808000', '6b8e23', 'ffa500', 'ff4500', 'da70d6', 'eee8aa', '98fb98', 'afeeee', 'db7093', 'ffefd5', 'ffdab9', 'cd853f', 'ffc0cb', 'dda0dd', 'b0e0e6', '800080', '663399', 'ff0000', 'bc8f8f', '4169e1', '8b4513', 'fa8072', 'f4a460', '2e8b57', 'fff5ee', 'a0522d', 'c0c0c0', '87ceeb', '6a5acd', '708090', '708090', 'fffafa', '00ff7f', '4682b4', 'd2b48c', '008080', 'd8bfd8', 'ff6347', '40e0d0', 'ee82ee', 'f5deb3', 'ffffff', 'f5f5f5', 'ffff00', '9acd32']; } -} - -function roundDecimals(c) { - c.red = Number(c.red.toFixed(0)); - c.green = Number(c.green.toFixed(0)); - c.blue = Number(c.blue.toFixed(0)); - c.hue = Number(c.hue.toFixed(0)); - c.sat = Number(c.sat.toFixed(2)); - c.lightness = Number(c.lightness.toFixed(2)); - c.whiteness = Number(c.whiteness.toFixed(2)); - c.blackness = Number(c.blackness.toFixed(2)); - c.cyan = Number(c.cyan.toFixed(2)); - c.magenta = Number(c.magenta.toFixed(2)); - c.yellow = Number(c.yellow.toFixed(2)); - c.black = Number(c.black.toFixed(2)); - c.ncol = c.ncol.substr(0, 1) + Math.round(Number(c.ncol.substr(1))); - c.opacity = Number(c.opacity.toFixed(2)); - return c; -} - -function hslToRgb(hue, sat, light) { - var t1, t2, r, g, b; - hue = hue / 60; - if (light <= 0.5) { - t2 = light * (sat + 1); - } else { - t2 = light + sat - (light * sat); - } - t1 = light * 2 - t2; - r = hueToRgb(t1, t2, hue + 2) * 255; - g = hueToRgb(t1, t2, hue) * 255; - b = hueToRgb(t1, t2, hue - 2) * 255; - return { r: r, g: g, b: b }; -} - -function hueToRgb(t1, t2, hue) { - if (hue < 0) hue += 6; - if (hue >= 6) hue -= 6; - if (hue < 1) return (t2 - t1) * hue + t1; - else if (hue < 3) return t2; - else if (hue < 4) return (t2 - t1) * (4 - hue) + t1; - else return t1; -} - -function hwbToRgb(hue, white, black) { - var i, rgb, rgbArr = [], tot; - rgb = hslToRgb(hue, 1, 0.50); - rgbArr[0] = rgb.r / 255; - rgbArr[1] = rgb.g / 255; - rgbArr[2] = rgb.b / 255; - tot = white + black; - if (tot > 1) { - white = Number((white / tot).toFixed(2)); - black = Number((black / tot).toFixed(2)); - } - for (i = 0; i < 3; i++) { - rgbArr[i] *= (1 - (white) - (black)); - rgbArr[i] += (white); - rgbArr[i] = Number(rgbArr[i] * 255); - } - return { r: rgbArr[0], g: rgbArr[1], b: rgbArr[2] }; -} - -function cmykToRgb(c, m, y, k) { - var r, g, b; - r = 255 - ((Math.min(1, c * (1 - k) + k)) * 255); - g = 255 - ((Math.min(1, m * (1 - k) + k)) * 255); - b = 255 - ((Math.min(1, y * (1 - k) + k)) * 255); - return { r: r, g: g, b: b }; -} - -function ncolToRgb(ncol, white, black) { - var letter, percent, h, w, b; - h = ncol; - if (isNaN(ncol.substr(0, 1))) { - letter = ncol.substr(0, 1).toUpperCase(); - percent = ncol.substr(1); - if (percent == "") { percent = 0; } - percent = Number(percent); - if (isNaN(percent)) { return false; } - if (letter == "R") { h = 0 + (percent * 0.6); } - if (letter == "Y") { h = 60 + (percent * 0.6); } - if (letter == "G") { h = 120 + (percent * 0.6); } - if (letter == "C") { h = 180 + (percent * 0.6); } - if (letter == "B") { h = 240 + (percent * 0.6); } - if (letter == "M") { h = 300 + (percent * 0.6); } - if (letter == "W") { - h = 0; - white = 1 - (percent / 100); - black = (percent / 100); - } - } - return hwbToRgb(h, white, black); -} - -function hueToNcol(hue) { - while (hue >= 360) { - hue = hue - 360; - } - if (hue < 60) { return "R" + (hue / 0.6); } - if (hue < 120) { return "Y" + ((hue - 60) / 0.6); } - if (hue < 180) { return "G" + ((hue - 120) / 0.6); } - if (hue < 240) { return "C" + ((hue - 180) / 0.6); } - if (hue < 300) { return "B" + ((hue - 240) / 0.6); } - if (hue < 360) { return "M" + ((hue - 300) / 0.6); } -} - -function ncsToRgb(ncs) { - var black, chroma, bc, percent, black1, chroma1, red1, factor1, blue1, red1, red2, green2, blue2, max, factor2, grey, r, g, b; - ncs = w3trim(ncs).toUpperCase(); - ncs = ncs.replace("(", ""); - ncs = ncs.replace(")", ""); - ncs = ncs.replace("NCS", "NCS "); - ncs = ncs.replace(/ /g, " "); - if (ncs.indexOf("NCS") == -1) { ncs = "NCS " + ncs; } - ncs = ncs.match(/^(?:NCS|NCS\sS)\s(\d{2})(\d{2})-(N|[A-Z])(\d{2})?([A-Z])?$/); - if (ncs === null) return false; - black = parseInt(ncs[1], 10); - chroma = parseInt(ncs[2], 10); - bc = ncs[3]; - if (bc != "N" && bc != "Y" && bc != "R" && bc != "B" && bc != "G") { return false; } - percent = parseInt(ncs[4], 10) || 0; - if (bc !== 'N') { - black1 = (1.05 * black - 5.25); - chroma1 = chroma; - if (bc === 'Y' && percent <= 60) { - red1 = 1; - } else if ((bc === 'Y' && percent > 60) || (bc === 'R' && percent <= 80)) { - if (bc === 'Y') { - factor1 = percent - 60; - } else { - factor1 = percent + 40; - } - red1 = ((Math.sqrt(14884 - Math.pow(factor1, 2))) - 22) / 100; - } else if ((bc === 'R' && percent > 80) || (bc === 'B')) { - red1 = 0; - } else if (bc === 'G') { - factor1 = (percent - 170); - red1 = ((Math.sqrt(33800 - Math.pow(factor1, 2))) - 70) / 100; - } - if (bc === 'Y' && percent <= 80) { - blue1 = 0; - } else if ((bc === 'Y' && percent > 80) || (bc === 'R' && percent <= 60)) { - if (bc === 'Y') { - factor1 = (percent - 80) + 20.5; - } else { - factor1 = (percent + 20) + 20.5; - } - blue1 = (104 - (Math.sqrt(11236 - Math.pow(factor1, 2)))) / 100; - } else if ((bc === 'R' && percent > 60) || (bc === 'B' && percent <= 80)) { - if (bc === 'R') { - factor1 = (percent - 60) - 60; - } else { - factor1 = (percent + 40) - 60; - } - blue1 = ((Math.sqrt(10000 - Math.pow(factor1, 2))) - 10) / 100; - } else if ((bc === 'B' && percent > 80) || (bc === 'G' && percent <= 40)) { - if (bc === 'B') { - factor1 = (percent - 80) - 131; - } else { - factor1 = (percent + 20) - 131; - } - blue1 = (122 - (Math.sqrt(19881 - Math.pow(factor1, 2)))) / 100; - } else if (bc === 'G' && percent > 40) { - blue1 = 0; - } - if (bc === 'Y') { - green1 = (85 - 17 / 20 * percent) / 100; - } else if (bc === 'R' && percent <= 60) { - green1 = 0; - } else if (bc === 'R' && percent > 60) { - factor1 = (percent - 60) + 35; - green1 = (67.5 - (Math.sqrt(5776 - Math.pow(factor1, 2)))) / 100; - } else if (bc === 'B' && percent <= 60) { - factor1 = (1 * percent - 68.5); - green1 = (6.5 + (Math.sqrt(7044.5 - Math.pow(factor1, 2)))) / 100; - } else if ((bc === 'B' && percent > 60) || (bc === 'G' && percent <= 60)) { - green1 = 0.9; - } else if (bc === 'G' && percent > 60) { - factor1 = (percent - 60); - green1 = (90 - (1 / 8 * factor1)) / 100; - } - factor1 = (red1 + green1 + blue1) / 3; - red2 = ((factor1 - red1) * (100 - chroma1) / 100) + red1; - green2 = ((factor1 - green1) * (100 - chroma1) / 100) + green1; - blue2 = ((factor1 - blue1) * (100 - chroma1) / 100) + blue1; - if (red2 > green2 && red2 > blue2) { - max = red2; - } else if (green2 > red2 && green2 > blue2) { - max = green2; - } else if (blue2 > red2 && blue2 > green2) { - max = blue2; - } else { - max = (red2 + green2 + blue2) / 3; - } - factor2 = 1 / max; - r = parseInt((red2 * factor2 * (100 - black1) / 100) * 255, 10); - g = parseInt((green2 * factor2 * (100 - black1) / 100) * 255, 10); - b = parseInt((blue2 * factor2 * (100 - black1) / 100) * 255, 10); - if (r > 255) { r = 255; } - if (g > 255) { g = 255; } - if (b > 255) { b = 255; } - if (r < 0) { r = 0; } - if (g < 0) { g = 0; } - if (b < 0) { b = 0; } - } else { - grey = parseInt((1 - black / 100) * 255, 10); - if (grey > 255) { grey = 255; } - if (grey < 0) { grey = 0; } - r = grey; - g = grey; - b = grey; - } - return { - r: r, - g: g, - b: b - }; -} - -function rgbToHsl(r, g, b) { - var min, max, i, l, s, maxcolor, h, rgb = []; - rgb[0] = r / 255; - rgb[1] = g / 255; - rgb[2] = b / 255; - min = rgb[0]; - max = rgb[0]; - maxcolor = 0; - for (i = 0; i < rgb.length - 1; i++) { - if (rgb[i + 1] <= min) { min = rgb[i + 1]; } - if (rgb[i + 1] >= max) { max = rgb[i + 1]; maxcolor = i + 1; } - } - if (maxcolor == 0) { - h = (rgb[1] - rgb[2]) / (max - min); - } - if (maxcolor == 1) { - h = 2 + (rgb[2] - rgb[0]) / (max - min); - } - if (maxcolor == 2) { - h = 4 + (rgb[0] - rgb[1]) / (max - min); - } - if (isNaN(h)) { h = 0; } - h = h * 60; - if (h < 0) { h = h + 360; } - l = (min + max) / 2; - if (min == max) { - s = 0; - } else { - if (l < 0.5) { - s = (max - min) / (max + min); - } else { - s = (max - min) / (2 - max - min); - } - } - s = s; - return { h: h, s: s, l: l }; -} - -function rgbToHwb(r, g, b) { - var h, w, bl; - r = r / 255; - g = g / 255; - b = b / 255; - max = Math.max(r, g, b); - min = Math.min(r, g, b); - chroma = max - min; - if (chroma == 0) { - h = 0; - } else if (r == max) { - h = (((g - b) / chroma) % 6) * 360; - } else if (g == max) { - h = ((((b - r) / chroma) + 2) % 6) * 360; - } else { - h = ((((r - g) / chroma) + 4) % 6) * 360; - } - w = min; - bl = 1 - max; - return { h: h, w: w, b: bl }; -} - -function rgbToCmyk(r, g, b) { - var c, m, y, k; - r = r / 255; - g = g / 255; - b = b / 255; - max = Math.max(r, g, b); - k = 1 - max; - if (k == 1) { - c = 0; - m = 0; - y = 0; - } else { - c = (1 - r - k) / (1 - k); - m = (1 - g - k) / (1 - k); - y = (1 - b - k) / (1 - k); - } - return { c: c, m: m, y: y, k: k }; -} - -function toHex(n) { - var hex = n.toString(16); - while (hex.length < 2) { hex = "0" + hex; } - return hex; -} - -function cl(x) { - console.log(x); -} - -function w3trim(x) { - return x.replace(/^\s+|\s+$/g, ''); -} - -function isHex(x) { - return ('0123456789ABCDEFabcdef'.indexOf(x) > -1); -} - -if(typeof window === undefined) window.w3color = w3color; - -function w3SetColorsByAttribute() { -var z, i, att; -z = document.getElementsByTagName("*"); -for (i = 0; i < z.length; i++) { - att = z[i].getAttribute("data-w3-color"); - if (att) { - z[i].style.backgroundColor = w3color(att).toRgbString(); - } -} - -} diff --git a/docs/lib/scripts/webpage.js b/docs/lib/scripts/webpage.js deleted file mode 100644 index ac3d6425e..000000000 --- a/docs/lib/scripts/webpage.js +++ /dev/null @@ -1,936 +0,0 @@ - -//#region Helpers - -function getAbsoluteRootPath() -{ - if (typeof rootPath == 'undefined') setupRootPath(document); - return new URL(window.location.href + "/../" + rootPath).pathname; -} - -function getURLPath(url = window.location.pathname) -{ - let absoluteRoot = getAbsoluteRootPath(); - let pathname = url.substring(absoluteRoot.length); - return pathname; -} - -function getURLRootPath(url = window.location.pathname) -{ - let path = getURLPath(url); - let splitPath = path.split("/"); - let rootPath = ""; - for (let i = 0; i < splitPath.length - 1; i++) - { - rootPath += "../"; - } - return rootPath; -} - -async function setTreeCollapsed(element, collapsed, animate = true) -{ - if (!element || !element.classList.contains("mod-collapsible")) return; - - let children = element.querySelector(".tree-item-children"); - - if (collapsed) - { - element.classList.add("is-collapsed"); - if(animate) slideUp(children, 100); - else children.style.display = "none"; - } - else - { - element.classList.remove("is-collapsed"); - if(animate) slideDown(children, 100); - else children.style.removeProperty("display"); - } -} - -async function setTreeCollapsedAll(elements, collapsed, animate = true) -{ - let childrenList = []; - elements.forEach(async element => - { - if (!element || !element.classList.contains("mod-collapsible")) return; - - let children = element.querySelector(".tree-item-children"); - - if (collapsed) - { - element.classList.add("is-collapsed"); - } - else - { - element.classList.remove("is-collapsed"); - } - - childrenList.push(children); - }); - - if (collapsed) - { - if(animate) slideUpAll(childrenList, 100); - else childrenList.forEach(async children => children.style.display = "none"); - } - else - { - if(animate) slideDownAll(childrenList, 100); - else childrenList.forEach(async children => children.style.removeProperty("display")); - } -} - -function toggleTreeCollapsed(element) -{ - if (!element) return; - setTreeCollapsed(element, !element.classList.contains("is-collapsed")); -} - -function toggleTreeCollapsedAll(elements) -{ - if (!elements) return; - setTreeCollapsedAll(elements, !elements[0].classList.contains("is-collapsed")); -} - -function getHeaderEl(headerDiv) -{ - let possibleChildHeader = headerDiv.firstChild; - let isHeader = false; - - while (possibleChildHeader != null) - { - isHeader = possibleChildHeader ? /[Hh][1-6]/g.test(possibleChildHeader.tagName) : false; - if (isHeader) break; - - possibleChildHeader = possibleChildHeader.nextElementSibling; - } - - return possibleChildHeader; -} - -function getPreviousHeader(headerDiv) -{ - let possibleParent = headerDiv.previousElementSibling; - let isHeader = false; - - while (possibleParent != null) - { - let possibleChildHeader = getHeaderEl(possibleParent); - isHeader = possibleChildHeader ? /[Hh][1-6]/g.test(possibleChildHeader.tagName) : false; - if (isHeader) break; - - possibleParent = possibleParent.previousElementSibling; - } - - return possibleParent; -} - -function setHeaderOpen(headerDiv, open, openParents = true) -{ - if(headerDiv.tagName != "DIV" || !getHeaderEl(headerDiv)) - { - console.error("setHeaderOpen() must be called with a header div"); - return; - } - - // let selector = getHeadingContentsSelector(header); - if (open) - { - headerDiv.classList.remove("is-collapsed"); - headerDiv.style.display = ""; - } - if (!open) - { - headerDiv.classList.add("is-collapsed"); - } - - let headerEl = getHeaderEl(headerDiv); - - let childHeaders = []; - - let possibleChild = headerDiv.nextElementSibling; - - // loop through next siblings showing/ hiding children until we reach a header of the same or lower level - while (possibleChild != null) - { - let possibleChildHeader = getHeaderEl(possibleChild); - - if(possibleChildHeader) - { - // if header is a sibling of this header then break - if (possibleChildHeader.tagName <= headerEl.tagName) break; - - // save child headers to be re closed afterwards - childHeaders.push(possibleChild); - } - - if (!open) possibleChild.style.display = "none"; - else possibleChild.style.display = ""; - - possibleChild = possibleChild.nextElementSibling; - } - - if(open) - { - // if we are opening the header then we need to make sure that all closed child headers stay closed - childHeaders.forEach(function(item) - { - if (item.classList.contains("is-collapsed")) - { - setHeaderOpen(item, false); - } - }); - - // if we are opening the header then we need to make sure that all parent headers are open - if (openParents) - { - let previousHeader = getPreviousHeader(headerDiv); - - while (previousHeader != null) - { - let previousHeaderEl = getHeaderEl(previousHeader); - - if (previousHeaderEl.tagName < headerEl.tagName) - { - // if header is a parent of this header then unhide - setHeaderOpen(previousHeader, true); - break; - } - - previousHeader = getPreviousHeader(previousHeader); - } - } - } -} - -let slideUp = (target, duration=500) => { - - target.style.transitionProperty = 'height, margin, padding'; - target.style.transitionDuration = duration + 'ms'; - target.style.boxSizing = 'border-box'; - target.style.height = target.offsetHeight + 'px'; - target.offsetHeight; - target.style.overflow = 'hidden'; - target.style.height = 0; - target.style.paddingTop = 0; - target.style.paddingBottom = 0; - target.style.marginTop = 0; - target.style.marginBottom = 0; - window.setTimeout(async () => { - target.style.display = 'none'; - target.style.removeProperty('height'); - target.style.removeProperty('padding-top'); - target.style.removeProperty('padding-bottom'); - target.style.removeProperty('margin-top'); - target.style.removeProperty('margin-bottom'); - target.style.removeProperty('overflow'); - target.style.removeProperty('transition-duration'); - target.style.removeProperty('transition-property'); - }, duration); -} - -let slideUpAll = (targets, duration=500) => { - - targets.forEach(async target => { - target.style.transitionProperty = 'height, margin, padding'; - target.style.transitionDuration = duration + 'ms'; - target.style.boxSizing = 'border-box'; - target.style.height = target.offsetHeight + 'px'; - target.offsetHeight; - target.style.overflow = 'hidden'; - target.style.height = 0; - target.style.paddingTop = 0; - target.style.paddingBottom = 0; - target.style.marginTop = 0; - target.style.marginBottom = 0; - }); - - window.setTimeout(async () => { - targets.forEach(async target => { - target.style.display = 'none'; - target.style.removeProperty('height'); - target.style.removeProperty('padding-top'); - target.style.removeProperty('padding-bottom'); - target.style.removeProperty('margin-top'); - target.style.removeProperty('margin-bottom'); - target.style.removeProperty('overflow'); - target.style.removeProperty('transition-duration'); - target.style.removeProperty('transition-property'); - }); - }, duration); -} - -let slideDown = (target, duration=500) => { - - target.style.removeProperty('display'); - let display = window.getComputedStyle(target).display; - if (display === 'none') display = 'block'; - target.style.display = display; - let height = target.offsetHeight; - target.style.overflow = 'hidden'; - target.style.height = 0; - target.style.paddingTop = 0; - target.style.paddingBottom = 0; - target.style.marginTop = 0; - target.style.marginBottom = 0; - target.offsetHeight; - target.style.boxSizing = 'border-box'; - target.style.transitionProperty = "height, margin, padding"; - target.style.transitionDuration = duration + 'ms'; - target.style.height = height + 'px'; - target.style.removeProperty('padding-top'); - target.style.removeProperty('padding-bottom'); - target.style.removeProperty('margin-top'); - target.style.removeProperty('margin-bottom'); - window.setTimeout(async () => { - target.style.removeProperty('height'); - target.style.removeProperty('overflow'); - target.style.removeProperty('transition-duration'); - target.style.removeProperty('transition-property'); - }, duration); -} - -let slideDownAll = (targets, duration=500) => { - - targets.forEach(async target => { - target.style.removeProperty('display'); - let display = window.getComputedStyle(target).display; - if (display === 'none') display = 'block'; - target.style.display = display; - let height = target.offsetHeight; - target.style.overflow = 'hidden'; - target.style.height = 0; - target.style.paddingTop = 0; - target.style.paddingBottom = 0; - target.style.marginTop = 0; - target.style.marginBottom = 0; - target.offsetHeight; - target.style.boxSizing = 'border-box'; - target.style.transitionProperty = "height, margin, padding"; - target.style.transitionDuration = duration + 'ms'; - target.style.height = height + 'px'; - target.style.removeProperty('padding-top'); - target.style.removeProperty('padding-bottom'); - target.style.removeProperty('margin-top'); - target.style.removeProperty('margin-bottom'); - }); - - window.setTimeout( async () => { - targets.forEach(async target => { - target.style.removeProperty('height'); - target.style.removeProperty('overflow'); - target.style.removeProperty('transition-duration'); - target.style.removeProperty('transition-property'); - }); - }, duration); -} - -var slideToggle = (target, duration = 500) => { - if (window.getComputedStyle(target).display === 'none') { - return slideDown(target, duration); - } else { - return slideUp(target, duration); - } -} - -var slideToggleAll = (targets, duration = 500) => { - if (window.getComputedStyle(targets[0]).display === 'none') { - return slideDownAll(targets, duration); - } else { - return slideUpAll(targets, duration); - } -} - -//#endregion - -async function loadDocument(url, pushHistory = true, scrollTo = true) -{ - console.log("Loading document: " + url); - - // change the active file - setActiveDocument(url, scrollTo, pushHistory); - - let response; - - // if(typeof embeddedDocuments == 'undefined') - // { - try - { - response = await fetch(url); - } - catch (error) - { - console.log("Cannot use fetch API (likely due to CORS), just loading the page normally."); - window.location.assign(url); - return; - } - // } - // else - // { - // response = new Response(embeddedDocuments[url], {status: 200, statusText: "OK"}); - // } - - let doc = document.implementation.createHTMLDocument(); - - if (response.ok) - { - let html = (await response.text()).replaceAll("", "").replaceAll("", "").replaceAll("", ""); - doc.documentElement.innerHTML = html; - - // copy document content and outline tree - document.querySelector(".document-container").innerHTML = doc.querySelector(".document-container").innerHTML; - document.querySelector(".outline-tree").innerHTML = doc.querySelector(".outline-tree").innerHTML; - - // if the url has a heading, scroll to it - let splitURL = url.split("#"); - let pathnameTarget = splitURL[0] ?? url; - let headingTarget = splitURL.length > 1 ? splitURL[1] : null; - if (headingTarget) document.getElementById(headingTarget).scrollIntoView(); - - // Change the root path to match the match from the new page - setupRootPath(doc); - - // initialize events on the new page - initializePage(document.querySelector(".document-container")); - initializePage(document.querySelector(".outline-tree")); - - document.title = doc.title; - } - else - { - // if the page is not able to load instead add a header saying the page doesn't exist - document.querySelector(".markdown-preview-view").innerHTML = - ` -
-
-

Page Not Found

-
-
- `; - - document.querySelector(".outline-tree").innerHTML = ""; - - console.log("Page not found: " + getAbsoluteRootPath() + url); - let newRootPath = getURLRootPath(getAbsoluteRootPath() + url); - rootPath = newRootPath; - document.querySelector("base").href = newRootPath; - - document.title = "Page Not Found"; - } - - return doc; -} - -function setActiveDocument(url, scrollTo = true, pushHistory = true) -{ - let pathnameTarget = url.split("#")[0] ?? url; // path with no header - - // switch active file in file tree - document.querySelector(".tree-item.mod-active")?.classList.remove("mod-active"); - let treeItems = Array.from(document.querySelectorAll(".tree-item > .tree-item-contents > .tree-item-link")); - let treeItem = undefined; - for (let item of treeItems) - { - if (item.getAttribute("href") == url) - { - let parent = item.parentElement.parentElement; - - parent.classList.add("mod-active"); - treeItem = parent; - - while (parent.hasAttribute("data-depth")) - { - setTreeCollapsed(parent, false, false); - parent = parent.parentElement.parentElement; - } - - continue; - } - } - - if(scrollTo) treeItem?.scrollIntoView({block: "center", inline: "nearest"}); - - // set the active file in th graph view - if(typeof nodes != 'undefined' && window.renderWorker) - { - let activeNode = nodes?.paths.findIndex(function(item) { return item.endsWith(pathnameTarget); }) ?? -1; - - if(activeNode >= 0) - { - window.renderWorker.activeNode = activeNode; - } - } - - if(pushHistory && window.location.protocol != "file:") window.history.pushState({ path: pathnameTarget }, '', pathnameTarget); -} - -//#region Initialization -function setupThemeToggle(setupOnNode) -{ - if (localStorage.getItem("theme_toggle") != null) - { - setThemeToggle(localStorage.getItem("theme_toggle") == "true"); - } - - // var lastScheme = "theme-dark"; - // change theme to match current system theme - // if (localStorage.getItem("theme_toggle") == null && window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches) - // { - // setThemeToggle(true); - // lastScheme = "theme-light"; - // } - // if (localStorage.getItem("theme_toggle") == null && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) - // { - // setThemeToggle(true); - // lastScheme = "theme-dark"; - // } - - // set initial toggle state based on body theme class - if (document.body.classList.contains("theme-light")) - { - setThemeToggle(true); - } - else - { - setThemeToggle(false); - } - - function setThemeToggle(state, instant = false) - { - let toggle = document.querySelector(".theme-toggle-input"); - - toggle.checked = state; - - if (instant) - { - var oldTransition = document.body.style.transition; - document.body.style.transition = "none"; - } - - if(!toggle.classList.contains("is-checked") && state) - { - toggle.classList.add("is-checked"); - } - else if (toggle.classList.contains("is-checked") && !state) - { - toggle.classList.remove("is-checked"); - } - - if(!state) - { - if (document.body.classList.contains("theme-light")) - { - document.body.classList.remove("theme-light"); - } - - if (!document.body.classList.contains("theme-dark")) - { - document.body.classList.add("theme-dark"); - } - } - else - { - if (document.body.classList.contains("theme-dark")) - { - document.body.classList.remove("theme-dark"); - } - - if (!document.body.classList.contains("theme-light")) - { - document.body.classList.add("theme-light"); - } - } - - if (instant) - { - setTimeout(function() - { - document.body.style.transition = oldTransition; - }, 100); - } - - localStorage.setItem("theme_toggle", state ? "true" : "false"); - } - - setupOnNode.querySelector(".theme-toggle-input")?.addEventListener("change", event => - { - console.log("Theme toggle changed to: " + !(localStorage.getItem("theme_toggle") == "true")); - setThemeToggle(!(localStorage.getItem("theme_toggle") == "true")); - }); - - // window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => - // { - // // return if we are printing - // if (window.matchMedia('print').matches) - // { - // printing = true; - // return; - // } - - // let newColorScheme = event.matches ? "theme-dark" : "theme-light"; - - // if (newColorScheme == lastScheme) return; - - // if (newColorScheme == "theme-dark") - // { - // setThemeToggle(false); - // } - - // if (newColorScheme == "theme-light") - // { - // setThemeToggle(true); - // } - - // lastScheme = newColorScheme; - // }); - -} - -function setupHeaders(setupOnNode) -{ - // MAKE HEADERS COLLAPSIBLE - setupOnNode.querySelectorAll(".heading-collapse-indicator").forEach(function (element) - { - element.addEventListener("click", function () - { - var isOpen = !this.parentElement.parentElement.classList.contains("is-collapsed"); - setHeaderOpen(this.parentElement.parentElement, !isOpen); - }); - }); - - // unfold header when an internal link that points to that header is clicked - setupOnNode.querySelectorAll("a.internal-link, a.tree-item-link").forEach(function (element) - { - element.addEventListener("click", function (event) - { - event.preventDefault(); - let target = this.getAttribute("href"); - - // if the target is a header uncollapse it - if (target.startsWith("#")) - { - console.log("Uncollapsing header: " + target); - let header = document.getElementById(target.substring(1)); - setHeaderOpen(header.parentElement, true); - } - }); - }); -} - -function setupTrees(setupOnNode) -{ - const fileTreeItems = Array.from(setupOnNode.querySelectorAll(".tree-container.file-tree .tree-item")); - - setupOnNode.querySelectorAll(".tree-item-contents > .collapse-icon").forEach(function(item) - { - item.addEventListener("click", function() - { - toggleTreeCollapsed(item.parentElement.parentElement); - }); - }); - - let fileTreeCollapse = setupOnNode.querySelector(".tree-container.file-tree .collapse-tree-button"); - if (fileTreeCollapse) fileTreeCollapse.addEventListener("click", async function() - { - let fileTreeIsCollapsed = fileTreeCollapse.classList.contains("is-collapsed"); - - setTreeCollapsedAll(fileTreeItems, !fileTreeIsCollapsed, fileTreeItems.length < 100); - - fileTreeCollapse.classList.toggle("is-collapsed"); - fileTreeCollapse.querySelector("iconify-icon").setAttribute("icon", fileTreeIsCollapsed ? "ph:arrows-out-line-horizontal-bold" : "ph:arrows-in-line-horizontal-bold"); - }); - - - let outlineTreeCollapse = setupOnNode.querySelector(".tree-container.outline-tree .collapse-tree-button"); - if(outlineTreeCollapse) outlineTreeCollapse.addEventListener("click", async function() - { - let outlineTreeIsCollapsed = outlineTreeCollapse.classList.contains("is-collapsed"); - - let items = Array.from(outlineTreeCollapse.parentElement.parentElement.querySelectorAll(".tree-item")); - setTreeCollapsedAll(items, !outlineTreeIsCollapsed, items.length < 100); - - outlineTreeCollapse.classList.toggle("is-collapsed"); - outlineTreeCollapse.querySelector("iconify-icon").setAttribute("icon", outlineTreeIsCollapsed ? "ph:arrows-out-line-horizontal-bold" : "ph:arrows-in-line-horizontal-bold"); - }); - - // start with all closed - setupOnNode.querySelectorAll(".tree-container .tree-item").forEach(function(item) - { - if (item.classList.contains("is-collapsed")) setTreeCollapsed(item, true, false); - }); - - // make sure the icons match their starting collaped state - setupOnNode.querySelectorAll(".tree-container > .tree-header > .collapse-tree-button").forEach(function(item) - { - if (item.classList.contains("is-collapsed")) - { - item.querySelector("iconify-icon").setAttribute("icon", "ph:arrows-out-line-horizontal-bold"); - } - else - { - item.querySelector("iconify-icon").setAttribute("icon", "ph:arrows-in-line-horizontal-bold"); - } - }); -} - -function setupCallouts(setupOnNode) -{ - // MAKE CALLOUTS COLLAPSIBLE - // if the callout title is clicked, toggle the display of .callout-content - setupOnNode.querySelectorAll(".callout.is-collapsible .callout-title").forEach(function (element) - { - element.addEventListener("click", function () - { - var parent = this.parentElement; - var isCollapsed = parent.classList.contains("is-collapsed"); - - parent.classList.toggle("is-collapsed"); - element.querySelector(".callout-fold").classList.toggle("is-collapsed"); - - slideToggle(parent.querySelector(".callout-content"), 100); - }); - }); - -} - -function setupCheckboxes(setupOnNode) -{ - // Fix checkboxed toggling .is-checked - setupOnNode.querySelectorAll(".task-list-item-checkbox").forEach(function (element) - { - element.addEventListener("click", function () - { - var parent = this.parentElement; - parent.classList.toggle("is-checked"); - parent.setAttribute("data-task", parent.classList.contains("is-checked") ? "x" : " "); - }); - }); - - setupOnNode.querySelectorAll(`.plugin-tasks-list-item input[type="checkbox"]`).forEach(function(checkbox) - { - checkbox.checked = checkbox.parentElement.classList.contains("is-checked"); - }); - - setupOnNode.querySelectorAll('.kanban-plugin__item.is-complete').forEach(function(checkbox) - { - checkbox.querySelector('input[type="checkbox"]').checked = true; - }); -} - -function setupCanvas(setupOnNode) -{ - let focusedNode = null; - - // make canvas nodes selectable - setupOnNode.querySelectorAll(".canvas-node-content-blocker").forEach(function (element) - { - element.addEventListener("click", function () - { - var parent = this.parentElement.parentElement; - parent.classList.toggle("is-focused"); - this.style.display = "none"; - - if (focusedNode) - { - focusedNode.classList.remove("is-focused"); - focusedNode.querySelector(".canvas-node-content-blocker").style.display = ""; - } - - focusedNode = parent; - }); - }); - - // make canvas node deselect when clicking outside - // document.addEventListener("click", function (event) - // { - // if (!event.target.closest(".canvas-node")) - // { - // document.querySelectorAll(".canvas-node").forEach(function (node) - // { - // node.classList.remove("is-focused"); - // node.querySelector(".canvas-node-content-blocker").style.display = ""; - // }); - // } - // }); - -} - -function setupCodeblocks(setupOnNode) -{ - // make code snippet block copy button copy the code to the clipboard - setupOnNode.querySelectorAll(".copy-code-button").forEach(function (element) - { - element.addEventListener("click", function () - { - var code = this.parentElement.querySelector("code").textContent; - navigator.clipboard.writeText(code); - this.textContent = "Copied!"; - // set a timeout to change the text back - setTimeout(function () - { - setupOnNode.querySelectorAll(".copy-code-button").forEach(function (button) - { - button.textContent = "Copy"; - }); - }, 2000); - }); - }); -} - -function setupLinks(setupOnNode) -{ - setupOnNode.querySelectorAll(".internal-link, .footnote-link, .tree-item-link").forEach(function(link) - { - link.addEventListener("click", function(event) - { - let target = link.getAttribute("href"); - event.preventDefault(); - - // this is linking to a different page - if (!target.startsWith("#")) - { - // load doc, if it is a tree link then don't scroll to the active doc in the file tree - loadDocument(target, true, !link.classList.contains("tree-item-link")); - return; - } - else - { - let headerTarget = document.getElementById(target.substring(1)); - setHeaderOpen(headerTarget.parentElement, true); - headerTarget.scrollIntoView(); - } - }); - }); - - window.onpopstate = function(event) - { - loadDocument(getURLPath(), false); - } -} - - -let sidebarWidth = undefined; -let lineWidth = undefined; -function setupResize(setupOnNode) -{ - if (setupOnNode != document) return; - - function updateSidebars() - { - let rightSidebar = document.querySelector(".sidebar-right"); - let leftSidebar = document.querySelector(".sidebar-left"); - let sidebarCount = (rightSidebar ? 1 : 0) + (leftSidebar ? 1 : 0); - - if (sidebarCount == 0) return; - - if(!sidebarWidth) sidebarWidth = Math.max(rightSidebar?.clientWidth, leftSidebar?.clientWidth); - - if (!lineWidth) - { - let docWidthTestEl = document.createElement("div"); - document.querySelector(".markdown-preview-view").appendChild(docWidthTestEl); - docWidthTestEl.style.width = "var(--line-width)"; - docWidthTestEl.style.minWidth = "var(--line-width)"; - docWidthTestEl.style.maxWidth = "var(--line-width)"; - lineWidth = docWidthTestEl.clientWidth; - docWidthTestEl.remove(); - } - - let letHideRightThreshold = sidebarWidth * sidebarCount + lineWidth / 2; - - if (window.innerWidth < letHideRightThreshold) - { - rightSidebar.style.display = "none"; - } - else - { - rightSidebar.style.display = ""; - } - - let letHideLeftThreshold = lineWidth / 2 + sidebarWidth; - - if (window.innerWidth < letHideLeftThreshold) - { - leftSidebar.style.display = "none"; - } - else - { - leftSidebar.style.display = ""; - } - } - - window.addEventListener("resize", function() - { - updateSidebars(); - }); - - updateSidebars(); -} - -function setupRootPath(fromDocument) -{ - let basePath = fromDocument.querySelector("#root-path").getAttribute("root-path"); - document.querySelector("base").href = basePath; - document.querySelector("#root-path").setAttribute("root-path", basePath); - rootPath = basePath; -} - -let touchDrag = false; - -function initializePage(setupOnNode) -{ - setupThemeToggle(setupOnNode); - setupHeaders(setupOnNode); - setupTrees(setupOnNode); - setupCallouts(setupOnNode); - setupCheckboxes(setupOnNode); - setupCanvas(setupOnNode); - setupCodeblocks(setupOnNode); - setupLinks(setupOnNode); - setupResize(setupOnNode); - - setupOnNode.querySelectorAll("*").forEach(function(element) - { - element.addEventListener("touchend", function(event) - { - if (touchDrag) - { - touchDrag = false; - event.stopPropagation(); - return; - } - - if (element instanceof HTMLElement) element.click(); - }); - }); - - if(setupOnNode == document) - { - document.body.addEventListener("touchmove", function(event) - { - event.stopImmediatePropagation(); - touchDrag = true; - }); - - setupRootPath(document); - setActiveDocument(getURLPath()); - } -} - -function initializeForFileProtocol() -{ - let graphEl = document.querySelector(".graph-view-placeholder"); - if(graphEl) - { - console.log("Running locally, skipping graph view initialization and hiding graph."); - graphEl.style.display = "none"; - graphEl.previousElementSibling.style.display = "none"; // hide the graph's header - } -} - -//#endregion - -window.onload = function() -{ - if (window.location.protocol == "file:") initializeForFileProtocol(); - initializePage(document); -} \ No newline at end of file diff --git a/docs/lib/styles/obsidian-styles.css b/docs/lib/styles/obsidian-styles.css deleted file mode 100644 index de1c833c2..000000000 --- a/docs/lib/styles/obsidian-styles.css +++ /dev/null @@ -1,2753 +0,0 @@ -.callout -{ - mix-blend-mode: normal !important; -} - -@media print -{ - - html body> :not(.print) - { - display: unset !important; - } - - .collapse-indicator - { - display: none !important; - } - - .is-collapsed > element > .collapse-indicator - { - display: unset !important; - } -} - -.list-collapse-indicator -{ - display: none !important; -} - -@font-face -{ - font-family: MJXZERO; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Zero.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Main-Regular.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-B; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Main-Bold.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-I; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Math-Italic.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-MI; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Main-Italic.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-BI; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Math-BoldItalic.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-S1; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Size1-Regular.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-S2; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Size2-Regular.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-S3; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Size3-Regular.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-S4; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Size4-Regular.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-A; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_AMS-Regular.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-C; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Regular.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-CB; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Calligraphic-Bold.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-FR; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Fraktur-Regular.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-FRB; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Fraktur-Bold.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-SS; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Regular.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-SSB; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Bold.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-SSI; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_SansSerif-Italic.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-SC; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Script-Regular.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-T; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Typewriter-Regular.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-V; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Vector-Regular.woff") format("woff"); -} - -@font-face -{ - font-family: MJXTEX-VB; - src: url("https://publish.obsidian.md/lib/mathjax/output/chtml/fonts/woff-v2/MathJax_Vector-Bold.woff") format("woff"); -} - -@font-face { - font-family: 'Avenir Next'; - font-weight: normal; - font-style: normal; - font-display: swap; - src: url('https://publish.obsidian.md/public/fonts/94f2f163d4b698242fef.otf'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 200; - font-display: swap; - src: url('https://publish.obsidian.md/public/fonts/72505e6a122c6acd5471.woff2') format('woff2'); -} - -@font-face { - font-family: 'Inter'; - font-style: normal; - font-weight: 300; - font-display: swap; - src: url('https://publish.obsidian.md/public/fonts/2d5198822ab091ce4305.woff2') format('woff2'); -} - -@font-face { - font-family: 'Inter'; - font-weight: 400; - font-style: normal; - font-display: swap; - src: url('https://publish.obsidian.md/public/fonts/c8ba52b05a9ef10f4758.woff2'); -} - -@font-face { - font-family: 'Inter'; - font-weight: 400; - font-style: italic; - font-display: swap; - src: url('https://publish.obsidian.md/public/fonts/cb10ffd7684cd9836a05.woff2'); -} - -@font-face { - font-family: 'Inter'; - font-weight: 600; - font-style: normal; - font-display: swap; - src: url('https://publish.obsidian.md/public/fonts/b5f0f109bc88052d4000.woff2'); -} - -@font-face { - font-family: 'Inter'; - font-weight: 800; - font-style: normal; - font-display: swap; - src: url('https://publish.obsidian.md/public/fonts/cbe0ae49c52c920fd563.woff2'); -} - -@font-face { - font-family: 'Inter'; - font-weight: 800; - font-style: italic; - font-display: swap; - src: url('https://publish.obsidian.md/public/fonts/535a6cf662596b3bd6a6.woff2'); -} - -@font-face { - font-family: 'Source Code Pro'; - font-weight: normal; - font-style: normal; - font-display: swap; - src: url('https://publish.obsidian.md/public/fonts/70cc7ff27245e82ad414.ttf'); -} - -@font-face { - font-family: 'Source Code Pro'; - font-weight: normal; - font-style: italic; - font-display: swap; - src: url('https://publish.obsidian.md/public/fonts/454577c22304619db035.ttf'); -} - -@font-face { - font-family: 'Source Code Pro'; - font-weight: bold; - font-style: normal; - font-display: swap; - src: url('https://publish.obsidian.md/public/fonts/52ac8f3034507f1d9e53.ttf'); -} - -@font-face { - font-family: 'Source Code Pro'; - font-weight: bold; - font-style: italic; - font-display: swap; - src: url('https://publish.obsidian.md/public/fonts/05b618077343fbbd92b7.ttf'); -} - -@font-face { - font-family: 'Flow Circular'; - font-display: swap; - src: url('https://publish.obsidian.md/public/fonts/853ff76f08786ae44ca0.woff'); -} - -.collapse-icon::before -{ - /* content: "​" !important; */ - content: "" !important; - visibility: hidden !important; -} -body { --anim-duration-none: 0; --anim-duration-superfast: 70ms; --anim-duration-fast: 140ms; --anim-duration-moderate: 300ms; --anim-duration-slow: 560ms; --anim-motion-smooth: cubic-bezier(0.45, 0.05, 0.55, 0.95); --anim-motion-delay: cubic-bezier(0.65, 0.05, 0.36, 1); --anim-motion-jumpy: cubic-bezier(0.68, -0.55, 0.27, 1.55); --anim-motion-swing: cubic-bezier(0, 0.55, 0.45, 1); --blockquote-border-thickness: 2px; --blockquote-border-color: var(--interactive-accent); --blockquote-font-style: normal; --blockquote-color: inherit; --blockquote-background-color: transparent; --bold-weight: var(--font-semibold); --bold-color: inherit; --border-width: 1px; --button-radius: var(--input-radius); --callout-border-width: 0px; --callout-border-opacity: 0.25; --callout-padding: var(--size-4-3) var(--size-4-3) var(--size-4-3) var(--size-4-6); --callout-radius: var(--radius-s); --callout-blend-mode: var(--highlight-mix-blend-mode); --callout-title-color: inherit; --callout-title-padding: 0; --callout-title-size: inherit; --callout-content-padding: 0; --callout-content-background: transparent; --callout-bug: var(--color-red-rgb); --callout-default: var(--color-blue-rgb); --callout-error: var(--color-red-rgb); --callout-example: var(--color-purple-rgb); --callout-fail: var(--color-red-rgb); --callout-important: var(--color-cyan-rgb); --callout-info: var(--color-blue-rgb); --callout-question: var(--color-yellow-rgb); --callout-success: var(--color-green-rgb); --callout-summary: var(--color-cyan-rgb); --callout-tip: var(--color-cyan-rgb); --callout-todo: var(--color-blue-rgb); --callout-warning: var(--color-orange-rgb); --callout-quote: 158, 158, 158; --canvas-background: var(--background-primary); --canvas-card-label-color: var(--text-faint); --canvas-color-1: var(--color-red-rgb); --canvas-color-2: var(--color-orange-rgb); --canvas-color-3: var(--color-yellow-rgb); --canvas-color-4: var(--color-green-rgb); --canvas-color-5: var(--color-cyan-rgb); --canvas-color-6: var(--color-purple-rgb); --canvas-dot-pattern: var(--color-base-30); --checkbox-radius: var(--radius-s); --checkbox-size: var(--font-text-size); --checkbox-marker-color: var(--background-primary); --checkbox-color: var(--interactive-accent); --checkbox-color-hover: var(--interactive-accent-hover); --checkbox-border-color: var(--text-faint); --checkbox-border-color-hover: var(--text-muted); --checklist-done-decoration: line-through; --checklist-done-color: var(--text-muted); --code-white-space: pre-wrap; --code-size: var(--font-smaller); --code-background: var(--background-primary-alt); --code-normal: var(--text-muted); --code-comment: var(--text-faint); --code-function: var(--color-yellow); --code-important: var(--color-orange); --code-keyword: var(--color-pink); --code-operator: var(--color-red); --code-property: var(--color-cyan); --code-punctuation: var(--text-muted); --code-string: var(--color-green); --code-tag: var(--color-red); --code-value: var(--color-purple); --collapse-icon-color: var(--text-faint); --collapse-icon-color-collapsed: var(--text-accent); --cursor: default; --cursor-link: pointer; --dialog-width: 560px; --dialog-max-width: 80vw; --dialog-max-height: 85vh; --divider-color: var(--background-modifier-border); --divider-color-hover: var(--interactive-accent); --divider-width: 1px; --divider-width-hover: 3px; --divider-vertical-height: calc(100% - var(--header-height)); --drag-ghost-background: rgba(0, 0, 0, 0.85); --drag-ghost-text-color: #fff; --embed-max-height: 4000px; --embed-canvas-max-height: 400px; --embed-background: inherit; --embed-border-left: 2px solid var(--interactive-accent); --embed-border-right: none; --embed-border-top: none; --embed-border-bottom: none; --embed-padding: 0 0 0 var(--size-4-6); --embed-font-style: inherit; --embed-block-shadow-hover: 0 0 0 1px var(--background-modifier-border), inset 0 0 0 1px var(--background-modifier-border); --file-line-width: 700px; --file-folding-offset: 24px; --file-margins: var(--size-4-8); --file-header-font-size: var(--font-ui-small); --file-header-font-weight: 400; --file-header-border: var(--border-width) solid transparent; --file-header-justify: center; --font-smallest: 0.8em; --font-smaller: 0.875em; --font-small: 0.933em; --font-ui-smaller: 12px; --font-ui-small: 13px; --font-ui-medium: 15px; --font-ui-large: 20px; --font-thin: 100; --font-extralight: 200; --font-light: 300; --font-normal: 400; --font-medium: 500; --font-semibold: 600; --font-bold: 700; --font-extrabold: 800; --font-black: 900; --footnote-size: var(--font-smaller); --graph-controls-width: 240px; --graph-text: var(--text-normal); --graph-line: var(--color-base-35, var(--background-modifier-border-focus)); --graph-node: var(--text-muted); --graph-node-unresolved: var(--text-faint); --graph-node-focused: var(--text-accent); --graph-node-tag: var(--color-green); --graph-node-attachment: var(--color-yellow); --heading-formatting: var(--text-faint); --h1-color: inherit; --h2-color: inherit; --h3-color: inherit; --h4-color: inherit; --h5-color: inherit; --h6-color: inherit; --h1-font: inherit; --h2-font: inherit; --h3-font: inherit; --h4-font: inherit; --h5-font: inherit; --h6-font: inherit; --h1-line-height: 1.2; --h2-line-height: 1.2; --h3-line-height: 1.3; --h4-line-height: 1.4; --h5-line-height: var(--line-height-normal); --h6-line-height: var(--line-height-normal); --h1-size: 2em; --h2-size: 1.6em; --h3-size: 1.37em; --h4-size: 1.25em; --h5-size: 1.12em; --h6-size: 1.12em; --h1-style: normal; --h2-style: normal; --h3-style: normal; --h4-style: normal; --h5-style: normal; --h6-style: normal; --h1-variant: normal; --h2-variant: normal; --h3-variant: normal; --h4-variant: normal; --h5-variant: normal; --h6-variant: normal; --h1-weight: 700; --h2-weight: 600; --h3-weight: 600; --h4-weight: 600; --h5-weight: 600; --h6-weight: 600; --header-height: 40px; --hr-color: var(--background-modifier-border); --hr-thickness: 2px; --icon-size: var(--icon-m); --icon-stroke: var(--icon-m-stroke-width); --icon-xs: 14px; --icon-s: 16px; --icon-m: 18px; --icon-l: 18px; --icon-xl: 32px; --icon-xs-stroke-width: 2px; --icon-s-stroke-width: 2px; --icon-m-stroke-width: 1.75px; --icon-l-stroke-width: 1.75px; --icon-xl-stroke-width: 1.25px; --icon-color: var(--text-muted); --icon-color-hover: var(--text-muted); --icon-color-active: var(--text-accent); --icon-color-focused: var(--text-normal); --icon-opacity: 0.85; --icon-opacity-hover: 1; --icon-opacity-active: 1; --clickable-icon-radius: var(--radius-s); --indentation-guide-width: 1px; --indentation-guide-color: rgba(var(--mono-rgb-100), 0.12); --indentation-guide-color-active: rgba(var(--mono-rgb-100), 0.3); --inline-title-color: var(--h1-color); --inline-title-font: var(--h1-font); --inline-title-line-height: var(--h1-line-height); --inline-title-size: var(--h1-size); --inline-title-style: var(--h1-style); --inline-title-variant: var(--h1-variant); --inline-title-weight: var(--h1-weight); --inline-title-margin-bottom: 0.5em; --input-height: 30px; --input-radius: 5px; --input-font-weight: var(--font-normal); --input-border-width: 1px; --italic-color: inherit; --italic-weight: inherit; --layer-cover: 5; --layer-sidedock: 10; --layer-status-bar: 15; --layer-popover: 30; --layer-slides: 45; --layer-modal: 50; --layer-notice: 60; --layer-menu: 65; --layer-tooltip: 70; --layer-dragged-item: 80; --line-height-normal: 1.5; --line-height-tight: 1.3; --link-color: var(--text-accent); --link-color-hover: var(--text-accent-hover); --link-decoration: underline; --link-decoration-hover: underline; --link-decoration-thickness: auto; --link-external-color: var(--text-accent); --link-external-color-hover: var(--text-accent-hover); --link-external-decoration: underline; --link-external-decoration-hover: underline; --link-external-filter: none; --link-unresolved-color: var(--text-accent); --link-unresolved-opacity: 0.7; --link-unresolved-filter: none; --link-unresolved-decoration-style: solid; --link-unresolved-decoration-color: hsla(var(--interactive-accent-hsl), 0.3); --list-indent: 2em; --list-spacing: 0.075em; --list-marker-color: var(--text-faint); --list-marker-color-hover: var(--text-muted); --list-marker-color-collapsed: var(--text-accent); --list-bullet-border: none; --list-bullet-radius: 50%; --list-bullet-size: 0.3em; --list-bullet-transform: none; --list-numbered-style: decimal; --nav-item-size: var(--font-ui-small); --nav-item-color: var(--text-muted); --nav-item-color-hover: var(--text-normal); --nav-item-color-active: var(--text-normal); --nav-item-color-selected: var(--text-normal); --nav-item-color-highlighted: var(--text-accent-hover); --nav-item-background-hover: var(--background-modifier-hover); --nav-item-background-active: var(--background-modifier-hover); --nav-item-background-selected: hsla(var(--color-accent-hsl), 0.15); --nav-item-padding: var(--size-4-1) var(--size-4-2) var(--size-4-1) var(--size-4-6); --nav-item-parent-padding: var(--nav-item-padding); --nav-item-children-padding-left: var(--size-2-2); --nav-item-children-margin-left: var(--size-4-3); --nav-item-weight: inherit; --nav-item-weight-hover: inherit; --nav-item-weight-active: inherit; --nav-item-white-space: nowrap; --nav-indentation-guide-width: var(--indentation-guide-width); --nav-indentation-guide-color: var(--indentation-guide-color); --nav-collapse-icon-color: var(--collapse-icon-color); --nav-collapse-icon-color-collapsed: var(--text-faint); --modal-background: var(--background-primary); --modal-width: 90vw; --modal-height: 85vh; --modal-max-width: 1100px; --modal-max-height: 1000px; --modal-max-width-narrow: 800px; --modal-border-width: var(--border-width); --modal-border-color: var(--color-base-40, var(--background-modifier-border-focus)); --modal-radius: var(--radius-l); --modal-community-sidebar-width: 280px; --pdf-background: var(--background-primary); --pdf-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 2px 8px rgba(0, 0, 0, 0.1); --pdf-spread-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05); --pdf-sidebar-background: var(--background-primary); --pdf-thumbnail-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15), 0 2px 8px rgba(0, 0, 0, 0.2); --popover-width: 450px; --popover-height: 400px; --popover-max-height: 70vh; --popover-pdf-width: 600px; --popover-pdf-height: 800px; --popover-font-size: var(--font-text-size); --prompt-width: 700px; --prompt-max-width: 80vw; --prompt-max-height: 70vh; --prompt-border-width: var(--border-width); --prompt-border-color: var(--color-base-40, var(--background-modifier-border-focus)); --radius-s: 4px; --radius-m: 8px; --radius-l: 12px; --radius-xl: 16px; --ribbon-background: var(--background-secondary); --ribbon-background-collapsed: var(--background-primary); --ribbon-width: 44px; --ribbon-padding: var(--size-4-2) var(--size-4-1) var(--size-4-3); --scrollbar-active-thumb-bg: rgba(var(--mono-rgb-100), 0.2); --scrollbar-bg: rgba(var(--mono-rgb-100), 0.05); --scrollbar-thumb-bg: rgba(var(--mono-rgb-100), 0.1); --search-clear-button-color: var(--text-muted); --search-clear-button-size: 13px; --search-icon-color: var(--text-muted); --search-icon-size: 18px; --search-result-background: var(--background-primary); --size-2-1: 2px; --size-2-2: 4px; --size-2-3: 6px; --size-4-1: 4px; --size-4-2: 8px; --size-4-3: 12px; --size-4-4: 16px; --size-4-5: 20px; --size-4-6: 24px; --size-4-8: 32px; --size-4-9: 36px; --size-4-12: 48px; --size-4-16: 64px; --size-4-18: 72px; --sidebar-markdown-font-size: calc(var(--font-text-size) * 0.9); --sidebar-tab-text-display: none; --slider-thumb-border-width: 1px; --slider-thumb-border-color: var(--background-modifier-border-hover); --slider-thumb-height: 18px; --slider-thumb-width: 18px; --slider-thumb-y: -6px; --slider-thumb-radius: 50%; --slider-s-thumb-size: 15px; --slider-s-thumb-position: -5px; --slider-track-background: var(--background-modifier-border); --slider-track-height: 3px; --status-bar-background: var(--background-secondary); --status-bar-border-color: var(--divider-color); --status-bar-border-width: 1px 0 0 1px; --status-bar-font-size: var(--font-ui-smaller); --status-bar-text-color: var(--text-muted); --status-bar-position: fixed; --status-bar-radius: var(--radius-m) 0 0 0; --status-bar-scroll-padding: calc(var(--status-bar-font-size) + 18px); --swatch-radius: 14px; --swatch-height: 24px; --swatch-width: 24px; --swatch-shadow: inset 0 0 0 1px rgba(var(--mono-rgb-100), 0.15); --tab-background-active: var(--background-primary); --tab-text-color: var(--text-faint); --tab-text-color-active: var(--text-muted); --tab-text-color-focused: var(--text-muted); --tab-text-color-focused-active: var(--text-muted); --tab-text-color-focused-highlighted: var(--text-accent); --tab-text-color-focused-active-current: var(--text-normal); --tab-font-size: var(--font-ui-small); --tab-font-weight: inherit; --tab-container-background: var(--background-secondary); --tab-divider-color: var(--background-modifier-border-hover); --tab-outline-color: var(--divider-color); --tab-outline-width: 1px; --tab-curve: 6px; --tab-radius: var(--radius-s); --tab-radius-active: 6px 6px 0 0; --tab-width: 200px; --tab-max-width: 320px; --tab-stacked-pane-width: 700px; --tab-stacked-header-width: var(--header-height); --tab-stacked-font-size: var(--font-ui-small); --tab-stacked-font-weight: 400; --tab-stacked-text-align: left; --tab-stacked-text-transform: rotate(0deg); --tab-stacked-text-writing-mode: vertical-lr; --tab-stacked-shadow: -8px 0 8px 0 rgba(0, 0, 0, 0.05); --table-background: transparent; --table-border-width: 1px; --table-border-color: var(--background-modifier-border); --table-white-space: normal; --table-header-background: var(--table-background); --table-header-background-hover: inherit; --table-header-border-width: var(--table-border-width); --table-header-border-color: var(--table-border-color); --table-header-font: inherit; --table-header-size: var(--font-text-size); --table-header-weight: var(--bold-weight); --table-header-color: var(--text-normal); --table-text-size: inherit; --table-text-color: inherit; --table-column-max-width: none; --table-column-alt-background: var(--table-background); --table-column-first-border-width: var(--table-border-width); --table-column-last-border-width: var(--table-border-width); --table-row-background-hover: var(--table-background); --table-row-alt-background: var(--table-background); --table-row-last-border-width: var(--table-border-width); --tag-size: var(--font-smaller); --tag-color: var(--text-accent); --tag-color-hover: var(--text-accent); --tag-decoration: none; --tag-decoration-hover: none; --tag-background: hsla(var(--interactive-accent-hsl), 0.1); --tag-background-hover: hsla(var(--interactive-accent-hsl), 0.2); --tag-border-color: hsla(var(--interactive-accent-hsl), 0.15); --tag-border-color-hover: hsla(var(--interactive-accent-hsl), 0.15); --tag-border-width: 0px; --tag-padding-x: 0.65em; --tag-padding-y: 0.25em; --tag-radius: 2em; --titlebar-background: var(--background-secondary); --titlebar-background-focused: var(--background-secondary-alt); --titlebar-border-width: 0px; --titlebar-border-color: var(--background-modifier-border); --titlebar-text-color: var(--text-muted); --titlebar-text-color-focused: var(--text-normal); --titlebar-text-weight: var(--font-bold); --toggle-border-width: 2px; --toggle-width: 40px; --toggle-radius: 18px; --toggle-thumb-color: white; --toggle-thumb-radius: 18px; --toggle-thumb-height: 18px; --toggle-thumb-width: 18px; --toggle-s-border-width: 2px; --toggle-s-width: 34px; --toggle-s-thumb-height: 15px; --toggle-s-thumb-width: 15px; --vault-name-font-size: var(--font-ui-small); --vault-name-font-weight: var(--font-medium); --vault-name-color: var(--text-normal); --workspace-background-translucent: rgba(var(--mono-rgb-0), 0.6); --accent-h: 254; --accent-s: 80%; --accent-l: 68%; --background-primary: var(--color-base-00); --background-primary-alt: var(--color-base-10); --background-secondary: var(--color-base-20); --background-modifier-hover: rgba(var(--mono-rgb-100), 0.075); --background-modifier-active-hover: hsla(var(--interactive-accent-hsl), 0.15); --background-modifier-border: var(--color-base-30); --background-modifier-border-hover: var(--color-base-35); --background-modifier-border-focus: var(--color-base-40); --background-modifier-error-rgb: var(--color-red-rgb); --background-modifier-error: var(--color-red); --background-modifier-error-hover: var(--color-red); --background-modifier-success-rgb: var(--color-green-rgb); --background-modifier-success: var(--color-green); --background-modifier-message: rgba(0, 0, 0, 0.9); --background-modifier-form-field: var(--color-base-00); --text-normal: var(--color-base-100); --text-muted: var(--color-base-70); --text-faint: var(--color-base-50); --text-on-accent: white; --text-on-accent-inverted: black; --text-error: var(--color-red); --text-success: var(--color-green); --text-selection: hsla(var(--color-accent-hsl), 0.2); --text-highlight-bg: rgba(255, 208, 0, 0.4); --text-accent: var(--color-accent); --text-accent-hover: var(--color-accent-2); --interactive-normal: var(--color-base-00); --interactive-hover: var(--color-base-10); --interactive-accent-hsl: var(--color-accent-hsl); --interactive-accent: var(--color-accent-1); --interactive-accent-hover: var(--color-accent-2); } -.theme-light { color-scheme: light; --highlight-mix-blend-mode: darken; --mono-rgb-0: 255, 255, 255; --mono-rgb-100: 0, 0, 0; --color-red-rgb: 233, 49, 71; --color-red: #e93147; --color-orange-rgb: 236, 117, 0; --color-orange: #ec7500; --color-yellow-rgb: 224, 172, 0; --color-yellow: #e0ac00; --color-green-rgb: 8, 185, 78; --color-green: #08b94e; --color-cyan-rgb: 0, 191, 188; --color-cyan: #00bfbc; --color-blue-rgb: 8, 109, 221; --color-blue: #086ddd; --color-purple-rgb: 120, 82, 238; --color-purple: #7852ee; --color-pink-rgb: 213, 57, 132; --color-pink: #d53984; --color-base-00: #ffffff; --color-base-05: #fcfcfc; --color-base-10: #fafafa; --color-base-20: #f6f6f6; --color-base-25: #e3e3e3; --color-base-30: #e0e0e0; --color-base-35: #d4d4d4; --color-base-40: #bdbdbd; --color-base-50: #ababab; --color-base-60: #707070; --color-base-70: #5a5a5a; --color-base-100: #222222; --color-accent-hsl: var(--accent-h), var(--accent-s), var(--accent-l); --color-accent: hsl(var(--accent-h), var(--accent-s), var(--accent-l)); --color-accent-1: hsl(var(--accent-h), var(--accent-s), calc(var(--accent-l) + 2.5%)); --color-accent-2: hsl(var(--accent-h), var(--accent-s), calc(var(--accent-l) + 5%)); --background-secondary-alt: var(--color-base-05); --background-modifier-box-shadow: rgba(0, 0, 0, 0.1); --background-modifier-cover: rgba(220, 220, 220, 0.4); --input-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12), 0 2px 3px 0 rgba(0,0,0,0.05), 0 1px 1.5px 0 rgba(0,0,0,0.03), 0 1px 2px 0 rgba(0,0,0,0.04), 0 0 0 0 transparent; --input-shadow-hover: inset 0 0 0 1px rgba(0, 0, 0, 0.17), 0 2px 3px 0 rgba(0,0,0,0.1), 0 1px 1.5px 0 rgba(0,0,0,0.03), 0 1px 2px 0 rgba(0,0,0,0.04), 0 0 0 0 transparent; --shadow-s: 0px 1px 2px rgba(0, 0, 0, 0.028), 0px 3.4px 6.7px rgba(0, 0, 0, 0.042), 0px 15px 30px rgba(0, 0, 0, 0.07); --shadow-l: 0px 1.8px 7.3px rgba(0, 0, 0, 0.071), 0px 6.3px 24.7px rgba(0, 0, 0, 0.112), 0px 30px 90px rgba(0, 0, 0, 0.2); } -.theme-dark { color-scheme: dark; --highlight-mix-blend-mode: lighten; --mono-rgb-0: 0, 0, 0; --mono-rgb-100: 255, 255, 255; --color-red-rgb: 251, 70, 76; --color-red: #fb464c; --color-orange-rgb: 233, 151, 63; --color-orange: #e9973f; --color-yellow-rgb: 224, 222, 113; --color-yellow: #e0de71; --color-green-rgb: 68, 207, 110; --color-green: #44cf6e; --color-cyan-rgb: 83, 223, 221; --color-cyan: #53dfdd; --color-blue-rgb: 2, 122, 255; --color-blue: #027aff; --color-purple-rgb: 168, 130, 255; --color-purple: #a882ff; --color-pink-rgb: 250, 153, 205; --color-pink: #fa99cd; --color-base-00: #1e1e1e; --color-base-05: #212121; --color-base-10: #242424; --color-base-20: #262626; --color-base-25: #2a2a2a; --color-base-30: #363636; --color-base-35: #3f3f3f; --color-base-40: #555555; --color-base-50: #666666; --color-base-60: #999999; --color-base-70: #bababa; --color-base-100: #dadada; --color-accent-hsl: var(--accent-h), var(--accent-s), var(--accent-l); --color-accent: hsl(var(--accent-h), var(--accent-s), var(--accent-l)); --color-accent-1: hsl(var(--accent-h), var(--accent-s), calc(var(--accent-l) - 3.8%)); --color-accent-2: hsl(var(--accent-h), var(--accent-s), calc(var(--accent-l) + 3.8%)); --background-modifier-form-field: var(--color-base-25); --background-secondary-alt: var(--color-base-30); --interactive-normal: var(--color-base-30); --interactive-hover: var(--color-base-35); --background-modifier-box-shadow: rgba(0, 0, 0, 0.3); --background-modifier-cover: rgba(10, 10, 10, 0.4); --text-selection: hsla(var(--interactive-accent-hsl), 0.25); --input-shadow: inset 0 0.5px 0.5px 0.5px rgba(255, 255, 255, 0.09), 0 2px 4px 0 rgba(0,0,0,0.15), 0 1px 1.5px 0 rgba(0,0,0,0.1), 0 1px 2px 0 rgba(0,0,0,0.2), 0 0 0 0 transparent; --input-shadow-hover: inset 0 0.5px 1px 0.5px rgba(255, 255, 255, 0.16), 0 2px 3px 0 rgba(0,0,0,0.3), 0 1px 1.5px 0 rgba(0,0,0,0.2), 0 1px 2px 0 rgba(0,0,0,0.4), 0 0 0 0 transparent; --shadow-s: 0px 1px 2px rgba(0, 0, 0, 0.121), 0px 3.4px 6.7px rgba(0, 0, 0, 0.179), 0px 15px 30px rgba(0, 0, 0, 0.3); --shadow-l: 0px 1.8px 7.3px rgba(0, 0, 0, 0.071), 0px 6.3px 24.7px rgba(0, 0, 0, 0.112), 0px 30px 90px rgba(0, 0, 0, 0.2); --pdf-shadow: 0 0 0 1px var(--background-modifier-border); --pdf-thumbnail-shadow: 0 0 0 1px var(--background-modifier-border); } -iframe { color-scheme: normal; } -@media print { - .theme-dark { --highlight-mix-blend-mode: darken; } -} -body { --font-default: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Inter", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Microsoft YaHei Light", sans-serif; --font-monospace-default: Menlo, SFMono-Regular, Consolas, "Roboto Mono", "Source Code Pro", monospace; --font-interface-override: "??"; --font-interface-theme: "??"; --font-interface: var(--font-interface-override), var(--font-interface-theme), var(--default-font, "??"), var(--font-default); --font-text-override: "??"; --font-text-theme: "??"; --font-text: var(--font-text-override), var(--font-text-theme), var(--font-interface); --font-print-override: "??"; --font-print: var(--font-print-override), var(--font-text-override), var(--font-text-theme), "Arial"; --font-monospace-override: "??"; --font-monospace-theme: "??"; --font-monospace: var(--font-monospace-override), var(--font-monospace-theme), var(--font-monospace-default); --font-text-size: 16px; --font-mermaid: var(--font-text); } -@media print { - html, body { padding-top: 0px !important; overflow: auto !important; height: auto !important; } - iframe, .titlebar, .app-container, .progress-bar, .popover, .markdown-embed-link { display: none !important; } - body > :not(.print) { display: none !important; } - .print .markdown-preview-view { -webkit-print-color-adjust: exact; color: initial; } - .print .markdown-preview-view mark { color: initial; } - .print .markdown-preview-view .frontmatter-container { display: none; } - .print .markdown-preview-view .markdown-embed-content { max-height: none; overflow: visible; } - .print .markdown-preview-view .callout-content { display: inherit !important; } - .print .external-link { background: none; padding-right: 0px; } - * { text-shadow: none !important; } - webview { display: none; } - ::-webkit-scrollbar { display: none; } - body { --font-text: var(--font-print) !important; } -} -* { box-sizing: border-box; } -html, body { margin: 0px; padding: 0px; height: 100%; width: 100%; overflow: hidden; } -body { text-rendering: optimizelegibility; font-family: var(--font-interface); line-height: var(--line-height-tight); font-size: var(--font-ui-medium); background-color: var(--background-primary); color: var(--text-normal); -webkit-tap-highlight-color: rgba(255, 255, 255, 0); } -body.is-translucent { background-color: transparent; } -@keyframes node-inserted { - 0% { outline-color: rgb(255, 255, 255); } - 100% { outline-color: rgb(0, 0, 0); } -} -.node-insert-event { animation-duration: 0.01s; animation-name: node-inserted; } -.is-flashing { transition: all 0.25s ease 0s; color: var(--text-normal); mix-blend-mode: var(--highlight-mix-blend-mode); border-radius: var(--radius-s); background-color: var(--text-highlight-bg) !important; } -body { user-select: none; overflow: hidden; } -body [contenteditable="true"], body [contenteditable=""] { user-select: text; } -body.is-grabbing, body.is-grabbing :not(.workspace-leaf-resize-handle) { cursor: grabbing !important; } -body.is-grabbing iframe:not(.is-controlled), body.is-grabbing webview { pointer-events: none; } -.app-container { display: flex; height: 100%; width: 100%; position: relative; flex-direction: column; } -.app-container.no-transition * { transition: none 0s ease 0s !important; } -.horizontal-main-container { width: 100%; display: flex; overflow: hidden; flex: 1 0 0px; } -:focus { outline: none; } -.is-text-garbled * { font-family: "Flow Circular", sans-serif !important; line-height: 1.45em !important; } -@-webkit-keyframes blink { - 50% { background-color: transparent; } -} -@keyframes blink { - 50% { background-color: transparent; } -} -div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 187, 0); } -div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(170, 34, 34); } -div.CodeMirror-cursors { visibility: hidden; position: relative; z-index: 3; } -div.CodeMirror-dragcursors { visibility: visible; } -@media print { - .CodeMirror div.CodeMirror-cursors { visibility: hidden; } -} -span.CodeMirror-selectedtext { background: none; } -.markdown-source-view { font-size: var(--font-text-size); font-family: var(--font-text); } -.markdown-source-view.mod-cm5 { height: 100%; } -.workspace-leaf-content.is-read-mode .markdown-source-view { z-index: 0; } -.markdown-source-view.is-readable-line-width .CodeMirror { max-width: var(--file-line-width); margin-left: auto; margin-right: auto; } -.drag-ghost { position: fixed; font-size: var(--font-ui-small); color: var(--drag-ghost-text-color); padding: var(--size-2-3) var(--size-4-2); border-radius: var(--radius-s); background-color: var(--drag-ghost-background); box-shadow: 0 2px 8px var(--background-modifier-box-shadow); z-index: var(--layer-dragged-item); max-width: 300px; font-weight: var(--font-medium); pointer-events: none; } -.drag-ghost.mod-leaf { display: flex; z-index: var(--layer-tooltip); } -.drag-ghost-icon { margin-right: var(--size-2-3); position: relative; } -.drag-reorder-ghost { position: fixed; border-radius: var(--radius-s); background-color: var(--background-primary); box-shadow: 0 2px 8px var(--background-modifier-box-shadow); z-index: var(--layer-dragged-item); pointer-events: none; } -.drag-ghost-self { display: flex; } -.drag-ghost-self > .svg-icon { --icon-size: var(--icon-xs); --icon-stroke: var(--icon-xs-stroke-width); opacity: 0.7; vertical-align: middle; align-self: center; margin-right: var(--size-2-2); flex-shrink: 0; } -.drag-ghost-self span { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } -.drag-ghost-action { padding: var(--size-2-1) 0 0 0; font-size: var(--font-ui-smaller); opacity: 0.7; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } -.drag-ghost-hidden { visibility: hidden; position: relative; } -.drag-ghost-hidden::before { content: " "; position: absolute; inset: 0px; visibility: visible; border-radius: 5px; background-color: hsla(var(--interactive-accent-hsl), 0.3); } -.markdown-source-view.mod-cm6 { height: 100%; display: flex; flex-direction: column; } -.markdown-source-view.mod-cm6 ::selection { background-color: var(--text-selection); } -.markdown-source-view.mod-cm6 .cm-line .cm-selection, .markdown-source-view.mod-cm6 .cm-line .cm-inline-code .cm-selection { background-color: var(--text-selection); } -.markdown-source-view.mod-cm6 .cm-selectionBackground, .markdown-source-view.mod-cm6 .cm-editor > .cm-scroller > .cm-selectionLayer > .cm-selectionBackground { background-color: var(--text-selection); } -.markdown-source-view.mod-cm6.is-readable-line-width .cm-sizer { max-width: var(--file-line-width); margin-left: auto; margin-right: auto; } -.markdown-source-view.mod-cm6.is-readable-line-width .cm-content { max-width: var(--file-line-width); } -.markdown-source-view.mod-cm6.is-readable-line-width .cm-line { max-width: var(--file-line-width); } -.markdown-source-view.mod-cm6.is-readable-line-width .cm-line.HyperMD-table-row { max-width: 100%; } -.markdown-source-view.mod-cm6 .cm-editor { flex: 1 1 0px; min-height: 0px; } -.markdown-source-view.mod-cm6 .cm-editor.cm-focused { outline: none; } -.markdown-source-view.mod-cm6 .cm-scroller { font-family: var(--font-text); line-height: var(--line-height-normal); scroll-padding-block-end: var(--status-bar-scroll-padding); } -.markdown-source-view.mod-cm6 .cm-sizer { display: flex; flex-direction: column; align-items: stretch; width: 100%; min-height: 100%; } -.markdown-source-view.mod-cm6 .cm-contentContainer { flex: 1 1 auto; display: flex; align-items: stretch; overflow-x: visible; } -.markdown-source-view.mod-cm6 .cm-content { width: 0px; caret-color: var(--text-normal); min-height: unset; padding: 0px; flex-basis: unset !important; } -.is-mobile.is-ios .markdown-source-view.mod-cm6 .cm-content { -webkit-user-modify: read-write; } -.markdown-source-view.mod-cm6 .cm-content > * { display: block; margin: 0px !important; } -.markdown-source-view.mod-cm6 .cm-content > [contenteditable="false"] { contain: paint !important; } -.markdown-source-view.mod-cm6 .cm-gutters { flex: 0 0 auto; background-color: transparent; padding-inline-end: var(--file-folding-offset); font-size: var(--font-ui-smaller); z-index: 1; font-variant: tabular-nums; color: var(--text-faint) !important; border-right: none !important; } -.markdown-source-view.mod-cm6 .cm-line > * { text-indent: 0px; } -.markdown-source-view.mod-cm6 .cm-transparent { color: transparent; } -.markdown-source-view.mod-cm6 .cm-html-embed, .markdown-source-view.mod-cm6 .cm-callout, .markdown-source-view.mod-cm6 .cm-table-widget { white-space: normal; overflow-wrap: normal; word-break: normal; } -.markdown-source-view.mod-cm6 .cm-line { position: relative; padding: 0px; } -.markdown-source-view.mod-cm6 .edit-block-button { padding: var(--size-2-2) var(--size-2-3); position: absolute; top: var(--size-2-2); right: var(--size-2-2); display: flex; opacity: 0; color: var(--text-muted); border-radius: var(--radius-s); cursor: var(--cursor); } -@media (hover: hover) { - .markdown-source-view.mod-cm6 .edit-block-button:hover { background-color: var(--background-modifier-hover); } -} -.markdown-source-view.mod-cm6 .cm-panels { background-color: inherit; color: inherit; } -.markdown-source-view.mod-cm6 img.cm-widgetBuffer { display: inline !important; width: 0px !important; border: 0px !important; margin: 0px !important; padding: 0px !important; } -.view-content > .markdown-source-view.mod-cm6 > .cm-editor > .cm-scroller { padding: var(--file-margins); } -.empty-state { position: absolute; height: 100%; width: 100%; top: 0px; left: 0px; display: flex; align-items: center; justify-content: center; flex-direction: column; } -.empty-state-container { max-width: 480px; max-height: 280px; margin: 20px; text-align: center; } -.empty-state-title { margin: 20px 0px; font-weight: var(--h2-weight); font-size: var(--h2-size); line-height: var(--line-height-tight); position: relative; } -.empty-state-action-list { font-size: var(--font-text-size); line-height: var(--line-height-tight); color: var(--text-muted); margin-top: 20px; } -.empty-state-action { cursor: var(--cursor); line-height: 36px; color: var(--text-accent); } -@media (hover: hover) { - .empty-state-action:hover { color: var(--text-accent-hover); } -} -.empty-state-close-button { display: none; } -body { --zoom-factor: 1; --titlebar-height: 30px; } -.mod-macos { --frame-left-space: calc(80px - var(--ribbon-width)); --frame-right-space: 0px; } -.mod-macos.is-popout-window { --frame-left-space: 80px; } -.mod-windows, .mod-linux { --frame-left-space: 0px; --frame-right-space: 126px; } -body.is-frameless:not(.is-hidden-frameless) { padding-top: calc(var(--titlebar-height) / var(--zoom-factor)); } -body.is-frameless:not(.is-hidden-frameless) .titlebar { height: var(--titlebar-height); zoom: calc(1 / var(--zoom-factor)); } -body.is-frameless:not(.is-hidden-frameless):not(.is-maximized) .titlebar { padding-top: 2px; } -body.is-frameless.is-hidden-frameless .titlebar { height: calc(var(--header-height) - 1px); } -body.is-frameless.is-hidden-frameless.starter .titlebar { height: var(--titlebar-height); } -.is-fullscreen .titlebar { display: none; } -.sidebar-toggle-button, .workspace-tabs.mod-top { --tab-container-background: var(--titlebar-background); } -body.is-focused .titlebar, body.is-focused .workspace-ribbon.mod-left { --titlebar-background: var(--titlebar-background-focused); } -body.is-focused .sidebar-toggle-button, body.is-focused .workspace-tabs.mod-top { --tab-container-background: var(--titlebar-background-focused); } -.is-hidden-frameless { --divider-vertical-height: 100%; } -.workspace-ribbon .sidebar-toggle-button { position: absolute; top: 0px; left: 0px; width: var(--ribbon-width); justify-content: center; } -.titlebar-button.mod-logo { width: var(--ribbon-width); justify-content: center; } -.is-hidden-frameless:not(.starter) .titlebar { app-region: no-drag; } -.is-hidden-frameless .titlebar-button.mod-logo { display: none; } -.is-hidden-frameless:not(.is-fullscreen) .workspace-tab-header-container { transition: padding-left 275ms var(--anim-motion-swing), padding-right 275ms var(--anim-motion-swing); } -.is-hidden-frameless:not(.is-fullscreen) .workspace-tabs.mod-top-left-space .workspace-tab-header-container { padding-left: var(--frame-left-space); } -.is-hidden-frameless:not(.is-fullscreen) .workspace-tabs.mod-top-left-space .workspace-tab-header-container::before { app-region: no-drag; content: ""; height: 100%; left: 0px; top: 0px; position: absolute; width: var(--frame-left-space); } -.is-hidden-frameless:not(.is-fullscreen) .workspace-tabs.mod-top-right-space .workspace-tab-header-container { padding-right: var(--frame-right-space); } -.is-hidden-frameless:not(.is-fullscreen) .workspace-tabs.mod-top-right-space .workspace-tab-header-container::after { app-region: no-drag; content: ""; height: 100%; right: 0px; top: 0px; position: absolute; width: var(--frame-right-space); } -.is-hidden-frameless:not(.is-fullscreen) .titlebar-button-container.mod-right { background-color: var(--titlebar-background); } -.is-hidden-frameless:not(.is-fullscreen).is-focused .titlebar-button-container.mod-right { background-color: var(--titlebar-background-focused); } -.titlebar-button.mod-logo:hover .logo-wireframe, .titlebar-button.mod-logo:not(:hover) .logo-full { display: none; } -body.is-frameless > .app-container ~ * { app-region: no-drag; } -body.is-frameless .modal-container, body.is-frameless .suggestion-bg { app-region: initial; } -body.is-frameless .modal { app-region: no-drag; } -.loader-cube { width: 40px; height: 40px; margin: 100px auto; } -.loader-cube .sk-cube { width: 33%; height: 33%; background-color: var(--interactive-accent); float: left; animation: 1.3s ease-in-out 0s infinite normal none running sk-cubeGridScaleDelay; } -.loader-cube .sk-cube1 { animation-delay: 0.2s; } -.loader-cube .sk-cube2 { animation-delay: 0.3s; } -.loader-cube .sk-cube3 { animation-delay: 0.4s; } -.loader-cube .sk-cube4 { animation-delay: 0.1s; } -.loader-cube .sk-cube5 { animation-delay: 0.2s; } -.loader-cube .sk-cube6 { animation-delay: 0.3s; } -.loader-cube .sk-cube7 { animation-delay: 0s; } -.loader-cube .sk-cube8 { animation-delay: 0.1s; } -.loader-cube .sk-cube9 { animation-delay: 0.2s; } -@-webkit-keyframes sk-cubeGridScaleDelay { - 0%, 70%, 100% { transform: scale3d(1, 1, 1); } - 35% { transform: scale3d(0, 0, 1); } -} -@keyframes sk-cubeGridScaleDelay { - 0%, 70%, 100% { transform: scale3d(1, 1, 1); } - 35% { transform: scale3d(0, 0, 1); } -} -.is-loading { position: relative; } -.is-loading::before { content: " "; position: absolute; top: 0px; width: 0px; height: 3px; background-color: var(--interactive-accent); animation: 1000ms ease-in-out 300ms infinite normal none running progress-bar; } -.pane-empty { color: var(--text-faint); font-size: var(--font-ui-small); margin: var(--size-4-2) auto; text-align: center; } -.view-header { height: var(--header-height); display: none; border-bottom: var(--file-header-border); background-color: var(--background-primary); z-index: 1; position: relative; gap: var(--size-4-2); padding: 0 var(--size-4-3); } -body.is-phone .view-header, .show-view-header .view-header { display: flex; } -.is-focused .workspace-leaf.mod-active .view-header { background-color: var(--background-primary); } -.workspace-split.mod-left-split .view-header, .workspace-split.mod-right-split .view-header, .workspace-fake-target-overlay.is-in-sidebar .view-header { display: none; } -.view-header.is-highlighted::after { content: " "; position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; background-color: hsla(var(--interactive-accent-hsl), 0.5); } -.view-header .view-header-icon { display: none; padding: var(--size-2-2); margin-right: var(--size-2-3); color: var(--text-muted); align-self: center; cursor: grab; } -.view-header .view-header-icon:active { cursor: grabbing; } -.view-header-title { font-size: var(--file-header-font-size); font-weight: var(--file-header-font-weight); flex: 1 1 0px; max-width: max-content; overflow: auto; padding: 0 var(--size-4-1); white-space: pre; overflow-wrap: normal; color: var(--text-muted); scroll-padding-inline-end: 20px; } -.is-focused .workspace-leaf.mod-active .view-header-title { color: var(--text-normal); } -.view-header-title::-webkit-scrollbar { display: none; } -.view-header-title-container { flex-grow: 1; overflow: hidden; position: relative; justify-content: var(--file-header-justify); display: flex; align-items: center; gap: 0px; white-space: nowrap; } -.view-header-title-container:not(.mod-at-start)::before { content: " "; position: absolute; top: 0px; left: 0px; width: 30px; height: 100%; background: linear-gradient(to right, var(--background-primary), transparent); } -.view-header-title-container:not(.mod-at-end)::after { content: " "; position: absolute; top: 0px; right: 0px; width: 30px; height: 100%; background: linear-gradient(to right, transparent, var(--background-primary)); } -.view-header-title-parent { font-size: var(--file-header-font-size); color: var(--text-muted); min-width: 0px; display: flex; gap: 0px; overflow: hidden; } -.view-header-title-parent .view-header-breadcrumb { padding: 2px 4px; border-radius: var(--radius-s); } -@media (hover: hover) { - .view-header-title-parent .view-header-breadcrumb:hover { background-color: var(--background-modifier-hover); color: var(--text-normal); } -} -.view-header-title-parent .view-header-breadcrumb-separator { padding: 2px 1px; color: var(--text-faint); } -.view-content { width: 100%; height: calc(100% - var(--header-height)); } -.workspace-split.mod-root .view-content { background-color: var(--background-primary); } -.workspace-split.mod-root .workspace-fake-target-overlay .view-content { background-color: transparent; } -.workspace-split.mod-left-split .view-content, .workspace-split.mod-right-split .view-content { height: 100%; overflow: auto; } -.inline-title { font-weight: var(--inline-title-weight); font-size: var(--inline-title-size); line-height: var(--inline-title-line-height); font-style: var(--inline-title-style); font-variant: var(--inline-title-variant); font-family: var(--inline-title-font); margin-bottom: var(--inline-title-margin-bottom); letter-spacing: -0.015em; color: var(--inline-title-color); } -.hover-popover .inline-title, .inline-embed .inline-title { display: none; } -body:not(.show-inline-title) .inline-title:not([data-level]) { display: none; } -::selection { background-color: var(--text-selection); } -.markdown-reading-view { display: flex; flex-direction: column; } -.markdown-preview-view { font-size: var(--font-text-size); font-family: var(--font-text); line-height: var(--line-height-normal); width: 100%; height: 100%; padding: var(--file-margins); position: relative; overflow-y: auto; overflow-wrap: break-word; color: var(--text-normal); user-select: text; } -.workspace-leaf-content.is-read-mode .markdown-preview-view { width: 100%; left: 0px; background-color: var(--background-primary); } -.markdown-preview-view.is-readable-line-width .markdown-preview-sizer { max-width: var(--file-line-width); margin-left: auto; margin-right: auto; } -.markdown-rendered.rtl { direction: rtl; } -.workspace-ribbon.mod-left { margin-top: var(--header-height); } -.workspace-ribbon.mod-left::before { position: absolute; left: 0px; top: 0px; background-color: var(--titlebar-background); content: " "; border-bottom: var(--tab-outline-width) solid var(--tab-outline-color); height: calc(var(--header-height) - var(--tab-outline-width)); width: var(--ribbon-width); } -.workspace-ribbon { width: var(--ribbon-width); flex: 0 0 var(--ribbon-width); display: flex; flex-direction: column; overflow: hidden; background-color: var(--ribbon-background); z-index: var(--layer-sidedock); color: var(--text-muted); padding: var(--ribbon-padding); gap: var(--size-4-1); border-right: var(--divider-width) solid var(--divider-color); } -.workspace-ribbon.mod-left.is-collapsed { transition: background-color 250ms ease-in-out 95ms; background-color: var(--ribbon-background-collapsed); border-right-color: var(--divider-color); } -.workspace-ribbon.mod-right { display: none; } -.workspace-ribbon.is-hidden { display: none; } -.workspace-ribbon.is-collapsed { background-color: var(--background-secondary); } -.side-dock-settings, .side-dock-actions { flex-direction: column; } -.side-dock-settings .side-dock-ribbon-action, .side-dock-actions .side-dock-ribbon-action { margin: 0px auto; } -.side-dock-settings { margin-top: auto; } -.release-notes-view { padding: var(--file-margins); } -.release-notes-view .markdown-preview-view { overflow: visible; } -.release-notes-view .is-readable-line-width { max-width: var(--file-line-width); margin-left: auto; margin-right: auto; } -.setting { display: flex; align-items: center; } -.setting-text { flex-grow: 1; } -.setting-title { font-size: var(--font-ui-large); line-height: var(--line-height-normal); } -.setting-explanation { color: var(--text-muted); } -.modal.mod-new-editor { max-width: 600px; } -.modal.mod-trust-folder { max-width: 700px; } -.modal.mod-settings .vertical-tab-header { flex: 0 0 25%; min-width: 180px; max-width: 250px; overflow: auto; border-right: 1px solid var(--divider-color); } -.modal.mod-settings .modal-content { margin-top: 0px; overflow: hidden; } -.modal.mod-plugin-options .modal-content { margin: var(--size-4-6) 0; } -.setting-item { display: flex; align-items: center; padding: 0.75em 0px; border-top: 1px solid var(--background-modifier-border); } -.setting-item + .setting-item-heading { margin-top: 0.75em; } -.setting-item:first-child { padding-top: 0px; border-top: none; } -.setting-item > :first-child { margin-right: var(--size-4-4); } -.setting-item > :last-child { margin-right: 0px; } -.setting-item.mod-cta { justify-content: center; } -.setting-item-heading { font-weight: var(--font-semibold); border-top: none; } -.setting-item-heading .setting-item-info { flex-grow: 0; margin-right: 0px; } -.setting-item-heading .setting-item-description { font-weight: var(--font-normal); } -.setting-item-info { flex: 1 1 auto; } -.setting-item-description { color: var(--text-muted); font-size: var(--font-ui-smaller); padding-top: var(--size-4-1); line-height: var(--line-height-tight); } -.setting-item-description:empty { display: none; } -.setting-item-description code { font-family: var(--font-monospace); font-size: var(--font-smaller); border-radius: var(--radius-s); padding: 0px 3px 2px; position: relative; bottom: 1px; } -.setting-item-description ul { margin: var(--size-4-1) 0; padding-left: var(--size-4-6); } -.setting-item-name { color: var(--text-normal); font-size: var(--font-ui-medium); line-height: var(--line-height-tight); } -.setting-item-control { flex: 1 1 auto; text-align: right; display: flex; justify-content: flex-end; align-items: center; gap: var(--size-4-2); } -.setting-item-control.mod-vertical { flex-direction: column; } -.setting-item-control.mod-vertical > :not(:last-child) { margin-bottom: 10px; margin-right: 0px; } -.setting-item-control.mod-hotkey { padding-top: 0px; cursor: default; } -.setting-item-control.mod-hotkey input { font-family: var(--font-monospace); font-size: var(--font-smaller); } -.setting-item-control.mod-hotkey input:focus { background-color: var(--interactive-accent); color: var(--text-on-accent); } -.setting-item-control select { width: inherit; max-width: 400px; } -.setting-command-hotkeys { display: flex; flex-wrap: wrap; gap: var(--size-4-1); } -.setting-hotkey { font-family: -apple-system, BlinkMacSystemFont, var(--font-monospace); font-size: var(--font-ui-small); background-color: var(--background-modifier-hover); border-radius: var(--radius-s); padding: 2px 4px 2px 8px; align-self: flex-end; white-space: nowrap; display: flex; align-items: center; gap: var(--size-4-1); } -.setting-hotkey.has-conflict { background-color: var(--background-modifier-error); color: var(--text-on-accent); } -@media (hover: hover) { - .setting-hotkey.has-conflict:hover { background-color: var(--background-modifier-error-hover); } -} -.setting-hotkey.mod-active { background-color: var(--interactive-accent); color: var(--text-on-accent); } -.setting-hotkey.mod-empty { padding-right: var(--size-4-2); } -.setting-hotkey-icon { display: flex; align-items: center; cursor: var(--cursor); border-radius: 50%; line-height: 1; text-align: center; } -.setting-hotkey-icon .svg-icon { width: 16px; height: 16px; stroke-width: 2px; opacity: 0.6; } -@media (hover: hover) { - .setting-hotkey-icon:hover .svg-icon { opacity: 1; } -} -@media (hover: hover) { - .setting-delete-hotkey:hover { background-color: var(--background-modifier-error); color: var(--text-on-accent); } -} -.setting-add-hotkey-button, .setting-restore-hotkey-button { padding: var(--size-2-2); border-radius: var(--radius-s); color: var(--text-faint); cursor: var(--cursor); height: calc(var(--icon-l) + var(--size-2-2) + var(--size-2-2)); } -.setting-add-hotkey-button.mod-active, .setting-restore-hotkey-button.mod-active { color: var(--text-accent); } -@media (hover: hover) { - .setting-add-hotkey-button:hover, .setting-restore-hotkey-button:hover { background-color: var(--background-modifier-hover); color: var(--text-normal); } -} -.setting-editor-extra-setting-button { line-height: 0; } -.setting-message { font-size: var(--font-ui-small); } -.setting-font-list { margin: 1.5em 0px 0.75em; } -.hotkey-settings-container { display: flex; flex-direction: column; } -.hotkey-settings-container .setting-item-description { padding-top: 0px; } -.hotkey-settings-container hr { margin: 20px 0px 10px; } -.hotkey-list-container { overflow: auto; } -.hotkey-header-container { justify-content: space-between; padding-bottom: var(--size-4-8); display: flex; flex-wrap: wrap; } -.hotkey-filter { align-items: center; background-color: var(--background-secondary); border-radius: var(--radius-s); display: flex; font-size: var(--font-ui-small); padding: var(--size-4-1) var(--size-4-1) var(--size-4-1) var(--size-4-2); gap: var(--size-2-1); } -.setting-filter-container { display: flex; gap: var(--size-4-2); margin-bottom: var(--size-4-8); } -.input-right-decorator { position: absolute; transform: translateY(-50%); top: 50%; right: var(--size-4-1); } -.search-input-container input:not(:placeholder-shown) ~ .input-right-decorator { right: calc(var(--size-4-1) + 28px); } -.search-input-container.mod-hotkey .clickable-icon { padding: var(--size-2-1); } -.hotkey-filter-remove-button { cursor: var(--cursor); color: var(--text-muted); padding: var(--size-2-1); border-radius: var(--radius-s); display: flex; align-items: center; --icon-size: var(--icon-xs); --icon-stroke: var(--icon-xs-stroke-width); } -@media (hover: hover) { - .hotkey-filter-remove-button:hover { background-color: var(--background-modifier-hover); } -} -.modal.mod-image-lightbox { max-width: 90vw; max-height: 90vh; padding: 0px; } -.modal.mod-image-lightbox .modal-content { padding: var(--size-4-12) var(--size-4-3) var(--size-4-2) var(--size-4-3); text-align: center; } -.login-field { max-width: 500px; margin: 1em auto; } -.spellchecker-dictionary-container { max-height: 60vh; overflow: auto; } -.spellchecker-dictionary-item { display: flex; margin-bottom: 10px; } -.spellchecker-dictionary-word { flex-grow: 1; } -.spellchecker-dictionary-remove-button { cursor: var(--cursor); color: var(--text-muted); margin-right: 10px; } -@media (hover: hover) { - .spellchecker-dictionary-remove-button:hover { color: var(--text-normal); } -} -.modal.mod-new-editor .card, .modal.mod-restricted-mode .card { flex: 1 0 0px; } -.input-right-decorator { position: absolute; transform: translateY(-50%); top: 50%; right: var(--size-4-1); } -.input-right-decorator.clickable-icon { padding: var(--size-2-1) var(--size-2-2); } -.input-right-decorator.clickable-icon.is-active { background-color: transparent; } -.search-input-container input:not(:placeholder-shown) ~ .input-right-decorator { right: calc(var(--size-4-1) + 28px); } -.search-input-container input:placeholder-shown ~ .search-input-clear-button { display: none; } -.mod-community-modal .modal-sidebar .setting-item { max-width: var(--modal-community-sidebar-width); padding: 0 var(--size-4-3) var(--size-4-1); border: none; gap: var(--size-4-2); } -.mod-community-modal .modal-sidebar .setting-item:first-child { max-width: 500px; gap: 0px; margin-bottom: var(--size-4-2); } -.mod-community-modal .modal-sidebar .setting-item-name { font-size: var(--font-ui-small); padding-left: var(--size-4-1); } -.mod-community-modal .modal-sidebar .setting-item-info { margin: 0px; flex-grow: 0; } -.mod-community-modal .modal-sidebar .search-input-container { width: 100%; } -.mod-community-modal .modal-sidebar button.clickable-icon { padding: 6px 10px; display: flex; align-items: center; color: var(--text-normal); } -.community-modal-details-empty-state { padding: 0px; text-align: center; } -.community-modal-search-summary { font-size: var(--font-ui-small); padding: var(--size-4-1) var(--size-4-3) var(--size-4-3) var(--size-4-4); } -.community-modal-search-results-wrapper { flex: 1 0 auto; overflow: auto; border-top: var(--border-width) solid var(--divider-color); scroll-padding: var(--size-4-3); contain: strict; } -.community-modal-search-results { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--size-4-3); padding: var(--size-4-3); } -.community-item { position: relative; background-color: var(--background-primary); padding: var(--size-4-3); cursor: var(--cursor); border-radius: var(--radius-m); border: 1px solid var(--background-modifier-border); display: flex; flex-direction: column; gap: var(--size-2-1); } -.community-item:last-child { margin-bottom: 0px; } -.community-item .suggestion-highlight { background-color: var(--text-highlight-bg); } -.community-item.is-selected, .community-item.is-selected:hover { border-color: var(--interactive-accent); background-color: var(--interactive-accent); color: var(--text-on-accent); } -.community-item.is-selected .community-item-author, .community-item.is-selected:hover .community-item-author, .community-item.is-selected .community-item-repo, .community-item.is-selected:hover .community-item-repo, .community-item.is-selected .community-item-downloads, .community-item.is-selected:hover .community-item-downloads, .community-item.is-selected .community-item-updated, .community-item.is-selected:hover .community-item-updated { color: var(--text-on-accent); opacity: 0.8; } -.community-item.is-selected .flair, .community-item.is-selected:hover .flair { color: var(--text-on-accent); background-color: transparent; } -@media (hover: hover) { - .community-item:hover { border-color: var(--background-modifier-border-hover); } -} -.is-mobile .community-item { max-width: 500px; } -.community-item .flair { margin-left: var(--size-4-1); background-color: var(--tag-background); color: var(--tag-color); vertical-align: middle; top: -1px; } -.community-item-name { font-size: var(--font-ui-medium); line-height: var(--line-height-tight); font-weight: var(--font-medium); } -.community-item-author { font-size: var(--font-ui-smaller); line-height: var(--line-height-tight); color: var(--text-muted); } -.community-item-downloads { font-size: var(--font-ui-smaller); color: var(--text-muted); --icon-color: var(--text-faint); --icon-size: var(--icon-xs); --icon-stroke: var(--icon-xs-stroke-width); } -.community-item-downloads svg { vertical-align: text-bottom; } -.community-item-updated { font-size: var(--font-ui-smaller); color: var(--text-muted); margin-bottom: var(--size-4-2); } -.community-item-downloads-text { margin-left: var(--size-2-2); } -.community-item-desc { font-size: var(--font-ui-small); line-height: var(--line-height-tight); margin-top: 4px; } -.community-item-badge.mod-update { --icon-size: var(--icon-xs); --icon-stroke: var(--icon-xs-stroke-width); color: var(--interactive-accent); position: absolute; top: var(--size-4-3); right: var(--size-4-3); } -.community-item-screenshot { max-width: 100%; object-fit: cover; border-radius: var(--radius-s); aspect-ratio: 16 / 9; image-rendering: -webkit-optimize-contrast; margin-top: var(--size-4-1); } -.community-item-screenshot.mod-unavailable { text-align: center; color: var(--text-muted); } -.community-item-screenshot .placeholder-icon { display: flex; align-items: center; justify-content: center; height: 100%; } -.community-item-screenshot .placeholder-icon .svg-icon { color: var(--text-faint); width: var(--size-4-8); height: var(--size-4-8); } -.community-modal-info-name { font-size: var(--h2-size); font-weight: var(--font-semibold); line-height: var(--line-height-tight); margin-bottom: var(--size-4-6); } -.community-modal-info-author, .community-modal-info-repo, .community-modal-info-version { font-size: var(--font-ui-small); line-height: var(--line-height-tight); color: var(--text-muted); } -.community-modal-info-desc { font-size: var(--font-ui-small); line-height: var(--line-height-tight); margin-top: 4px; } -.community-modal-details { flex: 1 1 calc(var(--modal-max-width) - var(--modal-community-sidebar-width)); overflow: auto; display: flex; flex-direction: column; border-left: 1px solid var(--divider-color); } -.community-modal-info { flex: 1 1 0px; overflow-y: auto; padding: var(--size-4-8) var(--size-4-16); scroll-padding: var(--size-4-4); } -.community-readme { overflow-y: visible; height: auto; padding: var(--size-4-4) 0; } -.community-readme video, .community-readme img { max-width: 100%; } -.community-modal-info-desc { font-size: var(--font-ui-medium); line-height: var(--line-height-tight); margin-top: var(--size-4-2); } -.community-modal-button-container { display: flex; flex-wrap: wrap; gap: var(--size-4-2); margin: 1.5em 0px; } -.community-modal-info-downloads { color: var(--text-muted); margin-top: var(--size-4-1); display: inline-block; --icon-size: var(--icon-xs); --icon-stroke: var(--icon-xs-stroke-width); } -.community-modal-info-downloads-text { margin-left: var(--size-4-1); position: relative; top: -1px; } -.community-modal-readme { font-size: var(--font-text-size); font-family: var(--font-text); line-height: var(--line-height-normal); overflow-wrap: break-word; color: var(--text-normal); user-select: text; } -.installed-plugins-container { padding-top: var(--size-4-4); border-top: 1px solid var(--background-modifier-border); } -.community-modal-grid-button-container { position: absolute; top: var(--size-4-4); right: var(--size-4-12); display: flex; gap: var(--size-4-2); } -.status-bar { position: var(--status-bar-position); width: auto; bottom: 0px; right: 0px; border-radius: var(--status-bar-radius); border-style: solid; border-width: var(--status-bar-border-width); border-color: var(--status-bar-border-color); background-color: var(--status-bar-background); color: var(--status-bar-text-color); display: flex; font-size: var(--status-bar-font-size); justify-content: flex-end; min-height: 18px; padding: var(--size-4-1); gap: var(--size-2-1); user-select: none; z-index: var(--layer-status-bar); font-variant-numeric: tabular-nums; } -.status-bar-item { border-radius: var(--radius-s); display: inline-flex; align-items: center; padding: 3px var(--size-2-2); line-height: 1; } -.status-bar-item.mod-clickable { cursor: var(--cursor); } -@media (hover: hover) { - .status-bar-item.mod-clickable:hover { background-color: var(--background-modifier-hover); color: var(--text-normal); } -} -.status-bar-item.plugin-editor-status, .status-bar-item.plugin-sync { padding: 0 var(--size-2-2); } -@media (hover: hover) { - .status-bar-item.plugin-editor-status:hover, .status-bar-item.plugin-sync:hover { background-color: var(--background-modifier-hover); } -} -.status-bar-item-icon { vertical-align: middle; display: flex; align-items: center; } -.status-bar-item-segment { margin-right: var(--size-4-2); } -.status-bar-item-segment:last-child { margin-right: 0px; } -.is-screenshotting .status-bar { display: none; } -.titlebar { app-region: drag; position: fixed; top: 0px; left: 0px; right: 0px; display: flex; background-color: var(--titlebar-background); border-bottom: var(--titlebar-border-width) solid var(--titlebar-border-color); } -.titlebar-inner { color: var(--titlebar-text-color); font-weight: var(--titlebar-text-weight); width: 100%; display: flex; } -.is-focused .titlebar-inner { color: var(--titlebar-text-color-focused); } -.titlebar-text { opacity: 0.85; position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; flex-grow: 1; font-size: var(--font-ui-small); text-align: center; display: flex; justify-content: center; align-items: center; padding: 0px 125px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } -.titlebar-button-container { display: flex; position: absolute; top: 0px; } -.mod-macos .titlebar-button-container { top: 8px; } -.titlebar-button-container.mod-left { left: 0px; } -.mod-macos .titlebar-button-container.mod-left { left: calc(80px / var(--zoom-factor)); } -.titlebar-button-container .mod-back, .titlebar-button-container .mod-forward { color: var(--icon-color); } -.titlebar-button-container .mod-back .svg-icon, .titlebar-button-container .mod-forward .svg-icon { width: 14px; height: 14px; stroke-width: 2.25px; } -@media (hover: hover) { - .titlebar-button-container .mod-back:hover, .titlebar-button-container .mod-forward:hover { color: var(--icon-color-hover); } -} -.titlebar-button-container.mod-right { right: 0px; } -.titlebar-button { app-region: no-drag; padding: var(--size-2-2) var(--size-2-3); cursor: var(--cursor); display: inline-flex; align-items: center; } -@media (hover: hover) { - .titlebar-button:hover { opacity: 1; background-color: var(--background-modifier-hover); } - .titlebar-button.mod-close:hover { background-color: var(--background-modifier-error); } -} -.mod-macos .titlebar-button { border-radius: var(--radius-s); } -body.is-frameless.is-hidden-frameless { padding-top: 0px !important; } -.is-hidden-frameless.mod-macos .titlebar { display: none; } -.is-hidden-frameless.mod-windows .titlebar, .is-hidden-frameless.mod-linux .titlebar { background: transparent; border: none; z-index: var(--layer-popover); pointer-events: none; } -.is-hidden-frameless.mod-windows .titlebar-button.mod-back, .is-hidden-frameless.mod-linux .titlebar-button.mod-back, .is-hidden-frameless.mod-windows .titlebar-button.mod-forward, .is-hidden-frameless.mod-linux .titlebar-button.mod-forward, .is-hidden-frameless.mod-windows .titlebar-text, .is-hidden-frameless.mod-linux .titlebar-text { display: none; } -.is-hidden-frameless.mod-windows .titlebar-button-container, .is-hidden-frameless.mod-linux .titlebar-button-container { pointer-events: auto; } -.mod-linux .titlebar-button-container, .mod-windows .titlebar-button-container { height: 100%; } -.mod-linux .titlebar-button, .mod-windows .titlebar-button { padding: 0px 16px; display: flex; align-items: center; } -.mod-linux .titlebar-button.mod-logo, .mod-windows .titlebar-button.mod-logo { padding: 4px 8px; } -@media (hover: hover) { - .mod-linux .titlebar-button.mod-close:hover, .mod-windows .titlebar-button.mod-close:hover { background-color: var(--background-modifier-error); } - .mod-linux .titlebar-button.mod-close:hover .svg-icon, .mod-windows .titlebar-button.mod-close:hover .svg-icon { fill: white; stroke: white; } -} -@media screen and (max-width: 300px) { - .titlebar-text { display: none; } -} -.is-translucent:not(.is-fullscreen) { --nav-collapse-icon-color: rgba(var(--mono-rgb-100), 0.3); --nav-collapse-icon-color-collapsed: rgba(var(--mono-rgb-100), 0.3); --divider-color: rgba(0, 0, 0, 0.15); } -.is-translucent:not(.is-fullscreen) .titlebar, .is-translucent:not(.is-fullscreen) .app-container { background-color: var(--workspace-background-translucent); } -.is-translucent:not(.is-fullscreen) .workspace-ribbon.mod-left, .is-translucent:not(.is-fullscreen) .workspace-tabs, .is-translucent:not(.is-fullscreen) .workspace-split.mod-root, .is-translucent:not(.is-fullscreen) .sidebar-toggle-button, .is-translucent:not(.is-fullscreen) .mod-left-split .workspace-tab-header-container, .is-translucent:not(.is-fullscreen) .mod-right-split .workspace-tab-header-container, .is-translucent:not(.is-fullscreen) .mod-top .workspace-tab-header-container, .is-translucent:not(.is-fullscreen) .workspace-tabs .workspace-leaf, .is-translucent:not(.is-fullscreen) .workspace-ribbon.mod-left::before { background-color: transparent !important; } -.workspace { background-color: var(--background-primary); display: flex; flex: 1 0 0px; transition: padding-left 100ms ease-in 0s; overflow: hidden; height: 100%; } -.is-translucent .workspace { background-color: transparent; } -.workspace-split { display: flex; position: relative; } -.workspace-split.mod-vertical > .workspace-split:last-child { padding-right: 0px; } -.workspace-split:last-child:not(.mod-right-split) > .workspace-leaf-resize-handle { display: none; } -.workspace-split.mod-vertical { flex-direction: row; } -.workspace-split.mod-horizontal { flex-direction: column; } -.workspace-split.mod-root { background-color: var(--background-primary); } -.workspace-leaf { display: flex; flex-direction: column; position: relative; overflow: hidden; isolation: isolate; contain: strict !important; } -.workspace-split.mod-root .workspace-leaf:last-child .workspace-leaf-resize-handle { display: none; } -.workspace-leaf.is-highlighted::before { content: " "; position: absolute; height: 100%; width: 100%; top: 0px; left: 0px; background-color: hsla(var(--interactive-accent-hsl), 0.25); z-index: var(--layer-popover); pointer-events: none; } -.workspace > .workspace-leaf, .workspace > .workspace-split { height: 100%; width: 100%; } -.workspace-split.mod-root > .workspace-leaf-resize-handle { display: none; } -.workspace-leaf-resize-handle { app-region: no-drag; position: absolute; z-index: var(--layer-cover); background-color: transparent; transition: background-color 200ms ease-in-out 0s, border-color 200ms ease-in-out 0s, opacity 200ms ease-in-out 0s; border-right-color: ; border-bottom-color: ; border-left-color: ; border-top-style: initial; border-top-color: initial; border-width: var(--divider-width); margin: 0px; } -@media (hover: hover) { - .workspace-leaf-resize-handle:hover { background-color: var(--divider-color-hover); border-color: var(--divider-color-hover); } - .is-translucent .workspace-leaf-resize-handle:hover { background-color: var(--divider-color-hover); border-color: var(--divider-color-hover); } -} -.workspace-split.mod-horizontal > * > .workspace-leaf-resize-handle { bottom: 0px; left: 0px; border-bottom-style: solid; border-bottom-width: var(--divider-width); height: var(--divider-width-hover); width: 100%; cursor: row-resize; } -.workspace-split.mod-vertical > * > .workspace-leaf-resize-handle, .workspace-split.mod-left-split > .workspace-leaf-resize-handle, .workspace-split.mod-right-split > .workspace-leaf-resize-handle { right: 0px; bottom: 0px; width: var(--divider-width-hover); height: var(--divider-vertical-height); cursor: col-resize; } -.workspace-split.mod-right-split > .workspace-leaf-resize-handle { border-left-style: solid; border-left-width: var(--divider-width); } -.workspace-split.mod-vertical > * > .workspace-leaf-resize-handle, .workspace-split.mod-left-split > .workspace-leaf-resize-handle { border-right-style: solid; border-right-width: var(--divider-width); } -.workspace-split.mod-right-split > .workspace-leaf-resize-handle { right: unset; left: 0px; } -.workspace-split.mod-vertical > * { height: 100%; flex: 1 0 0px; width: 0px; } -.workspace-split.mod-horizontal > * { width: 100%; flex: 1 0 0px; height: 0px; } -.workspace-split.mod-left-split, .workspace-split.mod-right-split { flex: 0 0 auto; } -.is-translucent .workspace-split.mod-left-split.is-sidedock-collapsed .workspace-tabs, .is-translucent .workspace-split.mod-right-split.is-sidedock-collapsed .workspace-tabs { visibility: hidden; } -.workspace-split.mod-left-split > .workspace-leaf-resize-handle, .workspace-split.mod-right-split > .workspace-leaf-resize-handle { z-index: var(--layer-status-bar); height: var(--divider-vertical-height); top: unset; bottom: 0px; } -.view-header-nav-buttons { --icon-size: var(--icon-s); align-items: center; display: flex; margin-right: var(--size-4-1); } -body.is-phone .view-header-nav-buttons { display: none; } -.workspace-leaf-content { width: 100%; height: 100%; overflow: hidden; position: relative; display: flex; flex-direction: column; } -.workspace-leaf-content .view-content { padding: var(--size-4-4); overflow: auto; } -.workspace-leaf-content[data-type="markdown"] .view-content { padding: 0px; overflow: hidden; } -.workspace-leaf-content[data-type="backlink"] .view-content, .workspace-leaf-content[data-type="outgoing-link"] .view-content { padding: 0px; overflow: hidden; display: flex; flex-direction: column; } -.workspace-leaf-content .image-container, .workspace-leaf-content .audio-container, .workspace-leaf-content .video-container { text-align: center; } -.workspace-leaf-content img:not([width]), .workspace-leaf-content audio, .workspace-leaf-content video { max-width: 100%; } -.workspace-fake-target-overlay, .workspace-drop-overlay { will-change: transform, width, height; position: fixed; left: 0px; top: 0px; width: 0px; height: 0px; transform: translate(0px, 0px); transition: all 100ms ease-in-out 0s; z-index: var(--layer-cover); pointer-events: none; } -.workspace-drop-overlay::before { content: " "; position: absolute; width: calc(100% - 6px); height: calc(100% - 6px); inset: 0px; margin: auto; background-color: var(--interactive-accent); border-radius: var(--radius-m); opacity: 0.5; } -.workspace-fake-target-container { visibility: hidden; position: absolute; pointer-events: none; top: 0px; left: 0px; } -.workspace-fake-target-overlay { visibility: visible; overflow: hidden; background-color: var(--background-primary); } -.workspace-fake-target-overlay > * { width: 100%; height: 100%; } -.workspace-tabs { overflow: hidden; display: flex; flex-direction: column; position: relative; } -.workspace-tabs > * { flex: 1 0 0px; } -.workspace-tabs .workspace-leaf { height: 100%; } -.workspace-split.mod-right-split .workspace-tabs { padding-right: 0px; } -.workspace-tabs:last-child .workspace-leaf-resize-handle { display: none; } -.workspace-fake-target-overlay:not(.is-in-sidebar) .workspace-tabs .workspace-leaf, .mod-root .workspace-tabs .workspace-leaf { background-color: var(--background-primary); } -.workspace-tabs .workspace-leaf { background-color: var(--background-secondary); } -.workspace-tabs .workspace-leaf .view-content { height: 100%; } -.workspace-tab-header-container { display: flex; background-color: var(--tab-container-background); height: var(--header-height); border-bottom: var(--tab-outline-width) solid var(--tab-outline-color); flex: 0 0 auto; padding-left: 0px; padding-right: var(--size-4-2); position: relative; } -.is-phone .workspace-tab-header-container { display: none; } -.workspace-tab-header-container-inner { display: flex; flex: 0 1 auto; overflow: auto; margin: 6px -5px calc(var(--tab-outline-width) * -1); padding: 1px 15px 0px; } -.mod-root .workspace-tab-header-container-inner { padding: 1px 15px 0px; } -.workspace-tab-header-container-inner::-webkit-scrollbar, .workspace-tab-header-container-inner::-webkit-scrollbar-thumb { display: none; } -.workspace-tab-header-inner-icon { flex: 0 0 auto; display: flex; } -.mod-root .workspace-tab-header[data-type="markdown"] .workspace-tab-header-inner-icon, .mod-root .workspace-tab-header[data-type="empty"] .workspace-tab-header-inner-icon { display: none; } -.is-focused .workspace-tab-header { color: var(--tab-text-color-focused); } -.is-focused .workspace-tab-header.is-active { color: var(--tab-text-color-focused-active); } -.is-focused .mod-active .workspace-tab-header.is-active .workspace-tab-header-inner-icon, .is-focused .mod-active .workspace-tab-header.is-active .workspace-tab-header-inner-title { color: var(--tab-text-color-focused-active-current); } -.is-focused .mod-active .workspace-tab-header.is-active.is-highlighted .workspace-tab-header-inner-icon, .is-focused .mod-active .workspace-tab-header.is-active.is-highlighted .workspace-tab-header-inner-title { color: var(--tab-text-color-focused-highlighted); } -.is-focused .workspace-tab-header.active.is-highlighted .workspace-tab-header-inner-icon, .is-focused .workspace-tab-header.is-highlighted .workspace-tab-header-inner-icon, .is-focused .workspace-tab-header.active.is-highlighted .workspace-tab-header-inner-title, .is-focused .workspace-tab-header.is-highlighted .workspace-tab-header-inner-title { color: var(--tab-text-color-focused-highlighted); } -.workspace-tab-header { app-region: no-drag; color: var(--tab-text-color); display: flex; position: relative; padding: 1px 4px 3.5px; scroll-margin-inline-start: var(--size-2-3); scroll-margin-inline-end: var(--size-4-1); text-align: center; border-radius: var(--tab-radius-active); } -.workspace-tab-header:not(.is-active):hover .workspace-tab-header-inner { background-color: var(--background-modifier-hover); } -.workspace-tab-header::before, .workspace-tab-header::after { position: absolute; bottom: 0px; content: ""; width: calc(var(--tab-curve) * 2); height: calc(var(--tab-curve) * 2); border-radius: 100%; box-shadow: 0 0 0 calc(var(--tab-curve) * 3) transparent; } -.workspace-tab-header::before { left: calc(var(--tab-curve) * -2); clip-path: inset(50% calc(var(--tab-curve) * -1) 0 50%); } -.workspace-tab-header::after { right: calc(var(--tab-curve) * -2); clip-path: inset(50% 50% 0 calc(var(--tab-curve) * -1)); } -.workspace-tab-header.is-active { box-shadow: 0 0 0 var(--tab-outline-width) var(--tab-outline-color); color: var(--tab-text-color-active); background-color: var(--tab-background-active); } -.workspace-split.mod-root .workspace-tab-header.is-active::before, .workspace-split.mod-root .workspace-tab-header.is-active::after { box-shadow: inset 0 0 0 var(--tab-outline-width) var(--tab-outline-color), 0 0 0 calc(var(--tab-curve) * 4) var(--tab-background-active); } -.workspace-tab-header.is-active .workspace-tab-header-inner::after { opacity: 0; } -.workspace-tab-container { display: flex; overflow: hidden; } -.workspace-tab-container > * { flex: 1 0 0px; } -.workspace-tab-header-inner { align-items: center; display: flex; gap: var(--size-2-1); height: 100%; border-radius: var(--tab-radius); overflow: hidden; padding: 0px 8px; width: 100%; } -.workspace-tab-header-inner .workspace-tab-header-inner-icon { color: var(--icon-color); opacity: var(--icon-opacity); } -@media (hover: hover) { - .workspace-tab-header-inner:hover .workspace-tab-header-inner-icon { color: var(--icon-color-hover); opacity: var(--icon-opacity-hover); } -} -.mod-root .workspace-tab-header-inner { padding: 0px 3px 0px 6px; } -.workspace-tab-header-inner-title { flex: 1 1 auto; font-size: var(--tab-font-size); font-weight: var(--tab-font-weight); overflow: hidden; text-align: left; text-overflow: ellipsis; white-space: nowrap; width: 100%; } -.workspace-tab-header-status-container { display: flex; flex-shrink: 0; gap: var(--size-2-1); justify-content: center; } -.workspace-tab-header-status-container:empty { display: none; } -.workspace-tab-header-status-icon, .workspace-tab-header-inner-close-button { cursor: var(--cursor); padding: var(--size-2-1); border-radius: var(--radius-s); display: flex; align-items: center; --icon-size: var(--icon-xs); --icon-stroke: var(--icon-xs-stroke-width); } -@media (hover: hover) { - .workspace-tab-header.is-active .workspace-tab-header-status-icon:hover, .workspace-tab-header.is-active .workspace-tab-header-inner-close-button:hover { background-color: var(--background-modifier-hover); } - .mod-root .workspace-tab-header.is-active .workspace-tab-header-status-icon.mod-linked:hover, .mod-root .workspace-tab-header.is-active .workspace-tab-header-inner-close-button.mod-linked:hover, .mod-root .workspace-tab-header.is-active .workspace-tab-header-status-icon.mod-pinned:hover, .mod-root .workspace-tab-header.is-active .workspace-tab-header-inner-close-button.mod-pinned:hover { background-color: var(--background-modifier-active-hover); } -} -.workspace-tab-header.is-active .workspace-tab-header-status-icon::after, .workspace-tab-header.is-active .workspace-tab-header-inner-close-button::after { background-color: transparent; } -@media (hover: hover) { - .workspace-tab-header-inner-close-button:hover { color: var(--tab-text-color-focused-active-current); } -} -.workspace-tab-header:hover .workspace-tab-header-inner-close-button { color: var(--tab-text-color-focused); } -@media (hover: hover) { - .workspace-tab-header:hover .workspace-tab-header-inner-close-button:hover { color: var(--tab-text-color-focused-active-current); } -} -.workspace-tab-header.is-active .workspace-tab-header-inner-close-button { color: var(--tab-text-color-focused); } -@media (hover: hover) { - .workspace-tab-header.is-active .workspace-tab-header-inner-close-button:hover { color: var(--tab-text-color-focused-active-current); } -} -.workspace-sidedock-empty-state { font-size: var(--font-ui-small); padding: 20px 30px; } -.workspace-tab-header.is-before-active .workspace-tab-header-inner { border-bottom-right-radius: 10px; } -.workspace-tab-header-spacer { display: flex; flex-grow: 1; } -body:not(.is-grabbing):not(.is-fullscreen) .workspace-tabs.mod-top .workspace-tab-header-spacer { app-region: drag; } -body:not(.is-grabbing):not(.is-fullscreen).is-hidden-frameless .mod-top .workspace-tab-header-container { app-region: drag; } -.workspace-tab-header-tab-list, .workspace-tab-header-new-tab { app-region: no-drag; display: none; z-index: 1; align-items: center; } -.titlebar .workspace-tab-header-tab-list, .titlebar .workspace-tab-header-new-tab, .mod-root .workspace-tab-header-tab-list, .mod-root .workspace-tab-header-new-tab { display: flex; } -.workspace-tab-header-tab-list .clickable-icon, .workspace-tab-header-new-tab .clickable-icon { color: var(--icon-color); padding: var(--size-2-2); --icon-size: var(--icon-m); --icon-stroke: var(--icon-m-stroke-width); align-items: center; } -.workspace-tab-header-new-tab { padding: var(--size-4-2) 0 var(--size-2-3); margin-right: var(--size-4-3); margin-left: -4px; } -.workspace-tab-header-tab-list { margin-right: var(--size-4-1); padding: var(--size-4-2) 0 var(--size-2-3); } -.workspace-fake-target-overlay.is-in-sidebar .workspace-tab-header-inner-title, .mod-left-split .workspace-tab-header-inner-title, .mod-right-split .workspace-tab-header-inner-title { display: var(--sidebar-tab-text-display); } -.workspace-fake-target-overlay.is-in-sidebar .workspace-tab-header-inner-close-button, .mod-left-split .workspace-tab-header-inner-close-button, .mod-right-split .workspace-tab-header-inner-close-button { display: none; } -body > .workspace-split { height: 100%; } -.mod-root .workspace-tabs > .workspace-leaf .view-header-title { white-space: normal; } -.mod-root .workspace-tab-header-status-icon { color: var(--text-accent); } -.mod-root .workspace-tab-header-status-icon, .mod-root .workspace-tab-header-inner-icon { --icon-size: var(--icon-xs); --icon-stroke: var(--icon-xs-stroke-width); } -.mod-root .mod-pinned, .mod-root .workspace-tab-header-inner-close-button { --icon-size: var(--icon-s); --icon-stroke: var(--icon-s-stroke-width); } -.mod-right-split .markdown-preview-view, .mod-left-split .markdown-preview-view, .mod-right-split .markdown-source-view.mod-cm6 .cm-scroller, .mod-left-split .markdown-source-view.mod-cm6 .cm-scroller { --file-margins: var(--size-4-5); } -.mod-right-split .markdown-preview-view, .mod-left-split .markdown-preview-view, .mod-right-split .markdown-source-view, .mod-left-split .markdown-source-view { font-size: var(--sidebar-markdown-font-size); } -.mod-left-split .workspace-tab-header-container-inner, .mod-right-split .workspace-tab-header-container-inner { padding: 1px 8px 7px; margin: 6px 0px 0px; gap: 3px; } -.mod-left-split .workspace-tab-header, .mod-right-split .workspace-tab-header { box-shadow: none; background-color: transparent; padding: 0px; margin: 0px; border-radius: var(--radius-s); } -.mod-left-split .workspace-tab-header::before, .mod-right-split .workspace-tab-header::before, .mod-left-split .workspace-tab-header::after, .mod-right-split .workspace-tab-header::after { display: none; } -.mod-left-split .workspace-tab-header:active .workspace-tab-header-inner-icon, .mod-right-split .workspace-tab-header:active .workspace-tab-header-inner-icon { color: var(--icon-color-focused); } -.mod-left-split .workspace-tab-header.has-active-menu, .mod-right-split .workspace-tab-header.has-active-menu, .mod-left-split .workspace-tab-header.is-active, .mod-right-split .workspace-tab-header.is-active { background-color: var(--background-modifier-hover); } -@media (hover: hover) { - .mod-left-split .workspace-tab-header.has-active-menu:hover, .mod-right-split .workspace-tab-header.has-active-menu:hover, .mod-left-split .workspace-tab-header.is-active:hover, .mod-right-split .workspace-tab-header.is-active:hover { background-color: var(--background-modifier-hover); } -} -.mod-left-split .workspace-tab-header.has-active-menu .workspace-tab-header-inner-icon, .mod-right-split .workspace-tab-header.has-active-menu .workspace-tab-header-inner-icon, .mod-left-split .workspace-tab-header.is-active .workspace-tab-header-inner-icon, .mod-right-split .workspace-tab-header.is-active .workspace-tab-header-inner-icon { opacity: var(--icon-opacity-active); color: var(--icon-color-focused); } -.workspace .mod-root .workspace-tab-header { app-region: no-drag; flex: 1 1 0px; width: var(--tab-width); min-width: 0px; max-width: var(--tab-max-width); padding: 1px 3px 3.5px; } -.workspace .mod-root .workspace-tab-header .workspace-tab-header-status-container { position: sticky; right: 0px; } -.workspace .mod-root .workspace-tab-header .workspace-tab-header-inner-close-button { position: sticky; right: 0px; } -.workspace .mod-root .workspace-tab-header.is-active:hover .workspace-tab-header-inner-close-button, .workspace .mod-root .workspace-tab-header.is-active .workspace-tab-header-inner-close-button { pointer-events: all; opacity: 1; } -.workspace .mod-root .workspace-tab-header.is-active:hover .workspace-tab-header-inner-close-button svg, .workspace .mod-root .workspace-tab-header.is-active .workspace-tab-header-inner-close-button svg { opacity: 1; } -.workspace .mod-root .workspace-tab-header.is-active .workspace-tab-header-inner-close-button::after { background-color: transparent; } -.workspace .mod-root .workspace-tab-header-inner::after { position: absolute; right: -0.5px; width: 1px; background-color: var(--tab-divider-color); content: ""; height: 20px; } -.workspace .mod-root .workspace-tab-header-inner-icon { display: flex; padding-right: 4px; } -.workspace .mod-root .workspace-tab-header[data-type="markdown"] .workspace-tab-header-inner-icon, .workspace .mod-root .workspace-tab-header[data-type="empty"] .workspace-tab-header-inner-icon { display: none; } -.workspace .mod-root .workspace-tab-header-inner-title { text-overflow: ellipsis; width: 100%; } -.workspace .mod-root .workspace-tab-header-status-container.mod-linked { display: none; } -.workspace .mod-root .workspace-tab-header-spacer { flex-shrink: 1; } -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-header-container-inner { padding: 0 0 0 var(--size-4-3); margin: 0px; } -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container { overflow: auto hidden; position: relative; display: flex; flex-direction: row; } -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container > * { flex: 0 0 auto; position: sticky; } -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-tab-header { width: var(--tab-stacked-header-width); writing-mode: var(--tab-stacked-text-writing-mode); text-orientation: sideways; background-color: var(--background-primary); padding: 0px; border-radius: 0px; box-shadow: -1px 0 0 0 var(--tab-outline-color), var(--tab-stacked-shadow); --no-tooltip: true; } -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-tab-header::before, .workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-tab-header::after { display: none; } -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-tab-header:hover .workspace-tab-header-inner { background-color: transparent; } -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-tab-header-inner { padding: var(--size-4-2) var(--size-4-2) var(--size-4-4); border-radius: 0px; } -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-tab-header-inner::after { display: none; } -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-tab-header-inner-title { order: 3; width: auto; -webkit-mask-image: unset; padding: var(--size-4-1) 0; transform: var(--tab-stacked-text-transform); text-align: var(--tab-stacked-text-align); font-weight: var(--tab-stacked-font-weight); font-size: var(--tab-stacked-font-size); text-orientation: mixed; } -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-tab-header-inner-icon { order: 2; cursor: grab; display: flex; padding: var(--size-2-2); border-radius: var(--radius-s); } -@media (hover: hover) { - .workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-tab-header-inner-icon:hover { background-color: var(--background-modifier-hover); } -} -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-tab-header-inner-icon:active { cursor: grabbing; } -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-tab-header-inner-close-button { color: var(--tab-text-color-focused); } -@media (hover: hover) { - .workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-tab-header-inner-close-button:hover { background-color: var(--background-modifier-hover); } -} -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-leaf { width: var(--tab-stacked-pane-width); contain: strict; } -.workspace .mod-root .workspace-tabs.mod-stacked .workspace-tab-container .workspace-leaf.is-hidden > * { display: none; } -.sidebar-toggle-button { height: calc(var(--header-height) - 1px); display: flex; justify-content: center; padding: var(--size-4-2) 0 7px 0; app-region: no-drag; --icon-size: var(--icon-l); --icon-stroke: var(--icon-l-stroke-width); } -.mod-macos.is-hidden-frameless:not(.is-popout-window) .sidebar-toggle-button.mod-right { background-color: var(--tab-container-background); position: fixed; top: 0px; right: 0px; padding-right: var(--size-4-2); z-index: var(--layer-popover); } -.mod-macos.is-hidden-frameless:not(.is-popout-window) .workspace .workspace-tabs.mod-top-right-space .workspace-tab-header-container { padding-right: 38px; } -.button-container { margin-top: 20px; } -button { app-region: no-drag; display: inline-flex; align-items: center; justify-content: center; color: var(--text-normal); font-size: var(--font-ui-small); border-radius: var(--button-radius); border: 0px; padding: var(--size-4-1) var(--size-4-3); height: var(--input-height); font-weight: var(--input-font-weight); cursor: var(--cursor); font-family: inherit; outline: none; user-select: none; white-space: nowrap; } -button:not(.clickable-icon) { background-color: var(--interactive-normal); box-shadow: var(--input-shadow); } -@media (hover: hover) { - button:hover { background-color: var(--interactive-hover); box-shadow: var(--input-shadow-hover); } -} -button[aria-disabled="true"] { background-color: var(--interactive-normal); } -button:focus-visible { box-shadow: 0 0 0 3px var(--background-modifier-border-focus); } -button[disabled="true"] { cursor: not-allowed; } -button.mod-cta { background-color: var(--interactive-accent); color: var(--text-on-accent); } -@media (hover: hover) { - button.mod-cta:hover { background-color: var(--interactive-accent-hover); } -} -button.mod-cta:focus-visible { box-shadow: 0 0 0 3px var(--background-modifier-border-focus); } -button.mod-muted { background-color: var(--background-secondary); color: var(--text-muted); } -@media (hover: hover) { - button.mod-muted:hover { background-color: var(--background-secondary); } -} -button.mod-warning { background-color: var(--background-modifier-error); color: var(--text-on-accent); } -@media (hover: hover) { - button.mod-warning:hover { background-color: var(--background-modifier-error-hover); } -} -button.mod-destructive { color: var(--background-modifier-error); } -.icon-button-group { display: inline-block; } -.icon-button { display: inline-block; color: var(--interactive-normal); } -.rich-button { width: auto; padding-top: 5px; } -.rich-button-icon { position: relative; top: 6px; } -.horizontal-preference-group { display: flex; } -.horizontal-preference-group button { border-radius: 0px; margin: 0px -1px; } -.horizontal-preference-group button:first-child { border-top-left-radius: var(--input-radius); border-bottom-left-radius: var(--input-radius); } -.horizontal-preference-group button:last-child { border-top-right-radius: var(--input-radius); border-bottom-right-radius: var(--input-radius); } -.horizontal-preference-group button.is-selected { background-color: var(--interactive-accent); color: var(--text-on-accent); } -@media (hover: hover) { - .horizontal-preference-group button.is-selected:hover { background-color: var(--interactive-accent-hover); } -} -.card-container { display: flex; } -.card-container.mod-horizontal { flex-direction: column; } -.card { background-color: var(--background-secondary-alt); border-radius: 4px; border: 1px solid var(--background-modifier-border); margin: 0px 10px; padding: 15px 30px; display: flex; flex-direction: column; flex-grow: 1; } -.card ul { padding: 0px; } -.card .button-container { margin: 10px 0px; } -.card-container.mod-horizontal .card { margin: 10px 0px; } -.card-container.mod-horizontal .card ul { padding-left: 24px; } -.card li { margin: 5px 0px; } -.card.u-clickable { cursor: var(--cursor); } -@media (hover: hover) { - .card.u-clickable:hover { border: 1px solid var(--interactive-accent); background-color: hsla(var(--interactive-accent-hsl), 0.1); } -} -.card.is-selected { border: 1px solid var(--interactive-accent); background-color: hsla(var(--interactive-accent-hsl), 0.2); } -.card-title { text-align: center; font-size: 20px; line-height: 30px; color: var(--text-muted); margin-bottom: 8px; } -.card-description { color: var(--text-muted); font-size: var(--font-ui-small); line-height: 20px; flex-grow: 1; } -.changelog-item { margin: var(--size-4-2) 0; font-size: var(--font-ui-medium); line-height: var(--line-height); } -.changelog-item::before { content: attr(data-label); width: 50px; border-radius: var(--radius-m); font-size: var(--font-ui-small); display: inline-block; text-align: center; margin-right: 14px; text-transform: uppercase; letter-spacing: 1px; line-height: 22px; } -.changelog-item.mod-success::before { background-color: var(--background-modifier-success); } -.changelog-item.mod-highlighted::before { background-color: var(--interactive-accent); } -.page-container { width: 50vw; max-width: 1000px; margin: 0px auto; padding: 50px 0px; background-color: var(--background-primary); } -.page-title { font-weight: var(--font-extrabold); font-size: 46px; } -[contenteditable] { outline: none; } -.rich-link { color: var(--text-accent); position: relative; padding-left: 30px; } -.rich-link-icon { position: absolute; left: 5px; top: 3px; } -.horizontal-link-group { text-align: center; } -.horizontal-link-group a, .horizontal-link-group span { margin: 0px 10px; } -.footer-link-group { list-style: none; display: inline-block; margin: 0px 30px; padding: 0px; } -.footer-header { font-size: 22px; line-height: 30px; margin-bottom: 10px; } -.footer-link { margin: 4px 0px; } -.components-container .menu { position: relative; display: inline-block; } -.list-item { display: flex; padding: 0px; margin: 8px 0px; gap: var(--size-4-2); align-items: center; } -.list-item-part.mod-extended { flex-grow: 1; overflow-wrap: anywhere; } -.list-item-part.clickable-icon { display: flex; align-items: center; justify-content: center; padding: var(--size-2-2); cursor: var(--cursor); border-radius: var(--radius-s); color: var(--icon-color); } -.list-item-part.clickable-icon:hover, .list-item-part.clickable-icon:active { color: var(--icon-color-hover); background-color: var(--background-modifier-hover); } -.lightbox { display: none; position: fixed; z-index: 999; width: 100%; height: 100%; text-align: center; top: 0px; left: 0px; background: rgba(0, 0, 0, 0.8); } -.lightbox img { max-width: 90vw; max-height: 90vh; margin-top: 5vh; } -.lightbox:target { display: block; } -.u-center-text { text-align: center; } -.u-faded-text { color: var(--text-muted); } -.u-pop { color: var(--text-accent); font-weight: var(--font-semibold); } -.u-muted { color: var(--text-muted); } -.u-small { font-size: 0.8em; } -.u-clickable { cursor: var(--cursor); } -.u-pop-bg { background-color: var(--interactive-accent); color: var(--text-on-accent); display: inline-block; padding: 3px 16px; border-radius: 20px; opacity: 0.6; cursor: default; } -@media (hover: hover) { - .u-pop-bg:hover { opacity: 1; } -} -.components-container h3 { font-weight: var(--font-semibold); font-size: 30px; margin: 60px 0px 25px; } -.components-container .vertical-tabs-container { height: 300px; } -.components-container .checkbox-demo { margin: 10px 0px; } -.components-container .checkbox-demo label { display: inline-block; width: 300px; } -.components-container .prompt { position: static; } -.diff-view { height: 100%; overflow: auto; user-select: text; } -.diff-line { padding: 0 var(--size-4-2); } -.diff-line.mod-left { background-color: rgba(var(--background-modifier-error-rgb), 0.2); } -.diff-line.mod-left .diff-changed { background-color: rgba(var(--background-modifier-error-rgb), 0.4); } -.diff-line.mod-right { background-color: rgba(var(--background-modifier-success-rgb), 0.2); } -.diff-line.mod-right .diff-changed { background-color: rgba(var(--background-modifier-success-rgb), 0.4); } -.diff-collapsed { text-align: center; color: var(--text-muted); cursor: pointer; font-size: var(--font-ui-small); margin: var(--size-4-2) 0; } -.diff-collapsed:hover { color: var(--text-accent); } -.markdown-reading-view.is-searching, .markdown-source-view.is-replacing, .markdown-source-view.is-searching { flex-direction: column-reverse; } -.mod-active .document-search-container { background-color: var(--background-primary); } -.document-search-container { display: flex; flex-direction: column; padding: var(--size-4-2) 0; margin: 0 var(--size-4-4); gap: var(--size-4-2); z-index: var(--layer-popover); } -.document-search, .document-replace { width: 100%; max-width: var(--file-line-width); margin: 0px auto; display: flex; padding: 0 var(--size-4-2); gap: var(--size-4-2); } -.document-replace { display: none; } -.document-search-container.mod-replace-mode .document-replace { display: flex; } -input.document-search-input, input.document-replace-input { flex-grow: 1; } -input.document-search-input.mod-no-match, input.document-replace-input.mod-no-match { background-color: rgba(var(--background-modifier-error-rgb), 0.2); } -@media (hover: hover) { - input.document-search-input.mod-no-match:hover, input.document-replace-input.mod-no-match:hover { background-color: rgba(var(--background-modifier-error-rgb), 0.2); } -} -.document-replace-buttons, .document-search-buttons { display: flex; gap: var(--size-4-2); align-items: center; } -.document-search-button { font-size: var(--font-ui-small); padding: 0 var(--size-4-2); color: var(--text-muted); } -.document-search-close-button { cursor: var(--cursor); position: relative; top: 2px; font-size: 24px; line-height: 20px; height: 24px; width: 24px; padding: 0 var(--size-2-2); border-radius: var(--radius-s); color: var(--text-muted); } -.document-search-close-button::before { font-family: Inter, sans-serif; content: "×"; font-weight: 300; } -@media (hover: hover) { - .document-search-close-button:hover { background-color: var(--background-modifier-hover); color: var(--text-normal); } -} -.markdown-rendered .search-highlight > div { position: absolute; pointer-events: none; box-shadow: 0 0 0px 2px var(--text-normal); opacity: 0.3; mix-blend-mode: var(--highlight-mix-blend-mode); border-radius: 2px; } -.markdown-rendered .search-highlight > div.is-active { box-shadow: 0 0 0px 3px var(--text-accent); opacity: 1; } -.markdown-source-view.mod-cm5 { position: relative; padding-left: 20px; padding-right: 30px; } -.workspace-leaf-content.is-read-mode .markdown-source-view.mod-cm5 { z-index: 0; } -.markdown-source-view.mod-cm5 .document-search-container { position: absolute; top: 0px; left: 0px; width: 100%; z-index: 5; } -.markdown-source-view.mod-cm6 .document-search-container { flex: 0 0 auto; } -[dir="rtl"] .dropdown, :root:lang(ar) .dropdown, :root:lang(iw) .dropdown { background-position: left 0.7em top 50%, 0px 0px; padding: 0.6em 0.8em 0.5em 1.4em; } -select, .dropdown { app-region: no-drag; height: var(--input-height); font-size: var(--font-ui-small); font-family: inherit; font-weight: var(--input-font-weight); color: var(--text-normal); line-height: var(--line-height-tight); padding: 0px 1.9em 0px 0.8em; max-width: 100%; box-sizing: border-box; margin: 0px; border: 0px; box-shadow: var(--input-shadow); border-radius: var(--input-radius); appearance: none; background-color: var(--interactive-normal); background-repeat: no-repeat, repeat; background-position: right 0.7em top 50%, 0px 0px; background-size: 0.65em, 100%; } -@media (hover: hover) { - select:hover, .dropdown:hover { box-shadow: var(--input-shadow-hover); background-color: var(--interactive-hover); } -} -select:focus, .dropdown:focus { box-shadow: 0 0 0px 3px var(--background-modifier-border-focus); outline: none; } -.dropdown { background-image: url("data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"292.4\" height=\"292.4\"%3E%3Cpath fill=\"%23000\" opacity=\"0.4\" d=\"M287 69.4a17.6 17.6 0 0 0-13-5.4H18.4c-5 0-9.3 1.8-12.9 5.4A17.6 17.6 0 0 0 0 82.2c0 5 1.8 9.3 5.4 12.9l128 127.9c3.6 3.6 7.8 5.4 12.8 5.4s9.2-1.8 12.8-5.4L287 95c3.5-3.5 5.4-7.8 5.4-12.8 0-5-1.9-9.2-5.5-12.8z\"/%3E%3C/svg%3E"); } -.theme-dark .dropdown { background-image: url("data:image/svg+xml,%3Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"292.4\" height=\"292.4\"%3E%3Cpath fill=\"%23FFF\" opacity=\"0.4\" d=\"M287 69.4a17.6 17.6 0 0 0-13-5.4H18.4c-5 0-9.3 1.8-12.9 5.4A17.6 17.6 0 0 0 0 82.2c0 5 1.8 9.3 5.4 12.9l128 127.9c3.6 3.6 7.8 5.4 12.8 5.4s9.2-1.8 12.8-5.4L287 95c3.5-3.5 5.4-7.8 5.4-12.8 0-5-1.9-9.2-5.5-12.8z\"/%3E%3C/svg%3E"); } -.dropdown option { font-weight: normal; background-color: var(--background-primary); } -.flair { background-color: var(--interactive-normal); border-radius: var(--radius-s); color: var(--text-normal); font-size: 10px; letter-spacing: 0.05em; margin-left: var(--size-4-2); padding: var(--size-2-1) var(--size-2-2); position: relative; text-transform: uppercase; white-space: nowrap; vertical-align: middle; } -.flair.mod-flat { vertical-align: top; } -.flair.mod-pop { background-color: var(--interactive-accent); color: var(--text-on-accent); } -.markdown-preview-view:not(.allow-fold-lists) .list-collapse-indicator, .markdown-preview-view:not(.allow-fold-headings) .heading-collapse-indicator { display: none; } -h1:hover .collapse-indicator, h2:hover .collapse-indicator, h3:hover .collapse-indicator, h4:hover .collapse-indicator, h5:hover .collapse-indicator, h6:hover .collapse-indicator, .collapse-indicator:hover, .is-collapsed .collapse-indicator, .cm-fold-indicator.is-collapsed .collapse-indicator, .cm-gutterElement:hover .collapse-indicator, .cm-gutterElement .is-collapsed .collapse-indicator, .cm-line:hover .cm-fold-indicator .collapse-indicator, .fold-gutter.is-collapsed, .fold-gutter:hover { opacity: 1; } -.collapse-icon { display: flex; align-items: center; } -.collapse-icon::before { content: "​"; } -.collapse-icon svg.svg-icon { color: var(--nav-collapse-icon-color); stroke-width: 4px; width: 10px; height: 10px; transition: transform 100ms ease-in-out 0s; } -.collapse-icon.is-collapsed svg.svg-icon { transform: rotate(-90deg); } -.rtl .collapse-icon.is-collapsed svg.svg-icon { transform: rotate(90deg); } -.view-content .list-collapse-indicator svg.svg-icon, .view-content .collapse-indicator svg.svg-icon { color: var(--collapse-icon-color); } -.view-content .is-collapsed .list-collapse-indicator svg.svg-icon, .view-content .is-collapsed .collapse-indicator svg.svg-icon { color: var(--collapse-icon-color-collapsed); } -.markdown-preview-view .collapse-indicator { float: left; cursor: var(--cursor); } -.markdown-preview-view .collapse-indicator .svg-icon { vertical-align: middle; } -.markdown-preview-view li.is-collapsed > ul, .markdown-preview-view li.is-collapsed > ol { display: none; } -.markdown-preview-view .heading-collapse-indicator { margin-left: -22px; padding: 0px 6px; } -.markdown-source-view.mod-cm6 .cm-fold-indicator .collapse-indicator { opacity: 0; } -.markdown-source-view.mod-cm6 .cm-line:hover .cm-fold-indicator .collapse-indicator, .markdown-source-view.mod-cm6 .cm-fold-indicator.is-collapsed .collapse-indicator { opacity: 1; } -.markdown-source-view.mod-cm6 .cm-foldPlaceholder { color: var(--text-faint); background-color: transparent; border: none; margin-left: 8px; } -.markdown-source-view.mod-cm6 .cm-fold-indicator { display: inline-block; position: relative; z-index: 1; } -.markdown-source-view.mod-cm6 .cm-fold-indicator .collapse-indicator { position: absolute; top: 0px; right: 0px; height: 100%; cursor: var(--cursor); padding-right: 5px; } -svg.svg-icon { height: var(--icon-size); width: var(--icon-size); stroke-width: var(--icon-stroke); } -.nav-buttons-container, .view-actions, .workspace-tab-header-inner, .side-dock-settings, .side-dock-actions { display: flex; justify-content: center; } -.side-dock-settings, .side-dock-actions { gap: var(--size-2-3); } -.view-actions { gap: 0px; align-items: center; --icon-size: var(--icon-s); } -.nav-file-icon .svg-icon, .suggestion-flair .svg-icon, .menu-item-icon .svg-icon, .status-bar-item .svg-icon { --icon-size: var(--icon-s); --icon-stroke: var(--icon-s-stroke-width); } -.clickable-icon.side-dock-ribbon-action .svg-icon, .mod-left-split .workspace-tab-header-inner-icon .svg-icon, .mod-right-split .workspace-tab-header-inner-icon .svg-icon { --icon-size: var(--icon-l); --icon-stroke: var(--icon-l-stroke-width); } -.clickable-icon.side-dock-ribbon-action:active, .mod-left-split .workspace-tab-header-inner-icon:active, .mod-right-split .workspace-tab-header-inner-icon:active { color: var(--icon-color-focused); } -.clickable-icon { app-region: no-drag; background-color: transparent; display: flex; align-items: center; justify-content: center; padding: var(--size-2-2) var(--size-2-3); cursor: var(--cursor); border-radius: var(--clickable-icon-radius); color: var(--icon-color); opacity: var(--icon-opacity); transition: opacity 0.15s ease-in-out 0s; height: auto; } -@media (hover: hover) { - .clickable-icon:hover { box-shadow: none; opacity: var(--icon-opacity-hover); color: var(--icon-color-hover); background-color: var(--background-modifier-hover); } - .clickable-icon.has-active-menu, .clickable-icon:active { opacity: var(--icon-opacity-hover); color: var(--icon-color-focused); background-color: var(--background-modifier-hover); } -} -.clickable-icon.is-active { opacity: var(--icon-opacity-hover); color: var(--icon-color-active); background-color: var(--background-modifier-active-hover); } -@media (hover: hover) { - .clickable-icon.is-active:hover { background-color: var(--background-modifier-active-hover); } -} -.clickable-icon[aria-disabled="true"] { background-color: unset; color: var(--text-muted); opacity: 0.4; } -@media (hover: hover) { - .clickable-icon[aria-disabled="true"]:hover { background-color: unset; } -} -.clickable-icon.mod-warning { color: var(--text-error); } -.setting-item-control .clickable-icon { padding: var(--size-2-2); } -.markdown-rendered.show-indentation-guide li > ul, .markdown-rendered.show-indentation-guide li > ol { position: relative; } -.markdown-rendered.show-indentation-guide li > ul::before, .markdown-rendered.show-indentation-guide li > ol::before { content: "​"; position: absolute; display: block; left: -1em; top: 0px; bottom: 0px; border-right: var(--indentation-guide-width) solid var(--indentation-guide-color); } -.markdown-source-view.mod-cm6 .cm-indent { display: inline-block; } -.markdown-source-view.mod-cm6 .cm-indent::before { content: "​"; display: block; width: 1px; border-right: var(--indentation-guide-width) solid var(--indentation-guide-color); color: transparent; position: absolute; top: 0px; bottom: 0px; transform: translateX(0.15em); } -.markdown-source-view.mod-cm6 .cm-active-indent::before { border-color: var(--indentation-guide-color-active); } -.input-label { display: inline-block; width: 150px; text-align: right; margin-right: var(--size-4-2); } -.input-button { padding: 6px 14px; margin-left: 14px; color: var(--text-muted); font-size: var(--font-ui-medium); position: relative; top: -1px; } -@media (hover: hover) { - .input-button:hover { color: var(--text-normal); } -} -textarea, input[type="text"], input[type="search"], input[type="email"], input[type="password"], input[type="number"] { app-region: no-drag; background: var(--background-modifier-form-field); border: var(--input-border-width) solid var(--background-modifier-border); color: var(--text-normal); font-family: inherit; padding: var(--size-4-1) var(--size-4-2); font-size: var(--font-ui-small); border-radius: var(--input-radius); outline: none; } -@media (hover: hover) { - textarea:hover, input[type="text"]:hover, input[type="search"]:hover, input[type="email"]:hover, input[type="password"]:hover, input[type="number"]:hover { border-color: var(--background-modifier-border-hover); transition: box-shadow 0.15s ease-in-out 0s, border 0.15s ease-in-out 0s; } -} -textarea:active, input[type="text"]:active, input[type="search"]:active, input[type="email"]:active, input[type="password"]:active, input[type="number"]:active, textarea:focus, input[type="text"]:focus, input[type="search"]:focus, input[type="email"]:focus, input[type="password"]:focus, input[type="number"]:focus { border-color: var(--background-modifier-border-focus); transition: box-shadow 0.15s ease-in-out 0s, border 0.15s ease-in-out 0s; } -textarea:active, input[type="text"]:active, input[type="search"]:active, input[type="email"]:active, input[type="password"]:active, input[type="number"]:active, textarea:focus, input[type="text"]:focus, input[type="search"]:focus, input[type="email"]:focus, input[type="password"]:focus, input[type="number"]:focus, textarea:focus-visible, input[type="text"]:focus-visible, input[type="search"]:focus-visible, input[type="email"]:focus-visible, input[type="password"]:focus-visible, input[type="number"]:focus-visible { box-shadow: 0 0 0 2px var(--background-modifier-border-focus); } -textarea::placeholder, input[type="text"]::placeholder, input[type="search"]::placeholder, input[type="email"]::placeholder, input[type="password"]::placeholder, input[type="number"]::placeholder { color: var(--text-faint); } -input[type="text"], input[type="search"], input[type="email"], input[type="password"], input[type="number"] { height: var(--input-height); } -textarea { line-height: var(--line-height-tight); } -input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button { display: none; pointer-events: none; } -input[type="number"]::-webkit-inner-spin-button { appearance: none; } -input[type="range"] { width: 100px; appearance: none; background-color: var(--slider-track-background); border-radius: var(--slider-track-height); height: var(--slider-track-height); padding: 0px; } -body:not(.is-mobile) input[type="range"]:focus { box-shadow: none; } -input[type="range"]::-webkit-slider-runnable-track { height: 6px; appearance: none; } -input[type="range"]::-webkit-slider-thumb { appearance: none; height: var(--slider-thumb-height); width: var(--slider-thumb-width); border-radius: var(--slider-thumb-radius); cursor: default; background: rgb(255, 255, 255); border: var(--slider-thumb-border-width) solid var(--slider-thumb-border-color); position: relative; top: var(--slider-thumb-y); transition: all 0.1s linear 0s; box-shadow: rgba(0, 0, 0, 0.05) 0px 1px 1px 0px, rgba(0, 0, 0, 0.1) 0px 2px 2px 0px; } -input[type="range"]::-webkit-slider-thumb:hover, input[type="range"]::-webkit-slider-thumb:active { background: white; border-color: var(--background-modifier-border-focus); box-shadow: rgba(0, 0, 0, 0.1) 0px 1px 2px 0px, rgba(0, 0, 0, 0.2) 0px 2px 3px 0px; transition: all 0.1s linear 0s; } -input[type="range"] { outline: none; } -body:not(.is-mobile) input[type="range"]:focus::-webkit-slider-thumb { box-shadow: rgba(0, 0, 0, 0.05) 0px 1px 2px 0px, rgba(0, 0, 0, 0.2) 0px 2px 3px 0px; } -body:not(.is-mobile) input[type="range"]:focus-visible::-webkit-slider-thumb { border-color: var(--background-modifier-border-focus); box-shadow: 0 1px 2px 0px rgba(0, 0, 0, 0.05), 0 2px 3px 0px rgba(0, 0, 0, 0.2), 0 0 0px 2px var(--background-modifier-border-focus); } -input[type="color"] { appearance: none; width: calc(var(--swatch-width) + 4px); background-color: transparent; border: none; cursor: var(--cursor); padding: 0px; } -input[type="color"]::-webkit-color-swatch-wrapper { padding: 2px; } -input[type="color"]::-webkit-color-swatch { border: 0px; box-shadow: var(--swatch-shadow); border-radius: var(--swatch-radius); height: var(--swatch-height); width: var(--swatch-width); align-self: center; } -@media (hover: hover) { - input[type="color"]::-webkit-color-swatch:hover { box-shadow: inset 0 0 0 1px rgba(var(--mono-rgb-100), 0.25), 0 0 0 3px var(--background-modifier-border-hover); } -} -input[type="color"]:focus-visible::-webkit-color-swatch, input[type="color"]:focus::-webkit-color-swatch { box-shadow: var(--swatch-shadow), 0 0 0 3px var(--background-modifier-border-focus); } -select.mod-hidden { display: none; } -.notice-container { z-index: var(--layer-notice); position: fixed; top: 22px; right: 0px; padding: 10px; overflow: hidden; } -.notice { background-color: var(--background-modifier-message); border-radius: var(--radius-m); box-shadow: 0 2px 8px var(--background-modifier-box-shadow); color: rgb(250, 250, 250); font-size: var(--font-ui-small); line-height: var(--line-height-tight); padding: 0.75em 1em; max-width: 300px; margin-bottom: 14px; white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; cursor: var(--cursor); } -.menu { app-region: no-drag; padding: var(--size-2-3); border: 1px solid var(--background-modifier-border-hover); background-color: var(--background-secondary); border-radius: var(--radius-m); box-shadow: var(--shadow-s); position: fixed; z-index: var(--layer-menu); user-select: none; max-height: calc(100% - var(--header-height)); overflow: hidden; } -.menu.mod-no-icon .menu-item-icon:first-child { display: none; } -.menu-separator { height: 0px; margin: var(--size-2-3) calc(var(--size-2-3) * -1); border-bottom: 1px solid var(--background-modifier-border); } -.menu-separator:last-child, .menu-separator:first-child { display: none; } -.menu-separator + .menu-separator { display: none; } -.menu-item { display: flex; align-items: center; gap: var(--size-4-2); padding: var(--size-4-1) var(--size-4-2); cursor: var(--cursor); font-size: var(--font-ui-small); border-radius: var(--radius-s); white-space: nowrap; } -.menu-item.is-disabled { cursor: default; color: var(--text-faint); } -.menu-item.is-warning.selected { color: var(--text-error); } -.menu-item.is-label { cursor: default; pointer-events: none; font-size: var(--font-ui-medium); color: var(--text-muted); white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; } -@media (hover: hover) { - .menu-item.is-warning:hover { color: var(--text-error); } - .menu-item:hover:not(.is-disabled):not(.is-label) { background-color: var(--background-modifier-hover); } -} -.menu-item.selected:not(.is-disabled):not(.is-label) { background-color: var(--background-modifier-hover); } -.menu-item-icon { flex: 0 1 auto; display: flex; color: var(--text-muted); } -.menu-item.is-warning.selected .menu-item-icon, .menu-item.is-warning:hover .menu-item-icon { color: var(--text-error); } -.menu-item.is-disabled .menu-item-icon { color: var(--text-faint); } -.menu-item-icon .mod-submenu { color: var(--text-faint); } -.menu-item-title { flex: 1 0 0px; } -.menu.mod-tab-list .menu-item-title { max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; } -.debug-textarea { width: 100%; height: 50vh; max-height: 80vh; font-family: var(--font-monospace); tab-size: 4; resize: none; } -.modal-container { display: flex; align-items: center; justify-content: center; position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; z-index: var(--layer-modal); } -.modal-container.mod-dim .modal { box-shadow: var(--shadow-l); } -.modal-bg { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; background-color: var(--background-modifier-cover); } -.modal { --checkbox-size: var(--font-ui-medium); background-color: var(--modal-background); border-radius: var(--modal-radius); border: var(--modal-border-width) solid var(--modal-border-color); padding: var(--size-4-4); position: relative; min-height: 100px; width: var(--dialog-width); max-width: var(--dialog-max-width); max-height: var(--dialog-max-height); display: flex; flex-direction: column; overflow: auto; } -.modal.mod-sidebar-layout { padding: 0px; width: var(--modal-width); height: var(--modal-height); max-width: var(--modal-max-width); max-height: var(--modal-max-height); overflow: hidden; display: flex; flex-direction: column; } -.modal.mod-sidebar-layout .modal-content { display: flex; } -.modal.mod-scrollable-content { padding: 0px; overflow: hidden; } -.modal.mod-scrollable-content .modal-title { padding: var(--size-4-4) var(--size-4-4) 0 var(--size-4-4); } -.modal.mod-scrollable-content .modal-content { padding: 0 var(--size-4-4) var(--size-4-4) var(--size-4-4); overflow: auto; } -.modal-sidebar { background-color: var(--background-secondary); flex: 1 1 var(--modal-community-sidebar-width); min-width: var(--modal-community-sidebar-width); padding: var(--size-4-3) 0 0 0; display: flex; flex-direction: column; } -body:not(.native-scrollbars) .modal-close-button { right: 12px; } -.modal-close-button { cursor: var(--cursor); position: absolute; top: var(--size-2-3); right: var(--size-2-3); font-size: 24px; line-height: 20px; height: 24px; width: 24px; padding: 0 var(--size-2-2); border-radius: var(--radius-s); color: var(--text-muted); } -@media (hover: hover) { - .modal-close-button:hover { background-color: var(--background-modifier-hover); color: var(--text-normal); } -} -.modal-close-button::before { font-family: Inter, sans-serif; content: "×"; font-weight: 300; } -.modal-title { font-size: 1.2em; margin-bottom: 0.75em; font-weight: var(--font-semibold); text-align: left; line-height: var(--line-height-tight); } -.mod-sidebar-layout .modal-title { display: none; } -.modal-title:empty { display: none; } -.modal-content { flex: 1 1 auto; font-size: var(--font-ui-medium); } -.modal-button-container { margin-top: 1.5em; display: flex; justify-content: flex-end; gap: var(--size-4-2); flex-wrap: wrap; font-size: var(--font-ui-medium); } -.modal-button-container .mod-checkbox { flex-grow: 1; display: flex; align-items: center; gap: var(--size-4-1); } -.modal-button-container .mod-secondary { margin-right: auto; } -.modal.mod-scrollable-content > .modal-button-container { margin-top: 0px; border-top: 1px solid var(--background-modifier-border); padding: var(--size-4-4); } -.modal-checkbox-label { cursor: var(--cursor); margin-left: 10px; user-select: none; } -.message-container { margin: var(--size-4-4) 0; } -.message { display: inline-block; padding: 6px 12px; border-radius: var(--radius-s); } -.message.mod-success { background-color: var(--background-modifier-success); color: var(--text-on-accent); } -.message.mod-success a { color: var(--text-normal); } -.message.mod-info { background-color: var(--background-modifier-info); } -.message.mod-error { background-color: var(--background-modifier-error); color: var(--text-on-accent); } -.message.mod-error a { color: var(--text-normal); } -.mod-warning { color: var(--text-error); } -.mod-success { color: var(--text-success); } -.mod-file-rename .rename-textarea { overflow: hidden; padding: var(--size-2-3) var(--size-4-2); resize: none; width: 100%; } -.modal-setting-back-button { position: absolute; top: var(--safe-area-inset-top); left: 0px; padding: var(--size-4-3) var(--size-4-3); height: var(--modal-header-height); color: var(--text-normal); font-weight: var(--font-semibold); } -.modal-setting-back-button-icon { display: flex; align-items: center; margin-right: 6px; } -.modal-setting-nav-bar { display: flex; flex: 0 1 auto; padding: var(--size-4-3); border-bottom: 1px solid var(--background-modifier-border); } -.modal .modal-nav-action { background-color: unset; margin-top: var(--size-4-1); position: absolute; top: 0px; width: unset; } -.modal .modal-nav-action.mod-secondary { left: 0px; } -.modal .modal-nav-action.mod-cta { color: var(--color-accent); font-weight: var(--font-semibold); right: 0px; } -.nav-header { padding: var(--size-4-2); } -.nav-header ~ .search-input-container { padding: 0px; width: calc(100% - var(--size-4-8)); margin: 4px auto; } -.nav-buttons-container { flex-wrap: wrap; gap: var(--size-2-1); } -.nav-buttons-container.has-separator { border-bottom: 1px solid var(--background-modifier-border); padding-bottom: var(--size-2-3); margin-bottom: var(--size-4-2); } -.multi-select-container { display: inline-flex; flex-wrap: wrap; width: 100%; background: var(--background-modifier-form-field); border: var(--input-border-width) solid var(--background-modifier-border); color: var(--text-normal); font-size: var(--font-ui-small); border-radius: var(--input-radius); outline: none; padding: 2px; } -.multi-select-selection { display: inline-flex; align-items: center; background-color: var(--tag-background); border: var(--tag-border-width) solid var(--tag-border-color); border-radius: var(--tag-radius); color: var(--tag-color); line-height: 1; padding: var(--tag-padding); margin: 0.5ch; } -.multi-select-selection-content { display: inline-flex; align-items: center; margin: 4px; } -.multi-select-input { min-width: 10ch; flex-grow: 1; background-color: inherit; border: none; } -@keyframes multi-select-highlight { - 0% { background-color: var(--background-modifier-error); } -} -.multi-select-duplicate { animation: 2000ms ease-in 0s 1 normal none running multi-select-highlight; } -.popover { background-color: var(--background-primary); border: 1px solid var(--background-modifier-border); box-shadow: var(--shadow-s); border-radius: var(--radius-m); padding: var(--size-4-5); position: relative; max-height: 95vh; } -.popover-title { font-weight: var(--font-extrabold); } -.popover-content { margin: var(--size-4-2) 0; } -.components-container .popover { width: 300px; margin-top: var(--size-4-5); } -.components-container .popover .popover-content { font-size: var(--font-ui-medium); } -.popover.hover-popover { position: absolute; z-index: var(--layer-popover); max-width: 80vw; min-height: 60px; overflow: hidden; width: fit-content; padding: 0px; } -.popover.hover-popover > * { width: var(--popover-width); } -.popover.hover-popover .markdown-preview-view { font-size: var(--popover-font-size); } -.popover.hover-popover > .mod-empty { display: flex; justify-content: center; align-items: center; padding: 20px; font-size: var(--popover-font-size); color: var(--text-muted); } -.popover.hover-popover > .media-embed { min-height: 0px; line-height: 0; border: none; } -.popover.hover-popover > .media-embed video { max-height: 100%; max-width: 100%; height: auto; } -.popover.hover-popover > .image-embed img { max-height: 100%; max-width: 100%; height: auto; } -.popover.hover-popover > .pdf-embed { width: var(--popover-pdf-width); height: var(--popover-pdf-height); max-height: var(--popover-max-height); } -.popover.hover-popover > .markdown-embed { height: var(--popover-height); max-height: var(--popover-max-height); border: 0px; padding: 0px; margin: 0px; } -.popover.hover-popover > .markdown-embed > .markdown-embed-content { height: 100%; overflow: auto; } -.popover.hover-popover > .markdown-embed > .markdown-embed-content > .markdown-preview-view { padding: var(--file-margins); } -.popover.hover-popover > .markdown-embed .mod-header + div > :first-child { margin-top: 0px; } -.follow-link-popover { box-shadow: 0 2px 8px var(--background-modifier-box-shadow); background-color: rgba(0, 0, 0, 0.9); border-radius: var(--radius-m); color: rgb(204, 204, 204); font-size: var(--font-ui-small); line-height: 20px; max-width: 300px; padding: 5px 12px; text-align: center; z-index: var(--layer-tooltip); white-space: pre-wrap; top: calc(100%); } -.follow-link-popover.mod-bottom { top: 0px; } -@media (hover: hover) { - .follow-link-popover:hover { background-color: rgb(0, 0, 0); } -} -.follow-link-popover .popover-arrow { position: absolute; top: calc(100%); left: 50%; width: 0px; margin-left: -5px; border-width: 5px; border-style: solid; border-color: rgba(0, 0, 0, 0.9) transparent transparent; content: " "; font-size: 0px; line-height: 0; } -.follow-link-popover.mod-bottom .popover-arrow { border-bottom: 5px solid rgba(0, 0, 0, 0.9); border-top: none; top: -5px; } -.markdown-preview-view progress, .markdown-rendered progress, .markdown-source-view.is-live-preview progress { -webkit-writing-mode: horizontal-tb; writing-mode: horizontal-tb; appearance: none; box-sizing: border-box; display: inline-block; height: 6px; margin-bottom: 4px; max-width: 100%; overflow: hidden; border-radius: 0px; border: 0px; vertical-align: -0.2rem; } -.markdown-preview-view progress[value]::-webkit-progress-bar, .markdown-rendered progress[value]::-webkit-progress-bar, .markdown-source-view.is-live-preview progress[value]::-webkit-progress-bar { background-color: var(--background-secondary); box-shadow: inset 0px 0px 0px 1px var(--background-modifier-border); border-radius: 6px; overflow: hidden; } -.markdown-preview-view progress[value]::-webkit-progress-value, .markdown-rendered progress[value]::-webkit-progress-value, .markdown-source-view.is-live-preview progress[value]::-webkit-progress-value { background-color: var(--interactive-accent); overflow: hidden; } -.progress-bar { position: absolute; height: 100vh; width: 100vw; top: 0px; left: 0px; background-color: var(--background-primary); z-index: 10000; display: flex; flex-direction: column; justify-content: center; align-items: center; } -.progress-bar-message { margin-bottom: var(--size-4-8); opacity: 1; color: var(--text-muted); } -.progress-bar-indicator { position: relative; height: 8px; margin: 0px 10vw; width: 90vw; overflow-x: hidden; border-radius: 3px; } -.progress-bar-line { position: absolute; opacity: 0.4; background-color: var(--interactive-accent); width: 150%; height: 8px; } -.progress-bar-subline { position: absolute; background-color: var(--interactive-accent); height: 8px; } -.progress-bar-subline.mod-increase { animation: 2s ease 0s infinite normal none running increase; } -.progress-bar-subline.mod-decrease { animation: 2s ease 0.5s infinite normal none running decrease; } -.progress-bar .progress-bar-subline { transition: width 150ms ease-in-out 0s; } -@keyframes increase { - 0% { left: -5%; width: 5%; } - 100% { left: 130%; width: 100%; } -} -@keyframes decrease { - 0% { left: -80%; width: 80%; } - 100% { left: 110%; width: 10%; } -} -.prompt { display: flex; flex-direction: column; border-radius: var(--radius-l); background-color: var(--background-primary); box-shadow: var(--shadow-l); border: var(--prompt-border-width) solid var(--prompt-border-color); z-index: 1; position: absolute; top: 80px; width: var(--prompt-width); max-width: var(--prompt-max-width); max-height: var(--prompt-max-height); overflow: hidden; } -.prompt-input-container { display: flex; } -input.prompt-input { width: 100%; padding: var(--size-4-6); background-color: var(--background-primary); font-size: var(--font-ui-medium); border-top: none; border-right: none; border-left: none; border-image: initial; height: 40px; border-radius: 0px; border-bottom: 1px solid var(--background-secondary); } -input.prompt-input:hover, input.prompt-input:focus, input.prompt-input:focus-visible { border-bottom: 1px solid var(--background-secondary); box-shadow: none; } -.prompt-results { list-style: none; margin: 0px; padding: var(--size-4-3); overflow-y: auto; } -.prompt-instructions { border-top: 1px solid var(--background-secondary); user-select: none; font-size: var(--font-ui-smaller); color: var(--text-muted); padding: var(--size-4-2); text-align: center; display: flex; flex-wrap: wrap; justify-content: center; gap: var(--size-4-3); } -.prompt-instruction { display: inline-block; } -.prompt-instruction-command { font-weight: var(--bold-weight); margin-right: var(--size-2-2); } -body:not(.native-scrollbars) ::-webkit-scrollbar { width: 12px; height: 12px; border-radius: var(--radius-l); background-color: transparent; } -body:not(.native-scrollbars) ::-webkit-scrollbar-track { background-color: transparent; } -body:not(.native-scrollbars) ::-webkit-scrollbar-thumb { background-color: var(--scrollbar-thumb-bg); border-radius: var(--radius-l); background-clip: padding-box; border-style: solid; border-color: transparent; border-image: initial; border-width: 3px 3px 3px 2px; min-height: 45px; } -body:not(.native-scrollbars) ::-webkit-scrollbar-thumb:active { border-radius: var(--radius-l); } -body:not(.native-scrollbars) ::-webkit-scrollbar-thumb:hover, body:not(.native-scrollbars) ::-webkit-scrollbar-thumb:active { background-color: var(--scrollbar-active-thumb-bg); } -body:not(.native-scrollbars) ::-webkit-scrollbar-corner { background: transparent; } -body:not(.native-scrollbars) * { } -.suggestion-container { position: absolute; background-color: var(--background-primary); max-width: 500px; border-radius: var(--radius-m); border: 1px solid var(--background-modifier-border); box-shadow: var(--shadow-s); z-index: var(--layer-notice); } -.suggestion { max-height: 300px; overflow-y: auto; padding: var(--size-2-3); } -.suggestion-item, .suggestion-empty { font-size: var(--font-ui-medium); margin-bottom: 1px; } -.suggestion-empty { color: var(--text-muted); padding-right: ; padding-bottom: ; padding-left: ; padding-top: var(--size-4-3); text-align: center; } -.suggestion-item { cursor: var(--cursor); padding-top: ; padding-right: ; padding-bottom: ; padding-left: 12px; white-space: pre-wrap; border-radius: var(--radius-s); } -.suggestion-item.is-selected { background-color: var(--background-modifier-hover); } -.suggestion-item.mod-downranked { color: var(--text-muted); } -.suggestion-item.mod-complex { align-items: baseline; display: flex; justify-content: space-between; } -.suggestion-item.mod-complex .suggestion-title { overflow-wrap: break-word; } -.suggestion-item.mod-complex .suggestion-content { display: flex; flex-direction: column; overflow: hidden; text-overflow: ellipsis; margin-right: auto; } -.suggestion-item.mod-complex .suggestion-prefix::after { content: ": "; } -.suggestion-item.mod-complex .suggestion-highlight { font-weight: bold; } -.suggestion-item.mod-complex .suggestion-note { font-size: 0.8em; color: var(--text-muted); width: 100%; flex-basis: 100%; overflow-wrap: break-word; } -.suggestion-item.mod-complex .suggestion-aux { display: flex; align-items: center; align-self: center; flex-shrink: 0; } -.suggestion-item.mod-complex .suggestion-hotkey { font-size: var(--font-ui-smaller); font-family: var(--font-interface); padding: 2px 6px; } -.suggestion-item.mod-complex .suggestion-hotkey:not(:last-child) { margin-left: 10px; } -.suggestion-item.mod-complex .suggestion-flair { color: var(--text-muted); opacity: var(--icon-opacity); margin: 0px 4px 0px 12px; display: flex; align-items: center; } -.suggestion-item.mod-complex .suggestion-flair:not(:last-child) { margin-left: 6px; } -.suggestion-highlight { font-weight: bold; } -.suggestion-bg { position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; background-color: var(--background-modifier-cover); z-index: var(--layer-popover); } -.horizontal-tab-header { display: flex; } -.horizontal-tab-nav-item, .vertical-tab-nav-item { padding: var(--size-4-1) var(--size-4-2); user-select: none; cursor: var(--cursor); font-size: calc(var(--font-ui-small) + 1px); border-radius: var(--radius-s); } -.horizontal-tab-nav-item.is-active, .vertical-tab-nav-item.is-active { background-color: var(--interactive-accent); color: var(--text-on-accent); } -@media (hover: hover) { - .horizontal-tab-nav-item.is-active:hover, .vertical-tab-nav-item.is-active:hover { background-color: var(--interactive-accent); } -} -@media (hover: hover) { - .horizontal-tab-nav-item:hover, .vertical-tab-nav-item:hover { background-color: var(--background-modifier-hover); } -} -.vertical-tab-nav-item { margin-bottom: var(--size-2-1); } -.vertical-tab-nav-item-chevron { display: none; } -.horizontal-tab-content, .vertical-tab-content { background-color: var(--background-primary); padding-left: var(--size-4-12); padding-right: var(--size-4-12); } -.vertical-tabs-container { display: flex; } -.vertical-tab-header { padding: var(--size-4-3); background-color: var(--background-secondary); } -.vertical-tab-header-group-items { display: flex; flex-direction: column; } -.vertical-tab-header-group-title { font-size: var(--font-ui-smaller); color: var(--text-faint); font-weight: var(--font-semibold); padding: var(--size-4-2); user-select: none; } -.vertical-tab-header-group { padding: var(--size-4-3) 0; } -.vertical-tab-content-container { overflow: hidden; flex-grow: 1; } -.vertical-tab-content { overflow-y: auto; height: 100%; padding-top: var(--size-4-8); padding-bottom: var(--size-4-16); } -.vertical-tab-content h2 { font-size: var(--font-ui-medium); font-weight: var(--font-semibold); } -.checkbox-container { app-region: no-drag; cursor: var(--cursor); background-color: var(--background-modifier-border-hover); border-radius: var(--toggle-radius); display: inline-block; flex-shrink: 0; height: calc(var(--toggle-thumb-height) + var(--toggle-border-width) * 2); position: relative; user-select: none; width: var(--toggle-width); box-shadow: rgba(0, 0, 0, 0.07) 0px 4px 10px inset, rgba(0, 0, 0, 0.21) 0px 0px 1px inset; transition: box-shadow 0.15s ease-in-out 0s, outline 0.15s ease-in-out 0s, border 0.15s ease-in-out 0s, opacity 0.15s ease-in-out 0s; outline: 0 solid var(--background-modifier-border-focus); } -.checkbox-container input[type="checkbox"] { position: absolute; opacity: 0; left: 0px; } -.checkbox-container:focus-within { outline: var(--toggle-border-width) solid var(--background-modifier-border-focus); } -@media (hover: hover) { - .checkbox-container:hover { box-shadow: rgba(0, 0, 0, 0.14) 0px 6px 20px inset, rgba(0, 0, 0, 0.28) 0px 0px 1px inset; } -} -.checkbox-container.is-enabled { background-color: var(--interactive-accent); } -.checkbox-container.is-enabled::after { transform: translate3d(calc(var(--toggle-width) - var(--toggle-thumb-width) - var(--toggle-border-width)), 0, 0); } -.checkbox-container.is-enabled:active::after { left: -4px; } -.checkbox-container::before { content: ""; display: block; position: absolute; inset: 0px; opacity: 0; } -.checkbox-container::after { pointer-events: none; content: ""; display: block; position: absolute; background-color: var(--toggle-thumb-color); width: var(--toggle-thumb-width); height: var(--toggle-thumb-height); margin: var(--toggle-border-width) 0 0 0; border-radius: var(--toggle-thumb-radius); transition: transform 0.15s ease-in-out 0s, width 0.1s ease-in-out 0s, left 0.1s ease-in-out 0s; left: 0px; transform: translate3d(var(--toggle-border-width), 0, 0); box-shadow: rgba(0, 0, 0, 0.15) 0px 1px 2px; } -.checkbox-container:active::after { width: calc(var(--toggle-thumb-width) + var(--toggle-border-width)); } -.checkbox-container.mod-small { width: var(--toggle-s-width); height: calc(var(--toggle-s-thumb-height) + var(--toggle-s-border-width) * 2); } -.checkbox-container.mod-small:focus-within { outline: var(--toggle-s-border-width) solid var(--background-modifier-border-focus); } -.checkbox-container.mod-small::after { width: var(--toggle-s-thumb-width); height: var(--toggle-s-thumb-height); margin: var(--toggle-s-border-width) 0 0 0; transform: translate3d(var(--toggle-s-border-width), 0, 0); } -.checkbox-container.mod-small.is-enabled::after { transform: translate3d(calc(var(--toggle-s-width) - var(--toggle-s-thumb-width) - var(--toggle-s-border-width)), 0, 0); } -.checkbox-container.mod-small:active::after { width: calc(var(--toggle-s-thumb-width) + var(--toggle-s-border-width)); } -.tooltip { animation: 200ms ease-in-out 0s 1 normal forwards running pop-down; box-shadow: 0 2px 8px var(--background-modifier-box-shadow); background-color: var(--background-modifier-message); border-radius: var(--radius-s); color: rgb(250, 250, 250); font-size: var(--font-ui-smaller); font-weight: var(--font-medium); left: 50%; line-height: var(--line-height-tight); max-width: 300px; padding: 4px 8px; position: fixed; text-align: center; transform: translateX(-50%); z-index: var(--layer-tooltip); pointer-events: none; white-space: pre-wrap; word-break: normal; overflow-wrap: anywhere; } -.tooltip.mod-right { animation: 200ms ease-in-out 0s 1 normal forwards running pop-right; transform: translateY(-50%); } -.tooltip.mod-left { animation: 200ms ease-in-out 0s 1 normal forwards running pop-right; transform: translateY(-50%); } -.tooltip.mod-error { width: 200px; background-color: var(--background-modifier-error); color: var(--text-on-accent); } -.tooltip.mod-wide { max-width: 450px; width: 400px; } -.tooltip .tooltip-arrow { position: absolute; top: -5px; left: 50%; width: 0px; margin-left: -5px; border-bottom: 5px solid var(--background-modifier-message); border-right: 5px solid transparent; border-left: 5px solid transparent; content: " "; font-size: 0px; line-height: 0; } -.tooltip.mod-right .tooltip-arrow { top: calc(50% - 5px); left: -5px; border-right: 5px solid var(--background-modifier-message); border-top: 5px solid transparent; border-bottom: 5px solid transparent; } -.tooltip.mod-left .tooltip-arrow { top: calc(50% - 5px); left: calc(100% + 5px); border-left: 5px solid var(--background-modifier-message); border-top: 5px solid transparent; border-bottom: 5px solid transparent; } -.tooltip.mod-top .tooltip-arrow { top: calc(100%); border-top: 5px solid var(--background-modifier-message); border-bottom: 5px solid transparent; } -.tooltip.mod-error .tooltip-arrow { border-bottom-color: var(--background-modifier-error); } -.tooltip.mod-error.mod-right .tooltip-arrow { border-right-color: var(--background-modifier-error); border-bottom: 5px solid transparent; } -.tooltip.mod-error.mod-left .tooltip-arrow { border-left-color: var(--background-modifier-error); border-bottom: 5px solid transparent; } -[aria-label] .svg-icon { pointer-events: none; } -@keyframes pop-down { - 0% { opacity: 0; transform: translateX(-50%) scale(1); } - 20% { opacity: 0.7; transform: translateX(-50%) scale(1.02); } - 40% { opacity: 1; transform: translateX(-50%) scale(1.05); } - 100% { opacity: 1; transform: translateX(-50%) scale(1); } -} -@keyframes pop-right { - 0% { opacity: 0; transform: translateY(-50%) scale(1); } - 20% { opacity: 0.7; transform: translateY(-50%) scale(1.02); } - 40% { opacity: 1; transform: translateY(-50%) scale(1.05); } - 100% { opacity: 1; transform: translateY(-50%) scale(1); } -} -.tree-item-self { padding: var(--nav-item-padding); margin-bottom: 1px; display: flex; align-items: flex-start; border-radius: var(--radius-s); font-size: var(--nav-item-size); font-weight: var(--nav-item-weight); color: var(--nav-item-color); position: relative; } -.workspace-leaf.mod-active .tree-item-self.has-focus { border-radius: var(--radius-s); box-shadow: 0 0 0 2px var(--background-modifier-border-focus); } -.workspace-leaf.mod-active .tree-item-self.has-focus:focus-within { box-shadow: 0 0 0 2px var(--interactive-accent); } -.tree-item-self.mod-collapsible { padding: var(--nav-item-parent-padding); } -.tree-item-self.mod-collapsible.is-being-dragged-over { border-radius: var(--radius-s); color: var(--nav-item-color-highlighted); background: hsla(var(--interactive-accent-hsl), 0.1); } -.tree-item-self.mod-collapsible.is-being-dragged-over .collapse-icon { color: var(--nav-item-color-highlighted); } -.tree-item-self.is-being-renamed .tree-item-inner { cursor: text; } -.tree-item-self.is-clickable { cursor: var(--cursor); } -@media (hover: hover) { - body:not(.is-grabbing) .tree-item-self.is-clickable:hover { color: var(--nav-item-color-hover); background-color: var(--nav-item-background-hover); font-weight: var(--nav-item-weight-hover); } -} -body:not(.is-grabbing) .tree-item-self.is-active:hover, .tree-item-self.is-active { color: var(--nav-item-color-active); background-color: var(--nav-item-background-active); font-weight: var(--nav-item-weight-active); } -body:not(.is-grabbing) .tree-item-self.is-selected:hover, .tree-item-self.is-selected { color: var(--nav-item-color-selected); background-color: var(--nav-item-background-selected); } -body:not(.is-grabbing) .tree-item-self.is-being-dragged:hover, .tree-item-self.is-being-dragged { color: var(--text-on-accent); background-color: var(--interactive-accent); } -body:not(.is-grabbing) .tree-item-self.is-being-dragged:hover .tree-item-icon, .tree-item-self.is-being-dragged .tree-item-icon { color: var(--text-on-accent); } -.tree-item-self .tree-item-icon { position: absolute; margin-left: calc(-1 * var(--size-4-5)); width: var(--size-4-4); display: flex; align-items: center; justify-content: center; opacity: var(--icon-opacity); color: var(--icon-color); flex: 0 0 auto; } -.tree-item-self .tree-item-icon::before { content: "​"; } -.tree-item-self .tree-item-icon .svg-icon:not(.right-triangle) { --icon-size: var(--icon-xs); --icon-stroke: var(--icon-s-stroke-width); } -.tree-item-flair-outer { padding-left: var(--size-4-1); margin-left: auto; } -.tree-item-flair { font-size: var(--font-ui-smaller); color: var(--text-faint); line-height: 1; border-radius: var(--radius-s); } -.tree-item-self:hover .tree-item-flair { color: var(--text-muted); } -.tree-item-inner { line-height: var(--line-height-tight); } -.tree-item-inner-subtext { color: var(--text-faint); font-size: 85%; } -.tree-item-children { padding-left: var(--nav-item-children-padding-left); margin-left: var(--nav-item-children-margin-left); margin-bottom: 1px; border-left: var(--nav-indentation-guide-width) solid var(--nav-indentation-guide-color); } -.drop-indicator { position: absolute; left: 0px; width: 100%; height: 0px; border: 2px solid var(--interactive-accent); pointer-events: none; } -.drop-indicator:not(.is-active) { display: none; } -audio { outline: none; } -.markdown-rendered audio { max-width: 100%; outline: none; } -audio { width: 100%; height: 42px; } -audio::-webkit-media-controls-enclosure { border-radius: calc(var(--radius-m) - 1px); border: 1px solid var(--background-modifier-border); background-color: var(--background-primary-alt); } -audio::-webkit-media-controls-current-time-display, audio::-webkit-media-controls-time-remaining-display { font-family: var(--font-interface); } -iframe { border: 0px; } -kbd { color: var(--code-normal); font-family: var(--font-monospace); background-color: var(--code-background); border-radius: var(--radius-s); font-size: var(--code-size); padding: 0.1em 0.25em; } -.workspace-leaf-content[data-type="pdf"] .view-content { display: flex; flex-direction: column; overflow: hidden; padding: 0px; } -.pdf-container { background-color: var(--pdf-background); flex-grow: 1; min-width: 350px; overflow: hidden; position: relative; } -.pdf-viewer-container { outline: none; overflow: auto; position: absolute; inset: 0px; } -.findbarOpen .pdf-viewer-container { margin-top: var(--findbar-height); } -.pdf-viewer { --scale-factor: 1; } -.pdf-content-container { --sidebar-width: 140px; } -.pdf-content-container.sidebarMoving .pdf-sidebar-container, .pdf-content-container.sidebarOpen .pdf-sidebar-container { visibility: visible; } -.pdf-content-container.sidebarOpen .pdf-sidebar-container { inset-inline-start: 0px; } -.pdf-content-container.sidebarOpen .pdf-viewer-container { inset-inline-start: var(--sidebar-width); transition-property: inset-inline-start; } -.pdf-embed .pdf-content-container.sidebarOpen .pdf-sidebar-container, .is-mobile .pdf-content-container.sidebarOpen .pdf-sidebar-container { inset-inline-start: 0px; } -.pdf-embed .pdf-content-container.sidebarOpen .pdf-findbar, .is-mobile .pdf-content-container.sidebarOpen .pdf-findbar, .pdf-embed .pdf-content-container.sidebarOpen .pdf-viewer-container, .is-mobile .pdf-content-container.sidebarOpen .pdf-viewer-container { inset-inline-start: 0px; } -.pdf-content-container .pdf-findbar, .pdf-content-container .pdf-sidebar-container, .pdf-content-container .pdf-viewer-container { transition-duration: 275ms; transition-timing-function: var(--anim-motion-swing); } -.pdf-content-container.sidebarResizing .pdf-findbar, .pdf-content-container.sidebarResizing .pdf-sidebar-container, .pdf-content-container.sidebarResizing .pdf-viewer-container { transition-duration: 0s; } -.pdf-content-container { inset: 0px; min-width: 350px; position: absolute; } -.pdf-content-container.is-loading::before { z-index: 1; } -.pdf-sidebar-container { background-color: var(--pdf-sidebar-background); border-right: var(--divider-width) solid var(--divider-color); bottom: 0px; display: flex; flex-direction: column; inset-inline-start: calc(-1 * var(--sidebar-width)); position: absolute; top: 0px; transition-property: inset-inline-start; visibility: hidden; width: var(--sidebar-width); z-index: 100; } -.findbarOpen .pdf-sidebar-container { top: var(--findbar-height); } -.is-mobile .pdf-sidebar-container[data-view="1"], .pdf-embed .pdf-sidebar-container[data-view="1"] { inset-inline-start: -140px; width: 140px; } -.is-mobile .pdf-sidebar-container[data-view="2"], .pdf-embed .pdf-sidebar-container[data-view="2"] { inset-inline-start: -275px; width: 275px; } -.pdf-sidebar-container .pdf-thumbnail-view, .pdf-sidebar-container .pdf-outline-view { bottom: 0px; overflow: auto; padding: var(--size-4-2) var(--size-4-2); position: absolute; top: 0px; user-select: none; width: 100%; } -.pdf-sidebar-container .pdf-thumbnail-view { display: flex; flex-wrap: wrap; gap: var(--size-4-1); place-content: flex-start center; padding: var(--size-4-3); width: 100%; } -.pdf-sidebar-container .pdf-thumbnail-view a { display: block; cursor: var(--cursor); } -.pdf-sidebar-container .pdf-thumbnail-view a:active, .pdf-sidebar-container .pdf-thumbnail-view a:focus { outline: 0px; } -.pdf-sidebar-container .thumbnail { --thumbnail-width: 0; --thumbnail-height: 0; position: relative; width: var(--thumbnail-width); height: var(--thumbnail-height); border: var(--size-4-2) solid transparent; border-radius: var(--radius-s); box-sizing: content-box; } -.pdf-sidebar-container .thumbnail::before { content: " "; position: absolute; inset: 0px; box-shadow: var(--pdf-thumbnail-shadow); } -.pdf-sidebar-container .thumbnail::after { background-color: var(--background-secondary); border-radius: 3px; bottom: var(--size-4-1); content: attr(data-page-label); color: var(--text-muted); display: block; font-size: var(--font-ui-smaller); line-height: 1; padding: var(--size-2-1) var(--size-4-1); position: absolute; right: var(--size-4-1); } -.pdf-sidebar-container .thumbnail:not([data-loaded]) { border: 1px dashed var(--background-modifier-border); margin: calc(var(--size-4-2) - 1px); } -.pdf-sidebar-container .thumbnail:hover, .pdf-sidebar-container .thumbnail.selected { border-color: var(--background-modifier-hover); } -.pdf-sidebar-container img.thumbnailImage { border: 1px solid transparent; max-width: unset; width: var(--thumbnail-width); height: var(--thumbnail-height); } -.pdf-outline-view .tree-item-self:not(.mod-collapsible) { padding-left: calc(10px + var(--size-4-2) + var(--size-2-3)); } -.pdf-outline-view .tree-item-self.mod-active { color: var(--nav-item-color-active); background-color: var(--nav-item-background-active); font-weight: var(--nav-item-weight-active); } -.pdf-outline-view .tree-item-flair { white-space: nowrap; } -.pdf-sidebar-content-wrapper { position: relative; flex-grow: 1; } -.pdf-sidebar-content { bottom: 0px; inset-inline-start: 0px; overflow: auto; position: absolute; top: 0px; width: 100%; } -.pdf-sidebar-content > .hidden { display: none; } -.pdf-sidebar-resizer { background-color: transparent; bottom: 0px; cursor: col-resize; inset-inline-end: calc(var(--divider-width-hover) * -1); position: absolute; top: 0px; transition: background-color 200ms ease-in-out 0s; width: var(--divider-width-hover); z-index: var(--layer-cover); } -.is-mobile .pdf-sidebar-resizer, .pdf-embed .pdf-sidebar-resizer { display: none; } -@media (hover: hover) { - .pdf-sidebar-resizer:hover { background-color: var(--divider-color-hover); } - .is-translucent .pdf-sidebar-resizer:hover { background-color: var(--divider-color-hover); } -} -.pdf-toolbar { align-items: stretch; background-color: var(--background-primary); border-bottom: 1px solid var(--background-modifier-border); display: flex; justify-content: space-between; overflow: auto; padding: var(--size-4-1) var(--size-4-3); position: relative; } -.hover-popover .pdf-toolbar { display: none; } -.pdf-page-numbers { white-space: nowrap; margin-right: var(--size-4-1); font-size: var(--font-ui-small); font-variant-numeric: tabular-nums; } -.pdf-toolbar-left, .pdf-toolbar-center, .pdf-toolbar-right { display: flex; align-items: center; gap: var(--size-4-1); } -.pdf-toolbar-left.hidden, .pdf-toolbar-center.hidden, .pdf-toolbar-right.hidden { display: none; } -.pdf-toolbar-center { position: absolute; top: var(--size-4-1); height: calc(100% - var(--size-4-2)); left: 50%; transform: translateX(-50%); } -.pdf-toolbar-spacer { width: var(--size-4-3); } -.pdf-toolbar-divider { width: var(--border-width); height: var(--icon-size); background-color: var(--background-modifier-border); } -.pdf-page-input { width: 7ch; text-align: right; font-variant-numeric: tabular-nums; } -.pdf-page-input.mod-page-loading { background-color: var(--background-secondary); opacity: 0.5; } -[data-main-rotation="90"] { transform: rotate(90deg) translateY(-100%); } -[data-main-rotation="180"] { transform: rotate(180deg) translate(-100%, -100%); } -[data-main-rotation="270"] { transform: rotate(270deg) translateX(-100%); } -.pdf-viewer .canvasWrapper { inset: 0px; box-shadow: var(--pdf-shadow); overflow: hidden; position: absolute; z-index: 1; } -.pdf-viewer .page { border: calc(var(--size-4-1) * var(--scale-factor)) solid transparent; box-sizing: content-box; direction: ltr; flex-shrink: 0; height: 1056px; margin: 0px auto; overflow: visible; position: relative; width: 816px; } -.pdf-viewer .spread .page { border: var(--size-4-1) solid transparent; } -.pdf-viewer.removePageBorders .page { border: none; } -.pdf-viewer.removePageBorders .page + .page { border-top: var(--size-4-1) solid transparent; } -.pdf-viewer.removePageBorders .spread .page + .page { border-top: none; } -.pdf-viewer.removePageBorders .spread .canvasWrapper { box-shadow: var(--pdf-spread-shadow); } -.pdf-viewer.removePageBorders .spread + .spread { border-top: var(--size-4-1) solid transparent; } -.pdf-viewer.mod-scroll-horizontal, .pdf-viewer.mod-scroll-wrapped, .pdf-spread { margin-left: 3.5px; margin-right: 3.5px; text-align: center; } -.pdf-viewer.mod-scroll-horizontal, .pdf-spread { white-space: nowrap; } -.pdf-viewer.mod-scroll-horizontal .pdf-spread, .pdf-viewer.mod-scroll-wrapped .pdf-spread { margin-left: 0px; margin-right: 0px; } -.pdf-spread .pdf-page, .pdf-viewer.mod-scroll-horizontal .pdf-page, .pdf-viewer.mod-scroll-wrapped .pdf-page, .pdf-viewer.mod-scroll-horizontal .pdf-spread, .pdf-viewer.mod-scroll-wrapped .pdf-spread { display: inline-block; vertical-align: middle; } -.pdf-viewer .page canvas { margin: 0px; display: block; } -.pdf-viewer .page canvas .pdf-struct-tree { contain: strict; } -.pdf-viewer .page canvas[hidden] { display: none; } -.pdf-viewer .page canvas[zooming] { width: 100%; height: 100%; } -.pdf-viewer:is(.scrollHorizontal, .scrollWrapped), .spread { margin-inline: 3.5px; text-align: center; } -.pdf-viewer.scrollHorizontal, .spread { white-space: nowrap; } -.pdf-viewer:is(.scrollHorizontal, .scrollWrapped) .spread { margin-inline: 0px; } -.spread :is(.page, .dummyPage), .pdf-viewer:is(.scrollHorizontal, .scrollWrapped) :is(.page, .spread) { display: inline-block; vertical-align: middle; } -.pdf-viewer.enablePermissions .textLayer span { cursor: not-allowed; user-select: none !important; } -.pdf-findbar { background-color: var(--background-primary); flex-direction: row-reverse; font-size: var(--font-ui-small); gap: var(--size-4-1); left: 0px; line-height: 1; padding: var(--size-2-3); position: absolute; right: 0px; top: 0px; transition-property: inset-inline-start; z-index: 101; } -.pdf-findbar input { min-width: 300px; } -.pdf-findbar.mod-hidden { display: none; } -.pdf-findbar input[type="checkbox"] { display: none; pointer-events: none; } -.pdf-findbar label { user-select: none; } -.pdf-findbar label:hover, .pdf-findbar input:focus-visible + label { color: var(--toggled-btn-color); background-color: var(--button-hover-color); } -.pdf-findbar .pdf-toolbar-field[type="checkbox"]:checked + .pdf-toolbar-label { color: var(--toggled-btn-color); background-color: var(--toggled-btn-bg-color) !important; } -.pdf-findbar .pdf-search-wrapper { display: flex; gap: var(--size-4-1); align-items: center; } -.pdf-findbar .mod-not-found { --background-modifier-form-field: rgba(var(--background-modifier-error-rgb), 0.1); --background-modifier-border-focus: rgba(var(--background-modifier-error-rgb), 0.6); } -.pdf-findbar .mod-pending::before { -webkit-mask-image: url("data:image/svg+xml,"); animation: 1s linear 0s infinite normal none running rotation; } -.is-phone .pdf-findbar { } -.is-phone .pdf-findbar .pdf-toolbar-button { height: auto; width: auto; padding: 6px 0px; background-color: transparent; color: var(--text-accent); flex-grow: 0; flex-shrink: 0; } -.is-phone .pdf-findbar .pdf-toolbar-divider, .is-phone .pdf-findbar .pdf-findbar-settings-btn, .is-phone .pdf-findbar .pdf-findbar-message { display: none; } -.is-phone .pdf-findbar input { min-width: 0px; } -.is-phone .pdf-findbar .search-input-container { flex-grow: 1; } -.is-phone .pdf-findbar .pdf-search-wrapper { gap: var(--size-4-2); } -@keyframes rotation { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} -.pdf-find-results-count { color: var(--text-muted); margin: 0 var(--size-4-2); font-style: italic; white-space: nowrap; } -.pdf-find-results-count:empty { display: none; } -.pdf-findbar-settings { background-color: var(--background-primary); border-radius: var(--radius-m); border: 1px solid var(--background-modifier-border); box-shadow: var(--shadow-s); padding: var(--size-4-1) var(--size-4-2); position: absolute; transform: translateX(-100%); width: 200px; z-index: 200; } -.pdf-content-container.sidebarOpen .pdf-findbar-settings { transform: translateX(calc(-100% + var(--sidebar-width))); } -.pdf-findbar-settings .setting-item { padding: var(--size-4-1) 0; border: none; } -.pdf-findbar-settings .setting-item-name { font-size: var(--font-ui-small); } -.pdf-password-dialog { align-items: center; display: flex; flex-direction: column; font-size: var(--font-ui-medium); gap: var(--size-4-1); justify-content: center; left: 50%; position: absolute; top: 50%; transform: translate(-50%, -50%); } -.pdf-password-dialog .mod-small { font-size: var(--font-ui-small); } -.pdf-password-dialog input { margin-top: var(--size-4-2); } -.pdf-lock-icon .svg-icon { --icon-size: var(--icon-xl); --icon-stroke: var(--icon-xl-stroke-width); } -.hiddenCopyElement { position: absolute; top: 0px; left: 0px; width: 0px; height: 0px; display: none; } -:root { --xfa-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,"); --xfa-focus-outline: auto; } -@media screen and (forced-colors: active) { - :root { --xfa-focus-outline: 2px solid CanvasText; } - .xfaLayer :required { outline: selecteditem solid 1.5px; } -} -.xfaLayer { background-color: transparent; } -.xfaLayer .highlight { margin: -1px; padding: 1px; background-color: rgb(239, 203, 237); border-radius: 4px; } -.xfaLayer .highlight.appended { position: initial; } -.xfaLayer .highlight.begin { border-radius: 4px 0px 0px 4px; } -.xfaLayer .highlight.end { border-radius: 0px 4px 4px 0px; } -.xfaLayer .highlight.middle { border-radius: 0px; } -.xfaLayer .highlight.selected { background-color: rgb(203, 223, 203); } -.xfaPage { overflow: hidden; position: relative; } -.xfaContentarea { position: absolute; } -.xfaPrintOnly { display: none; } -.xfaLayer { position: absolute; text-align: initial; top: 0px; left: 0px; transform-origin: 0px 0px; line-height: 1.2; } -.xfaLayer * { color: inherit; font: inherit; letter-spacing: -0.01px; text-align: inherit; text-decoration: inherit; box-sizing: border-box; background-color: transparent; padding: 0px; margin: 0px; pointer-events: auto; } -.xfaLayer :required { outline: red solid 1.5px; } -.xfaLayer div { pointer-events: none; } -.xfaLayer svg { pointer-events: none; } -.xfaLayer svg * { pointer-events: none; } -.xfaLayer a { color: blue; } -.xfaRich li { margin-left: 3em; } -.xfaFont { color: black; font-weight: normal; font-kerning: none; font-size: 10px; font-style: normal; letter-spacing: 0px; text-decoration: none; vertical-align: 0px; } -.xfaCaption { overflow: hidden; flex: 0 0 auto; } -.xfaCaptionForCheckButton { overflow: hidden; flex: 1 1 auto; } -.xfaLabel { height: 100%; width: 100%; } -.xfaLeft { display: flex; flex-direction: row; align-items: center; } -.xfaRight { display: flex; flex-direction: row-reverse; align-items: center; } -.xfaLeft > .xfaCaption, .xfaLeft > .xfaCaptionForCheckButton, .xfaRight > .xfaCaption, .xfaRight > .xfaCaptionForCheckButton { max-height: 100%; } -.xfaTop { display: flex; flex-direction: column; align-items: flex-start; } -.xfaBottom { display: flex; flex-direction: column-reverse; align-items: flex-start; } -.xfaTop > .xfaCaption, .xfaTop > .xfaCaptionForCheckButton, .xfaBottom > .xfaCaption, .xfaBottom > .xfaCaptionForCheckButton { width: 100%; } -.xfaBorder { background-color: transparent; position: absolute; pointer-events: none; } -.xfaWrapped { width: 100%; height: 100%; } -.xfaTextfield:focus, .xfaSelect:focus { background-image: none; background-color: transparent; outline: var(--xfa-focus-outline); outline-offset: -1px; } -.xfaCheckbox:focus, .xfaRadio:focus { outline: var(--xfa-focus-outline); } -.xfaTextfield, .xfaSelect { height: 100%; width: 100%; flex: 1 1 auto; border: none; resize: none; background-image: var(--xfa-unfocused-field-background); } -.xfaSelect { padding-inline: 2px; } -.xfaTop > .xfaTextfield, .xfaTop > .xfaSelect, .xfaBottom > .xfaTextfield, .xfaBottom > .xfaSelect { flex: 0 1 auto; } -.xfaButton { cursor: pointer; width: 100%; height: 100%; border: none; text-align: center; } -.xfaLink { width: 100%; height: 100%; position: absolute; top: 0px; left: 0px; } -.xfaCheckbox, .xfaRadio { width: 100%; height: 100%; flex: 0 0 auto; border: none; } -.xfaRich { white-space: pre-wrap; width: 100%; height: 100%; } -.xfaImage { object-position: left top; object-fit: contain; width: 100%; height: 100%; } -.xfaLrTb, .xfaRlTb, .xfaTb { display: flex; flex-direction: column; align-items: stretch; } -.xfaLr { display: flex; flex-direction: row; align-items: stretch; } -.xfaRl { display: flex; flex-direction: row-reverse; align-items: stretch; } -.xfaTb > div { justify-content: left; } -.xfaPosition { position: relative; } -.xfaArea { position: relative; } -.xfaValignMiddle { display: flex; align-items: center; } -.xfaTable { display: flex; flex-direction: column; align-items: stretch; } -.xfaTable .xfaRow { display: flex; flex-direction: row; align-items: stretch; } -.xfaTable .xfaRlRow { display: flex; flex-direction: row-reverse; align-items: stretch; flex: 1 1 0%; } -.xfaTable .xfaRlRow > div { flex: 1 1 0%; } -.xfaNonInteractive input, .xfaNonInteractive textarea, .xfaDisabled input, .xfaDisabled textarea, .xfaReadOnly input, .xfaReadOnly textarea { background: initial; } -@media print { - .xfaTextfield, .xfaSelect { background: transparent; } - .xfaSelect { appearance: none; text-indent: 1px; } -} -.textLayer { inset: 0px; line-height: 1; overflow: hidden; position: absolute; text-align: initial; text-size-adjust: none; transform-origin: 0px 0px; user-select: text; z-index: 2; opacity: 0.2; } -.textLayer ::selection { background-color: hsl(var(--color-accent-hsl)); } -.textLayer span, .textLayer br { color: transparent; position: absolute; white-space: pre; cursor: text; transform-origin: 0% 0%; } -.textLayer span.markedContent { top: 0px; height: 0px; } -.textLayer .highlight { margin: -1px; padding: 1px; border-radius: var(--radius-s); } -.textLayer .highlight.appended { position: static; display: inline-block; } -.textLayer .highlight.begin { border-radius: var(--radius-s) 0 0 var(--radius-s); } -.textLayer .highlight.end { border-radius: 0 var(--radius-s) var(--radius-s) 0; } -.textLayer .highlight.middle { border-radius: 0px; } -.textLayer .highlight.selected { box-shadow: 0 0 0 2px hsl(var(--interactive-accent-hsl)); background-color: hsl(var(--interactive-accent-hsl)); } -.textLayer .highlight:not(.selected) { box-shadow: 0 0 0 2px rgb(var(--color-yellow-rgb)); background-color: rgb(var(--color-yellow-rgb)); } -.textLayer br::selection { background: transparent; } -:root { --annotation-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,"); --input-focus-border-color: Highlight; --input-focus-outline: 1px solid Canvas; --input-unfocused-border-color: transparent; --input-disabled-border-color: transparent; --input-hover-border-color: black; } -@media screen and (forced-colors: active) { - :root { --input-focus-border-color: CanvasText; --input-unfocused-border-color: ActiveText; --input-disabled-border-color: GrayText; --input-hover-border-color: Highlight; } - .annotationLayer .textWidgetAnnotation input:required, .annotationLayer .textWidgetAnnotation textarea:required, .annotationLayer .choiceWidgetAnnotation select:required, .annotationLayer .buttonWidgetAnnotation.checkBox input:required, .annotationLayer .buttonWidgetAnnotation.radioButton input:required { outline: selecteditem solid 1.5px; } -} -.annotationLayer { position: absolute; top: 0px; left: 0px; pointer-events: none; transform-origin: 0px 0px; z-index: 3; } -.annotationLayer[data-main-rotation="90"] .norotate { transform: rotate(270deg) translateX(-100%); } -.annotationLayer[data-main-rotation="180"] .norotate { transform: rotate(180deg) translate(-100%, -100%); } -.annotationLayer[data-main-rotation="270"] .norotate { transform: rotate(90deg) translateY(-100%); } -.annotationLayer canvas { position: absolute; width: 100%; height: 100%; } -.annotationLayer section { position: absolute; text-align: initial; pointer-events: auto; box-sizing: border-box; transform-origin: 0px 0px; } -.annotationLayer .linkAnnotation > a, .annotationLayer .buttonWidgetAnnotation.pushButton > a { position: absolute; font-size: 1em; top: 0px; left: 0px; width: 100%; height: 100%; } -.annotationLayer .linkAnnotation > a:hover, .annotationLayer .buttonWidgetAnnotation.pushButton > a:hover { opacity: 0.2; background: rgb(255, 255, 0); box-shadow: rgb(255, 255, 0) 0px 2px 10px; } -.annotationLayer .textAnnotation img, .annotationLayer .textAnnotation canvas { position: absolute; cursor: pointer; width: 100%; height: 100%; top: 0px; left: 0px; } -.annotationLayer .textWidgetAnnotation input, .annotationLayer .textWidgetAnnotation textarea, .annotationLayer .choiceWidgetAnnotation select, .annotationLayer .buttonWidgetAnnotation.checkBox input, .annotationLayer .buttonWidgetAnnotation.radioButton input { background-image: var(--annotation-unfocused-field-background); border: 2px solid var(--input-unfocused-border-color); box-sizing: border-box; font: calc(9px * var(--scale-factor)) sans-serif; height: 100%; margin: 0px; vertical-align: top; width: 100%; } -.annotationLayer .textWidgetAnnotation input:required, .annotationLayer .textWidgetAnnotation textarea:required, .annotationLayer .choiceWidgetAnnotation select:required, .annotationLayer .buttonWidgetAnnotation.checkBox input:required, .annotationLayer .buttonWidgetAnnotation.radioButton input:required { outline: red solid 1.5px; } -.annotationLayer .choiceWidgetAnnotation select option { padding: 0px; } -.annotationLayer .buttonWidgetAnnotation.radioButton input { border-radius: 50%; } -.annotationLayer .textWidgetAnnotation textarea { resize: none; } -.annotationLayer .textWidgetAnnotation input[disabled], .annotationLayer .textWidgetAnnotation textarea[disabled], .annotationLayer .choiceWidgetAnnotation select[disabled], .annotationLayer .buttonWidgetAnnotation.checkBox input[disabled], .annotationLayer .buttonWidgetAnnotation.radioButton input[disabled] { background: none; border: 2px solid var(--input-disabled-border-color); cursor: not-allowed; } -.annotationLayer .textWidgetAnnotation input:hover, .annotationLayer .textWidgetAnnotation textarea:hover, .annotationLayer .choiceWidgetAnnotation select:hover, .annotationLayer .buttonWidgetAnnotation.checkBox input:hover, .annotationLayer .buttonWidgetAnnotation.radioButton input:hover { border: 2px solid var(--input-hover-border-color); } -.annotationLayer .textWidgetAnnotation input:hover, .annotationLayer .textWidgetAnnotation textarea:hover, .annotationLayer .choiceWidgetAnnotation select:hover, .annotationLayer .buttonWidgetAnnotation.checkBox input:hover { border-radius: 2px; } -.annotationLayer .textWidgetAnnotation input:focus, .annotationLayer .textWidgetAnnotation textarea:focus, .annotationLayer .choiceWidgetAnnotation select:focus { background: none; border: 2px solid var(--input-focus-border-color); border-radius: 2px; outline: var(--input-focus-outline); } -.annotationLayer .buttonWidgetAnnotation.checkBox :focus, .annotationLayer .buttonWidgetAnnotation.radioButton :focus { background-image: none; background-color: transparent; } -.annotationLayer .buttonWidgetAnnotation.checkBox :focus { border: 2px solid var(--input-focus-border-color); border-radius: 2px; outline: var(--input-focus-outline); } -.annotationLayer .buttonWidgetAnnotation.radioButton :focus { border: 2px solid var(--input-focus-border-color); outline: var(--input-focus-outline); } -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before, .annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after, .annotationLayer .buttonWidgetAnnotation.radioButton input:checked::before { background-color: canvastext; content: ""; display: block; position: absolute; } -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before, .annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after { height: 80%; left: 45%; width: 1px; } -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before { transform: rotate(45deg); } -.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after { transform: rotate(-45deg); } -.annotationLayer .buttonWidgetAnnotation.radioButton input:checked::before { border-radius: 50%; height: 50%; left: 30%; top: 20%; width: 50%; } -.annotationLayer .textWidgetAnnotation input.comb { font-family: monospace; padding-left: 2px; padding-right: 0px; } -.annotationLayer .textWidgetAnnotation input.comb:focus { width: 103%; } -.annotationLayer .buttonWidgetAnnotation.checkBox input, .annotationLayer .buttonWidgetAnnotation.radioButton input { appearance: none; } -.annotationLayer .fileAttachmentAnnotation .popupTriggerArea { position: absolute; } -.popupTriggerArea { height: 100%; width: 100%; } -.annotationLayer section.boundingRect { pointer-events: none; } -.annotationLayer section.boundingRect > * { pointer-events: initial; } -.popupWrapper { --pdf-popup-width: 280px; animation: 200ms cubic-bezier(0.34, 1.56, 0.64, 1) 0s 1 normal none running popIn; font-size: var(--font-ui-medium); pointer-events: none; position: absolute; transform: translate(-50%, 0px); z-index: 10000; } -.popupWrapper > div { margin: var(--size-4-3); background-color: var(--background-primary); border-radius: var(--radius-s); filter: drop-shadow(rgba(0, 0, 0, 0.2) 0px 0px 1px) drop-shadow(rgba(0, 0, 0, 0.3) 0px 1px 2px) drop-shadow(rgba(0, 0, 0, 0.3) 0px 4px 6px); } -.popupWrapper > div::after { background: var(--background-primary); border-top-left-radius: 2px; content: ""; height: var(--size-4-3); left: calc(50% - 2px); position: absolute; top: -5px; transform: rotate(45deg); width: var(--size-4-3); z-index: -1; } -@keyframes popIn { - 0% { transform: translate(-50%, -1px) scale(0.97); } - 100% { transform: translate(-50%, 0px) scale(1); } -} -.popup { cursor: initial; display: flex; flex-direction: column; pointer-events: auto; user-select: text; white-space: normal; width: 280px; overflow-wrap: break-word; } -.popupContent { font-size: var(--font-ui-small); line-height: var(--line-height-tight); max-height: 200px; overflow: auto; padding: var(--size-4-4); } -.popupContent:empty { display: none; } -.popupMeta { align-items: center; background-color: var(--background-secondary); border-top: 1px solid var(--background-modifier-border); color: var(--text-muted); display: flex; font-size: var(--font-ui-smaller); gap: var(--size-4-1); justify-content: space-between; padding: var(--size-4-1) var(--size-4-2) var(--size-4-1); border-bottom-left-radius: var(--radius-s); border-bottom-right-radius: var(--radius-s); } -.popupContent:empty + .popupMeta { border-top: none; background-color: var(--background-primary); border-top-left-radius: var(--radius-s); border-top-right-radius: var(--radius-s); } -.popupDate { white-space: nowrap; } -.richText > * { white-space: pre-wrap; } -.annotationLayer .highlightAnnotation, .annotationLayer .underlineAnnotation, .annotationLayer .squigglyAnnotation, .annotationLayer .strikeoutAnnotation, .annotationLayer .freeTextAnnotation, .annotationLayer .lineAnnotation svg line, .annotationLayer .squareAnnotation svg rect, .annotationLayer .circleAnnotation svg ellipse, .annotationLayer .polylineAnnotation svg polyline, .annotationLayer .polygonAnnotation svg polygon, .annotationLayer .caretAnnotation, .annotationLayer .inkAnnotation svg polyline, .annotationLayer .stampAnnotation, .annotationLayer .fileAttachmentAnnotation { cursor: pointer; } -.annotationLayer section svg { position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; } -.annotationLayer .annotationTextContent { position: absolute; width: 100%; height: 100%; opacity: 0; color: transparent; user-select: none; pointer-events: none; } -.annotationLayer .annotationTextContent span { width: 100%; display: inline-block; } -.markdown-rendered video { max-width: 100%; outline: none; } -.markdown-rendered blockquote { color: var(--blockquote-color); font-style: var(--blockquote-font-style); background-color: var(--blockquote-background-color); border-left: var(--blockquote-border-thickness) solid var(--blockquote-border-color); padding: 0 0 0 var(--size-4-6); margin-inline: 0px; } -.markdown-rendered blockquote > :first-child { margin-top: 0px; } -.markdown-rendered blockquote > :last-child { margin-bottom: 0px; } -.markdown-source-view.mod-cm6.is-live-preview .HyperMD-quote::before, .markdown-source-view.mod-cm6 .cm-blockquote-border::before { content: "​"; display: block; width: 1px; border-left: var(--blockquote-border-thickness) solid var(--blockquote-border-color); color: transparent; position: absolute; top: 0px; bottom: 0px; } -.markdown-source-view.mod-cm6.is-live-preview .HyperMD-quote { font-style: var(--blockquote-style); background-color: var(--blockquote-background-color); } -.markdown-source-view.mod-cm6.is-live-preview .HyperMD-quote::before { left: 0px; } -.markdown-source-view.mod-cm6 .cm-blockquote-border { display: inline-block; } -.callout { --callout-color: var(--callout-default); --callout-icon: lucide-pencil; } -.callout[data-callout="abstract"], .callout[data-callout="summary"], .callout[data-callout="tldr"] { --callout-color: var(--callout-summary); --callout-icon: lucide-clipboard-list; } -.callout[data-callout="info"] { --callout-color: var(--callout-info); --callout-icon: lucide-info; } -.callout[data-callout="todo"] { --callout-color: var(--callout-todo); --callout-icon: lucide-check-circle-2; } -.callout[data-callout="important"] { --callout-color: var(--callout-important); --callout-icon: lucide-flame; } -.callout[data-callout="tip"], .callout[data-callout="hint"] { --callout-color: var(--callout-tip); --callout-icon: lucide-flame; } -.callout[data-callout="success"], .callout[data-callout="check"], .callout[data-callout="done"] { --callout-color: var(--callout-success); --callout-icon: lucide-check; } -.callout[data-callout="question"], .callout[data-callout="help"], .callout[data-callout="faq"] { --callout-color: var(--callout-question); --callout-icon: help-circle; } -.callout[data-callout="warning"], .callout[data-callout="caution"], .callout[data-callout="attention"] { --callout-color: var(--callout-warning); --callout-icon: lucide-alert-triangle; } -.callout[data-callout="failure"], .callout[data-callout="fail"], .callout[data-callout="missing"] { --callout-color: var(--callout-fail); --callout-icon: lucide-x; } -.callout[data-callout="danger"], .callout[data-callout="error"] { --callout-color: var(--callout-error); --callout-icon: lucide-zap; } -.callout[data-callout="bug"] { --callout-color: var(--callout-bug); --callout-icon: lucide-bug; } -.callout[data-callout="example"] { --callout-color: var(--callout-example); --callout-icon: lucide-list; } -.callout[data-callout="quote"], .callout[data-callout="cite"] { --callout-color: var(--callout-quote); --callout-icon: quote-glyph; } -.callout { overflow: hidden; border-style: solid; border-color: rgba(var(--callout-color), var(--callout-border-opacity)); border-width: var(--callout-border-width); border-radius: var(--callout-radius); margin: 1em 0px; mix-blend-mode: var(--callout-blend-mode); background-color: rgba(var(--callout-color), 0.1); padding: var(--callout-padding); } -.callout.is-collapsible .callout-title { cursor: var(--cursor); } -.callout-title { padding: var(--callout-title-padding); display: flex; gap: var(--size-4-1); font-size: var(--callout-title-size); color: rgb(var(--callout-color)); line-height: var(--line-height-tight); } -.callout-content { overflow-x: auto; padding: var(--callout-content-padding); background-color: var(--callout-content-background); } -.callout-icon { flex: 0 0 auto; display: flex; margin-top: 0.15em; align-self: flex-start; } -.callout-icon .svg-icon { color: rgb(var(--callout-color)); } -.callout-title-inner { font-weight: var(--bold-weight); color: var(--callout-title-color); } -.callout-fold { display: flex; margin-top: 0.15em; align-self: flex-start; padding-right: var(--size-4-2); } -.callout-fold .svg-icon { transition: transform 100ms ease-in-out 0s; } -.callout-fold.is-collapsed .svg-icon { transform: rotate(-90deg); } -.markdown-source-view.mod-cm6 .callout { margin: 0px; } -.markdown-rendered code { color: var(--code-normal); font-family: var(--font-monospace); background-color: var(--code-background); border-radius: var(--radius-s); font-size: var(--code-size); padding: 0.1em 0.25em; } -.markdown-rendered pre { position: relative; padding: var(--size-4-2) var(--size-4-4); min-height: 38px; background-color: var(--code-background); border-radius: var(--radius-s); white-space: var(--code-white-space); overflow-x: auto; } -.markdown-rendered pre code { border: none; padding: 0px; background-color: transparent; } -.markdown-rendered pre:not(:hover) > button.copy-code-button { display: none; } -.markdown-rendered button.copy-code-button { margin: 6px; padding: 6px 8px; height: auto; background-color: transparent; box-shadow: none; color: var(--text-muted); font-size: var(--font-ui-smaller); font-family: var(--font-interface); position: absolute; top: 0px; right: 0px; } -@media (hover: hover) { - .markdown-rendered button.copy-code-button:hover { background-color: var(--background-modifier-hover); } -} -.markdown-source-view.mod-cm6 .cm-preview-code-block pre { margin: 0px; } -.markdown-source-view.mod-cm6 .code-block-flair { position: absolute; right: 6px; top: 6px; z-index: 1; display: inline-block; padding: var(--size-4-1) var(--size-4-2); border-radius: var(--radius-s); font-family: var(--font-interface); font-size: var(--font-ui-smaller); color: var(--text-muted); cursor: var(--cursor); } -@media (hover: hover) { - .markdown-source-view.mod-cm6 .code-block-flair:hover { background-color: var(--background-modifier-hover); } -} -.markdown-source-view.mod-cm6 .cm-line.HyperMD-codeblock { padding-left: var(--size-4-4); color: var(--code-normal); } -code[class*="language-"], pre[class*="language-"] { color: var(--code-normal); background: none; overflow-wrap: break-word; white-space: pre-wrap; word-break: normal; font-family: var(--font-monospace); text-align: left; word-spacing: normal; line-height: var(--line-height-normal); hyphens: none; } -@media print { - code[class*="language-"], pre[class*="language-"] { text-shadow: none; } -} -:not(pre) > code[class*="language-"], pre[class*="language-"] { background: var(--code-background); } -pre[class*="language-"] { overflow: hidden; } -code[class*="language-"] { display: block; padding: 1em; overflow: auto; } -:not(pre) > code[class*="language-"] { padding: 0.1em; border-radius: 0.3em; white-space: normal; } -.token.important, .token.bold { font-weight: bold; } -.token.italic { font-style: italic; } -.token.entity { cursor: help; } -.token.comment, .token.prolog, .token.doctype, .token.cdata { color: var(--code-comment); } -.token.namespace { opacity: 0.7; } -.token.tag, .token.constant, .token.symbol, .token.deleted { color: var(--code-tag); } -.token.punctuation { color: var(--code-punctuation); } -.token.boolean, .token.number { color: var(--code-value); } -.token.selector, .token.attr-name, .token.string, .token.char, .token.inserted { color: var(--code-string); } -.token.operator { color: var(--code-operator); } -.token.entity, .token.parameter, .token.property, .token.url, .language-css .token.string, .style .token.string, .token.variable { color: var(--code-property); } -.token.atrule, .token.attr-value, .token.builtin, .token.function, .token.class-name, .token.property-access { color: var(--code-function); } -.token.keyword { color: var(--code-keyword); } -.token.regex, .token.important { color: var(--code-important); } -.markdown-preview-view .markdown-embed .markdown-preview-view { --file-folding-offset: 0px; height: 100%; padding: 0px; } -.markdown-preview-view .markdown-embed .markdown-preview-view .markdown-preview-pusher h1, .markdown-preview-view .markdown-embed .markdown-preview-view .markdown-preview-pusher h2, .markdown-preview-view .markdown-embed .markdown-preview-view .markdown-preview-pusher h3, .markdown-preview-view .markdown-embed .markdown-preview-view .markdown-preview-pusher h4, .markdown-preview-view .markdown-embed .markdown-preview-view .markdown-preview-pusher h5, .markdown-preview-view .markdown-embed .markdown-preview-view .markdown-preview-pusher h6 { margin-top: 0px; } -.pdf-embed, .markdown-source-view .pdf-embed, .markdown-source-view.mod-cm6 .cm-content > .pdf-embed, .internal-embed.pdf-embed:not(.image-embed) { width: 100%; height: 800px; display: flex; flex-direction: column; } -.pdf-embed { overflow: hidden; position: relative; } -.pdf-embed:not(.canvas-node-content) { border: 1px solid var(--background-modifier-border); border-radius: var(--radius-s); } -.pdf-embed:not(.canvas-node-content) .pdf-toolbar { padding-right: var(--size-4-9); } -.markdown-source-view.mod-cm6 .pdf-embed .edit-block-button { background-color: var(--background-primary); opacity: 1; top: 6px; z-index: 1; } -.markdown-source-view.mod-cm6 .pdf-embed .edit-block-button:hover { color: var(--icon-color-hover); background-color: var(--background-modifier-hover); } -.markdown-embed, .file-embed { position: relative; } -.markdown-embed-link, .file-embed-link { position: absolute; top: 4px; right: 4px; color: var(--icon-color); opacity: var(--icon-opacity); cursor: var(--cursor-link); padding: var(--size-2-2); border-radius: var(--radius-s); display: flex; align-items: center; --icon-size: var(--icon-s); --icon-stroke: var(--icon-s-stroke-width); } -@media (hover: hover) { - .markdown-embed-link:hover, .file-embed-link:hover { color: var(--icon-color-hover); opacity: var(--icon-opacity-hover); background: var(--background-modifier-hover); } -} -.file-embed-title { display: flex; align-items: center; justify-content: center; gap: var(--size-4-2); } -.file-embed-icon { color: var(--text-muted); display: flex; } -.file-embed { display: flex; justify-content: center; border-radius: var(--radius-m); background-color: var(--background-primary-alt); } -.file-embed.mod-generic, .file-embed.mod-empty { cursor: var(--cursor-link); padding: var(--size-4-2); color: var(--text-muted); text-align: center; font-size: var(--font-smaller); } -@media (hover: hover) { - .file-embed.mod-generic:hover, .file-embed.mod-empty:hover { color: var(--text-normal); background-color: var(--background-secondary); } -} -.markdown-embed-content { height: 100%; } -.embed-title { align-items: center; display: flex; gap: var(--size-4-1); font-size: var(--font-text-size); font-weight: var(--bold-weight); text-align: left; text-overflow: ellipsis; white-space: nowrap; padding: 0 0 var(--size-4-2) 0; } -.markdown-embed { font-style: var(--embed-font-style); background-color: var(--embed-background); border-top: var(--embed-border-top); border-right: var(--embed-border-right); border-bottom: var(--embed-border-bottom); border-left: var(--embed-border-left); margin: 0px; padding: var(--embed-padding); } -.markdown-embed .markdown-preview-view { padding: 0px; } -.internal-embed:not(.image-embed) { display: block; } -.internal-embed img:not([width]), .internal-embed audio, .internal-embed video { max-width: 100%; } -.inline-embed .markdown-embed-content { height: fit-content; max-height: var(--embed-max-height); overflow: auto; } -.inline-embed .markdown-embed-content p:first-child { margin-top: 0px; } -.inline-embed .markdown-source-view.mod-cm6 .cm-editor { min-height: unset; } -.embed-iframe { width: 100%; height: 100%; } -iframe.external-embed { width: 600px; max-width: 100%; height: 350px; } -.markdown-source-view.mod-cm6 .internal-embed { white-space: normal; } -.markdown-source-view.mod-cm6 .cm-embed-block { position: relative; white-space: normal; overflow-wrap: normal; word-break: normal; } -@media (hover: hover) { - .markdown-source-view.mod-cm6 .cm-embed-block:hover { box-shadow: var(--embed-block-shadow-hover); border-radius: var(--radius-s); overflow: hidden; cursor: text; } - .markdown-source-view.mod-cm6 .cm-embed-block:hover .edit-block-button { opacity: 1; } - .markdown-source-view.mod-cm6 .cm-embed-block:hover .edit-block-button:hover { background-color: var(--background-modifier-hover); } -} -.markdown-source-view.mod-cm6 .cm-embed-block pre { margin: 0px; } -.markdown-source-view.mod-inside-iframe > .cm-editor > .cm-scroller { flex-direction: column; padding: 0 var(--size-4-4); } -.markdown-source-view.mod-inside-iframe > .cm-editor > .cm-scroller::before, .markdown-source-view.mod-inside-iframe > .cm-editor > .cm-scroller::after { content: " "; display: block; min-height: min(calc(10vh - 3px), var(--size-4-4)); max-height: var(--size-4-4); flex: 1 1 0px; } -.markdown-source-view.mod-inside-iframe > .cm-editor > .cm-scroller > .cm-sizer { min-height: unset; flex: 1 0 0px; } -.footnote-link { text-decoration: none; } -.footnotes { font-size: var(--footnote-size); } -.footnote-ref { vertical-align: super; } -.footnote-backref { color: var(--text-faint); text-decoration: none; } -@media (hover: hover) { - .footnote-backref:hover { color: var(--text-accent); text-decoration: none; } -} -@media (hover: hover) { - .cm-s-obsidian .cm-line.HyperMD-footnote span.cm-hmd-footnote:hover { color: var(--text-accent); } -} -.markdown-preview-view:not(.show-frontmatter) .frontmatter-container { display: none; } -.markdown-rendered .frontmatter.mod-failed { position: relative; } -.markdown-rendered .frontmatter.mod-failed .mod-error { color: var(--text-error); font-size: var(--font-smaller); } -.markdown-rendered .frontmatter.mod-failed::after { content: ""; position: absolute; top: 0px; right: 0px; width: 100%; height: 100%; background-color: var(--background-modifier-error); opacity: 0.3; mix-blend-mode: var(--highlight-mix-blend-mode); } -.frontmatter-container { padding: var(--size-4-2) 0 var(--size-4-4); color: var(--text-muted); position: relative; } -.frontmatter-container .frontmatter-section { display: flex; align-items: center; margin-bottom: var(--size-2-2); } -.frontmatter-container .frontmatter-section:last-child { margin-bottom: 0px; } -.frontmatter-container .frontmatter-section .svg-icon { color: var(--text-faint); margin-right: var(--size-4-2); } -.frontmatter-container .frontmatter-section-label { padding-right: 0.5em; flex-basis: 7em; flex-shrink: 0; font-size: var(--font-smaller); display: flex; align-items: center; } -.frontmatter-container .frontmatter-section-data { display: inline-flex; flex-wrap: wrap; flex-grow: 1; align-items: center; gap: var(--size-2-2); } -.markdown-embed-content .frontmatter-container { display: none; } -.frontmatter-container.is-collapsed .frontmatter-section { display: none; } -.frontmatter-container .frontmatter-collapse-indicator { margin-right: 6px; align-self: center; display: none; } -.frontmatter-container .frontmatter-container-header { color: var(--text-normal); font-size: var(--font-smaller); user-select: none; cursor: var(--cursor); font-weight: var(--font-medium); display: flex; content: "Metadata"; border-bottom: 1px solid var(--background-modifier-border); padding-bottom: var(--size-4-2); margin-bottom: var(--size-4-2); } -.frontmatter-container.is-collapsed .frontmatter-container-header { color: var(--text-faint); } -@media (hover: hover) { - .frontmatter-container.is-collapsed .frontmatter-container-header:hover { color: var(--text-muted); } -} -.frontmatter-container .frontmatter-input-text { width: 100%; min-height: var(--input-height); height: var(--input-height); border-width: 0px; resize: none; overflow-y: hidden; } -.frontmatter-container .frontmatter-input-number { width: 100%; border-width: 0px; } -.frontmatter-container .frontmatter-input-checkbox { margin-left: var(--size-4-2); } -.frontmatter-container .frontmatter-alias { font-size: var(--font-smaller); color: var(--text-normal); cursor: default; display: inline-flex; align-items: center; line-height: 1; white-space: nowrap; padding-right: 4px; } -.frontmatter-container .frontmatter-alias-icon { margin-right: var(--size-2-1); color: var(--text-accent); display: flex; align-items: center; } -.frontmatter-container .frontmatter-alias-icon .svg-icon { width: 12px; height: 12px; stroke-width: 2.5px; } -.frontmatter-container .frontmatter-key-input { border: none; } -.markdown-rendered h1, .markdown-rendered h2, .markdown-rendered h3, .markdown-rendered h4, .markdown-rendered h5, .markdown-rendered h6 { margin: 15px 0px; } -.markdown-rendered li h1, .markdown-rendered li h2, .markdown-rendered li h3, .markdown-rendered li h4, .markdown-rendered li h5 { margin-top: 0px; margin-bottom: 0px; } -h1, .markdown-rendered h1 { font-variant: var(--h1-variant); letter-spacing: -0.015em; line-height: var(--h1-line-height); font-size: var(--h1-size); color: var(--h1-color); font-weight: var(--h1-weight); font-style: var(--h1-style); font-family: var(--h1-font); } -h1 a, .markdown-rendered h1 a { font-weight: inherit; } -h2, .markdown-rendered h2 { font-variant: var(--h2-variant); letter-spacing: -0.015em; line-height: var(--h2-line-height); font-size: var(--h2-size); color: var(--h2-color); font-weight: var(--h2-weight); font-style: var(--h2-style); font-family: var(--h2-font); } -h2 a, .markdown-rendered h2 a { font-weight: inherit; } -h3, .markdown-rendered h3 { font-variant: var(--h3-variant); letter-spacing: -0.015em; line-height: var(--h3-line-height); font-size: var(--h3-size); color: var(--h3-color); font-weight: var(--h3-weight); font-style: var(--h3-style); font-family: var(--h3-font); } -h3 a, .markdown-rendered h3 a { font-weight: inherit; } -h4, .markdown-rendered h4 { font-variant: var(--h4-variant); letter-spacing: 0.01em; line-height: var(--h4-line-height); font-size: var(--h4-size); color: var(--h4-color); font-weight: var(--h4-weight); font-style: var(--h4-style); font-family: var(--h4-font); } -h4 a, .markdown-rendered h4 a { font-weight: inherit; } -h5, .markdown-rendered h5 { font-variant: var(--h5-variant); letter-spacing: 0.015em; font-size: var(--h5-size); line-height: var(--h5-line-height); color: var(--h5-color); font-weight: var(--h5-weight); font-style: var(--h5-style); font-family: var(--h5-font); } -h5 a, .markdown-rendered h5 a { font-weight: inherit; } -h6, .markdown-rendered h6 { font-variant: var(--h6-variant); letter-spacing: 0.015em; font-size: var(--h6-size); line-height: var(--h6-line-height); color: var(--h6-color); font-weight: var(--h6-weight); font-style: var(--h6-style); font-family: var(--h6-font); } -h6 a, .markdown-rendered h6 a { font-weight: inherit; } -.HyperMD-header-1, .inline-title[data-level="1"], .HyperMD-list-line .cm-header-1 { font-variant: var(--h1-variant); letter-spacing: -0.015em; line-height: var(--h1-line-height); font-size: var(--h1-size); color: var(--h1-color); font-weight: var(--h1-weight); font-style: var(--h1-style); font-family: var(--h1-font); } -.HyperMD-header-1 a, .inline-title[data-level="1"] a, .HyperMD-list-line .cm-header-1 a { font-weight: inherit; } -.HyperMD-header-2, .inline-title[data-level="2"], .HyperMD-list-line .cm-header-2 { font-variant: var(--h2-variant); letter-spacing: -0.015em; line-height: var(--h2-line-height); font-size: var(--h2-size); color: var(--h2-color); font-weight: var(--h2-weight); font-style: var(--h2-style); font-family: var(--h2-font); } -.HyperMD-header-2 a, .inline-title[data-level="2"] a, .HyperMD-list-line .cm-header-2 a { font-weight: inherit; } -.HyperMD-header-3, .inline-title[data-level="3"], .HyperMD-list-line .cm-header-3 { font-variant: var(--h3-variant); letter-spacing: -0.015em; line-height: var(--h3-line-height); font-size: var(--h3-size); color: var(--h3-color); font-weight: var(--h3-weight); font-style: var(--h3-style); font-family: var(--h3-font); } -.HyperMD-header-3 a, .inline-title[data-level="3"] a, .HyperMD-list-line .cm-header-3 a { font-weight: inherit; } -.HyperMD-header-4, .inline-title[data-level="4"], .HyperMD-list-line .cm-header-4 { font-variant: var(--h4-variant); letter-spacing: 0.015em; line-height: var(--h4-line-height); font-size: var(--h4-size); color: var(--h4-color); font-weight: var(--h4-weight); font-style: var(--h4-style); font-family: var(--h4-font); } -.HyperMD-header-4 a, .inline-title[data-level="4"] a, .HyperMD-list-line .cm-header-4 a { font-weight: inherit; } -.HyperMD-header-5, .inline-title[data-level="5"], .HyperMD-list-line .cm-header-5 { font-variant: var(--h5-variant); letter-spacing: 0.015em; font-size: var(--h5-size); line-height: var(--h5-line-height); color: var(--h5-color); font-weight: var(--h5-weight); font-style: var(--h5-style); font-family: var(--h5-font); } -.HyperMD-header-5 a, .inline-title[data-level="5"] a, .HyperMD-list-line .cm-header-5 a { font-weight: inherit; } -.HyperMD-header-6, .inline-title[data-level="6"], .HyperMD-list-line .cm-header-6 { font-variant: var(--h6-variant); letter-spacing: 0.015em; font-size: var(--h6-size); line-height: var(--h6-line-height); color: var(--h6-color); font-weight: var(--h6-weight); font-style: var(--h6-style); font-family: var(--h6-font); } -.HyperMD-header-6 a, .inline-title[data-level="6"] a, .HyperMD-list-line .cm-header-6 a { font-weight: inherit; } -.HyperMD-header .cm-header-1, .HyperMD-header .cm-header-2, .HyperMD-header .cm-header-3, .HyperMD-header .cm-header-4, .HyperMD-header .cm-header-5, .HyperMD-header .cm-header-6 { font-size: inherit !important; } -hr { border-right-width: initial; border-bottom-width: initial; border-left-width: initial; border-right-style: none; border-bottom-style: none; border-left-style: none; border-image: initial; border-top-width: ; border-top-style: ; border-color: var(--hr-color); margin: 1.5em 0px; } -.markdown-rendered hr { border-right-width: initial; border-bottom-width: initial; border-left-width: initial; border-right-style: none; border-bottom-style: none; border-left-style: none; border-image: initial; border-top-width: ; border-top-style: ; border-color: var(--hr-color); } -.markdown-source-view.mod-cm6 .hr { display: flex; align-items: center; } -.markdown-source-view.mod-cm6 hr { margin: 0px; flex: 1 0 0px; } -@media (hover: hover) { - .cm-s-obsidian .hmd-fold-html:hover { border: 1px dashed rgb(153, 153, 153); } -} -.markdown-preview-view img, .markdown-rendered img { image-rendering: -webkit-optimize-contrast; } -.markdown-preview-view img:not([width]), .markdown-rendered img:not([width]) { max-width: 100%; outline: none; } -.markdown-source-view.mod-cm6 .cm-line .internal-embed.image-embed { display: inline; } -.internal-query { margin: 0px; border-top: 1px solid var(--background-modifier-border); } -.internal-query .search-result-container { padding: var(--size-4-2); max-height: 800px; overflow: auto; border: 1px solid var(--background-modifier-border); background-color: var(--background-secondary); border-radius: var(--radius-m); } -.internal-query .internal-query-header { text-align: center; padding: var(--size-4-3) 0 var(--size-4-3) var(--size-4-1); color: var(--text-normal); display: flex; justify-content: flex-start; align-items: center; } -.internal-query .internal-query-header-icon { color: var(--text-faint); margin-right: var(--size-4-1); display: flex; } -.internal-query .internal-query-header-title { font-weight: var(--font-medium); } -.internal-query .internal-query-header-title::before, .internal-query .internal-query-header-title::after { content: "\""; } -ul ul, ol ul, ol ol ul, ol ul ul, ul ol ul, ul ul ul { list-style-type: disc; } -ol { list-style-type: var(--list-numbered-style); } -ol > li::marker, ul > li::marker { color: var(--list-marker-color); } -ol > li.is-collapsed::marker, ul > li.is-collapsed::marker { color: var(--list-marker-color-collapsed); } -.markdown-rendered ul, .markdown-rendered ol { padding-inline-start: var(--list-indent); } -.markdown-rendered ol > li, .markdown-rendered ul > li { padding-top: var(--list-spacing); padding-bottom: var(--list-spacing); } -.markdown-rendered ul li p:first-of-type, .markdown-rendered ol li p:first-of-type { margin-block-start: 0px; } -.markdown-rendered ul li p:last-of-type, .markdown-rendered ol li p:last-of-type { margin-block-end: 0px; } -.markdown-source-view.mod-cm6 .cm-content > .cm-line.HyperMD-list-line { margin-left: 0.5em; } -.markdown-source-view ol > li, .markdown-source-view ul > li, .markdown-preview-view ol > li, .markdown-preview-view ul > li, .mod-cm6 .HyperMD-list-line.cm-line { padding-top: var(--list-spacing); padding-bottom: var(--list-spacing); } -.markdown-rendered .list-collapse-indicator { margin-left: -3em; padding-right: 2em; } -.markdown-rendered .list-bullet { float: left; margin-left: -1em; } -.markdown-rendered .task-list-item > .list-bullet { display: none; } -.markdown-rendered ul.has-list-bullet { list-style-type: "​"; } -.markdown-rendered ul.has-list-bullet > li::marker { color: transparent; } -.list-bullet { color: transparent; position: relative; display: inline-flex; justify-content: center; align-items: center; } -.list-bullet::before { content: "​"; } -.list-bullet::after { position: absolute; content: "​"; pointer-events: none; color: var(--list-marker-color); border-radius: var(--list-bullet-radius); width: var(--list-bullet-size); height: var(--list-bullet-size); border: var(--list-bullet-border); transform: var(--list-bullet-transform); background-color: var(--list-marker-color); transition: transform 0.15s ease 0s, box-shadow 0.15s ease 0s; } -.list-bullet::selection { background-color: transparent !important; } -@media (hover: hover) { - .list-collapse-indicator:hover ~ .list-bullet::after, .cm-fold-indicator:hover ~ .list-bullet::after, .list-collapse-indicator:hover ~ .cm-formatting-list .list-bullet::after, .cm-fold-indicator:hover ~ .cm-formatting-list .list-bullet::after { background-color: var(--list-marker-color-hover); box-shadow: 0 0 0 4px var(--background-modifier-hover); } - li.is-collapsed .list-collapse-indicator:hover ~ .list-bullet::after, li.is-collapsed .cm-fold-indicator:hover ~ .list-bullet::after, .list-collapse-indicator:hover.is-collapsed ~ .list-bullet::after, .cm-fold-indicator:hover.is-collapsed ~ .list-bullet::after, li.is-collapsed .list-collapse-indicator:hover ~ .cm-formatting-list .list-bullet::after, li.is-collapsed .cm-fold-indicator:hover ~ .cm-formatting-list .list-bullet::after, .list-collapse-indicator:hover.is-collapsed ~ .cm-formatting-list .list-bullet::after, .cm-fold-indicator:hover.is-collapsed ~ .cm-formatting-list .list-bullet::after { background-color: var(--list-marker-color-collapsed); box-shadow: 0 0 0 4px var(--background-modifier-active-hover); } -} -li.is-collapsed .list-bullet::after, .is-collapsed ~ .cm-formatting-list .list-bullet::after { background-color: var(--list-marker-color-collapsed); box-shadow: 0 0 0 4px var(--background-modifier-active-hover); } -.markdown-source-view.mod-cm6 { } -.markdown-source-view.mod-cm6 .cm-fold-indicator .collapse-indicator { padding-right: 0.5rem; } -.markdown-source-view.mod-cm6 .cm-line:not(.cm-active):not(.HyperMD-header):not(.HyperMD-task-line) .cm-fold-indicator .collapse-indicator { padding-right: 1em; right: -0.5em; } -@media (hover: hover) { - .list-collapse-indicator:hover ~ .list-bullet::after, .cm-fold-indicator:hover ~ .list-bullet::after, .list-collapse-indicator:hover ~ .cm-formatting-list .list-bullet::after, .cm-fold-indicator:hover ~ .cm-formatting-list .list-bullet::after { background-color: var(--list-marker-color-hover); box-shadow: 0 0 0 4px var(--background-modifier-hover); } - li.is-collapsed .list-collapse-indicator:hover ~ .list-bullet::after, li.is-collapsed .cm-fold-indicator:hover ~ .list-bullet::after, .list-collapse-indicator:hover.is-collapsed ~ .list-bullet::after, .cm-fold-indicator:hover.is-collapsed ~ .list-bullet::after, li.is-collapsed .list-collapse-indicator:hover ~ .cm-formatting-list .list-bullet::after, li.is-collapsed .cm-fold-indicator:hover ~ .cm-formatting-list .list-bullet::after, .list-collapse-indicator:hover.is-collapsed ~ .cm-formatting-list .list-bullet::after, .cm-fold-indicator:hover.is-collapsed ~ .cm-formatting-list .list-bullet::after { background-color: var(--list-marker-color-collapsed); box-shadow: 0 0 0 4px var(--background-modifier-active-hover); } -} -.markdown-source-view.mod-cm6 .cm-hmd-list-indent { display: inline-block; } -.markdown-source-view.mod-cm6 .cm-formatting-list-ul, .markdown-source-view.mod-cm6 .cm-formatting-list-ol { white-space: pre; } -a { color: var(--link-color); outline: none; text-decoration-line: var(--link-decoration); text-decoration-thickness: var(--link-decoration-thickness); cursor: var(--cursor-link); } -@media (hover: hover) { - a:hover { color: var(--link-color-hover); text-decoration-line: var(--link-decoration-hover); } -} -.external-link { color: var(--link-external-color); text-decoration-line: var(--link-external-decoration); background-position: right 4px; background-repeat: no-repeat; background-image: linear-gradient(transparent, transparent), url("https://publish.obsidian.md/public/images/874d8b8e340f75575caa.svg"); background-size: 13px; padding-right: 16px; cursor: var(--cursor-link); filter: var(--link-external-filter); } -@media (hover: hover) { - .external-link:hover { color: var(--link-external-color-hover); text-decoration-line: var(--link-external-decoration-hover); } -} -.markdown-rendered .internal-link { cursor: var(--cursor-link); text-decoration-line: var(--link-decoration); } -@media (hover: hover) { - .markdown-rendered .internal-link:hover { text-decoration-line: var(--link-decoration-hover); } -} -.markdown-rendered .internal-link.is-unresolved { color: var(--link-unresolved-color); opacity: var(--link-unresolved-opacity); filter: var(--link-unresolved-filter); text-decoration-style: var(--link-unresolved-decoration-style); text-decoration-color: var(--link-unresolved-decoration-color); } -@media (hover: hover) { - .markdown-rendered .internal-link.is-unresolved:hover { opacity: 1; color: var(--link-color-hover); text-decoration-color: var(--link-color-hover); text-decoration-line: var(--link-decoration-hover); } -} -@media (hover: hover) { - .cm-s-obsidian span.cm-link:hover { color: var(--link-external-color-hover); text-decoration-line: var(--link-external-decoration-hover); } -} -@media (hover: hover) { - .cm-s-obsidian span.cm-formatting-link.cm-url:hover, .cm-s-obsidian span.cm-url:hover { color: var(--link-external-color-hover); text-decoration-line: var(--link-external-decoration-hover); } -} -@media (hover: hover) { - .cm-s-obsidian span.hmd-link-icon:hover { opacity: 1; } -} -.markdown-source-view.mod-cm6 .is-unresolved { color: var(--link-unresolved-color); opacity: var(--link-unresolved-opacity); filter: var(--link-unresolved-filter); } -@media (hover: hover) { - .markdown-source-view.mod-cm6 .is-unresolved:hover { opacity: 1; color: var(--link-color-hover); text-decoration-color: var(--link-color-hover); } -} -.markdown-source-view.mod-cm6 .is-unresolved .cm-underline { text-decoration-line: var(--link-decoration); text-decoration-style: var(--link-unresolved-decoration-style); text-decoration-color: var(--link-unresolved-decoration-color); } -.markdown-source-view.mod-cm6 .cm-underline { text-decoration-line: var(--link-decoration); text-decoration-thickness: var(--link-decoration-thickness); } -body.is-mobile .markdown-source-view.mod-cm6 .cm-underline { user-select: text; } -.markdown-source-view.mod-cm6.is-live-preview .cm-hashtag.cm-meta, .markdown-source-view.mod-cm6 .cm-hmd-internal-link .cm-underline, .markdown-source-view.mod-cm6 .cm-link .cm-underline, .markdown-source-view.mod-cm6 .cm-url .cm-underline { cursor: var(--cursor-link); } -@media (hover: hover) { - .markdown-source-view.mod-cm6 .cm-hmd-internal-link .cm-underline:hover { text-decoration-line: var(--link-decoration-hover); } -} -.markdown-source-view.mod-cm6 .cm-link .cm-underline, .markdown-source-view.mod-cm6 .cm-url .cm-underline { text-decoration-line: var(--link-external-decoration); } -@media (hover: hover) { - .markdown-source-view.mod-cm6 .cm-link .cm-underline:hover, .markdown-source-view.mod-cm6 .cm-url .cm-underline:hover { color: var(--link-external-color-hover); text-decoration-line: var(--link-external-decoration-hover); } -} -.inline-block { display: inline-block; vertical-align: middle; } -.hidden-token { display: inline; letter-spacing: -1ch; font-family: monospace; color: transparent; font-size: 1px !important; } -.mod-cm5 .cm-s-obsidian .HyperMD-table-row > :last-child { padding-right: 52px !important; } -@keyframes hmd-file-uploading-ani { - 0%, 100% { opacity: 0.4; } - 50% { opacity: 0.7; } -} -@media (hover: hover) { - .cm-s-obsidian div.HyperMD-goback-button:hover { color: transparent; text-align: left; } - .cm-s-obsidian div.HyperMD-goback-button:hover::before { position: absolute; padding-left: 5px; content: "Back"; color: rgb(247, 247, 247); } -} -mjx-container { outline: none; } -.markdown-source-view.mod-cm6 .math-block > mjx-container { margin: 0px; padding: 1em 0px; overflow-x: auto; } -.markdown-rendered table { border-collapse: collapse; margin-block: 1em; } -.markdown-rendered td, .markdown-rendered th { padding: var(--size-2-2) var(--size-4-2); border: var(--table-border-width) solid var(--table-border-color); max-width: var(--table-column-max-width); } -.markdown-rendered td { font-size: var(--table-text-size); color: var(--table-text-color); } -.markdown-rendered th { font-size: var(--table-header-size); font-weight: var(--table-header-weight); color: var(--table-header-color); font-family: var(--table-header-font); text-align: left; line-height: var(--line-height-tight); } -.markdown-rendered th[align="center"] { text-align: center; } -.markdown-rendered th[align="right"] { text-align: right; } -.markdown-rendered thead > tr > th, .markdown-rendered tbody > tr > td { white-space: var(--table-white-space); text-overflow: ellipsis; overflow: hidden; } -.markdown-rendered tbody tr { background-color: var(--table-background); } -@media (hover: hover) { - .markdown-rendered tbody tr:hover { background-color: var(--table-row-background-hover); } -} -.markdown-rendered tbody tr:nth-child(2n+1) { background-color: var(--table-row-alt-background); } -@media (hover: hover) { - .markdown-rendered tbody tr:nth-child(2n+1):hover { background-color: var(--table-row-background-hover); } -} -.markdown-rendered tbody tr > td:nth-child(2n+2) { background-color: var(--table-column-alt-background); } -.markdown-rendered tbody tr:last-child > td { border-bottom-width: var(--table-row-last-border-width); } -.markdown-rendered tbody tr > td:first-child { border-left-width: var(--table-column-first-border-width); } -.markdown-rendered tbody tr > td:last-child { border-right-width: var(--table-column-last-border-width); } -.markdown-rendered thead tr { background-color: var(--table-header-background); } -@media (hover: hover) { - .markdown-rendered thead tr:hover { background-color: var(--table-header-background-hover); } -} -.markdown-rendered thead tr > th { border-top-width: var(--table-header-border-width); border-color: var(--table-header-border-color); } -.markdown-rendered thead tr > th:nth-child(2n+2) { background-color: var(--table-column-alt-background); } -.markdown-rendered thead tr > th:first-child { border-left-width: var(--table-column-first-border-width); } -.markdown-rendered thead tr > th:last-child { border-right-width: var(--table-column-last-border-width); } -.markdown-source-view.mod-cm6 .cm-line.HyperMD-table-row { min-width: max-content; } -.markdown-source-view.mod-cm6 .cm-table-widget table { margin-bottom: 0px; } -a.tag { background-color: var(--tag-background); border: var(--tag-border-width) solid var(--tag-border-color); border-radius: var(--tag-radius); color: var(--tag-color); font-size: var(--tag-size); text-decoration: var(--tag-decoration); padding: var(--tag-padding-y) var(--tag-padding-x); line-height: 1; } -@media (hover: hover) { - a.tag:hover { background-color: var(--tag-background-hover); border: var(--tag-border-width) solid var(--tag-border-color-hover); color: var(--tag-color-hover); text-decoration: var(--tag-decoration-hover); } -} -a.tag { background-color: var(--tag-background); border: var(--tag-border-width) solid var(--tag-border-color); border-radius: var(--tag-radius); color: var(--tag-color); font-size: var(--tag-size); text-decoration: var(--tag-decoration); padding: var(--tag-padding-y) var(--tag-padding-x); line-height: 1; } -@media (hover: hover) { - a.tag:hover { background-color: var(--tag-background-hover); border: var(--tag-border-width) solid var(--tag-border-color-hover); color: var(--tag-color-hover); text-decoration: var(--tag-decoration-hover); } -} -input[type="checkbox"] { appearance: none; border-radius: var(--checkbox-radius); border: 1px solid var(--checkbox-border-color); flex-shrink: 0; padding: 0px; margin: 0px 6px 0px 0px; width: var(--checkbox-size); height: var(--checkbox-size); position: relative; transition: box-shadow 0.15s ease-in-out 0s; } -input[type="checkbox"]:hover, input[type="checkbox"]:active, input[type="checkbox"]:focus { outline: 0px; border-color: var(--checkbox-border-color-hover); } -input[type="checkbox"]:focus-visible { box-shadow: 0 0 0 2px var(--background-modifier-border-focus); } -input[type="checkbox"]:checked::after { content: ""; top: -1px; left: -1px; position: absolute; width: var(--checkbox-size); height: var(--checkbox-size); display: block; background-color: var(--checkbox-marker-color); -webkit-mask-position: 52% 52%; -webkit-mask-size: 65%; -webkit-mask-repeat: no-repeat; -webkit-mask-image: url("data:image/svg+xml; utf8, "); } -input[type="checkbox"]:checked { background-color: var(--checkbox-color); border-color: var(--checkbox-color); } -@media (hover: hover) { - input[type="checkbox"]:checked:hover { background-color: var(--checkbox-color-hover); border-color: var(--checkbox-color-hover); } -} -.task-list-item-checkbox { width: var(--checkbox-size); height: var(--checkbox-size); } -.markdown-preview-view .task-list-item-checkbox { position: relative; top: 0.2em; margin-right: 0.6em; } -ul > li.task-list-item { list-style: none; } -ul > li.task-list-item .task-list-item-checkbox { margin-inline-start: calc(var(--checkbox-size) * -1.5); } -ul > li.task-list-item[data-task="x"], ul > li.task-list-item[data-task="X"] { text-decoration: var(--checklist-done-decoration); color: var(--checklist-done-color); } -.markdown-source-view.mod-cm6 .task-list-label { padding: 0px; margin-left: -0.25em; } -.markdown-source-view.mod-cm6 .task-list-item-checkbox { top: -0.1em; vertical-align: middle; margin-left: 2px; } -.markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="x"], .markdown-source-view.mod-cm6 .HyperMD-task-line[data-task="X"] { text-decoration: var(--checklist-done-decoration); color: var(--checklist-done-color); } -b, strong { font-weight: var(--bold-weight); color: var(--bold-color); } -i, em { font-style: italic; color: var(--italic-color); } -.markdown-rendered mark { background-color: var(--text-highlight-bg); color: var(--text-normal); } -.markdown-rendered mark .internal-link { color: var(--text-normal); } -.embedded-backlinks { border-top: 1px solid var(--background-modifier-border); } -.markdown-preview-view .embedded-backlinks { margin-top: 3em; } -.embedded-backlinks .backlink-pane { padding: var(--size-4-3) 0 0 0; } -.embedded-backlinks .backlink-pane .search-empty-state, .embedded-backlinks .backlink-pane .tree-item-self { font-size: max(var(--font-ui-small),var(--font-smaller)); align-items: center; } -.embedded-backlinks .backlink-pane > .tree-item-self { font-size: max(var(--font-ui-small),1em); gap: var(--size-2-3); width: fit-content; } -.embedded-backlinks .backlink-pane .tree-item-flair { font-size: max(var(--font-ui-small),var(--font-smallest)); } -.embedded-backlinks .nav-header { padding: 0px; position: relative; } -.embedded-backlinks .nav-header ~ .search-input-container { width: calc(100% - 150px); margin: var(--size-4-3) 0 0 0; } -.embedded-backlinks .nav-buttons-container { position: absolute; right: 0px; top: 14px; z-index: 1; } -.view-action.mod-bookmark { --icon-color: var(--icon-color-active); --icon-color-hover: var(--icon-color-active); } -.workspace-leaf-content[data-type="bookmarks"] .view-content { padding: var(--size-4-3) var(--size-4-3) var(--size-4-8); } -.modal.mod-bookmark .setting-item-control input { width: 100%; } -.nav-buttons-container.has-separator { border-bottom: 1px solid var(--background-modifier-border); padding-bottom: var(--size-2-3); margin-bottom: var(--size-4-2); } -.nav-files-container { flex-grow: 1; overflow: hidden auto; padding: 0 var(--size-4-3) var(--size-4-6) var(--size-4-3); scroll-padding-block: var(--size-4-2); } -.nav-folder.mod-root > .nav-folder-title { font-size: var(--vault-name-font-size); color: var(--vault-name-color); font-weight: var(--vault-name-font-weight); cursor: default; } -@media (hover: hover) { - .nav-folder.mod-root > .nav-folder-title:hover { background-color: inherit; font-weight: var(--vault-name-font-weight); } -} -.nav-folder.mod-root > .nav-folder-title.is-being-dragged-over { background-color: hsla(var(--interactive-accent-hsl), 0.2); } -.nav-folder.mod-root > .nav-folder-children { border-left: none; margin-left: 0px; padding-left: 0px; } -.workspace-leaf.mod-active .nav-folder.has-focus > .nav-folder-title, .workspace-leaf.mod-active .nav-file.has-focus > .nav-file-title { border-radius: var(--radius-s); box-shadow: 0 0 0 2px var(--background-modifier-border-focus); } -.workspace-leaf.mod-active .nav-folder.has-focus > .nav-folder-title:focus-within, .workspace-leaf.mod-active .nav-file.has-focus > .nav-file-title:focus-within { box-shadow: 0 0 0 2px var(--interactive-accent); } -.nav-file-tag { background-color: var(--background-modifier-hover); border-radius: var(--radius-s); font-size: 9px; font-weight: var(--font-semibold); letter-spacing: 0.05em; line-height: var(--line-height-normal); margin-left: var(--size-2-3); padding: 0 var(--size-4-1); text-transform: uppercase; align-self: center; } -.nav-file-icon { display: inline-flex; align-items: center; margin-right: var(--size-2-3); position: relative; color: var(--icon-color); opacity: var(--icon-opacity); } -.nav-files-container:not(.show-unsupported) .is-unsupported { display: none; } -.nav-file-title-content, .nav-folder-title-content { display: inline-block; overflow-wrap: anywhere; overflow: hidden; white-space: var(--nav-item-white-space); text-overflow: ellipsis; } -.nav-file-title-content.is-being-renamed, .nav-folder-title-content.is-being-renamed { flex-grow: 1; white-space: normal; cursor: text; } -.nav-files-container { flex-grow: 1; overflow: hidden auto; padding: 0 var(--size-4-3) var(--size-4-6) var(--size-4-3); scroll-padding-block: var(--size-4-2); } -.nav-folder.mod-root > .nav-folder-title { font-size: var(--vault-name-font-size); color: var(--vault-name-color); font-weight: var(--vault-name-font-weight); cursor: default; } -@media (hover: hover) { - .nav-folder.mod-root > .nav-folder-title:hover { background-color: inherit; font-weight: var(--vault-name-font-weight); } -} -.nav-folder.mod-root > .nav-folder-title.is-being-dragged-over { background-color: hsla(var(--interactive-accent-hsl), 0.2); } -.nav-folder.mod-root .nav-folder > .nav-folder-children { padding-left: var(--nav-item-children-padding-left); margin: 0 0 0 var(--nav-item-children-margin-left); border-left: var(--nav-indentation-guide-width) solid var(--nav-indentation-guide-color); } -.nav-file { border-radius: var(--radius-s); } -.nav-folder-title { padding: var(--nav-item-parent-padding); } -.nav-file-title { padding: var(--nav-item-padding); } -.nav-file-title, .nav-folder-title { margin-bottom: var(--size-2-1); display: flex; border-radius: var(--radius-s); cursor: var(--cursor); color: var(--nav-item-color); font-size: var(--nav-item-size); font-weight: var(--nav-item-weight); line-height: var(--line-height-tight); } -@media (hover: hover) { - body:not(.is-grabbing) .nav-file-title:hover, body:not(.is-grabbing) .nav-folder-title:hover { background-color: var(--nav-item-background-hover); color: var(--nav-item-color-hover); font-weight: var(--nav-item-weight-hover); } -} -body:not(.is-grabbing) .nav-file-title.is-active:hover, body:not(.is-grabbing) .nav-folder-title.is-active:hover, .nav-file-title.is-active, .nav-folder-title.is-active { color: var(--nav-item-color-active); background-color: var(--nav-item-background-active); font-weight: var(--nav-item-weight-active); } -body:not(.is-grabbing) .nav-file-title.is-selected:hover, body:not(.is-grabbing) .nav-folder-title.is-selected:hover, .nav-file-title.is-selected, .nav-folder-title.is-selected { color: var(--nav-item-color-selected); background-color: var(--nav-item-background-selected); } -body:not(.is-grabbing) .nav-file-title.is-being-dragged, body:not(.is-grabbing) .nav-folder-title.is-being-dragged, .nav-file-title.is-being-dragged, .nav-folder-title.is-being-dragged { background-color: var(--interactive-accent); color: var(--text-on-accent); } -body:not(.is-grabbing) .nav-file-title.is-being-dragged .nav-folder-collapse-indicator, body:not(.is-grabbing) .nav-folder-title.is-being-dragged .nav-folder-collapse-indicator, .nav-file-title.is-being-dragged .nav-folder-collapse-indicator, .nav-folder-title.is-being-dragged .nav-folder-collapse-indicator { color: var(--text-on-accent); } -body:not(.is-grabbing) .nav-file-title.is-being-dragged .nav-file-tag, body:not(.is-grabbing) .nav-folder-title.is-being-dragged .nav-file-tag, .nav-file-title.is-being-dragged .nav-file-tag, .nav-folder-title.is-being-dragged .nav-file-tag { color: var(--text-normal); } -.workspace-leaf.mod-active .nav-folder.has-focus > .nav-folder-title, .workspace-leaf.mod-active .nav-file.has-focus > .nav-file-title { border-radius: var(--radius-s); box-shadow: 0 0 0 2px var(--background-modifier-border-focus); } -.workspace-leaf.mod-active .nav-folder.has-focus > .nav-folder-title:focus-within, .workspace-leaf.mod-active .nav-file.has-focus > .nav-file-title:focus-within { box-shadow: 0 0 0 2px var(--interactive-accent); } -.nav-folder-title.is-being-dragged-over { border-radius: var(--radius-s); color: var(--nav-item-color-highlighted); background: hsla(var(--interactive-accent-hsl), 0.1); } -.nav-folder-title.is-being-dragged-over .collapse-icon { color: var(--nav-item-color-highlighted); } -.file-tree-item-checkbox, .file-tree-item-icon { flex-shrink: 0; } -.file-tree-item-title { flex-grow: 1; word-break: break-word; } -.file-tree-item-icon { --icon-size: var(--icon-s); --icon-stroke: var(--icon-s-stroke-width); margin-right: var(--size-4-1); color: var(--icon-color); position: relative; top: var(--size-2-1); } -.file-tree .tree-item-inner { display: flex; align-items: center; position: relative; } -.file-tree .tree-item-flair { line-height: 1; padding: var(--size-2-1) var(--size-2-3); color: var(--text-on-accent); } -.file-tree .is-selected { color: var(--text-normal); } -.file-tree .mod-changed.is-selected { background-color: hsla(var(--interactive-accent-hsl), 0.2); } -.file-tree .mod-changed .tree-item-flair { color: var(--text-accent-hover); } -.file-tree .mod-new.is-selected { background-color: rgba(var(--background-modifier-success-rgb), 0.2); } -.file-tree .mod-new .tree-item-flair { color: var(--text-success); } -.file-tree .mod-deleted.is-selected, .file-tree .mod-to-delete.is-selected { background-color: rgba(var(--background-modifier-error-rgb), 0.2); } -.file-tree .mod-deleted .tree-item-flair, .file-tree .mod-to-delete .tree-item-flair { color: var(--text-error); } -.file-tree .mod-to-delete .tree-item-flair { display: none; } -.file-tree .mod-to-delete.is-selected .tree-item-flair { display: block; } -.file-tree .clickable-icon { display: flex; --icon-size: var(--icon-s); --icon-stroke: var(--icon-s-stroke-width); } -.graph-view.color-fill { color: var(--graph-node); } -.graph-view.color-fill-focused { color: var(--graph-node-focused); } -.graph-view.color-fill-tag { color: var(--graph-node-tag); } -.graph-view.color-fill-attachment { color: var(--graph-node-attachment); } -.graph-view.color-fill-unresolved { color: var(--graph-node-unresolved); opacity: 0.5; } -.graph-view.color-fill-1 { color: var(--text-muted); } -.graph-view.color-fill-2 { color: var(--text-muted); } -.graph-view.color-fill-3 { color: var(--text-muted); } -.graph-view.color-fill-4 { color: var(--text-muted); } -.graph-view.color-fill-5 { color: var(--text-muted); } -.graph-view.color-fill-6 { color: var(--text-muted); } -.graph-view.color-arrow { color: var(--text-normal); opacity: 0.5; } -.graph-view.color-circle { color: var(--graph-node-focused); } -.graph-view.color-line { color: var(--graph-line); } -.graph-view.color-text { color: var(--graph-text); } -.graph-view.color-fill-highlight { color: var(--interactive-accent); } -.graph-view.color-line-highlight { color: var(--interactive-accent); } -.graph-controls { border-radius: var(--radius-m); position: absolute; right: var(--size-4-3); top: var(--size-4-3); padding: 0px; background-color: var(--background-primary); width: var(--graph-controls-width); overflow: auto; } -.graph-controls:not(.is-close) { max-height: calc(100% - var(--size-4-4)); border: 1px solid var(--background-modifier-border); box-shadow: var(--shadow-s); } -.graph-controls.is-close { min-width: inherit; width: auto; background-color: var(--background-primary); border: 1px solid transparent; padding: var(--size-2-3); } -.graph-controls.is-close > .graph-control-section { display: none; } -.workspace-split:not(.mod-root) .graph-controls.is-close { background-color: var(--background-secondary); } -.graph-controls input[type="text"], .graph-controls input[type="range"] { width: 100%; font-size: var(--font-ui-small); } -.graph-controls .mod-cta { margin-top: var(--size-2-3); width: 100%; } -.graph-controls .setting-item { padding: var(--size-2-3) 0; border: none; } -.graph-controls .setting-item .setting-item-info { display: flex; align-items: center; } -.graph-controls .setting-item:first-of-type { border-top: none; } -.graph-controls .setting-item.mod-slider { flex-direction: column; } -.graph-controls .setting-item.mod-slider > * { width: 100%; } -.graph-controls .setting-item.mod-slider .setting-item-info { margin-right: 0px; } -.graph-controls .setting-item.mod-slider .setting-item-control { padding-top: var(--size-4-3); } -.graph-controls .setting-item.mod-toggle .setting-item-control { padding-top: 0px; } -.graph-controls .setting-item.mod-search-setting .setting-item-info { margin-right: 0px; } -.graph-controls .setting-item-name { font-size: var(--font-ui-small); } -.graph-controls::-webkit-scrollbar, .graph-controls::-webkit-scrollbar-thumb { display: none; } -.graph-color-group { --swatch-height: 18px; --swatch-width: 18px; position: relative; display: flex; align-items: center; padding: 0px 0px 6px; transition: top 200ms ease-in-out 0s; } -.graph-color-group input[type="color"] { margin: 0px 2px 0px 6px; } -.graph-color-group .clickable-icon { padding: var(--size-2-2); } -.graph-color-button-container { text-align: center; margin-bottom: 10px; } -.graph-color-button-container button { margin: 0px; width: 100%; } -.graph-color-group.drag-ghost { position: fixed; display: flex; max-width: unset; border: none; box-shadow: none; background-color: var(--background-primary-alt); padding: 0px; transition: none 0s ease 0s; pointer-events: none; } -.graph-color-group.drag-ghost input[type="text"] { width: 100%; } -.graph-color-group.drag-ghost input[type="color"] { margin-left: 6px; } -.graph-control-section.mod-color-groups .tree-item-children.is-grabbing .graph-color-groups-container { padding-bottom: 40px; } -.graph-controls-button { display: none; z-index: 1; } -.graph-controls-button.mod-close, .graph-controls-button.mod-reset { position: absolute; top: var(--size-4-2); right: var(--size-4-2); padding: var(--size-2-2); } -.graph-controls:not(.is-close) .graph-controls-button.mod-close, .graph-controls:not(.is-close) .graph-controls-button.mod-reset { display: flex; } -.graph-controls-button.mod-reset { right: 36px; } -.graph-controls.is-close .graph-controls-button.mod-open { display: flex; } -.graph-controls-button.mod-animate { margin-top: var(--size-4-2); } -.graph-controls.is-close .graph-controls-button.mod-animate { display: flex; } -.setting-item.mod-search-setting .setting-item-info { display: none; } -.setting-item.mod-search-setting .setting-item-control .search-input-container { position: relative; flex-grow: 1; margin: 0px; } -.setting-item.mod-search-setting.is-loading .setting-item-control::before { background-color: var(--interactive-accent); animation: 1000ms ease-in-out 300ms infinite normal none running progress-bar; } -.graph-control-section-header { font-weight: var(--font-semibold); font-size: var(--font-ui-small); color: var(--text-normal); } -.graph-control-section { padding: var(--size-2-3) var(--size-4-3); border-bottom: 1px solid var(--background-modifier-border); } -.graph-control-section:last-child { border-bottom: none; } -.graph-control-section:last-child .tree-item-children { padding-bottom: var(--size-4-4); } -.graph-control-section > .tree-item-self { padding-left: var(--size-4-4); } -.graph-control-section .tree-item-children { margin: 0px; padding: var(--size-4-1) 0; border-left: none; } -.graph-control-section.mod-display .setting-item:not(.mod-slider):last-child .setting-item-info { display: none; } -.workspace-leaf-content[data-type="outline"] .view-content { padding: 0px; } -.outline { padding: var(--size-4-3) var(--size-4-3) var(--size-4-8); } -.modal.mod-publish { height: var(--modal-height); width: var(--modal-width); max-width: var(--modal-max-width-narrow); padding: var(--size-4-4) 0 0 0; position: relative; overflow: hidden; } -.modal.mod-publish .modal-title { padding: 0 var(--size-4-4); } -.modal.mod-publish .modal-content { overflow: auto; padding: 0 var(--size-4-4) var(--size-4-4); margin-bottom: calc(var(--input-height) + var(--size-4-8)); border-top: var(--border-width) solid var(--background-modifier-border); } -.modal.mod-publish .modal-button-container { margin: 0 0 0 calc(var(--size-4-4) * -1); padding: var(--size-4-4); gap: var(--size-4-2); position: absolute; bottom: 0px; background-color: var(--background-primary); border-top: var(--border-width) solid var(--background-modifier-border); width: 100%; } -.publish-section { margin-bottom: var(--size-4-1); } -.publish-change-list { padding: var(--size-4-2) 0 var(--size-4-2) 0; } -.site-list-site-id-setting { margin-top: var(--size-4-4); } -.publish-section-header-text, .publish-section-header-toggle-collapsed-button, .publish-section-header-action { cursor: var(--cursor); } -@media (hover: hover) { - .publish-section-header-text:hover, .publish-section-header-toggle-collapsed-button:hover, .publish-section-header-action:hover { color: var(--text-accent-hover); } -} -.publish-section-header { border-bottom: 1px solid var(--background-modifier-border); font-size: var(--font-ui-small); line-height: 1.1; color: var(--text-muted); display: flex; padding: var(--size-4-2) 0; align-items: center; } -.publish-section-header-text { flex-grow: 1; font-size: var(--font-ui-medium); color: var(--text-normal); line-height: var(--line-height-tight); font-weight: var(--font-medium); } -.publish-changes-switch-site { margin-left: var(--size-4-2); display: flex; flex-direction: row; flex-grow: 1; font-size: var(--font-ui-small); position: relative; gap: var(--size-2-1); top: 2px; } -.publish-changes-switch-site .clickable-icon { --icon-size: var(--icon-s); --icon-stroke: var(--icon-s-stroke-width); padding: var(--size-2-2); } -.upload-progress-container { max-height: 60vh; overflow: auto; } -.upload-progress-container.is-finished { max-height: calc(60vh - 200px); } -.publish-changes-current-site-name { margin-left: var(--size-2-3); text-decoration: underline; } -.publish-changes-info { display: flex; align-items: center; margin-bottom: 20px; } -.publish-changes-info button { margin-right: 0px; margin-left: var(--size-4-2); } -.publish-changes-info .search-input-container { margin: 0px; width: 0px; flex: 1 0 auto; } -.publish-section-header-toggle-collapsed-button { margin-right: var(--size-4-1); color: var(--text-faint); width: 9px; height: 9px; } -.publish-section-header-action { color: var(--text-faint); margin-left: var(--size-4-3); } -.publish-upload-item-title { word-break: break-word; font-size: var(--nav-item-size); line-height: var(--line-height-tight); } -.publish-changes-buttons { text-align: right; padding-bottom: var(--size-4-4); } -.publish-upload-item { position: relative; padding: var(--size-4-1) var(--size-4-2); } -.publish-upload-item .flair { background-color: transparent; text-transform: unset; letter-spacing: normal; font-size: var(--font-ui-smaller); } -.publish-upload-item .list-item-part { --icon-size: var(--icon-s); --icon-stroke: var(--icon-s-stroke-width); display: flex; align-items: center; } -.publish-upload-item::before { content: " "; position: absolute; top: 0px; left: 0px; width: 0px; height: 100%; transition: width 150ms ease-in-out 0s; background-color: rgba(var(--background-modifier-success-rgb), 0.2); z-index: 0; border-radius: var(--radius-s); } -.publish-upload-item.mod-failed { color: var(--text-error); } -.publish-upload-item.mod-failed::before { background-color: rgba(var(--background-modifier-error-rgb), 0.2); } -.publish-upload-item.mod-completed { color: var(--text-success); } -.publish-upload-item.mod-completed > * { position: relative; } -.publish-upload-item.mod-completed::before { width: 100%; } -.site-list-container { border-top: 1px solid var(--background-modifier-border); margin-bottom: var(--size-4-4); } -.site-list-container .list-item:last-child { padding-top: var(--size-4-4); } -.site-list-item-name { flex-grow: 1; } -.slug-input { text-transform: lowercase; } -.passwords-container { margin-bottom: var(--size-4-4); } -.password-item { border-radius: var(--radius-s); padding: var(--size-4-2) var(--size-4-4); margin: var(--size-4-1) 0; } -@media (hover: hover) { - .password-item:hover { background-color: var(--background-primary); } -} -.tree-item.mod-custom-nav.hidden .tree-item-self { color: var(--text-faint); } -.tree-item.mod-custom-nav .tree-item-inner { display: flex; align-items: center; position: relative; } -.tree-list { padding: var(--size-4-4) 0; } -.tree-list-header { border-bottom: 1px solid var(--background-modifier-border); padding: var(--size-4-2) 0; line-height: 1.1; display: flex; align-items: center; justify-content: space-between; } -.tree-list-title { font-size: var(--font-ui-medium); font-weight: var(--font-semibold); } -.tree-list-action { align-items: center; display: flex; color: var(--text-muted); font-size: var(--font-ui-small); } -.search-input-container { position: relative; } -.search-input-container::before { top: calc((var(--input-height) - var(--search-icon-size)) / 2); left: 8px; position: absolute; content: ""; height: var(--search-icon-size); width: var(--search-icon-size); display: block; background-color: var(--search-icon-color); -webkit-mask-image: url("data:image/svg+xml,"); -webkit-mask-repeat: no-repeat; } -.search-input-container input { display: block; width: 100%; padding-right: 28px; padding-left: 36px; } -.global-search-input-container.search-input-container input { padding-right: 56px; } -.search-input-clear-button { position: absolute; background: transparent; border-radius: 50%; color: var(--search-clear-button-color); cursor: var(--cursor); top: 0px; right: 2px; bottom: 0px; line-height: 0; height: var(--input-height); width: 28px; margin: auto; padding: 0px; text-align: center; display: flex; justify-content: center; align-items: center; transition: color 0.15s ease-in-out 0s; } -.search-input-clear-button::after { content: ""; height: var(--search-clear-button-size); width: var(--search-clear-button-size); display: block; background-color: currentcolor; -webkit-mask-image: url("data:image/svg+xml,"); -webkit-mask-repeat: no-repeat; } -.search-input-clear-button:hover, .search-input-clear-button:active { color: var(--text-normal); transition: color 0.15s ease-in-out 0s; } -.search-input-suggest-button { position: absolute; left: 0px; top: 0px; color: var(--text-faint); cursor: var(--cursor); padding: var(--size-4-1) var(--size-4-2); opacity: 0; z-index: 10; } -@media (hover: hover) { - .search-input-suggest-button:hover { color: var(--text-muted); } -} -.backlink-pane, .outgoing-link-pane { overflow-y: auto; padding: var(--size-4-3) var(--size-4-3) var(--size-4-8); flex: 1 0 0px; } -.backlink-pane .search-result-container, .outgoing-link-pane .search-result-container { padding: var(--size-4-1) 1px var(--size-4-4); } -.backlink-pane > .tree-item-self, .outgoing-link-pane > .tree-item-self { color: var(--text-normal); padding-left: var(--size-4-2); } -.backlink-pane > .tree-item-self .tree-item-inner, .outgoing-link-pane > .tree-item-self .tree-item-inner { font-weight: var(--font-medium); } -.backlink-pane > .tree-item-self.is-collapsed, .outgoing-link-pane > .tree-item-self.is-collapsed { color: var(--text-faint); } -@media (hover: hover) { - .backlink-pane > .tree-item-self.is-collapsed:hover, .outgoing-link-pane > .tree-item-self.is-collapsed:hover { color: var(--text-muted); } -} -.backlink-pane > .tree-item-self .collapse-icon, .outgoing-link-pane > .tree-item-self .collapse-icon { display: none; } -.search-result-container { padding: var(--size-4-3) var(--size-4-3) var(--size-4-4); position: relative; flex: 1 0 0px; } -.search-result-container.mod-global-search { overflow-y: auto; } -.search-result-container::before { content: " "; position: absolute; top: 0px; width: 0px; height: 3px; } -.search-result-container.is-loading::before { background-color: var(--interactive-accent); animation: 1000ms ease-in-out 300ms infinite normal none running progress-bar; } -.search-suggest-info-text { color: var(--text-muted); margin-left: 4px; } -.search-suggest-icon { padding: 4px; border-radius: var(--radius-s); } -@media (hover: hover) { - .search-suggest-icon:hover { background-color: var(--background-modifier-hover); } -} -.suggestion-container.mod-search-suggestion { max-width: unset; background-color: var(--background-secondary); border-color: var(--prompt-border-color); } -.suggestion-container.mod-search-suggestion .suggestion { max-height: 600px; padding: var(--size-2-3); background-color: var(--background-secondary); border-radius: var(--radius-m); } -.search-suggest-icon { align-items: center; display: flex; } -.search-suggest-item { padding: var(--size-4-1) var(--size-4-2); border-radius: var(--radius-s); } -.search-suggest-item.suggestion-item { font-size: var(--font-ui-small); } -.search-suggest-item.mod-group { align-items: center; margin: 0px; color: var(--text-muted); padding: 0 0 0 var(--size-4-2); cursor: default; font-weight: var(--font-semibold); font-size: var(--font-ui-smaller); border-radius: 0px; } -.search-suggest-item.mod-group:not(:first-child) { border-top: 1px solid var(--background-modifier-border); margin-top: 6px; padding: 6px 6px 0px 14px; margin-left: -6px; margin-right: -6px; } -.search-suggest-item.mod-group:hover, .search-suggest-item.mod-group.is-selected { background-color: initial; } -@keyframes progress-bar { - 0% { width: 0px; left: 0px; } - 5% { width: 0px; left: 0px; } - 50% { width: 100%; right: 0px; } - 95% { width: 0px; right: 0px; } - 100% { width: 0px; right: 0px; } -} -.search-empty-state { color: var(--text-faint); font-size: var(--font-ui-small); margin: 0 0 var(--size-4-3); padding-left: var(--size-4-2); } -.search-result { word-break: break-word; } -.search-result:not(.is-collapsed) .search-result-file-title { color: var(--nav-item-color-active); } -.search-result-file-matches { font-size: var(--font-ui-smaller); line-height: var(--line-height-tight); background-color: var(--search-result-background); border-radius: var(--radius-s); overflow: hidden; margin: var(--size-4-1) 0 var(--size-4-2); color: var(--text-muted); box-shadow: 0 0 0 1px var(--background-modifier-border); } -.search-info-more-matches { color: var(--text-faint); } -.search-result-file-match { cursor: var(--cursor); position: relative; padding: var(--size-4-2) var(--size-4-5) var(--size-4-2) var(--size-4-3); white-space: pre-wrap; width: 100%; border-bottom: 1px solid var(--background-modifier-border); } -.search-result-file-match:last-child { border-bottom: none; } -@media (hover: hover) { - .search-result-file-match:hover { color: var(--text-normal); background-color: var(--text-selection); } -} -.search-result-file-match:hover .search-result-file-match-replace-button { display: block; } -.search-result-file-match-replace-button { display: none; position: absolute; height: auto; bottom: 5px; right: 24px; padding: var(--size-4-1) var(--size-4-2); color: var(--text-muted); font-size: var(--font-ui-smaller); } -@media (hover: hover) { - .search-result-file-match-replace-button:hover { color: var(--text-normal); } -} -.search-result-hover-button { position: absolute; display: flex; right: 2px; border-radius: var(--radius-s); color: var(--text-faint); padding: 1px 3px; } -@media (hover: hover) { - .search-result-hover-button:hover { opacity: 1; background-color: var(--background-modifier-hover); } -} -.search-result-hover-button.mod-top { top: 2px; } -.search-result-hover-button.mod-bottom { bottom: 2px; } -.search-result-file-matched-text { color: var(--text-normal); background-color: var(--text-highlight-bg); } -.search-info-container { color: var(--text-muted); padding: var(--size-4-1) var(--size-4-4) var(--size-4-1); font-size: var(--font-ui-smaller); } -.search-info-children { padding-left: 20px; border-left: 1px solid var(--background-modifier-border); margin: 1px 0px; } -.copy-search-result-container { display: flex; flex-direction: column; } -.copy-search-result-textarea { height: 300px; max-height: 20vh; resize: none; } -.copy-search-result-textarea + .setting-item { border-top: none; } -.search-result-file-match-destination-file-container { margin-top: var(--size-2-3); } -.search-result-file-match-destination-file { display: inline-flex; background-color: var(--interactive-normal); border-radius: var(--radius-s); box-shadow: var(--input-shadow); color: var(--text-muted); padding: var(--size-2-2) var(--size-2-3); margin-bottom: var(--size-2-1); } -@media (hover: hover) { - .search-result-file-match:hover .search-result-file-match-destination-file { background-color: var(--background-secondary); } - .search-result-file-match:hover .search-result-file-match-destination-file:hover { background-color: var(--interactive-hover); box-shadow: var(--input-shadow-hover); color: var(--text-normal); } -} -.search-result-file-match-destination-file-icon { --icon-size: var(--icon-xs); --icon-stroke: var(--icon-xs-stroke-width); margin-right: var(--size-4-1); display: flex; color: var(--text-faint); } -.search-result-file-match-destination-file-icon .svg-icon { align-self: center; } -.search-result-file-match-destination-file-name { white-space: pre-wrap; word-break: break-all; } -.workspace-leaf.mod-active .search-result.has-focus .tree-item-self, .workspace-leaf.mod-active .search-result-file-match.has-focus { border-radius: var(--radius-s); box-shadow: inset 0 0 0 2px var(--background-modifier-border-focus); } -.search-results-info { color: var(--text-muted); display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--background-modifier-border); margin: var(--size-4-1) var(--size-4-2) 0; padding-bottom: var(--size-4-1); white-space: nowrap; } -.search-results-info .dropdown { height: 24px; box-shadow: none; background-color: transparent; font-size: 12px; color: var(--text-muted); text-align-last: right; max-width: 60%; text-overflow: ellipsis; white-space: nowrap; } -@media (hover: hover) { - .search-results-info .dropdown:hover { color: var(--interactive-accent); } -} -.search-results-info .dropdown option { color: initial; text-align: left; } -.search-results-result-count { font-size: var(--font-ui-smaller); } -.search-row { display: flex; margin: var(--size-4-2); gap: var(--size-4-1); } -.search-params { margin: var(--size-4-1) var(--size-4-4); } -.search-params input[type="text"], .search-params input[type="range"] { width: 100%; font-size: var(--font-ui-small); } -.search-params .mod-cta { margin-top: var(--size-2-3); width: 100%; } -.search-params .setting-item { padding: var(--size-2-3) 0; border: none; } -.search-params .setting-item .setting-item-info { display: flex; align-items: center; } -.search-params .setting-item:first-of-type { border-top: none; } -.search-params .setting-item.mod-slider { flex-direction: column; } -.search-params .setting-item.mod-slider > * { width: 100%; } -.search-params .setting-item.mod-slider .setting-item-info { margin-right: 0px; } -.search-params .setting-item.mod-slider .setting-item-control { padding-top: var(--size-4-3); } -.search-params .setting-item.mod-toggle .setting-item-control { padding-top: 0px; } -.search-params .setting-item.mod-search-setting .setting-item-info { margin-right: 0px; } -.search-params .setting-item-name { font-size: var(--font-ui-small); } -.search-params::-webkit-scrollbar, .search-params::-webkit-scrollbar-thumb { display: none; } -.global-search-input-container { flex-grow: 1; } -.more-options-icon { --icon-size: 10px; background-color: var(--icon-color); border-radius: 50%; color: var(--background-secondary); display: flex; margin-left: var(--size-2-3); opacity: var(--icon-opacity); padding: 0.5px; } -.clickable-icon:hover .more-options-icon { background-color: var(--icon-color-hover); opacity: var(--icon-opacity-hover); } -.slides-container { position: fixed; top: 0px; left: 0px; height: 100vh; width: 100vw; transition: -webkit-transform 0.8s ease 0s; background-color: rgb(25, 25, 25); z-index: var(--layer-slides); border: none; } -.slides-container li .collapse-indicator { display: none; } -.slides-close-btn { display: inline-block; position: absolute; top: var(--size-4-2); right: var(--size-4-2); color: var(--text-faint); cursor: var(--cursor); z-index: 1; } -@media (hover: hover) { - .slides-close-btn:hover { color: var(--text-muted); } -} -.reveal input[type="checkbox"] { width: 24px; height: 24px; } -.reveal .task-list-item, .reveal .footnote-item { list-style: none; } -.reveal .task-list-item { margin-left: -1.5em; } -.mod-sync-history .modal-content { height: 100%; } -.vault-list-item { margin: 6px 0px; display: flex; } -.vault-list-item.is-connected .vault-list-item-title { color: var(--text-normal); } -.vault-list-item-icon { color: var(--text-muted); position: relative; top: 1px; } -.vault-list-item-title { color: var(--text-muted); user-select: none; } -.vault-list-item-creation-time { color: var(--text-faint); font-size: var(--font-ui-small); } -.sync-status-icon { display: flex; align-items: center; cursor: var(--cursor); } -.sync-status-icon.mod-success { color: var(--text-success); } -.sync-status-icon.mod-working { color: var(--interactive-accent); } -.sync-status-icon.mod-error { color: var(--text-error); } -.sync-history-list-container { display: flex; flex-direction: column; flex-basis: 250px; flex-shrink: 0; border-right: 1px solid var(--background-modifier-border); } -.sync-history-list { overflow: auto; padding: var(--size-4-3); flex-grow: 1; display: flex; flex-direction: column; } -.sync-history-list .search-input-container { width: 100%; } -.sync-history-list-item-container { overflow: auto; flex: 1 1 0px; } -.sync-history-list-item { padding: var(--size-4-2) var(--size-4-3); margin-bottom: var(--size-4-2); cursor: var(--cursor); font-size: var(--font-ui-small); border-radius: var(--radius-s); transition: background-color 200ms ease-in-out 0s, color 200ms ease-in-out 0s; } -.sync-history-list-item:last-child { margin-bottom: 0px; } -.sync-history-list-item.is-active, .sync-history-list-item.is-active:hover { background-color: var(--interactive-accent); color: var(--text-on-accent); } -.sync-history-list-item.is-active .u-muted, .sync-history-list-item.is-active:hover .u-muted { color: var(--text-on-accent); opacity: 0.8; } -@media (hover: hover) { - .sync-history-list-item:hover { background-color: var(--background-modifier-hover); } -} -.sync-history-content-container { background-color: var(--background-primary); padding: 0px; height: auto; display: flex; flex-direction: column; width: 0px; flex: 1 1 auto; } -.sync-history-content-container .modal-button-container { border-top: 1px solid var(--background-modifier-border); margin: 0px; padding: 12px; justify-content: center; } -.sync-history-content-container textarea { resize: none; border: none; box-shadow: none; } -.sync-history-content-container textarea:hover, .sync-history-content-container textarea:active, .sync-history-content-container textarea:focus { border: none; box-shadow: none; } -.sync-history-content-empty { display: none; } -.sync-history-content-container.mod-empty .sync-history-content-empty { display: block; text-align: center; padding: 24px; } -.sync-history-content { display: flex; flex-direction: column; flex-grow: 1; overflow: hidden; padding: 0px; } -.sync-history-content .setting-item:first-child { padding: var(--size-4-4) var(--size-4-6) var(--size-4-4); border-bottom: 1px solid var(--background-modifier-border); } -.sync-history-content .setting-item-info { flex-grow: 0; font-weight: var(--bold-weight); } -.sync-history-content .setting-item-control { justify-content: flex-start; } -.sync-history-text, .sync-history-diff { flex: 1 0 auto; padding: var(--size-4-6); } -.sync-history-content-other { flex-grow: 1; padding: var(--size-4-6); text-align: center; } -.sync-history-content-other img { max-width: 100%; } -.sync-history-content-container.mod-empty .sync-history-content, .sync-history-content-container.mod-empty .sync-history-content-buttons { display: none; } -.sync-history-content-buttons { border-top: 1px solid var(--background-modifier-border); margin: 0px; padding: var(--size-4-3); } -.mod-selectable { cursor: var(--cursor); padding: var(--size-4-2) var(--size-4-4); border-radius: var(--radius-m); } -@media (hover: hover) { - .mod-selectable:hover { background-color: var(--background-modifier-hover); } -} -.sync-history-load-more-button { height: 38px; text-align: center; line-height: 38px; cursor: var(--cursor); color: var(--text-muted); } -@media (hover: hover) { - .sync-history-load-more-button:hover { color: var(--text-normal); } -} -.modal.mod-sync-log { height: var(--modal-height); width: var(--modal-width); max-width: var(--modal-max-width-narrow); padding: var(--size-4-4) 0 0 0; } -.modal.mod-sync-log .modal-title { padding: 0 var(--size-4-4); } -.modal.mod-sync-log .modal-content { display: flex; flex-direction: column; overflow: hidden; } -.modal.mod-sync-log .modal-button-container { margin: 0px; padding: var(--size-4-4); } -.modal.mod-sync-log .setting-item.mod-toggle { padding: 0 var(--size-4-4) var(--size-4-4); } -.modal.mod-sync-log .sync-log-container { overflow: auto; flex-grow: 1; font-family: var(--font-monospace); font-size: var(--font-ui-smaller); color: var(--text-muted); border-top: 1px solid var(--background-modifier-border); border-bottom: 1px solid var(--background-modifier-border); padding: var(--size-4-4); background-color: var(--background-secondary); } -.modal.mod-sync-log .sync-log-container .list-item { line-height: var(--line-height-normal); margin: 0px; } -.modal.mod-sync-log .sync-log-container .list-item.mod-error { color: var(--text-error); } -.sync-file-tree-container { max-height: calc(90vh - 250px); overflow: auto; } -.sync-exclude-folder { display: flex; margin: var(--size-4-3) 0; } -.sync-exclude-folder > * { align-self: center; display: flex; } -.sync-exclude-folder-name { flex-grow: 1; } -.sync-exclude-folder-remove { visibility: hidden; margin-right: 6px; } -.sync-exclude-folder:hover .sync-exclude-folder-remove { visibility: visible; } -.tag-pane-tag.is-active { background-color: var(--interactive-accent); color: var(--text-on-accent); } -.tag-pane-tag.is-active .tag-pane-tag-count { background-color: var(--background-modifier-hover); color: var(--text-normal); } -@media (hover: hover) { - .tag-pane-tag.is-active:hover { background-color: var(--interactive-accent); color: var(--text-on-accent); } -} -.tag-container { font-size: var(--font-ui-small); padding: var(--size-4-3) var(--size-4-3) var(--size-4-8); overflow: auto; } -.tree-item-children .tag-pane-tag .tag-pane-tag-parent { display: none; } -.workspace-leaf.mod-active .tree-item.has-focus > .tag-pane-tag { border-radius: var(--radius-s); box-shadow: 0 0 0 2px var(--background-modifier-border-focus); } -.mod-canvas-color-1 { --canvas-color: var(--canvas-color-1); } -.mod-canvas-color-2 { --canvas-color: var(--canvas-color-2); } -.mod-canvas-color-3 { --canvas-color: var(--canvas-color-3); } -.mod-canvas-color-4 { --canvas-color: var(--canvas-color-4); } -.mod-canvas-color-5 { --canvas-color: var(--canvas-color-5); } -.mod-canvas-color-6 { --canvas-color: var(--canvas-color-6); } -.workspace-leaf-content[data-type="canvas"] .view-content { padding: 0px; position: relative; } -body { --canvas-color: 192, 192, 192; } -body.theme-dark { --canvas-color: 126, 126, 126; } -.canvas-wrapper { position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; --resizer-size: 20px; --shadow-stationary: 0px 0.5px 1px 0.5px rgba(0, 0, 0, 0.1); --shadow-drag: 0px 2px 10px rgba(0, 0, 0, 0.1); --shadow-border-accent: 0 0 0 2px var(--color-accent); --zoom-multiplier: 1; background-color: var(--canvas-background); overflow: hidden; contain: strict; touch-action: none; user-select: none; } -.canvas-wrapper.is-dragging { cursor: grabbing; } -.canvas-wrapper.is-dragging iframe:not(.is-controlled), .canvas-wrapper.is-dragging webview { pointer-events: none; } -.canvas-wrapper.is-screenshotting { z-index: 999999; } -.canvas-wrapper.is-screenshotting .canvas-card-menu, .canvas-wrapper.is-screenshotting .canvas-controls { display: none !important; } -.canvas-wrapper.is-screenshotting * { pointer-events: none !important; } -.canvas-mover { position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; cursor: grab; } -.canvas-mover:active { cursor: grabbing; } -.canvas-background { position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; pointer-events: none; } -.canvas-background circle { fill: var(--canvas-dot-pattern); } -.canvas { position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; transform-origin: 0px 0px; pointer-events: none; } -.canvas > * { pointer-events: initial; } -.canvas-selection { pointer-events: none; position: absolute; background-color: hsla(var(--color-accent-hsl), 0.1); border: 2px solid var(--color-accent); z-index: -1; } -.canvas-selection.mod-group-selection { border-width: 3px; border-radius: 3px; background-color: hsla(var(--color-accent-hsl), 0.03); border-color: hsla(var(--color-accent-hsl), 0.3); pointer-events: initial; } -.canvas-wrapper:not(.mod-readonly) .canvas-selection.mod-group-selection { cursor: grab; } -.canvas-wrapper:not(.mod-readonly) .canvas-selection.mod-group-selection:active { cursor: grabbing; } -.canvas-selection.mod-node-highlight { border-radius: var(--radius-m); } -.canvas-controls, .canvas-card-menu { display: flex; position: absolute; z-index: var(--layer-cover); font-size: var(--font-ui-medium); } -.canvas-card-menu { background-color: var(--background-primary); border-radius: var(--radius-s); box-shadow: var(--input-shadow); bottom: var(--size-4-4); left: 50%; transform: translateX(-50%); align-items: stretch; } -.is-phone .canvas-card-menu, .mod-toolbar-open .canvas-card-menu { display: none; } -.theme-dark .canvas-card-menu { background-color: var(--background-secondary); } -.canvas-card-menu .canvas-card-menu-divider { width: 1px; background-color: var(--background-modifier-border); } -.canvas-card-menu .canvas-card-menu-button { color: var(--text-muted); height: auto; display: flex; line-height: 1; align-items: center; justify-content: center; padding: var(--size-4-2); --icon-size: var(--icon-xl); --icon-stroke: var(--icon-xl-stroke-width); } -@media (hover: hover) { - .canvas-card-menu .canvas-card-menu-button:hover { color: var(--color-accent); } -} -.canvas-card-menu .canvas-card-menu-button svg { fill: var(--background-primary); } -.theme-dark .canvas-card-menu .canvas-card-menu-button svg { fill: var(--background-secondary); } -.canvas-card-menu .canvas-card-menu-button.mod-draggable { cursor: grab; } -.canvas-card-menu .canvas-card-menu-button.mod-draggable:active { cursor: grabbing; } -.canvas-card-menu .canvas-card-menu-button.mod-draggable svg { transition: transform 90ms ease-out 0s; } -@media (hover: hover) { - .canvas-card-menu .canvas-card-menu-button.mod-draggable:hover svg { transform: translateY(-6px); filter: drop-shadow(rgba(0, 0, 0, 0.1) 0px 6px 2px); } -} -.canvas-controls { right: var(--size-4-2); top: var(--size-4-2); gap: var(--size-4-2); display: flex; flex-direction: column; } -.canvas-control-group { border-radius: var(--radius-s); background-color: var(--background-primary); border: 1px solid var(--background-modifier-border); box-shadow: var(--input-shadow); display: flex; flex-direction: column; overflow: hidden; } -.canvas-control-item { border-radius: 0px; box-shadow: none; height: auto; display: flex; line-height: 1; font-size: inherit; align-items: center; justify-content: center; cursor: var(--cursor); padding: var(--size-4-2); border-bottom: 1px solid var(--background-modifier-border); color: var(--text-muted); background-color: var(--interactive-normal); --icon-size: var(--icon-s); --icon-stroke: var(--icon-s-stroke-width); } -.canvas-control-item:last-child { border-bottom: none; } -@media (hover: hover) { - .canvas-control-item:hover { color: var(--text-normal); background-color: var(--interactive-hover); } -} -.canvas-control-item.is-active { color: var(--color-accent); } -.canvas-control-item.is-disabled svg { color: var(--text-faint); } -.canvas-control-item svg { pointer-events: none; } -.canvas-node-container { background-color: var(--background-primary); border-radius: var(--radius-m); border: 2px solid rgb(var(--canvas-color)); contain: strict; display: flex; flex-direction: column; overflow: hidden; position: absolute; left: 0px; top: 0px; width: 100%; height: 100%; box-shadow: var(--shadow-stationary); } -.canvas-wrapper:not(.mod-readonly) .canvas-node:not(.is-editing) .canvas-node-container { cursor: grab; } -.canvas-wrapper:not(.mod-readonly) .canvas-node:not(.is-editing) .canvas-node-container:active { cursor: grabbing; } -.canvas-node-label { position: absolute; left: 0px; top: calc(-1 * var(--size-4-1) * var(--zoom-multiplier)); transform: translate(0, -100%) scale(var(--zoom-multiplier)); transform-origin: left bottom; max-width: calc(100% / var(--zoom-multiplier)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--canvas-card-label-color); --icon-size: 1em; } -body:not(.is-ios) .canvas-wrapper.mod-animating .canvas-node-label { transition: transform 500ms cubic-bezier(0.16, 1, 0.3, 1) 0s; } -.canvas-node-label svg { position: relative; top: 2px; margin-right: var(--size-4-1); } -.canvas-node-label.mod-hover-label { opacity: 0; } -@media (hover: hover) { - .canvas-node-label:hover { color: var(--text-muted); } - .canvas-node:hover .canvas-node-label.mod-hover-label { opacity: 1; } -} -@media (hover: none) { - .canvas-node.is-focused .canvas-node-label.mod-hover-label { opacity: 1; } -} -.canvas-wrapper.mod-zoomed-out .canvas-node-label { display: none; } -.canvas-node-placeholder { display: flex; align-items: center; justify-content: center; text-align: center; width: 100%; height: 100%; overflow: hidden; overflow-wrap: anywhere; padding: var(--size-4-6); font-size: 32px; font-weight: var(--font-semibold); } -.canvas-node-placeholder::after { border-radius: var(--radius-s); content: " "; display: block; position: absolute; top: var(--size-4-4); right: var(--size-4-4); bottom: var(--size-4-4); left: var(--size-4-4); background-color: rgba(var(--canvas-color), 0.1); } -.canvas-icon-placeholder { display: flex; width: 40%; height: 40%; } -.canvas-icon-placeholder svg { opacity: 0.3; color: rgb(var(--canvas-color)); width: 100%; height: 100%; } -.canvas-node-interaction-layer { position: absolute; width: 0px; height: 0px; pointer-events: none; } -.canvas-node-interaction-layer > * { pointer-events: initial; } -.canvas-node { --shadow-border-themed-inset: inset 0 0 0 1px rgb(var(--canvas-color)); --shadow-border-themed: 0 0 0 2px rgb(var(--canvas-color)); position: absolute; width: 0px; height: 0px; } -.canvas-node.is-dragging { pointer-events: none; } -.canvas-node.is-dragging .canvas-node-container { box-shadow: var(--shadow-drag); } -.canvas-node.is-selected, .canvas-node.is-focused { touch-action: initial; } -.canvas-node.is-selected .canvas-node-label, .canvas-node.is-focused .canvas-node-label { color: var(--text-muted); } -.canvas-node.is-selected .canvas-node-container, .canvas-node.is-focused .canvas-node-container { border-color: var(--color-accent); box-shadow: var(--shadow-stationary), var(--shadow-border-accent); } -.canvas-node.is-selected.is-dragging .canvas-node-container, .canvas-node.is-focused.is-dragging .canvas-node-container { box-shadow: var(--shadow-drag), var(--shadow-border-accent); } -.canvas-node.is-themed .canvas-node-container { border-color: rgba(var(--canvas-color), 0.7); box-shadow: inset 0 0 0 1px rgba(var(--canvas-color), 0.7), var(--shadow-stationary); } -.canvas-node.is-selected.is-themed .canvas-node-container, .canvas-node.is-focused.is-themed .canvas-node-container { border-color: rgb(var(--canvas-color)); box-shadow: var(--shadow-border-themed-inset), var(--shadow-border-themed); } -.canvas-node.is-selected.is-themed.is-dragging .canvas-node-container, .canvas-node.is-focused.is-themed.is-dragging .canvas-node-container { box-shadow: var(--shadow-border-themed-inset), var(--shadow-border-themed); } -.canvas-node.is-dummy { cursor: grabbing; } -.canvas-node.is-dummy .canvas-node-container { border: 4px solid var(--color-accent); box-shadow: rgba(0, 0, 0, 0.15) 0px 2px 10px; background-color: hsla(var(--color-accent-hsl), 0.2); } -.canvas-node.is-focused:not(.is-dragging) .canvas-node-content-blocker { display: none; } -.canvas-node-content-blocker { position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; z-index: var(--layer-cover); } -.canvas-node-group:not(.is-focused):not(.is-selected) { pointer-events: none; } -.canvas-node-group .canvas-node-resizer { pointer-events: initial; } -.canvas-node-group .canvas-node-container { background-color: transparent; } -.canvas-node-group .canvas-node-content { background-color: rgba(var(--canvas-color), 0.07); } -.canvas-group-label { position: absolute; left: 0px; top: calc(-1 * var(--size-4-1) * var(--zoom-multiplier)); transform: translate(0, -100%) scale(var(--zoom-multiplier)); transform-origin: left bottom; max-width: calc(100% / var(--zoom-multiplier)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; pointer-events: initial; font-size: 1.5em; padding: var(--size-4-1) var(--size-4-2); border-radius: var(--radius-s); color: var(--text-muted); background-color: rgba(var(--canvas-color), 0.1); line-height: 1; } -body:not(.is-ios) .canvas-wrapper.mod-animating .canvas-group-label { transition: transform 500ms cubic-bezier(0.16, 1, 0.3, 1) 0s; } -.canvas-wrapper:not(.mod-readonly) .canvas-group-label { cursor: grab; } -.canvas-wrapper:not(.mod-readonly) .canvas-group-label:active { cursor: grabbing; } -.canvas-group-label[contenteditable="true"] { cursor: text; background-color: var(--background-primary); box-shadow: 0 0 0 2px rgb(var(--canvas-color)); color: var(--text-normal); text-overflow: initial; } -.canvas-node-group.is-themed .canvas-group-label:not([contenteditable="true"]) { background-color: rgb(var(--canvas-color)); } -.canvas-node-group.is-themed .canvas-group-label:not([contenteditable="true"]).mod-foreground-light { color: var(--text-on-accent); } -.canvas-node-group.is-themed .canvas-group-label:not([contenteditable="true"]).mod-foreground-dark { color: var(--text-on-accent-inverted); } -.canvas-node-content { backface-visibility: hidden; width: 100%; height: 100%; overflow: hidden; position: relative; } -.canvas-node-content.markdown-embed { border: none; padding: 0px; } -.canvas-node-content.markdown-embed .inline-title { cursor: text; } -.canvas-node-content.markdown-embed > .markdown-embed-content > .markdown-preview-view { padding: 0 var(--size-4-6); display: flex; flex-direction: column; } -.canvas-wrapper:not(.mod-readonly) .canvas-node-content.markdown-embed > .markdown-embed-content > .markdown-preview-view { user-select: none; } -.canvas-node-content.markdown-embed > .markdown-embed-content > .markdown-preview-view::before, .canvas-node-content.markdown-embed > .markdown-embed-content > .markdown-preview-view::after { content: " "; display: block; min-height: min(calc(var(--canvas-node-height) * 0.1 - 3px), var(--size-4-6)); max-height: var(--size-4-4); flex: 1 1 0px; } -.canvas-node-content.markdown-embed > .markdown-embed-content > .markdown-preview-view > .markdown-preview-sizer { flex: 1 0 0px; } -.canvas-node-content.markdown-embed > .markdown-embed-content > .markdown-preview-view .callout { mix-blend-mode: normal; } -.canvas-node-content.markdown-embed > .markdown-embed-content > .markdown-preview-view .markdown-preview-pusher + div > :first-child { margin-top: 0px; } -.canvas-node-content.markdown-embed > .markdown-embed-content > .markdown-preview-view .mod-header + div > :first-child { margin-top: 0px; } -.canvas-node-content.markdown-embed > .markdown-embed-content > .markdown-preview-view .markdown-preview-sizer > div:last-child > :last-child { margin-bottom: 0px; } -.is-focused .canvas-node-content.markdown-embed > .markdown-embed-content > .markdown-preview-view { transform: translateZ(0px); } -.canvas-node.is-themed .canvas-node-content { background-color: rgba(var(--canvas-color), 0.07); } -.canvas-node-content.media-embed { justify-content: center; align-items: center; display: flex; } -.canvas-node-content.media-embed img, .canvas-node-content.media-embed video, .canvas-node-content.media-embed audio { flex-shrink: 0; flex-grow: 1; } -.canvas-node-content.media-embed img:not([width]), .canvas-node-content.media-embed video, .canvas-node-content.media-embed audio { max-width: 100%; } -.canvas-node-resizer { position: absolute; height: calc(var(--resizer-size) * var(--zoom-multiplier)); width: calc(var(--resizer-size) * var(--zoom-multiplier)); } -.is-selected .canvas-node-resizer { pointer-events: none; } -body.is-mobile .canvas-node-resizer { --zoom-multiplier: 1; } -.canvas-wrapper.mod-readonly .canvas-node-resizer { display: none; } -.canvas-node-resizer[data-resize="top"] { left: 0px; right: 0px; width: auto; top: calc(var(--resizer-size) * var(--zoom-multiplier) * -0.5); cursor: ns-resize; } -.canvas-node-resizer[data-resize="bottom"] { left: 0px; right: 0px; width: auto; bottom: calc(var(--resizer-size) * var(--zoom-multiplier) * -0.5); cursor: ns-resize; } -.canvas-node-resizer[data-resize="left"] { top: 0px; bottom: 0px; height: auto; left: calc(var(--resizer-size) * var(--zoom-multiplier) * -0.5); cursor: ew-resize; } -.canvas-node-resizer[data-resize="right"] { top: 0px; bottom: 0px; height: auto; right: calc(var(--resizer-size) * var(--zoom-multiplier) * -0.5); cursor: ew-resize; } -.canvas-node-resizer[data-resize="topright"] { right: calc(var(--resizer-size) * var(--zoom-multiplier) * -0.5); top: calc(var(--resizer-size) * var(--zoom-multiplier) * -0.5); cursor: nesw-resize; } -.canvas-node-resizer[data-resize="bottomright"] { right: calc(var(--resizer-size) * var(--zoom-multiplier) * -0.5); bottom: calc(var(--resizer-size) * var(--zoom-multiplier) * -0.5); cursor: nwse-resize; } -.canvas-node-resizer[data-resize="topleft"] { left: calc(var(--resizer-size) * var(--zoom-multiplier) * -0.5); top: calc(var(--resizer-size) * var(--zoom-multiplier) * -0.5); cursor: nwse-resize; } -.canvas-node-resizer[data-resize="bottomleft"] { left: calc(var(--resizer-size) * var(--zoom-multiplier) * -0.5); bottom: calc(var(--resizer-size) * var(--zoom-multiplier) * -0.5); cursor: nesw-resize; } -.is-mobile .canvas-node-resizer { pointer-events: none; } -.is-mobile .canvas-wrapper:not(.mod-readonly) .canvas-node-interaction-layer .canvas-node-resizer[data-resize="topright"], .is-mobile .canvas-wrapper:not(.mod-readonly) .canvas-node-interaction-layer .canvas-node-resizer[data-resize="bottomright"], .is-mobile .canvas-wrapper:not(.mod-readonly) .canvas-node-interaction-layer .canvas-node-resizer[data-resize="topleft"], .is-mobile .canvas-wrapper:not(.mod-readonly) .canvas-node-interaction-layer .canvas-node-resizer[data-resize="bottomleft"] { pointer-events: all; width: 20px; height: 20px; display: block; background-color: var(--background-primary); border: 2px solid var(--color-accent); border-radius: 3px; } -.canvas-node-connection-point { width: calc(var(--resizer-size) * var(--zoom-multiplier)); height: calc(var(--resizer-size) * var(--zoom-multiplier)); position: absolute; pointer-events: all; cursor: pointer; } -.canvas-node-connection-point[data-side="top"] { top: 1px; left: calc(50% - var(--resizer-size) * var(--zoom-multiplier) / 2); } -.canvas-node-connection-point[data-side="right"] { right: 1px; top: calc(50% - var(--resizer-size) * var(--zoom-multiplier) / 2); } -.canvas-node-connection-point[data-side="bottom"] { bottom: 1px; left: calc(50% - var(--resizer-size) * var(--zoom-multiplier) / 2); } -.canvas-node-connection-point[data-side="left"] { left: 1px; top: calc(50% - var(--resizer-size) * var(--zoom-multiplier) / 2); } -.canvas-node-connection-point::after { content: " "; background-color: var(--color-accent); border-radius: 50%; border: 3px solid var(--background-modifier-border); box-sizing: border-box; display: block; height: calc(var(--resizer-size) * var(--zoom-multiplier)); opacity: 0; position: relative; width: calc(var(--resizer-size) * var(--zoom-multiplier)); left: 0px; top: 0px; } -.is-mobile .canvas-node-interaction-layer .canvas-node-connection-point::after, .canvas-node-resizer:hover .canvas-node-connection-point::after { opacity: 1; } -.canvas-snaps { position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; overflow: visible; pointer-events: none; opacity: 0.6; } -.canvas-snaps line { stroke-width: 1px; stroke: var(--color-accent); } -.canvas-snaps circle { fill: var(--color-accent); } -.canvas-edges { position: absolute; width: 100%; height: 100%; left: 0px; top: 0px; overflow: visible; pointer-events: none; } -.canvas-edges > * { pointer-events: initial; } -.canvas-edges path.canvas-display-path { pointer-events: none; stroke-width: calc(3px * var(--zoom-multiplier)); stroke: rgb(var(--canvas-color)); fill: none; transition: stroke-width 100ms ease-out 0s; } -.canvas-edges path.canvas-interaction-path { pointer-events: stroke; stroke-width: calc(24px * var(--zoom-multiplier)); stroke-linecap: round; stroke: transparent; fill: none; transition: stroke 100ms ease-out 0s; } -.canvas-wrapper:not(.mod-readonly) .canvas-edges path.canvas-interaction-path { cursor: grab; } -.canvas-wrapper:not(.mod-readonly) .canvas-edges path.canvas-interaction-path:active { cursor: grabbing; } -.canvas-edges polygon.canvas-path-end { pointer-events: none; stroke: rgb(var(--canvas-color)); fill: rgb(var(--canvas-color)); stroke-linecap: round; stroke-linejoin: round; stroke-width: 1px; transform-box: fill-box; transform: scale(var(--zoom-multiplier)); transform-origin: center top; } -.canvas-edges g.is-focused path.canvas-display-path, .canvas:not(.is-connecting) .canvas-edges g:hover path.canvas-display-path { stroke-width: calc(5.5px * var(--zoom-multiplier)); } -.canvas-edges g.is-focused path.canvas-interaction-path, .canvas:not(.is-connecting) .canvas-edges g:hover path.canvas-interaction-path { stroke: rgba(var(--canvas-color), 0.1); } -.canvas-path-label-wrapper { position: absolute; width: fit-content; height: fit-content; } -.canvas-path-label { font-size: calc(var(--font-ui-large) * var(--zoom-multiplier)); background-color: var(--background-primary); border-radius: var(--radius-s); padding: calc(var(--size-2-3) * var(--zoom-multiplier)); line-height: var(--line-height-tight); white-space: pre-wrap; transform: translate(-50%, -50%); text-align: center; max-width: calc(17em * var(--zoom-multiplier)); } -.canvas-path-label.is-editing { border-color: rgb(var(--canvas-color)); box-shadow: var(--shadow-stationary), 0 0 0 calc(3px * var(--zoom-multiplier)) rgb(var(--canvas-color)); } -.canvas-menu-container { position: absolute; width: 0px; height: 0px; top: 0px; left: 0px; } -.canvas-menu { position: relative; width: fit-content; height: fit-content; line-height: 1; background-color: var(--background-primary); border: 1px solid var(--background-modifier-border); border-radius: var(--radius-s); box-shadow: rgba(0, 0, 0, 0.07) 0px 2px 10px; display: flex; padding: var(--size-2-1); gap: 1px; } -.canvas-menu .clickable-icon { padding: var(--size-2-3) var(--size-4-2); } -.canvas-submenu { display: flex; position: absolute; top: calc(100% + 5px); left: 50%; transform: translateX(-50%); padding: var(--size-4-2); border: 1px solid var(--background-modifier-border); background-color: var(--background-primary); border-radius: var(--radius-s); box-shadow: rgba(0, 0, 0, 0.07) 0px 2px 10px; overflow: hidden; gap: 1px; } -.canvas-submenu .clickable-icon { padding: var(--size-2-2) var(--size-2-3); } -.canvas-color-picker-item { cursor: var(--cursor); width: 24px; height: 24px; margin: 2px; border-radius: 12px; border: 2px solid var(--background-primary); background-color: rgb(var(--canvas-color)); } -.canvas-color-picker-item.is-active { box-shadow: 0 0 0 2px rgb(var(--canvas-color)); } -@media (hover: hover) { - .canvas-color-picker-item:hover { box-shadow: 0 0 0 2px rgb(var(--canvas-color)); } -} -.canvas-color-picker-item input[type="color"] { margin: -4px 0px 0px -2px; --swatch-width: 20px; --swatch-height: 20px; opacity: 0; } -.canvas-color-picker-item.canvas-color-picker-custom:not(.is-active) { background: conic-gradient(var(--color-red), var(--color-yellow), var(--color-green), var(--color-blue), var(--color-purple), var(--color-red)); } -@media (hover: hover) { - .canvas-color-picker-item.canvas-color-picker-custom:not(.is-active):hover { box-shadow: 0 0 0 2px var(--background-modifier-border-hover); } -} -.canvas-empty-embed-container { align-items: center; display: flex; flex-direction: column; gap: var(--size-4-6); justify-content: center; height: 100%; padding: var(--size-4-3); text-align: center; } -.canvas-empty-embed-action-list { display: flex; flex-direction: column; gap: var(--size-4-3); } -.canvas-empty-embed-action-list button { font-size: var(--font-text-size); padding: var(--size-4-5) var(--size-4-9); } -.canvas-help { display: flex; flex-direction: column; gap: var(--size-4-3); } -.canvas-instruction { display: flex; justify-content: space-between; } -.canvas-instruction-desc { display: flex; gap: var(--size-4-1); } -.canvas-instruction-desc .setting-hotkey { display: inline; align-self: unset; padding: var(--size-4-1); margin: 0px; line-height: 1; } -.canvas-placeholder-message { max-width: 70vw; background: hsla(var(--color-accent-hsl), 0.1); border-radius: var(--radius-m); color: var(--color-accent); font-size: var(--font-ui-large); line-height: var(--line-height-normal); padding: var(--size-4-4) var(--size-4-6); pointer-events: none; position: absolute; text-align: center; transform: translate(-50%, -50%); } -.canvas-minimap { width: 100%; height: 100%; padding: var(--size-4-1); } -.inline-embed > .canvas-minimap { max-height: var(--embed-canvas-max-height); } -.canvas-minimap rect { stroke-width: 5px; stroke: var(--background-modifier-border); fill: var(--background-modifier-border); fill-opacity: 0.65; } -.canvas-minimap rect.is-themed { stroke: rgb(var(--canvas-color)); fill: rgb(var(--canvas-color)); fill-opacity: 0.5; } -.canvas-minimap path { stroke: rgb(192, 192, 192); fill: none; } -.canvas-minimap path.is-themed { stroke: rgb(var(--canvas-color)); } -.canvas-cursor { position: absolute; width: 1px; height: 1px; border: 5px solid var(--color-accent); border-radius: 5px; pointer-events: none; } -.canvas-watermark * { font-family: var(--font-default) !important; } -.starter.is-hidden-frameless .titlebar { display: block; } -.starter { user-select: none; padding-top: 0px !important; } -.starter .titlebar { background-color: transparent; border: none; } -.starter .titlebar-inner .titlebar-text { display: none; } -.starter-screen { display: flex; flex-direction: column; background-color: var(--background-primary); width: 100%; height: 100%; } -.starter-screen-inner { flex-grow: 1; display: flex; height: calc(100% - 24px); } -.splash { align-items: center; background-color: var(--background-primary); display: flex; flex-direction: column; justify-content: center; flex: 1 1 auto; text-align: center; padding: 36px 0px 0px; } -.splash-brand { flex: 0 0 content; padding: 20px 0px; } -.splash-brand-logo-text { margin-top: 20px; color: white; } -.splash-brand-version { color: var(--text-muted); margin-top: 8px; font-size: var(--font-ui-small); } -.help-options-container { flex: 1 0 0px; overflow: auto; width: 100%; max-width: 82%; text-align: left; padding: var(--size-4-6) 0; } -.help-options-container::-webkit-scrollbar { display: none; } -.help-options-container .setting-item-description { max-width: 30em; padding-right: 12px; } -.help-options-container .setting-icon .svg-icon { stroke-width: 1px; --icon-size: 48px; color: var(--text-faint); } -.open-vault-options-container { flex: 1 0 0px; overflow: auto; width: 100%; position: relative; } -.open-vault-options-container::-webkit-scrollbar { display: none; } -.open-vault-options { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; padding: 12px 36px; text-align: left; overflow-y: auto; display: flex; flex-direction: column; } -.open-vault-options input[type="text"] { width: 150px; } -.open-vault-options .setting-item-control button { width: 100px; } -.open-vault-options .back-button { display: flex; align-items: center; app-region: no-drag; color: var(--text-muted); user-select: none; cursor: var(--cursor); } -@media (hover: hover) { - .open-vault-options .back-button:hover { color: var(--text-normal); } -} -.open-vault-options .setting-item-description { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; } -.open-vault-options.mod-login { justify-content: flex-start; } -.open-vault-options.mod-login input[type="text"] { width: 250px; } -.quick-start-container { margin-bottom: 10px; } -.quick-start-container button { font-size: var(--font-ui-medium); padding: 8px 60px; } -.quick-start-container + .setting-item { border-top: none; } -.open-folder-input[type="text"] { font-size: var(--font-ui-small); width: 200px; height: 28px; } -.browse-folder-button { margin-left: 10px; } -.open-folder-button { margin-top: 14px; padding: 6px 36px; } -.starter .notice { top: 38px; } -.setting-item.mod-change-language { app-region: no-drag; } -.setting-item.mod-change-language .setting-item-info { flex-grow: 0; } -.setting-item.mod-change-language .setting-item-control { flex-grow: 1; justify-content: flex-start; } -.setting-item.mod-change-language select { width: 100%; max-width: 100%; } -.setting-item.mod-change-language .setting-item-name { color: var(--text-faint); position: relative; top: 3px; cursor: var(--cursor); } -@media (hover: hover) { - .setting-item.mod-change-language .setting-item-name:hover { color: var(--text-muted); } -} -.setting-icon { display: flex; color: var(--text-muted); margin-right: 24px; } -.choose-vault-clickable-area { text-align: center; padding: 40px 60px; border: 5px dashed var(--interactive-accent); border-radius: 10px; cursor: var(--cursor); } -@media (hover: hover) { - .choose-vault-clickable-area:hover { background-color: hsla(var(--interactive-accent-hsl), 0.4); border: 5px solid hsla(var(--interactive-accent-hsl), 0.4); } -} -.choose-vault-label-welcome { line-height: 46px; color: var(--text-muted); } -.choose-vault-label-choose { font-weight: var(--font-extrabold); font-size: 32px; } -.recent-vaults { background-color: var(--background-secondary); border-right: 1px solid var(--background-modifier-border); padding: var(--size-4-8) 0 0 0; flex-shrink: 0; width: 280px; overflow-y: hidden; height: 100%; } -.recent-vaults-header { height: 30px; line-height: 30px; font-size: 18px; color: var(--text-muted); } -.recent-vaults-list { overflow-y: auto; height: 100%; padding: var(--size-4-2); display: flex; flex-direction: column; } -.recent-vaults-list::after { app-region: drag; display: block; content: " "; width: 100%; height: 100px; flex-grow: 1; } -.recent-vaults-list-item { app-region: no-drag; border-radius: var(--radius-s); margin-bottom: var(--size-4-1); padding: var(--size-4-2) var(--size-4-6) var(--size-4-2) var(--size-4-3); cursor: var(--cursor); position: relative; } -@media (hover: hover) { - .recent-vaults-list-item:hover { background-color: var(--background-modifier-hover); color: var(--text-on-accent); } -} -.recent-vaults-list-item-name, .recent-vaults-list-item-path { word-break: break-all; } -.recent-vaults-list-item-name { border-radius: 2px; border: 1px solid transparent; } -.recent-vaults-list-item-name[contenteditable] { cursor: text; border-color: var(--interactive-accent); background-color: var(--background-modifier-hover); font-size: 0.9em; padding: 0 var(--size-4-1); } -.recent-vaults-list-item-path { font-size: var(--font-ui-smaller); color: var(--text-muted); line-height: 16px; } -.recent-vaults-list-item-option-button { position: absolute; top: var(--size-4-3); right: var(--size-4-1); color: var(--text-faint); width: 30px; height: 30px; line-height: 36px; text-align: center; transition: background-color 200ms ease-in-out 0s; } -.recent-vaults-list-item-option-button:hover { color: var(--text-normal); } -:root { --safe-area-inset-top: env(safe-area-inset-top); --safe-area-inset-bottom: env(safe-area-inset-bottom); --safe-area-inset-left: env(safe-area-inset-left); --safe-area-inset-right: env(safe-area-inset-right); } -.is-mobile { --ribbon-width: 58px; --view-header-height: 50px; --mobile-toolbar-height: 40px; --caret-color: var(--text-accent); --font-ui-smaller: calc(var(--font-text-size) * 0.8); --font-ui-small: calc(var(--font-text-size) * 0.937); --font-ui-medium: var(--font-text-size); --font-ui-large: calc(var(--font-text-size) * 1.2); --icon-s: 18px; --icon-m: 20px; --icon-l: 24px; --icon-l-stroke-width: 1.8px; --icon-opacity: 1; --input-height: 40px; --input-shadow: none; --input-shadow-hover: none; --input-font-weight: var(--font-medium); --input-border-width: 0px; --interactive-normal: var(--background-secondary); --mobile-sidebar-width: 340px; --mobile-sidebar-max-width: 500px; --nav-item-padding: var(--size-2-3) var(--size-4-2) var(--size-2-3) var(--size-4-6); --nav-item-color: var(--text-normal); --search-clear-button-size: 16px; --search-icon-size: 20px; --settings-home-background: var(--background-secondary); --slider-thumb-border-width: 0px; --slider-thumb-height: 24px; --slider-thumb-width: 24px; --slider-thumb-y: -9px; --slider-track-height: 6px; --swatch-shadow: none; --swatch-height: 40px; --swatch-width: 40px; --swatch-radius: 40px; --toggle-width: 48px; --toggle-radius: 26px; --toggle-thumb-radius: 26px; --toggle-thumb-height: 26px; --toggle-thumb-width: 26px; --file-margins: var(--size-4-2) var(--size-4-5); --background-modifier-cover: rgba(0, 0, 0, 0.25); --background-modifier-form-field: var(--background-secondary); --keyboard-background: var(--background-primary); --checkbox-size: 17px; } -.is-mobile.theme-dark { --color-base-00: #000; --color-base-10: #111; --color-base-20: #1e1e1e; --tag-background: hsla(var(--interactive-accent-hsl), 0.2); --modal-background: var(--background-secondary); --search-result-background: var(--background-secondary); --background-modifier-form-field: var(--background-modifier-border); --background-modifier-cover: rgba(0, 0, 0, 0.5); --background-modifier-hover: rgba(var(--mono-rgb-100), 0.15); --settings-home-background: var(--background-primary); } -.is-tablet { --nav-item-padding: var(--size-2-3) var(--size-4-2) var(--size-2-3) var(--size-4-6); --tab-font-size: var(--font-ui-smaller); } -.is-tablet.theme-dark { --titlebar-background: var(--background-primary); --titlebar-background-focused: var(--background-primary); --interactive-normal: var(--background-modifier-border); } -.is-phone { --border-width: 0.5pt; --divider-width: 0.5pt; --tab-outline-width: 0.5pt; --modal-header-height: 44px; --modal-community-sidebar-width: 100%; --nav-item-size: var(--font-ui-medium); } -body.is-mobile { height: 100vh; width: 100vw; caret-color: var(--caret-color); padding-bottom: 50px; } -.is-mobile .markdown-source-view.mod-cm6 .cm-content, .is-mobile .mod-cm6 .cm-line { caret-color: var(--caret-color); } -.is-mobile .markdown-source-view.mod-cm6 .cm-gutters { margin-left: -18px; } -.is-mobile .workspace > .mod-root { padding-left: var(--safe-area-inset-left); } -body.is-mobile { padding: var(--safe-area-inset-top) 0 0 0; text-size-adjust: 100%; } -.is-mobile .workspace-split.mod-left-split, .is-mobile .workspace-split.mod-right-split { display: none; } -.is-mobile .tree-item .tree-item-self { padding-right: var(--size-4-2); } -.is-mobile .input-label { display: block; text-align: left; color: var(--text-muted); margin-bottom: 8px; } -.is-mobile input[type="text"] { display: block; width: 100%; padding: 8px 12px; height: auto; } -.is-mobile .markdown-rendered pre:not(:hover) > button.copy-code-button { display: block; } -.is-mobile .markdown-rendered button.copy-code-button { width: auto; } -.is-mobile .empty-state-action-list { margin-top: 40px; } -.is-mobile .empty-state-action { background-color: var(--background-primary-alt); margin: 12px 0px; padding: 6px 30px; border-radius: var(--button-radius); text-align: center; } -.is-mobile .login-field { width: 100%; margin: 0.5em 0px; } -.is-mobile .login-field input { width: 100%; } -.is-mobile .markdown-rendered .frontmatter-container { margin-top: 20px; } -.is-mobile .markdown-rendered .heading-collapse-indicator { margin-left: -20px; } -.is-mobile .markdown-rendered ul, .is-mobile .markdown-rendered ol { padding-inline-start: 25px; } -.is-mobile .message-container { text-align: center; margin: 8px 0px; } -.is-mobile .search-result-file-match-replace-button { display: block; position: relative; padding: 6px 10px; right: 0px; margin-top: var(--size-4-3); background-color: var(--settings-home-background); } -.is-mobile .suggestion-flair { position: relative; margin-right: 6px; left: 0px; top: 0px; } -.is-mobile .document-search-container { height: auto; margin-left: 0px; margin-right: 0px; padding: 0 var(--size-4-4) var(--size-4-2); border-bottom: var(--border-width) solid var(--background-modifier-border); } -.is-mobile .document-search-container.mod-replace-mode { height: auto; } -.is-mobile .document-search, .is-mobile .document-replace { height: auto; padding: 0px; } -.is-mobile .document-search .document-search-button, .is-mobile .document-replace .document-search-button { height: auto; padding: 6px 0px; background-color: transparent; color: var(--text-accent); } -.is-mobile .document-search input, .is-mobile .document-replace input, .is-mobile .document-search button, .is-mobile .document-replace button { width: auto; flex-grow: 1; } -.is-mobile .document-search .document-search-buttons, .is-mobile .document-replace .document-search-buttons, .is-mobile .document-search .document-replace-buttons, .is-mobile .document-replace .document-replace-buttons { display: flex; flex-grow: 1; } -.is-mobile .document-search .document-search-close-button, .is-mobile .document-replace .document-search-close-button { height: 34px; line-height: 34px; top: 0px; } -.is-tablet .mod-left-split-toggle { display: none; } -.is-tablet button:not(.clickable-icon) { padding: var(--size-4-1) var(--size-4-5); } -.is-phone button { width: 100%; } -.is-phone .vault-list-item-creation-time { display: none; } -.is-phone .vault-list-item { padding: 5px 0px; } -.is-phone .vault-list-item .flair { display: none; } -.is-phone .vault-list-item-title { flex: 1 0 auto; } -.is-phone .vault-list-item-button { margin-right: 0px; } -.suggestion-bg { display: none; } -body.is-phone .suggestion-bg { display: block; } -@keyframes fadeIn { - 0% { opacity: 0; } - 100% { opacity: 1; } -} -@keyframes fadeOut { - 0% { opacity: 1; } - 100% { opacity: 0; } -} -.mobile-image-viewer { position: absolute; height: 100%; width: 100%; top: 0px; left: 0px; background-color: var(--background-modifier-cover); display: flex; justify-content: center; overflow: hidden; z-index: var(--layer-modal); } -.mobile-image-viewer img { align-self: center; max-height: 100%; max-width: 100%; } -.mod-tappable { transition: opacity 0.15s ease-in-out 0s; } -.mod-tappable.mod-tap { opacity: 0.5; } -.is-mobile .document-search-container { height: auto; margin-left: 0px; margin-right: 0px; padding: 0 var(--size-4-4) var(--size-4-2); border-bottom: var(--border-width) solid var(--background-modifier-border); } -.is-mobile .document-search-container.mod-replace-mode { height: auto; } -.is-mobile .document-search, .is-mobile .document-replace { height: auto; padding: 0px; } -.is-mobile .document-search .document-search-button, .is-mobile .document-replace .document-search-button { height: auto; padding: 6px 0px; background-color: transparent; color: var(--text-accent); } -.is-mobile .document-search input, .is-mobile .document-replace input, .is-mobile .document-search button, .is-mobile .document-replace button { width: auto; flex-grow: 1; } -.is-mobile .document-search .document-search-buttons, .is-mobile .document-replace .document-search-buttons, .is-mobile .document-search .document-replace-buttons, .is-mobile .document-replace .document-replace-buttons { display: flex; flex-grow: 1; } -.is-mobile .document-search .document-search-close-button, .is-mobile .document-replace .document-search-close-button { height: 34px; line-height: 34px; top: 0px; } -.is-mobile .view-header { border-top: none; height: var(--view-header-height); } -.is-mobile .workspace-split.mod-root > .workspace-leaf:first-of-type .workspace-leaf-content, .is-mobile .workspace-split.mod-root > .workspace-leaf:last-of-type .workspace-leaf-content { border-radius: 0px; } -.is-mobile .view-header-title { padding-right: 0px; } -.is-mobile .view-header-title-container { padding-left: 24px; } -.is-mobile .view-header-title-container::after { display: none; } -.is-mobile .view-header-icon { padding: 10px; } -.is-mobile .inline-title { padding-top: 0.25em; } -.is-mobile .horizontal-main-container { position: relative; } -.is-mobile .view-header-title-container { height: 50px; } -.is-mobile .view-actions { padding: var(--size-4-2) 0; gap: var(--size-2-1); } -.is-mobile .view-header-nav-buttons, .is-mobile .view-header .view-action { --icon-color: var(--interactive-accent); --icon-color-hover: var(--interactive-accent); --icon-color-active: var(--interactive-accent-hover); --icon-color-focus: var(--interactive-accent-hover); --icon-size: var(--icon-l); --icon-stroke: var(--icon-l-stroke-width); } -.is-mobile .view-action { margin: auto 0px; width: auto; } -.is-phone .view-header-title-parent, .is-phone .view-header-title { display: block; text-overflow: ellipsis; opacity: 0.7; } -.is-phone .view-header-title-parent:focus-within, .is-phone .view-header-title:focus-within { text-overflow: unset; opacity: 1; } -.is-mobile .hotkey-list-container .setting-item { flex-direction: column; align-items: stretch; } -.is-mobile .hotkey-list-container .setting-item-control { margin-top: 10px; align-items: flex-start; } -.is-mobile .hotkey-list-container .setting-command-hotkeys { flex: 1 0 auto; } -.is-mobile .hotkey-list-container .setting-hotkey { align-self: flex-start; } -.is-tablet .horizontal-tab-nav-item, .is-tablet .vertical-tab-nav-item { padding: var(--size-4-2) var(--size-4-3); } -.is-tablet .modal.mod-settings .vertical-tab-header { max-width: none; } -.is-tablet.theme-dark .community-item, .is-tablet.theme-dark .vertical-tab-content { background-color: var(--background-secondary); } -.is-phone.theme-dark .modal.mod-settings { background-color: var(--background-primary); } -.is-phone.theme-dark .modal.mod-settings .vertical-tab-header { background-color: var(--background-primary); } -.is-phone.theme-dark .modal.mod-settings .vertical-tab-nav-item { background-color: var(--background-secondary); } -.is-phone.theme-dark .modal.mod-settings .vertical-tab-header-title { background-color: var(--background-primary); } -.is-phone .setting-item-heading { margin-top: 1.5em; } -.is-phone .vertical-tab-header-group { margin: 0px auto; width: calc(100% - var(--size-4-8)); } -.is-phone .vertical-tab-header-group-title { padding-bottom: 1em; } -.is-phone .vertical-tab-header-group-title, .is-phone .setting-item-heading .setting-item-name { color: var(--text-normal); font-weight: var(--font-bold); font-size: var(--font-ui-large); } -.is-phone .setting-item { padding: 1em 0px; border-width: var(--border-width) 0 0 0; gap: var(--size-4-1); } -.is-phone .setting-item-name { font-weight: var(--font-medium); } -.is-phone .setting-item-info { min-width: 0px; } -.is-phone .setting-item:not(.mod-toggle):not(.setting-item-heading) { flex-direction: column; align-items: flex-start; } -.is-phone .setting-item:not(.mod-toggle):not(.setting-item-heading) .setting-item-control { margin-top: 12px; width: 100%; } -.is-phone .setting-icon { margin-right: 10px; display: inline-flex; vertical-align: middle; } -.is-phone .setting-item-control select, .is-phone .setting-item-control input, .is-phone .setting-item-control button { width: 100%; margin: 0px; } -.is-phone .setting-item-control button { padding: 10px; } -.is-phone .setting-item-control select { max-width: 100%; } -.is-phone .modal.mod-settings { background-color: var(--background-secondary); } -.is-phone .modal.mod-settings .modal-title { border-bottom: var(--border-width) solid var(--background-modifier-border); } -.is-phone .modal.mod-settings .vertical-tabs-container { display: block; overflow-y: auto; } -.is-phone .modal.mod-settings .vertical-tab-header { background-color: var(--background-secondary); border-right: none; flex-grow: 1; height: 100%; min-width: 100%; padding: var(--size-4-4); width: 100%; } -.is-phone .modal.mod-settings .vertical-tab-content { background-color: var(--background-primary); padding: var(--size-4-5) max(var(--size-4-5), var(--safe-area-inset-right)) 100px max(var(--size-4-5), var(--safe-area-inset-left)); } -.is-phone .modal.mod-settings .vertical-tab-header-group-items { border-radius: var(--radius-m); overflow: hidden; } -.is-phone .modal.mod-settings .vertical-tab-nav-item { display: flex; align-items: center; height: 44px; background-color: var(--background-primary); padding: 0 var(--size-4-2) 0 var(--size-4-3); margin: 0px; border-radius: 0px; border-bottom: var(--border-width) solid var(--background-modifier-border); transition: background-color 200ms ease-in-out 0s, color 200ms ease-in-out 0s; } -.is-phone .modal.mod-settings .vertical-tab-nav-item.is-active { background-color: var(--interactive-accent); } -.is-phone .modal.mod-settings .vertical-tab-nav-item:last-child { border-bottom: none; } -.is-phone .modal.mod-settings .vertical-tab-nav-item-chevron { display: flex; margin-left: auto; color: var(--text-faint); } -.is-phone .vertical-tab-header-title { font-weight: var(--font-semibold); } -.is-phone .community-modal { width: 100%; margin-bottom: 10px; } -.is-phone .modal.mod-community-theme { min-height: unset; } -.is-phone .community-modal-sidebar { background-color: var(--background-primary); } -.is-phone .community-modal-controls { background-color: transparent; } -.is-phone .community-modal-controls .setting-item { flex: 0 0 auto; padding: 0.25em 0px; } -.is-phone .community-modal-controls .setting-item-control { flex-direction: column; align-items: flex-end; } -.is-phone .community-modal-controls .search-input-container { width: 100%; } -.is-phone .community-modal-search-results { gap: 0px; padding: 0px; } -.is-phone .community-modal-info { padding: var(--size-4-4); } -.is-phone .community-item { border-width: 0 0 var(--border-width) 0; border-radius: 0px; padding: var(--size-4-4); } -.is-phone .community-item-info { padding: 20px; } -.is-phone .community-modal-details { background-color: var(--background-primary); border: none; } -.is-phone .community-modal-readme { padding: 20px 0px; } -.is-phone .community-modal-controls { padding: 0 var(--size-4-4); } -.is-phone .community-modal-search-summary { padding: var(--size-4-1) var(--size-4-1) var(--size-4-4); } -.is-phone .mod-community-theme .community-item { display: grid; grid-template-columns: 1fr 160px; grid-auto-flow: column dense; } -.is-phone .mod-community-theme .community-item .community-item-name { grid-column: 1 / 2; } -.is-phone .mod-community-theme .community-item .community-item-author { grid-column: 1 / 2; } -.is-phone .mod-community-theme .community-item .community-item-badge.mod-update { position: static; grid-row: 4 / auto; } -.is-phone .mod-community-theme .community-item .community-item-downloads { grid-column: 1 / 2; } -.is-phone .mod-community-theme .community-item .community-item-screenshot { grid-row: 1 / span 4; height: 90px; } -.is-phone .mod-community-plugin .community-item { display: grid; grid-template-columns: 3fr 1fr; grid-auto-flow: column dense; } -.is-phone .mod-community-plugin .community-item .community-item-name { grid-column: 1 / 2; } -.is-phone .mod-community-plugin .community-item .community-item-author { grid-column: 1 / 2; } -.is-phone .mod-community-plugin .community-item .community-item-badge.mod-update { position: static; grid-row: 4 / auto; } -.is-phone .mod-community-plugin .community-item .community-item-downloads { grid-column: 2 / 2; text-align: right; color: var(--text-faint); } -.is-phone .mod-community-plugin .community-item .community-item-desc { grid-column: 1 / span 2; } -.is-phone .community-modal-button-container { flex-direction: column; } -.mobile-option-setting-item { font-size: var(--font-ui-medium); display: flex; align-items: center; margin: 8px 0px; gap: var(--size-4-1); transition: transform 1000ms ease-in-out 0s; color: var(--text-muted); } -.mobile-option-setting-item:first-of-type:last-of-type .mobile-option-setting-drag-icon { display: none; } -.mobile-option-setting-item-name { flex: 1 0 0px; color: var(--text-normal); } -.mobile-option-setting-item-option-icon { display: flex; align-items: center; justify-content: center; padding: 4px; cursor: var(--cursor); border-radius: var(--radius-s); } -:not(.is-mobile) .mobile-option-setting-item-option-icon:hover, :not(.is-mobile) .mobile-option-setting-item-option-icon:active { background-color: var(--background-modifier-hover); } -.mobile-option-setting-item-option-icon.mobile-option-setting-drag-icon { cursor: grab; } -.mobile-option-setting-item-option-icon.mobile-option-setting-drag-icon:active { cursor: grabbing; } -.mobile-option-setting-item-remove-icon { color: var(--text-error); display: flex; } -.mobile-option-setting-item-add-icon { color: var(--text-success); display: flex; } -.is-mobile .status-bar { display: none; } -.workspace-drawer { position: fixed; top: 0px; bottom: 0px; display: flex; overflow: hidden; font-size: var(--font-ui-small); min-width: var(--mobile-sidebar-width); max-width: var(--mobile-sidebar-max-width); width: 85vw; z-index: var(--layer-popover); margin: 0px; border-radius: 0px; padding-top: var(--safe-area-inset-top); background-color: var(--background-primary); } -.workspace-drawer .nav-folder.mod-root > .nav-folder-title { display: none; } -.workspace-drawer .nav-header { margin-top: auto; padding-bottom: max(var(--size-4-2), var(--safe-area-inset-bottom)); order: 10; } -.workspace-drawer .nav-header ~ .search-input-container { width: calc(100% - var(--size-4-9)); } -.workspace-drawer .workspace-leaf { background-color: transparent; } -.theme-dark .workspace-drawer { background-color: var(--background-secondary); } -.workspace-drawer.is-pinned { height: 100%; position: relative; max-width: var(--mobile-sidebar-width); z-index: var(--layer-cover); border-radius: 0px; margin: 0px; box-shadow: none; } -.workspace-drawer.mod-left { left: 0px; padding-left: var(--safe-area-inset-left); border-top-right-radius: var(--radius-xl); border-bottom-right-radius: var(--radius-xl); } -.workspace-drawer.mod-left.is-pinned { border-right: var(--divider-width) solid var(--divider-color); border-radius: 0px; } -body.is-tablet .workspace-drawer.mod-left .workspace-drawer-inner { padding-left: var(--ribbon-width); } -.workspace-drawer.mod-right { right: 0px; padding-right: var(--safe-area-inset-right); border-top-left-radius: var(--radius-xl); border-bottom-left-radius: var(--radius-xl); } -.workspace-drawer.mod-right.is-pinned { border-left: var(--divider-width) solid var(--divider-color); border-radius: 0px; } -.workspace-drawer.is-collapsed { overflow: hidden; } -.workspace-drawer .nav-buttons-container { padding-left: var(--size-4-3); padding-right: var(--size-4-3); --icon-size: var(--icon-l); --icon-stroke: var(--icon-l-stroke-width); --icon-color: var(--interactive-accent); --icon-color-hover: var(--interactive-accent); --icon-color-active: var(--interactive-accent); --icon-color-focus: var(--interactive-accent-hover); } -.workspace-drawer .nav-buttons-container .nav-action-button { flex-grow: 1; } -.workspace-drawer .workspace-drawer-actions, .workspace-drawer .nav-buttons-container { overflow: auto; flex-wrap: nowrap; } -.workspace-drawer .workspace-drawer-actions::-webkit-scrollbar, .workspace-drawer .nav-buttons-container::-webkit-scrollbar, .workspace-drawer .workspace-drawer-actions::-webkit-scrollbar-thumb, .workspace-drawer .nav-buttons-container::-webkit-scrollbar-thumb { visibility: hidden; } -.workspace-drawer .side-dock-settings { margin-bottom: 0px; } -.workspace-drawer-inner { flex: 1 1 auto; overflow: hidden; display: flex; flex-direction: column; background-color: var(--background-primary); position: relative; transition: width 150ms ease-out 0s; } -.theme-dark .workspace-drawer-inner { background-color: var(--background-secondary); } -.workspace-drawer.is-collapsed .workspace-drawer-inner { padding: 0px; width: 0px; } -.workspace-drawer-backdrop { display: block; position: fixed; z-index: var(--layer-cover); width: 100%; height: 100%; background-color: var(--background-modifier-cover); top: 0px; left: 0px; opacity: 1; transition: opacity 150ms ease-out 0s; } -.workspace-drawer.is-collapsed .workspace-drawer-backdrop { display: none; opacity: 0; } -.workspace-drawer-ribbon { position: absolute; left: 0px; top: 0px; height: 100%; overflow: auto; width: var(--ribbon-width); padding: var(--size-4-1) 0 var(--safe-area-inset-bottom); } -.workspace-drawer-ribbon::-webkit-scrollbar, .workspace-drawer-ribbon::-webkit-scrollbar-thumb { visibility: hidden; width: 0px; } -.workspace-drawer-ribbon .side-dock-actions { padding: var(--size-4-2) 0; } -.workspace-drawer-ribbon .side-dock-actions, .workspace-drawer-ribbon .side-dock-settings { gap: var(--size-4-2); } -.workspace-drawer-ribbon .side-dock-ribbon-action { padding: var(--size-4-2); } -.workspace-drawer-header { padding: var(--size-4-2) var(--size-4-5) 0 var(--size-4-5); display: flex; align-items: flex-start; } -.workspace-drawer.is-pinned .workspace-drawer-header { padding-top: 0px; } -.workspace-drawer-header-left { display: flex; flex-direction: column; flex: 1 1 auto; overflow: hidden; } -.workspace-drawer-header-name { display: flex; } -.workspace-drawer-header-switcher { display: flex; flex: 0 1 auto; position: relative; } -.workspace-drawer-header-switcher select { opacity: 0; position: absolute; } -.workspace-drawer-header-name-text { text-overflow: ellipsis; overflow: hidden; font-size: var(--font-ui-large); font-weight: var(--font-semibold); } -.workspace-drawer-header-name-chevron { --icon-size: var(--icon-m); --icon-stroke: 2.25px; color: var(--text-faint); display: flex; align-items: center; margin-left: var(--size-2-1); } -.workspace-drawer-header-name-action-icon { color: var(--text-muted); margin-left: var(--size-4-2); display: flex; align-items: center; } -.workspace-drawer-header-info { color: var(--text-muted); margin: var(--size-4-1) 0 var(--size-4-4) 0; font-size: var(--font-ui-small); } -.workspace-drawer-header-icon { --icon-size: var(--icon-l); --icon-stroke: var(--icon-l-stroke-width); padding-top: var(--size-2-2); color: var(--interactive-accent); margin-left: var(--size-4-3); } -.workspace-drawer-actions { margin: var(--size-4-4) 0 var(--size-4-3) 0; display: flex; color: var(--text-muted); } -.workspace-drawer-action-item { flex: 0 0 70px; display: flex; flex-direction: column; align-items: center; overflow: hidden; } -.workspace-drawer-action-icon { color: var(--text-faint); } -.workspace-drawer-action-short-name { font-size: var(--font-ui-small); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; max-width: 80px; } -.workspace-drawer-separator { margin: 0px 0px 12px; } -.workspace-drawer-tab-option-item { display: flex; align-items: center; margin: var(--size-4-5); gap: var(--size-4-2); } -.workspace-drawer-active-tab-icon, .workspace-drawer-tab-option-item-icon { --icon-size: var(--icon-l); --icon-stroke: var(--icon-l-stroke-width); color: var(--text-normal); display: flex; } -.workspace-drawer-active-tab-icon:last-child { color: var(--interactive-accent); order: 2; } -.workspace-drawer-active-tab-back-icon { --icon-size: var(--icon-l); --icon-stroke: var(--icon-l-stroke-width); display: flex; color: var(--interactive-accent); order: 1; margin-right: var(--size-4-1); } -.workspace-drawer-tab-option-item-title, .workspace-drawer-active-tab-title { color: var(--text-normal); font-weight: var(--font-medium); font-size: var(--font-ui-medium); flex: 1 0 0px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } -.workspace-drawer-active-tab-header { display: flex; align-items: center; padding: var(--size-4-3) var(--size-4-5) var(--size-4-4); margin: 0px; gap: var(--size-4-2); } -.workspace-drawer-tab-container { overflow: hidden; position: relative; flex: 1 0 0px; } -.workspace-drawer-tab-container > * { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; } -.workspace-drawer-active-tab-icon.mod-exit-fullscreen { display: none; } -.workspace-drawer-active-tab-container { display: flex; flex-direction: column; } -.theme-dark .workspace-drawer-active-tab-container.is-fullscreen { background-color: var(--background-secondary); } -.workspace-drawer-active-tab-container .workspace-drawer-active-tab-content .nav-files-container { padding-top: var(--size-4-3); } -.workspace-drawer-active-tab-container.is-fullscreen { position: fixed; width: 100%; top: 0px; left: 0px; background-color: var(--background-primary); margin: 0 env(safe-area-inset-right, 20px) 0 env(safe-area-inset-left, 20px); padding: env(safe-area-inset-top, 20px) 0 0; } -.workspace-drawer-active-tab-container.is-fullscreen .workspace-drawer-active-tab-back-icon { display: none; } -.workspace-drawer-active-tab-container.is-fullscreen .workspace-leaf { width: 100%; } -.workspace-drawer-active-tab-container.is-fullscreen .workspace-drawer-active-tab-header { margin: 0 env(safe-area-inset-right, 20px) 0 env(safe-area-inset-left, 20px); padding: var(--size-4-4) var(--size-4-6); } -.workspace-drawer-active-tab-content { flex: 1 0 0px; overflow: auto; display: flex; } -.workspace-drawer-active-tab-content > * { flex: 1 0 0px; width: 100%; height: 100%; } -.workspace-drawer-active-tab-content .view-header { display: none !important; } -.workspace-drawer-active-tab-content .view-content { padding-top: 4px; height: 100%; } -.workspace-drawer-active-tab-content .graph-controls { display: none; } -.workspace-drawer-active-tab-content .outline { font-size: var(--font-ui-medium); } -.is-phone .side-dock-ribbon { display: none; } -.is-phone .workspace-drawer .workspace-drawer-header-icon.mod-pin { display: none; } -.is-phone .mod-root .workspace-split:not(.mod-visible), .is-phone .mod-root .workspace-tabs:not(.mod-visible) { display: none; } -.is-tablet .workspace-drawer .workspace-drawer-header-icon.mod-settings { display: none; } -body.is-tablet .sidebar-toggle-button { padding-left: var(--size-4-2); --icon-color: var(--interactive-accent); --icon-color-hover: var(--interactive-accent); --icon-color-active: var(--interactive-accent-hover); --icon-color-focus: var(--interactive-accent-hover); --icon-size: var(--icon-l); --icon-stroke: var(--icon-l-stroke-width); } -.is-mobile .menu { border: none; max-width: 100%; } -.is-phone .menu { background-color: var(--background-secondary); max-height: 60vh; width: calc(100% - var(--safe-area-inset-left) - var(--safe-area-inset-right)); min-width: unset; position: absolute; padding-bottom: var(--safe-area-inset-bottom); border-radius: var(--radius-l) var(--radius-l) 0 0; bottom: 0px; left: 0px; right: 0px; margin: 0px auto; overflow-y: auto; top: unset !important; } -.is-phone .menu-item { padding: var(--size-4-3) var(--size-4-3); height: unset; line-height: unset; } -.is-mobile .modal { border: none; } -.is-mobile .modal-button-container { display: flex; flex-direction: column; } -.is-mobile .community-modal { width: 100%; margin-bottom: 10px; } -.is-mobile .modal.mod-community-theme { min-height: unset; } -.is-mobile .mod-confirmation .modal-close-button { display: none; } -.is-phone .modal, .is-phone .prompt, .is-phone .suggestion-container { border-radius: 0px; border: none; max-height: 100vh; width: 100vw; max-width: 100vw; min-width: unset; position: absolute; bottom: unset; padding: 0px; left: 0px; right: 0px; } -.is-phone .modal { --modal-top: calc(var(--safe-area-inset-top) + var(--size-4-2)); --modal-bottom: var(--safe-area-inset-bottom); border-radius: var(--radius-m) var(--radius-m) 0 0; margin-top: var(--modal-top); padding: 0 var(--safe-area-inset-right) 0 var(--safe-area-inset-left); top: 0px; bottom: 0px; height: 100%; max-height: calc(100vh - var(--modal-top)); width: 100vw; } -.is-phone .modal .modal-close-button { top: var(--size-4-3); } -.is-phone .modal .modal-title { display: block; font-size: var(--font-ui-medium); margin-bottom: 0px; padding-top: var(--size-4-4); text-align: center; } -.is-phone .modal-sidebar { background-color: var(--background-primary); } -.is-phone .modal-content { display: flex; position: relative; flex-direction: column; margin-top: 0px; overflow: auto; padding: var(--size-4-3); } -.is-phone .modal-button-container { width: 100%; padding: var(--size-4-3); margin-top: 0px; margin-bottom: var(--safe-area-inset-bottom); } -.is-phone .modal.mod-lg { max-height: 100%; } -.is-phone .modal.mod-lg .modal-title { padding-top: calc(env(safe-area-inset-top) + var(--size-4-3)); padding-bottom: var(--size-4-3); } -.is-phone .modal.mod-lg .modal-close-button, .is-phone .modal.mod-sidebar-layout .modal-close-button { top: calc(var(--safe-area-inset-top) + 10px); right: var(--size-4-5); } -.is-phone .modal.mod-sidebar-layout { bottom: 0px; top: 0px; border-radius: 0px; height: 100%; max-height: 100%; margin: 0px; padding: 0 var(--safe-area-inset-right) 0 var(--safe-area-inset-left); width: 100vw; } -.is-phone .modal.mod-sidebar-layout .search-input-container { flex-grow: 1; } -.is-phone .modal.mod-sidebar-layout .modal-title { display: block; padding-top: calc(env(safe-area-inset-top) + var(--size-4-3)); padding-bottom: var(--size-4-3); margin-bottom: 0px; } -.is-phone .modal.mod-sidebar-layout .modal-content > * { width: 100%; height: 100%; position: absolute; top: 0px; left: 0px; right: 0px; padding: 0 var(--safe-area-inset-right) 0 var(--safe-area-inset-left); } -.mobile-navbar { background-color: var(--background-primary); padding: 0 max(var(--safe-area-inset-right), var(--size-4-4)) 0 max(var(--safe-area-inset-left), var(--size-4-4)); position: absolute; left: 0px; right: 0px; bottom: 0px; } -body.is-tablet .mobile-navbar { display: none; } -.mobile-navbar-text { font-size: var(--font-ui-small); padding: var(--size-4-1) 0; white-space: nowrap; text-overflow: clip; width: 100%; -webkit-mask-image: linear-gradient(to left, rgba(0, 0, 0, 0) var(--size-4-4), #000000 var(--size-4-8)); } -.mobile-navbar-actions { --icon-size: var(--icon-l); --icon-stroke: var(--icon-l-stroke-width); --icon-color: var(--interactive-accent); --icon-color-hover: var(--interactive-accent); --icon-color-active: var(--interactive-accent-hover); --icon-color-focus: var(--interactive-accent-hover); display: flex; align-items: center; justify-content: space-between; padding: var(--size-4-2) 0 max(var(--size-4-2), var(--safe-area-inset-bottom)) 0; } -.mobile-navbar-tabs-action { align-items: center; border-radius: var(--clickable-icon-radius); border: 2px solid var(--icon-color); display: flex; font-size: calc(var(--icon-size) * 0.6); font-weight: var(--bold-weight); justify-content: center; height: 20px; width: var(--icon-size); } -.mobile-navbar-action.has-longpress-menu { position: relative; } -.mobile-navbar-action.has-longpress-menu .navbar-action-flair { --icon-size: 12px; --icon-stroke: 3px; color: var(--interactive-accent); position: absolute; left: -6px; top: 0px; height: 100%; align-items: center; display: flex; } -.is-phone .notice-container { padding: 0px; top: max(var(--size-4-1), var(--safe-area-inset-top)); left: 0px; right: 0px; max-width: 96%; margin: 0px auto; } -.is-phone .notice { background-color: var(--interactive-accent); color: var(--text-on-accent); margin: 0 auto var(--size-4-1); text-align: center; border-radius: 30px; max-width: none; box-shadow: none; } -.is-mobile .prompt { border: none; } -.theme-dark.is-mobile .prompt { background-color: var(--background-secondary); } -.theme-dark.is-mobile .prompt input.prompt-input { background-color: var(--background-secondary); } -.is-mobile .prompt-input[type="text"] { padding: var(--size-4-4); } -.is-phone .prompt { position: relative; margin: 0px auto; width: calc(100% - var(--safe-area-inset-left) - var(--safe-area-inset-right)); } -.is-phone .prompt .suggestion-hotkey { display: none; } -.is-phone .prompt { --mobile-height: 100vh; --prompt-bottom: 0px; --prompt-top: calc(var(--safe-area-inset-top) + var(--header-height) + var(--size-4-2)); border-radius: var(--radius-l) var(--radius-l) 0 0; min-width: unset; margin-bottom: var(--prompt-bottom); margin-top: var(--prompt-top); box-shadow: none; top: 0px; height: calc(var(--mobile-height) - var(--prompt-top) - var(--prompt-bottom)); } -.is-phone .prompt-input-container { border-bottom: var(--border-width) solid var(--background-modifier-border); } -.is-phone .prompt-input[type="text"] { border: none; } -.is-phone .prompt-input-cta { --icon-color: var(--interactive-accent); display: flex; align-items: center; padding: 0 var(--size-4-3); flex: 0 1 auto; } -.is-phone .prompt-instructions { display: none; } -.pull-action { position: absolute; background-color: var(--background-secondary); z-index: var(--layer-popover); color: var(--text-muted); font-size: 90%; transition: background-color 150ms ease-in-out 0s; } -.pull-action.mod-activated { background-color: var(--interactive-accent); color: var(--text-on-accent); } -.pull-down-action { top: 0px; left: 0px; right: 0px; width: 96%; max-width: 500px; margin: var(--safe-area-inset-top) auto 0 auto; padding: var(--size-4-3) var(--size-4-4); text-align: center; border-radius: 40px; } -.pull-out-action { top: 50%; padding: var(--size-4-3) var(--size-4-4); border-radius: 40px; margin: 0 var(--size-4-4); } -.mobile-toolbar { app-region: drag; flex: 0 0 auto; width: 100%; overflow-y: hidden; background-color: var(--background-primary); bottom: 0px; z-index: var(--layer-menu); } -.mobile-toolbar-options-container { height: var(--mobile-toolbar-height); display: flex; overflow: auto hidden; width: 100%; padding: 0px 10px; } -.mobile-toolbar-options-container::-webkit-scrollbar { width: 0px !important; height: 0px !important; } -.mobile-toolbar-option { display: flex; font-size: var(--font-ui-medium); color: var(--text-muted); font-family: var(--font-monospace); justify-content: center; align-items: center; min-width: 50px; position: relative; left: 0px; transition: left 200ms ease-in-out 0s; } -.mobile-toolbar-option.mod-ghost { position: absolute; transition: left 250ms ease-in-out 0s; } -.mobile-toolbar-option.mod-ghost::before { content: " "; position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; border-radius: 6px; background-color: var(--interactive-accent); } -.mobile-toolbar-done-button { position: fixed; margin-top: var(--size-4-2); margin-right: var(--size-4-3); top: env(safe-area-inset-top, 20px); right: env(safe-area-inset-right, 20px); z-index: var(--layer-status-bar); } -.is-mobile .suggestion-item { padding: var(--size-4-2) var(--size-4-3); } -.is-tablet.theme-dark .suggestion-container { background-color: var(--background-secondary); } -.is-phone .suggestion-container { margin: 0px auto; padding-bottom: calc(var(--safe-area-inset-bottom) + var(--mobile-toolbar-height)); width: calc(100% - var(--safe-area-inset-left) - var(--safe-area-inset-right)); border-top: 1px solid var(--background-modifier-border); background-color: var(--background-primary); box-shadow: none; border-radius: 0px; bottom: 0px; overflow: auto; max-height: 35vh; } -.is-phone .suggestion { position: relative; } -.is-phone .suggestion-item.mod-group { border-radius: 0px; } -.is-mobile .modal.mod-publish { background-color: var(--modal-background); border-radius: 0px; height: 100%; margin: 0px; padding-top: var(--safe-area-inset-top); width: 100vw; } -.is-mobile .publish-changes-info-publishing-to { display: none; } -.is-mobile .publish-changes-add-linked-btn { width: auto; } -.is-phone .modal.mod-publish .modal-button-container { background-color: var(--modal-background); position: fixed; } -.is-phone .modal.mod-publish .modal-content { display: unset; } -.is-mobile .sync-history-list { padding: 0px; } -.is-mobile .sync-history-list-item { padding: 12px 16px; } -.is-mobile .sync-history-content-container { display: flex; flex-direction: column; max-width: unset; } -.is-mobile .sync-history-content { flex: 1 1 auto; padding: 10px; border-radius: 0px; border: none; } -.is-phone .sync-log-container { flex: 1 1 auto; } -.is-phone .modal.mod-sync-history .search-input-container { width: 100%; margin-bottom: 0px; } -.mobile-vault-chooser { width: 100%; height: 100%; background-color: var(--background-primary); position: relative; } -.mobile-vault-chooser hr { margin: 12px 0px; border-width: var(--border-width); } -.mobile-vault-chooser-screen { display: flex; flex-direction: column; position: absolute; left: 0px; top: 0px; width: 100%; height: 100%; } -.mobile-vault-chooser-header { display: flex; background-color: var(--background-primary); border-bottom: var(--border-width) solid var(--background-modifier-border); color: var(--text-muted); flex: 0 0 50px; font-size: 18px; align-items: center; } -.mobile-vault-chooser-header-icon { display: flex; margin: 0px 6px 0px 10px; } -.mobile-vault-chooser-content { flex: 1 0 0px; padding: 20px; height: 100%; overflow-y: auto; max-width: 800px; width: 100%; margin: 0px auto; } -.mobile-vault-chooser-logo-container { margin: 40px 0px; text-align: center; color: var(--text-muted); } -.mobile-vault-logo-text { margin-top: 10px; margin-bottom: 10px; color: white; } -.mobile-vault-chooser-version { font-size: var(--font-ui-small); color: var(--text-faint); } -.mobile-vault-chooser-empty-state { margin: 20px 0px; font-size: 17px; color: var(--text-muted); } -.mobile-vault-chooser-actions { padding-bottom: 40px; } -.mobile-vault-chooser-action-icon { color: var(--text-muted); display: flex; padding: 10px; margin: -10px 0px; } -.mobile-vault-chooser-action { display: flex; padding: 14px 0px; align-items: center; font-size: 18px; } -.mobile-vault-chooser-action-name { flex: 1 0 0px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } -.mobile-vault-chooser-action-description { color: var(--text-muted); font-size: 17px; overflow: hidden; text-overflow: ellipsis; max-width: calc(100vw - 110px); white-space: nowrap; } -.mobile-vault-chooser-field-name { color: var(--text-muted); margin: 20px 0px 10px; font-size: 18px; } -input.mobile-vault-chooser-field-input { width: 100%; font-size: var(--font-ui-medium); padding: 8px 12px; height: auto; } -.mobile-vault-chooser-button-container { margin: 20px 0px; } -.mobile-vault-chooser-button-container button { padding: 10px 20px; font-size: var(--font-ui-medium); width: 100%; } diff --git a/docs/lib/styles/plugin-styles.css b/docs/lib/styles/plugin-styles.css deleted file mode 100644 index 2bf05299a..000000000 --- a/docs/lib/styles/plugin-styles.css +++ /dev/null @@ -1,733 +0,0 @@ -/*#region Code Copy */ - -/* Make code block copy button fade in and out */ -.markdown-rendered pre:not(:hover) > button.copy-code-button -{ - display: unset; - opacity: 0; -} - -.markdown-rendered pre:hover > button.copy-code-button -{ - opacity: 1; -} - -.markdown-rendered pre button.copy-code-button -{ - transition: opacity 0.2s ease-in-out, width 0.3s ease-in-out, background-color 0.2s ease-in-out; - text-overflow: clip; -} - -.markdown-rendered pre > button.copy-code-button:hover -{ - background-color: var(--interactive-normal); -} - -.markdown-rendered pre > button.copy-code-button:active -{ - background-color: var(--interactive-hover); - box-shadow: var(--input-shadow); - transition: none; -} - -/*#endregion */ - -/*#region Canvas */ -.canvas-card-menu { - display: none; - cursor: default !important; - -} - -.canvas-controls { - display: none; - cursor: default !important; - -} - -.canvas-node-connection-point -{ - display: none; - cursor: default !important; - -} - -.canvas-menu-container { - display: none; -} - -.canvas-node-content-blocker -{ - display: none; - cursor: pointer !important; -} - -.canvas-wrapper -{ - position: relative; - cursor: default !important; -} - -.canvas-node-resizer -{ - cursor: default !important; -} - -.canvas-node-container -{ - cursor: default !important; -} - -/*#endregion */ - -/*#region Sidebars */ - -.sidebar { - background-color: var(--background-secondary); - flex: 1 0 min-content; - display: flex; - align-items: flex-start; - font-size: 14px; -} - -.sidebar-section-header -{ - margin: 0em 0 0em var(--sidebar-margin); - text-transform: uppercase; - letter-spacing: 0.06em; - font-weight: 600; -} - -.sidebar-content { - width: var(--sidebar-width); - line-height: var(--line-height-tight); - display: flex; - flex-direction: column; - padding: 10px; - padding-bottom: 0; - height: 100%; -} - -.sidebar-scroll-area -{ - width: 100%; - height: 100%; - line-height: var(--line-height-tight); - display: flex; - flex-direction: column; - overflow-y: scroll; -} - -.sidebar-left -{ - border-right: 1px dashed var(--divider-color); - z-index: 1000; - align-items: flex-end; - flex-direction: row-reverse; -} - -.sidebar-right -{ - border-left: 1px dashed var(--divider-color); - z-index: 1000; - align-items: flex-start; - flex-direction: row; -} - -@media print -{ - .sidebar, .outline-container, .theme-toggle-container, .theme-toggle-container-inline, .toggle-background, .theme-toggle-input - { - display: none !important; - } -} - -/*#endregion */ - -/*#region Content / Markdown Preview View */ - -.webpage-container { - background-color: var(--background-primary); - display: flex; - flex-direction: row; - height: 100%; - width: 100%; - align-items: stretch; - position: fixed; -} - -.document-container -{ - flex-basis: var(--content-width); -} - -.markdown-reading-view -{ - align-self: center; - -ms-flex-align: center; - width: 100%; -} - -.markdown-preview-view -{ - display: flex; - width: 100%; - max-width: 100%; - padding-bottom: 30em; - align-items: flex-start; - justify-content: center; -} - -.document-container > .markdown-preview-view > .markdown-preview-sizer -{ - padding: unset; - width: unset; - height: unset; - margin: unset; - max-width: unset; - min-height: unset; - max-width: var(--line-width); - flex-basis: var(--line-width); -} - -/*#endregion */ - -/*#region Kanban */ - -.markdown-preview-view.kanban-plugin__markdown-preview-view { - font-family: var(--font-text, var(--default-font)); - font-size: .875rem; - line-height: var(--line-height-tight); - padding: unset; - width: unset; - height: unset; - position: unset; - overflow-y: unset; - overflow-wrap: unset; - color: unset; - user-select: unset; - -webkit-user-select: unset; -} - -.kanban-plugin__item-button-wrapper, .kanban-plugin__lane-grip, .kanban-plugin__lane-settings-button.clickable-icon, .kanban-plugin__item-postfix-button.clickable-icon -{ - display: none; -} - -/*#endregion */ - -/*#region Tree */ - -/* Base tree */ -.tree-container -{ - /* padding-bottom: 12px; */ - /* margin: 12px; */ - /* height: 100%; */ - /* position: relative; */ - /* display: contents; */ - position: relative; - height: 100%; - width: auto; - margin: var(--sidebar-margin); - margin-top: 3em; - margin-bottom: 0; -} - -.tree-container .tree-header -{ - display: flex; - flex-direction: row; - align-items: center; - position: absolute; - top: -3em; -} - -.tree-container .tree-header .sidebar-section-header -{ - margin: 1em; - margin-left: 0; -} - -.tree-container:has(.tree-scroll-area:empty) -{ - display: none; -} - -.tree-container .tree-scroll-area -{ - width: 100%; - height: 100%; - max-height: 100%; - overflow-y: scroll; - padding: 1em; - padding-right: calc(1em + var(--sidebar-margin)); - padding-bottom: 3em; - border-radius: var(--radius-m); - position: absolute; -} - -.tree-container .tree-item -{ - display: flex; - flex-direction: column; - align-items: flex-start; - padding: 0; -} - -.tree-container .tree-item-children -{ - padding: 0; - margin-left: 0; - border-left: none; - width: 100%; -} - -.tree-container .tree-item.mod-active > .tree-item-contents > .tree-item-link -{ - color: var(--color-accent); -} - -.tree-container .tree-item-contents { - position: relative; - display: flex; - flex-direction: row; - align-items: center; - border-radius: 0.4em; - color: var(--nav-item-color); - width: 100%; - margin-left: var(--tree-horizontal-spacing); -} - -.tree-container .tree-item-contents:active -{ - color: var(--nav-item-color-active); -} - -.tree-container a.tree-item-link -{ - width: 100%; - height: 100%; - transition: background-color 0.1s; - border-radius: var(--radius-s); - padding-left: calc(var(--tree-horizontal-spacing) + var(--collapse-arrow-size)/2 + 1px); - padding-bottom: calc(var(--tree-vertical-spacing) / 2); - padding-top: calc(var(--tree-vertical-spacing) / 2); - color: var(--nav-item-color); - text-decoration: none; -} - -.tree-container .tree-item-icon.collapse-icon { - display: flex; - justify-content: flex-start; - align-items: center; - border-radius: var(--radius-s); - transition: background-color 0.1s; - position: absolute; - height: 100%; -} - -.tree-container .tree-item.mod-tree-folder > .tree-item-contents > .tree-item-icon.collapse-icon -{ - width: 100%; -} - -.collapse-icon > svg { - color: unset !important; -} - -.collapse-icon:hover -{ - color: var(--nav-item-color-hover); -} - -.tree-container a.tree-item-link:hover -{ - cursor: pointer; - color: var(--nav-item-color-hover); - text-decoration: underline; -} - -/* Indentation guide */ - -.tree-container > .tree-scroll-area > * .tree-item -{ - margin-left: calc(var(--tree-horizontal-spacing) + var(--collapse-arrow-size) / 2 + 1px); - border-left: var(--nav-indentation-guide-width) solid var(--nav-indentation-guide-color); -} - -.tree-container .tree-scroll-area > * > * > .tree-item -{ - margin-left: calc(var(--collapse-arrow-size) / 2 + 1px); -} - -.tree-container .tree-item.mod-active -{ - border-left: var(--nav-indentation-guide-width) solid var(--color-accent); -} - - -.tree-container .tree-item:hover:not(.mod-active):not(.mod-collapsible):not(:has(.tree-item:hover)) /* Hover */ -{ - border-left: var(--nav-indentation-guide-width) solid var(--nav-item-color-hover); -} - -.webpage-container .tree-container .tree-item:not(.mod-collapsible) > .tree-item-children > .tree-item, -.webpage-container .tree-container > .tree-scroll-area > .tree-item, -.webpage-container .tree-container:not(.mod-nav-indicator) .tree-item -{ - border-left: none !important; -} - -.webpage-container .tree-container .tree-item:not(.mod-collapsible) > .tree-item-children > .tree-item > .tree-item-contents, -.webpage-container .tree-container:not(.mod-nav-indicator) .tree-item .tree-item-contents, -.webpage-container .tree-container > .tree-scroll-area > .tree-item > .tree-item-contents -{ - margin-left: 0 !important; -} - -/* Special */ - -.tree-container.outline-tree .tree-item[data-depth='1'] > .tree-item-contents > .tree-item-link -{ - font-weight: 900; - font-size: 1.1em; - margin-left: 0; -} - -.tree-container .tree-item.is-collapsed > .tree-item-contents > .tree-item-icon.collapse-icon > svg -{ - transition: transform 0.1s ease-in-out; - transform: rotate(-90deg); -} - - - -/*#endregion */ - -/*#region Headers */ - -.collapse-icon svg.svg-icon { - color: var(--nav-collapse-icon-color); - stroke-width: 4px; - width: var(--collapse-arrow-size); - height: var(--collapse-arrow-size); - transition: transform 100ms ease-in-out 0s; - min-width: 10px; - min-height: 10px; -} - -div.is-collapsed > * > .heading-collapse-indicator.collapse-icon > svg -{ - transition: transform 0.1s ease-in-out; - transform: rotate(-90deg); -} - -/*#endregion */ - -/*#region Text Wrapping */ -a { - overflow-wrap: anywhere; -} - -* -{ - overflow-wrap: break-word; -} - -/*#endregion */ - -/*#region Obsidian Columns Plugin */ -.columnParent { - display: flex; - padding: 15px 20px; - flex-wrap: wrap; - gap: 20px; -} - -.columnParent { - white-space: normal; -} - -.columnChild { - flex-grow: 1; - flex-basis: 0px; -} -/*#endregion */ - -/*#region Theme Toggle */ - -.theme-toggle-container { - --toggle-width: 50px; - --toggle-height: 23px; - --border-radius: calc(var(--toggle-height) / 2); - --handle-width: calc(var(--toggle-height) * 0.65); - --handle-radius: calc(var(--handle-width) / 2); - --handle-margin: calc((var(--toggle-height) / 2.0) - var(--handle-radius)); - --handle-translation: calc(var(--toggle-width) - var(--handle-width) - (var(--handle-margin) * 2)); - - display: inline-block; - cursor: pointer; - margin: 10px; -} - -/* animation to expand width, move handle, then contract width */ -@keyframes toggle-slide-right -{ - 0% - { - width: var(--handle-width); - transform: translateX(0); - } - 50% - { - width: calc(var(--toggle-width) * 0.5); - } - 90% - { - width: var(--handle-width); - } - 100% - { - transform: translateX(var(--handle-translation)); - } -} - -@keyframes toggle-slide-left -{ - 0% - { - width: var(--handle-width); - transform: translateX(calc(var(--handle-translation) - ((var(--toggle-width) * 0.33) - var(--handle-width)))); - } - 70% - { - width: calc(var(--toggle-width) * 0.5); - } - 100% - { - width: var(--handle-width); - transform: translateX(0); - } -} - -/* just exapnd and contract */ -@keyframes toggle-expand-right -{ - 0% - { - width: var(--handle-width); - } - 100% - { - width: calc(var(--toggle-width) * 0.33); - } -} - -@keyframes toggle-expand-left -{ - 0% - { - width: var(--handle-width); - transform: translateX(var(--handle-translation)); - } - 100% - { - width: calc(var(--toggle-width) * 0.33); - transform: translateX(calc(var(--handle-translation) - ((var(--toggle-width) * 0.33) - var(--handle-width)))); - } -} - -@keyframes toggle-contract -{ - 0% - { - width: calc(var(--toggle-width) * 0.33); - } - 100% - { - width: var(--handle-width); - } -} - -.theme-toggle-input { - display: none; - z-index: 1000; -} - -/* Fill in dark mode / default */ -.toggle-background { - position: relative; - width: var(--toggle-width); - height: var(--toggle-height); - border-radius: var(--border-radius); - background-color: var(--background-modifier-border); - - transition: background-color 0.2s; - z-index: 1000; - - /* box-shadow: inset 0px 0px 100px -70px var(--color-accent); */ -} - -/* Handle default */ -.toggle-background::before -{ - content: ""; - position: absolute; - left: var(--handle-margin); - top: var(--handle-margin); - height: var(--handle-width); - width: var(--handle-width); - - border-radius: var(--handle-radius); - background-color: var(--text-normal); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.2); - animation: toggle-slide-left 0.2s ease-in-out normal both; - - z-index: 1000; -} - -/* handle light*/ -.theme-toggle-input:checked ~ .toggle-background::before -{ - animation: toggle-slide-right 0.2s ease-in-out normal both; -} - -.theme-toggle-input:active ~ .toggle-background::before -{ - animation: toggle-expand-right 0.2s ease-in-out normal both; -} - -.theme-toggle-input:active:checked ~ .toggle-background::before -{ - animation: toggle-expand-left 0.2s ease-in-out normal both; -} - -/* sun moon icon icon default */ -.toggle-background::after -{ - content: ""; - position: absolute; - right: var(--handle-margin); - top: calc(var(--handle-margin)); - height: var(--handle-width); - width: var(--handle-width); - transition: transform 0.3s; - background: url('https://api.iconify.design/lucide/moon.svg?color=white') no-repeat center center; - transform: scale(0.9); -} - -/* sun moon icon icon light */ -.theme-toggle-input:checked ~ .toggle-background::after -{ - transform: translateX(calc(var(--handle-translation) * -1)) scale(0.9); - background: url('https://api.iconify.design/lucide/sun.svg') no-repeat center center; -} - -/*#endregion */ - -/*#region Graph View */ -#graph-canvas -{ - width: 100%; - height: 100%; - border: 1px solid var(--modal-border-color); - border-radius: var(--modal-radius); - aspect-ratio: 1/1; -} - -.graph-view-container.expanded -{ - position: fixed; - width: 60%; - height: 90%; - right: 20%; - top: 5%; - background-color: var(--background-secondary); - z-index: 1000; -} - -.graph-view-container -{ - position: relative; - width: 100%; - aspect-ratio: 1/1; - display: flex; -} - -.graph-icon -{ - cursor: pointer; - color: var(--text-muted); -} - -.graph-view-container .graph-icon > svg -{ - width: 24px; - height: 24px; - - background-color: var(--color-base-00); - outline-width: 6px; - outline-color: var(--color-base-00); - outline-offset: -1px; - outline-style: solid; - border-radius: 100px; - margin: 10px; -} - -.graph-view-placeholder -{ - padding: 0; - width: auto; - aspect-ratio: 1/1; - position: relative; - flex: none; - margin: var(--sidebar-margin); -} - -.graph-view-placeholder:has(.expanded) -{ - border-radius: var(--modal-radius); - border: 1px solid var(--modal-border-color); -} - -.scale-down -{ - transition: transform 0.2s ease-in-out; - transform: scale(0.9); -} - -.scale-up -{ - transition: transform 0.2s ease-in-out; - transform: scale(1); -} - -.graph-expand -{ - position: absolute; - top: 5px; - right: 5px; -} - - - -/*#endregion */ - -/*#region Tweaks */ - -hr -{ - border: none; - border-top: var(--hr-thickness) solid; - border-color: var(--hr-color); -} - -.markdown-embed-link -{ - display: none; -} - -/*#endregion */ - - diff --git a/docs/lib/styles/snippets.css b/docs/lib/styles/snippets.css deleted file mode 100644 index 8b1378917..000000000 --- a/docs/lib/styles/snippets.css +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/lib/styles/theme.css b/docs/lib/styles/theme.css deleted file mode 100644 index 0a5480389..000000000 --- a/docs/lib/styles/theme.css +++ /dev/null @@ -1 +0,0 @@ -/* Using default theme. */ \ No newline at end of file diff --git a/docs/management/1on1s.html b/docs/management/1on1s.html deleted file mode 100644 index 2b815a96e..000000000 --- a/docs/management/1on1s.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - 1on1s - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1on1s

Performance

    -
  1. What was your biggest highlight or proudest achievement in the past 6 months?
  2. -
  3. What were the main objectives that you wanted to accomplish?
  4. -
  5. Do you feel recognised for your good work?
  6. -
  7. Do you feel like you are using your strengths to their best abilities in your role?
  8. -
  9. Is there anything you’ve worked on that you don’t like doing?
  10. -
  11. How do you feel about communication within the team? Are there any areas or processes you think can be improved on?
  12. -

Roadblocks and challenges

    -
  1. What was your greatest challenge or concern in the past 6 months?
  2. -
  3. Do you think it was resolved to your satisfaction, or can more be done?
  4. -
  5. What did you learn from overcoming the challenge(s)?
  6. -
  7. Do you feel like you have enough resources to support you in your role?
  8. -
  9. Do you anticipate any upcoming challenges in the next 6 months?
  10. -

Happiness

    -
  1. What is your current Happiness Score between 0-10, and why?
  2. -
  3. Is there anything that is making you feel frustrated or upset in your role?
  4. -
  5. How has your work/life balance been, and are you seeking any additional support in this area?
  6. -

Learning and development

    -
  1. Is there anything you’d like to work on that you’re not currently doing?
  2. -
  3. What’s one new skill you’d like to improve on over the next 6 months?
  4. -
  5. Are you satisfied with the current upskill opportunities provided, or do you have a specific course in mind that’s not currently available to you?
  6. -

Management

    -
  1. What can I do as your manager to support you in achieving your goals?
  2. -
  3. Do you think I’ve been responsive and helpful enough to your questions and requests?
  4. -
  5. Do you like my management style? If not, what management style do you think you would best respond to?
  6. -

Moving forward

    -
  1. What are your goals for the rest of the year?
  2. -
  3. How can we measure the success of those goals?
  4. -
  5. Let’s plan out three key action steps we can focus on for the rest of the year.
  6. -
  7. Is there anything else that you’d like to discuss
  8. -
\ No newline at end of file diff --git a/docs/management/career.html b/docs/management/career.html deleted file mode 100644 index 1b1552f84..000000000 --- a/docs/management/career.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - Career - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/docs/management/change-management.html b/docs/management/change-management.html deleted file mode 100644 index e36ecdde2..000000000 --- a/docs/management/change-management.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - Change Management - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Change Management

ADKAR Model

The ADKAR model is an outcome-oriented change management method that aims to limit resistance to organizational change. It is based on five building blocks that bring about successful change, and each letter in the ADKAR acronym represents a different step in the change management process. The five steps are:

    -
  1. Awareness: This involves understanding the need for change and becoming aware of the implications of not changing. Leaders need to create awareness of the need for change among people who will be impacted by it.
  2. -
  3. Desire: Once people are aware of the need for change, they need to be motivated to make it happen. Leaders need to create a desire for change in individuals by explaining why it is essential and what benefits it will bring.
  4. -
  5. Knowledge: In this step, people need to be provided with the right information and knowledge about the change that is happening. Leaders should provide training and instruction to individuals on how to make the change happen.
  6. -
  7. Ability: Individuals need to possess the skills and resources necessary to make the change happen. Leaders need to provide the necessary resources and support to ensure that individuals can execute the change.
  8. -
  9. Reinforcement: In the final step, individuals need to be supported in maintaining the change. Leaders should continue to provide reinforcement to ensure that the change sticks and becomes a permanent part of the organization.
  10. -

The ADKAR model is a widely used framework for managing organizational change. It provides a structured approach to change management that helps to minimize resistance and create a successful transition.

What is the CLARC framework?

The CLARC framework is a change management model that helps people managers navigate change effectively. CLARC stands for:

    -
  • C: Communicate clearly
  • -
  • L: Lead with empathy
  • -
  • A: Align to the vision
  • -
  • R: Respect the individual
  • -
  • C: Create momentum
  • -

This framework is based on the ADKAR model, which describes the stages an individual goes through during change: Awareness, Desire, Knowledge, Ability, Reinforcement. By fulfilling each of the CLARC roles, people managers can have a positive impact on an individual's journey through each stage of the ADKAR mode.

\ No newline at end of file diff --git a/docs/management/coaching.html b/docs/management/coaching.html deleted file mode 100644 index 580110931..000000000 --- a/docs/management/coaching.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - Coaching - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/management/community-of-practice.html b/docs/management/community-of-practice.html deleted file mode 100644 index e88859ec8..000000000 --- a/docs/management/community-of-practice.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - Community Of Practice - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Community Of Practice

Communities of practice are groups of people who share a concern or a
-passion for something they do and learn how to do it better as they
-interact regularly.

Three characteristics are crucial:

    -
  • Domain
  • -
  • Community
  • -
  • Practice
  • -

The domain. A community of practice is not
-merely a club of friends or a network of connections between people. It
-has an identity defined by a shared domain of interest. Membership
-therefore implies a commitment to the domain, and therefore a shared
-competence that distinguishes members from other people. (You could
-belong to the same network as someone and never know it.) The domain is
-not necessarily something recognized as “expertise” outside the
-community. A youth gang may have developed all sorts of ways of dealing
-with their domain: surviving on the street and maintaining some kind of
-identity they can live with. They value their collective competence and
-learn from each other, even though few people outside the group may
-value or even recognize their expertise.

The community. In pursuing their interest in
-their domain, members engage in joint activities and discussions, help
-each other, and share information. They build relationships that enable
-them to learn from each other; they care about their standing with each
-other. A website in itself is not a community of practice. Having the
-same job or the same title does not make for a community of practice
-unless members interact and learn together. The claims processors in a
-large insurance company or students in American high schools may have
-much in common, yet unless they interact and learn together, they do not
-form a community of practice. But members of a community of practice do
-not necessarily work together on a daily basis. The Impressionists, for
-instance, used to meet in cafes and studios to discuss the style of
-painting they were inventing together. These interactions were essential
-to making them a community of practice even though they often painted
-alone.

The practice. A community of practice is not
-merely a community of interest–people who like certain kinds of movies,
-for instance. Members of a community of practice are practitioners. They
-develop a shared repertoire of resources: experiences, stories, tools,
-ways of addressing recurring problems—in short a shared practice. This
-takes time and sustained interaction. A good conversation with a
-stranger on an airplane may give you all sorts of interesting insights,
-but it does not in itself make for a community of practice. The
-development of a shared practice may be more or less self-conscious. The
-“windshield wipers” engineers at an auto manufacturer make a concerted
-effort to collect and document the tricks and lessons they have learned
-into a knowledge base. By contrast, nurses who meet regularly for lunch
-in a hospital cafeteria may not realize that their lunch discussions are
-one of their main sources of knowledge about how to care for patients.
-Still, in the course of all these conversations, they have developed a
-set of stories and cases that have become a shared repertoire for their
-practice.

It is the combination of these three elements that constitutes
-a community of practice. And it is by developing these three elements
-in parallel that one cultivates such a community.

"../../assets/image_1672704213276_0.png" is not created yet. Click to create.

Sources

\ No newline at end of file diff --git a/docs/management/culture.html b/docs/management/culture.html deleted file mode 100644 index c83212a03..000000000 --- a/docs/management/culture.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - Culture - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/management/effective-meetings.html b/docs/management/effective-meetings.html deleted file mode 100644 index 176dae5d9..000000000 --- a/docs/management/effective-meetings.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - Effective Meetings - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/management/goals.html b/docs/management/goals.html deleted file mode 100644 index 22971e732..000000000 --- a/docs/management/goals.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - Goals - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Objectives

OKRs

Definition

OKR stands for Objectives and Key Results. OKRs help break up big, audacious missions into actionable goals and milestones.

    -
  • Objectives (The “What”): An objective is what you want to do. It describes our mission-supporting goal.
  • -
  • Key Results (The “How”): Objectives must be paired with a roadmap that will help you know whether or not you’re on the path to meeting your goals.
  • -

Resources

\ No newline at end of file diff --git a/docs/management/health-monitor.html b/docs/management/health-monitor.html deleted file mode 100644 index a8f81a464..000000000 --- a/docs/management/health-monitor.html +++ /dev/null @@ -1,126 +0,0 @@ - - - - Health Monitor - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Health Monitor

Employee

    -
  • I know what is expected of me at work.
  • -
  • I have the materials and equipment I need to do my work right.
  • -
  • At work, I have the opportunity to do what I do best every day.
  • -
  • In the last seven days, I have received recognition or praise for doing good work.
  • -
  • My supervisor, or someone at work, seems to care about me as a person.
  • -
  • There is someone at work who encourages my development.
  • -
  • At work, my opinions seem to count.
  • -
  • The mission or purpose of my company makes me feel my job is important.
  • -
  • My associates or fellow employees are committed to doing quality work.
  • -
  • I have a best friend at work.
  • -
  • In the last six months, someone at work has talked to me about my progress.
  • -
  • This last year, I have had opportunities at work to learn and grow.
  • -

Developer Velocity

Manager

    -
  • I would recommend my manager to others.
  • -
  • My manager assigns stretch opportunities to help me develop in my career.
  • -
  • My manager communicates clear goals for our team.
  • -
  • My manager gives me actionable feedback on a regular basis.
  • -
  • My manager provides the autonomy I need to do my job (i.e., does not "micro-manage" by getting involved in details that should be handled at other levels).
  • -
  • My manager consistently shows consideration for me as a person.
  • -
  • My manager keeps the team focused on priorities, even when it’s difficult (e.g., declining or deprioritizing other projects).
  • -
  • My manager regularly shares relevant information from their manager and senior leadership.
  • -
  • My manager has had a meaningful discussion with me about my career development in the past six months.
  • -
  • My manager has the technical expertise (e.g., technical judgment in Tech, selling in Sales, accounting in Finance) required to effectively manage me.
  • -
  • The actions of my manager show they value the perspective I bring to the team, even if it is different from their own.
  • -
  • My manager makes tough decisions effectively (e.g., decisions involving multiple teams, competing priorities).
  • -
  • My manager effectively collaborates across boundaries (e.g., team, organizational).
  • -
  • What would you recommend your manager keep doing?
  • -
  • What would you have your manager change?
  • -

Psychological Safety

    -
  • If you make a mistake on this team, it is often held against you.
  • -
  • Members of this team are able to bring up problems and tough issues.
  • -
  • People on this team sometimes reject others for being different.
  • -
  • It is safe to take a risk on this team.
  • -
  • It is difficult to ask other members of this team for help.
  • -
  • No one on this team would deliberately act in a way that undermines my efforts.
  • -
  • Working with members of this team, my unique skills and talents are valued and utilized.
  • -

Stress

We’ve all been working under a lot of stress this past year. I wanted to gauge how the team is feeling, and see if there’s anything I can do to help mitigate feelings of burnout. Please answer these questions and send your responses back to me before the end of the day tomorrow. Feel free to provide more context in any of your answers. And please be honest — the goal here is for me to find out how you’re really doing, not to punish anyone for feeling unproductive or overwhelmed. Everything you say will be kept confidential.

Over the past week…

    -
  • How overwhelmed did you feel, on a scale of 1 to 5? (1 is lowest, 5 is highest)
  • -
  • How many days did you work later than you should?
  • -
  • How many days did you answer emails after hours?
  • -
  • How effective did you feel, on a scale of 1 to 5?
  • -
  • How productive did you feel, on a scale of 1 to 5?
  • -
  • How much fun did you have, on a scale of 1 to 5?
  • -

Service Team

Team leadership

    -
  • There is a team lead who is responsible for team performance, communication and process ownership.
  • -
  • The team lead actively monitors work, identifies and successfully advocates improvements in process, and communicates opportunities both inside and outside of the team.
  • -

Balanced team

    -
  • The team has the right specialist skills and experience.
  • -
  • The team is empowered to make decisions and escalate where appropriate.
  • -
  • The team share stories, collaborate on tricky problems and share lessons learned.
  • -
  • Individual service excellence is recognized.
  • -
  • Team schedules and rosters are set and agreed with an even distribution of work across the team.
  • -
  • There is a smooth onboarding process for new team members.
  • -

Service mandate

    -
  • The services offered by the team are defined and documented. The scope of the team’s work is clear.
  • -
  • Ownership and accountabilities for individuals and leads are defined.
  • -
  • The service mandate has been communicated and agreed by key stakeholders, with agreed-upon success metrics that are well-defined and actively monitored.
  • -

Service levels

    -
  • Service levels for all areas of the teams’ service mandate are defined, agreed and visible to key stakeholders, including customers.
  • -
  • All service levels are current, applicable and there is queue management, categorization, prioritization & escalation in place to meet SLAs.
  • -
  • The team operates at a good velocity with recognized consequences for not meeting SLAs.
  • -

Customer centricity

    -
  • You understand what your customers need and have the necessary information about the customer to resolve their issues.
  • -
  • You are skilled at understanding, empathizing and resolving requests with an effective customer feedback loop in place which drives improvements to build trust and
    -improve your service offering.
  • -
  • Your service offering balances quality with velocity.
  • -
  • Customers can self serve and your team has a mechanism or cycle in place to detect, correct and prevent problem management.
  • -

Tools and processes

    -
  • The team has the necessary tool set that is well designed and optimized towards delivering the services offered by your team.
  • -
  • Processes are well documented, and have defined workflows and owners.
  • -
  • There is a well defined and followed hand-over process to operationalize new services and handle rootcause analysis.
  • -

Effective partnership

    -
  • Your vendors and partners are known, key contracts are documented and there is a trusting relationship(s) in place.
  • -
  • There are established operational level agreements (OLAs) for down-level teams and partners.
  • -
  • Partner contracts are current and their OLAs allow your team to uphold your commitments and retain ownership of the customer request.
  • -

Reporting and analytics

    -
  • You are capturing feedback and your performance reporting is available, visible and helping your team improve established service levels.
  • -
  • KPIs are realistic, focused on the correct metrics and you are meeting your KPIs.
  • -
  • Your cost to serve is known and a focus area for the team to improve on.
  • -
\ No newline at end of file diff --git a/docs/management/high-performing-teams.html b/docs/management/high-performing-teams.html deleted file mode 100644 index 4251a9a47..000000000 --- a/docs/management/high-performing-teams.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - High Performing Teams - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/management/hiring.html b/docs/management/hiring.html deleted file mode 100644 index 82d7edeaa..000000000 --- a/docs/management/hiring.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - Hiring - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/management/interview.html b/docs/management/interview.html deleted file mode 100644 index 32a171df1..000000000 --- a/docs/management/interview.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - Interview - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/docs/management/leadership.html b/docs/management/leadership.html deleted file mode 100644 index 79bd7bf13..000000000 --- a/docs/management/leadership.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - Leadership - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/management/management.html b/docs/management/management.html deleted file mode 100644 index c400d754e..000000000 --- a/docs/management/management.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - Management - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/docs/management/metrics.html b/docs/management/metrics.html deleted file mode 100644 index fe73c1c81..000000000 --- a/docs/management/metrics.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - Metrics - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/docs/management/onboarding.html b/docs/management/onboarding.html deleted file mode 100644 index 7f54a7126..000000000 --- a/docs/management/onboarding.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - Onboarding - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/docs/management/psychological-safety.html b/docs/management/psychological-safety.html deleted file mode 100644 index d05f8663c..000000000 --- a/docs/management/psychological-safety.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - Psychological Safety - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/management/reports.html b/docs/management/reports.html deleted file mode 100644 index 71720e0d2..000000000 --- a/docs/management/reports.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - Reports - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/docs/management/salary.html b/docs/management/salary.html deleted file mode 100644 index 474cc6cfc..000000000 --- a/docs/management/salary.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - Salary - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/management/software-development-strategy.html b/docs/management/software-development-strategy.html deleted file mode 100644 index bc93be980..000000000 --- a/docs/management/software-development-strategy.html +++ /dev/null @@ -1,245 +0,0 @@ - - - - Software Development Strategy - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Software Development Strategy

Table of contents

Introduction

This document is a set of upfront decisions that allows the team to come up with an effective set of dos, don’ts and how's regarding
-the future application design, development and deployment, and move consistently through each step of a development project.

General

    -
  • Use GitHub folder structure (src, doc, test, build, tool)
  • -
  • Use sqlproj project file for SQL databases
  • -
  • Use the latest .NET LTS version. See .NET Roadmap
  • -

Guidelines

Tools, Frameworks and Libraries

Code Reviews

Tools

Logging

Always use Structured Logging, which makes it easier to store and query log-events.
-https://datatracker.ietf.org/doc/html/rfc7807

Health Checks

A health check API is a separate REST service that is implemented within a microservice component that quickly returns the operational status of the service and an indication of its ability to connect to downstream dependent services.
-Example: myservice.com/health

Caching

A distributed cache is a cache shared by multiple app servers, typically maintained as an external service to the app servers that access it. A distributed cache can improve the performance and scalability of an application, especially when the application is hosted by a cloud service or a server farm.

When cached data is distributed, the data:

- Is coherent (consistent) across requests to multiple servers.
-- Survives server restarts and app deployments.
-- Doesn't use local memory.
-

API Versioning

Versioning is an important aspect of any mature web service. Microsoft has published REST API guidelines that require that all compliant services must support explicit versioning. This ensures that clients can rely on services to be stable over time, while still enabling service changes and new features. Detailed information about the recommended guidance can be found in the Microsoft REST Guidelines for versioning.

Example

Code

// Define a 'version set' that applies to an API group
-var versionSet = app.NewApiVersionSet()
-                    .HasApiVersion(1.0)
-                    .HasApiVersion(2.0)
-                    .ReportApiVersions()
-                    .Build();
-
-app.MapGet("{instanceId}/endpoint", [Authorize] async (IMediator mediator, [FromHeader] string authorization, Guid instanceId, CancellationToken cancellationToken) => await mediator.Send(new RequestV1() { InstanceId = instanceId }, cancellationToken))
-   .WithApiVersionSet(versionSet)
-   .MapToApiVersion(1.0);
-
-app.MapGet("{instanceId}/endpoint", [Authorize] async (IMediator mediator, [FromHeader] string authorization, Guid instanceId, CancellationToken cancellationToken) => await mediator.Send(new RequestV2() { InstanceId = instanceId }, cancellationToken))
-   .WithApiVersionSet(versionSet)
-   .MapToApiVersion(2.0);
-

Rate Limiting

Output Caching

Paging

Coding Standards

Clean Code

✅ Detect and address Code Smells with Sonarlint

✅ Follow Clean Code Programming Principles

✅ Follow Clean Code Best Practices: .NET | Typescrypt

✅ Follow Unit Testing Best Practices: .NET

✅ Follow Coding Style Guidelines: C# | TypeScript | Angular | SQL

APIs

Security

✅ Follow Security Guidelines:

Guidelines

Style Guides

Linting

Linting is essentially a form of static code analysis. It analyzes the code you wrote against some rules for stylistic or programmatic errors. Think of it as a tool that flags suspicious usage in software.

A linter can help you save a lot of time by:

    -
  • -

    Preventing broken code from being pushed

    -
  • -
  • -

    Helping establish coding best practices

    -
  • -
  • -

    Building guidelines for code layout and format

    -
  • -
  • -

    Helping code reviews be a lot smoother

    -
  • -
  • -

    Flagging bugs in your code from syntax errors

    -

    Given the useful nature of linting tools, you would ideally want to run a linter before any code reviews happen on every single piece of code that is pushed to your repository. This definitely helps you write better, more readable, and more stable code.

    -
  • -

Super Linter

You first want to pull the latest Docker container down from DockerHub with this command:

docker pull github/super-linter:latest

To run this container you then run the following:

docker run -e RUN_LOCAL=true -e USE_FIND_ALGORITHM=true -v /project/directory:/tmp/lint github/super-linter

Notice a couple of things here:

    -
  • We run it with the RUN_LOCAL flag to bypass some of the GitHub Actions checks. This automatically sets VALIDATE_ALL_CODEBASE to true.
  • -
  • We map our local codebase to /tmp/lint so that the linter can pick up the code.
  • -
  • The way we set environment variables is of course different, but the overall process of running the GitHub Super Linter remains the same.
  • -

Pre-Commit Hooks

Rules Catalog

Code Quality Rules

<PropertyGroup>
-<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-<CodeAnalysisTreatWarningsAsErrors>true</CodeAnalysisTreatWarningsAsErrors>
-</PropertyGroup>
-

Best Practices

Reference Material

\ No newline at end of file diff --git a/docs/management/ways-of-working.html b/docs/management/ways-of-working.html deleted file mode 100644 index 054ec0adf..000000000 --- a/docs/management/ways-of-working.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - Ways of Working - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Ways of Working

Project Planning

Capacity Planning

A great resource to help with Public Holidays is Google Calendar API

Definition of Ready (DOR)

    -
  • Independent (of all others).
  • -
  • Negotiable (not a specific contract for features).
  • -
  • Valuable (or vertical).
  • -
  • Estimable (to a good approximation).
  • -
  • Small (so as to fit within an iteration).
  • -
  • Testable (in principle, even if there isn’t a test for it yet).
  • -

Definition of Done (DOD)

The Definition of Done creates transparency by providing everyone a shared understanding of what work was completed.

    -
  • Unit tests are passing.
  • -
  • Automation tests are passing.
  • -
  • Documentation is updated.
  • -
  • The change is code reviewed via a pull request.
  • -
  • Code is merged into the main branch.
  • -
  • Testing is done by Testers.
  • -

Managing Risks, Assumptions, Impediments, and Dependencies

Strategy

\ No newline at end of file diff --git a/docs/management/wellbeing.html b/docs/management/wellbeing.html deleted file mode 100644 index c342f95cb..000000000 --- a/docs/management/wellbeing.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - Wellbeing - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Wellbeing

Mental Health

Happiness

\ No newline at end of file diff --git a/docs/performance/general.html b/docs/performance/general.html index cd6845be6..f2fa718f0 100644 --- a/docs/performance/general.html +++ b/docs/performance/general.html @@ -1,46 +1,28 @@ - - - + General - - - - + + - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + +

General

.𝗡𝗘𝗧 𝗣𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲 𝟭𝟬𝟭:

𝟭. 𝗖𝗮𝗰𝗵𝗶𝗻𝗴 (in-mem Memory Cache or Redis)
+𝟮. 𝗗𝗮𝘁𝗮𝗯𝗮𝘀𝗲 𝗢𝗽𝘁𝗶𝗺𝗶𝘇𝗮𝘁𝗶𝗼𝗻 (optimize queries, proper indexing, connection pooling)
+𝟯. 𝗔𝘀𝘆𝗻𝗰 𝗽𝗿𝗼𝗴𝗿𝗮𝗺𝗺𝗶𝗻𝗴 (offload all CPU extensive or I/O bound operations to DB, file systems, ext. systems)
+𝟰. 𝗨𝘀𝗲 𝗘𝗻𝘁𝗶𝘁𝘆 𝗙𝗿𝗮𝗺𝗲𝘄𝗼𝗿𝗸 𝗖𝗼𝗿𝗲 𝗪𝗶𝘀𝗲𝗹𝘆 (use eager loading, projections, and optimizations like compiled queries)
+𝟱. 𝗠𝗲𝗺𝗼𝗿𝘆 𝗠𝗮𝗻𝗮𝗴𝗲𝗺𝗲𝗻𝘁 (use value types and be cautious with large object graphs. Use dispose pattern to db connections or streams. Avoid boxing/unboxing. Use StringBuilder instead of String for a large number of concatenations.)
+𝟲. 𝗛𝗧𝗧𝗣 𝗖𝗮𝗰𝗵𝗶𝗻𝗴 (use ETags, Last-Modified headers)
+𝟳. 𝗠𝗶𝗻𝗶𝗺𝗶𝘇𝗲 𝗥𝗼𝘂𝗻𝗱-𝗧𝗿𝗶𝗽𝘀 (reduce the number of HTTP requests and database round-trips)
+𝟴. 𝗖𝗼𝗻𝘁𝗲𝗻𝘁 𝗗𝗲𝗹𝗶𝘃𝗲𝗿𝘆 𝗡𝗲𝘁𝘄𝗼𝗿𝗸𝘀 (𝗖𝗗𝗡𝘀) - (Offload static assets (CSS, JavaScript, images) to CDNs for faster delivery to users)
+𝟵. 𝗖𝗼𝗺𝗽𝗿𝗲𝘀𝘀𝗶𝗼𝗻 (Enable GZIP or Brotli compression for HTTP responses to reduce data transfer size)
+𝟭𝟬 𝗟𝗼𝗴𝗴𝗶𝗻𝗴 𝗮𝗻𝗱 𝗧𝗿𝗮𝗰𝗶𝗻𝗴 (Avoid excessive logging in production. Use distributed tracing across microservices)
+𝟭𝟭. 𝗣𝗮𝗿𝗮𝗹𝗹𝗲𝗹𝗶𝘀𝗺 𝗮𝗻𝗱 𝗖𝗼𝗻𝗰𝘂𝗿𝗿𝗲𝗻𝗰y (Utilize parallelism and multithreading for CPU-bound tasks using Parallel class or Task Parallel Library (TPL))
+𝟭𝟮. 𝗥𝗲𝘀𝗼𝘂𝗿𝗰𝗲 𝗢𝗽𝘁𝗶𝗺𝗶𝘇𝗮𝘁𝗶𝗼𝗻 (Optimize images and assets for the web to reduce load times)
+𝟭𝟯. 𝗛𝗧𝗧𝗣/𝟮 𝗼𝘃𝗲𝗿 𝗦𝗦𝗟 (now make intelligent decisions about the page content)
+𝟭𝟰. 𝗠𝗲𝗮𝘀𝘂𝗿𝗲 𝗮𝗻𝗱 𝗠𝗼𝗻𝗶𝘁𝗼𝗿 𝗽𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲 (use VS Diagnostic Tools, App Insights or BenchmarkDotNet)
+𝟭𝟱. 𝗨𝘀𝗲 𝗦𝗽𝗮𝗻<> 𝗶𝗻𝘀𝘁𝗲𝗮𝗱 𝗼𝗳 𝗖𝗼𝗹𝗹𝗲𝗰𝘁𝗶𝗼𝗻𝘀 (spans can represent a contiguous section of memory, this means we can use them to operate over arrays)

\ No newline at end of file diff --git a/docs/security/cve.html b/docs/security/cve.html index b4ad2742c..7a62c0dff 100644 --- a/docs/security/cve.html +++ b/docs/security/cve.html @@ -1,49 +1,17 @@ - - - + CVE - - - - + + - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + +
\ No newline at end of file diff --git a/docs/security/hackerone.html b/docs/security/hackerone.html index 3ae8a323c..e9754d017 100644 --- a/docs/security/hackerone.html +++ b/docs/security/hackerone.html @@ -1,52 +1,20 @@ - - - + HackerOne - - - - + + - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + +
\ No newline at end of file diff --git a/docs/security/jwt.html b/docs/security/jwt.html index d2a011c02..e66a58d22 100644 --- a/docs/security/jwt.html +++ b/docs/security/jwt.html @@ -1,45 +1,18 @@ - - - + JWT - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
    -
  • + + + + + + + +

    Encryption

    Encryption

    Symmetric key and asymmetric keys

    A JWT can be encrypted using either a symmetric key (shared secret) or asymmetric keys (the private key of a private–public pair).

      +

Symmetric key and asymmetric keys

A JWT can be encrypted using either a symmetric key (shared secret) or asymmetric keys (the private key of a private–public pair).

  1. Symmetric key: Both encryption (JWT signing) and verification are done with the symmetric key—also known as the shared secret.
  2. Asymmetric keys: The encryption (JWT signing) is done with the private key, and verification is done with the public key.
  3. -
    -
  • -

    Tools

    +
\ No newline at end of file +
  • +
    \ No newline at end of file diff --git a/docs/security/owasp-top-10.html b/docs/security/owasp-top-10.html deleted file mode 100644 index 69f6a8010..000000000 --- a/docs/security/owasp-top-10.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - OWASP TOP 10 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/security/secure-code-warriors.html b/docs/security/secure-code-warriors.html deleted file mode 100644 index 396e63cf3..000000000 --- a/docs/security/secure-code-warriors.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - Secure Code Warriors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/security/security.html b/docs/security/security.html index 13573892a..712ce919c 100644 --- a/docs/security/security.html +++ b/docs/security/security.html @@ -1,51 +1,20 @@ - - - + Security - - - - + + - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + +
    \ No newline at end of file diff --git a/docs/technology/ai.html b/docs/technology/ai.html index b831453ed..9afee7e2e 100644 --- a/docs/technology/ai.html +++ b/docs/technology/ai.html @@ -1,51 +1,19 @@ - - - + AI - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
    AI

    AWS CodeWhisperer
    + + + + + + + +

    \ No newline at end of file +https://you.com/search?q=who+are+you&tbm=youchat

    \ No newline at end of file diff --git a/docs/technology/architecture.html b/docs/technology/architecture.html index eef0f7fce..143ebc682 100644 --- a/docs/technology/architecture.html +++ b/docs/technology/architecture.html @@ -1,77 +1,45 @@ - - - + Architecture - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
    Architecture

    Reference Material

      -
    • + + + + + + + +
      \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/technology/aws.html b/docs/technology/aws.html deleted file mode 100644 index 1182771da..000000000 --- a/docs/technology/aws.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - AWS - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    AWS

    Tools

    Upgrade

      -
    • winget upgrade -e --id Amazon.SAM-CLI
    • -
    • sam --version
    • -
    • winget upgrade -e --id Amazon.AWSCLI
    • -
    • aws --version
    • -
    • npm upgrade -g aws-cdk
    • -
    • cdk --version
    • -
    • dotnet tool update -g Amazon.Lambda.Tools
    • -

    Credentials

      -
    1. Run aws configure
    2. -
    3. AWS Access Key ID: test
    4. -
    5. AWS Secret Access Key: test
    6. -
    7. Default region name: ap-southeast-2
    8. -
    9. Default output format: json
    10. -
    11. Run aws configure list to verify the newly configured credentials (stored in C:\Users\{USER}\.aws\credentials)
    12. -

    AWS CDK

    Commands

      -
    • mkdir CDK
    • -
    • CD CDK
    • -
    • cdk init app --language csharp
    • -
    • dotnet build src compile this app
    • -
    • cdk deploy deploy this stack to your default AWS account/region
    • -
    • cdk diff compare deployed stack with current state
    • -
    • cdk synth emits the synthesized CloudFormation template
    • -

    The cdk.json file tells the CDK Toolkit how to execute your app.


    Documentation

    SAM CLI

    Commands

      -
    • sam init image
    • -

    Documentation

    AWS CLI

    Commands

      -
    • aws --endpoint-url=http://localhost:4566 dynamodb create-table --table-name ServiceName_Setting --attribute-definitions AttributeName=TenantId,AttributeType=S --key-schema AttributeName=TenantId,KeyType=HASH --billing-mode PAY_PER_REQUEST
    • -
    • aws --endpoint-url=http://localhost:4566 sqs create-queue --queue-name sample-queue2
    • -
    • aws --endpoint-url=http://localhost:4566 kms --region ap-southeast-2 create-key --tags TagKey=Purpose,TagValue=Test --description "Development test key"
    • -
    • aws --endpoint-url=http://localhost:4566 kms encrypt --region ap-southeast-2 --key-id 1cc95196-acb1-4279-9063-a3daa3d9a20d --plaintext fileb://C:\TEMP\connectionstring.txt
    • -

    Documentation

    Moto

    Documentation

    LocalStack

    Installation

      -
    1. Run winget install -e --id Python.Python.3
    2. -
    3. Install pip py -m ensurepip --upgrade
    4. -
    5. Install Docker winget install -e --id Docker.DockerDesktop
    6. -
    7. Go to -> "start" and type "Manage App Execution Aliases". Go to it and turn off "Python"
    8. -
    9. Install LocalStack Cockpit
    10. -
    11. Install localstack-cli pip install localstack and check version `localstack --version``
    12. -
    13. Browse http://localhost:4566/ and http://localhost:4566/health to test the setup
    14. -

    Usage: aws --endpoint-url=http://localhost:4566 sqs create-queue --queue-name myQueue

    Documentation

    Environment Variables

    AWS_DEFAULT_REGION=ap-southeast-2
    -SERVICES=s3,sns,kms,sqs,lambda,dynamodb,iam,serverless,ecr,sts,ssm,logs
    -DYNAMODB_SHARE_DB=1
    -PERSIST_ALL=1
    -USE_SINGLE_REGION=true
    -LAMBDA_EXECUTOR=docker
    -LAMBDA_REMOTE_DOCKER=true
    -LAMBDA_REMOVE_CONTAINERS=true
    -DEBUG=1
    -DATA_DIR=/tmp/localstack/data
    -LOCALSTACK_HOSTNAME=localhost
    -LOCALSTACK_API_KEY=[Insert PRO Version Key]
    -

    DynamoDB

    Commands

      -
    • aws --endpoint-url=http://localhost:4566 dynamodb list-tables
    • -
    • aws --endpoint-url=http://localhost:4566 dynamodb create-table --table-name DEV_Settings_TEMP22 --attribute-definitions AttributeName=InstanceId,AttributeType=S AttributeName=SettingA,AttributeType=N --key-schema AttributeName=InstanceId,KeyType=HASH AttributeName=SettingA,KeyType=RANGE --billing-mode PAY_PER_REQUEST
    • -

    NoSQL Workbench

      -
    1. Open NoSQL Workbench
    2. -
    3. Add Connection
    4. -
    5. Click "DynamoDB Local"
    6. -
    7. Hostname: localhost | Port: 8000
    8. -

    Documentation

    Lambda

      -
    • dotnet new lambda.EmptyFunction --help
    • -

    Create Lambda Function

      -
    • Install DotNet Lambda templates dotnet new -i Amazon.Lambda.Templates
    • -
    • Install dotnet tool install -g Amazon.Lambda.Tools
    • -
    • List templates dotnet new --list
    • -
    • Run dotnet new serverless.AspNetCoreMinimalAPI --name MinimalApi
    • -
    • dotnet build
    • -
    • dotnet publish -c Release -o publish p:PublishReadyToRun=false
    • -
    • zip content of the .\publish\ folder (function.zip)
    • -

    Create Deployment Package

      -
    1. Create Cdk folder and run cdk init app --language=csharp
    2. -
    3. configure deployment settings (CdkStack.cs)
    4. -
    // The code that defines your stack goes here
    -var lambda = new Function(this, "MinimalApiNet6", new FunctionProps
    -{
    -  Runtime = Runtime.DOTNET_6,
    -  Code = Code.FromAsset("../MinimalApi/bin/Debug/net6.0"),
    -  Handler = "MinimalApi",
    -  FunctionName = "minimalApiNet6"
    -});
    -
    -var api = new LambdaRestApi(this, "APIGatewayNet6", new LambdaRestApiProps
    -{
    -  RestApiName = "APIGatewayNet6",
    -  Description = "A simple Minimal API with .NET 6",
    -  Handler = lambda
    -}); 
    -
      -
    1. Emit the synthesized CloudFormation template cdk synth
    2. -

    Test with LocalStack

      -
    1. Add Environment Variable EDGE_PORT=52005 (custom LocalStack port number)
    2. -
    3. cdklocal init app --language=csharp
    4. -
    5. Change Stack.cs file
    6. -
    7. cdklocal synth -v (this must be run where the cdk.json file is located. It creates the cdk.out folder)
    8. -
    9. cdklocal bootstrap --profile default (if you get "Unable to resolve AWS account to use." make sure the localstack service is running http://localhost:4566/health)
    10. -
    11. cdklocal deploy -v
    12. -
    13. Test endpoint using Postmanimage
    14. -

    Documentation

    Cognito

    Commands

      -
    • aws --endpoint-url=http://localhost:9229 cognito-idp create-user-pool-client --user-pool-id "user-pool-test" --client-name "client-test2222" --generate-secret --allowed-o-auth-flows client_credentials --explicit-auth-flows "ALLOW_USER_PASSWORD_AUTH" --allowed-o-auth-flows-user-pool-client --allowed-o-auth-flows-user-pool-client --allowed-o-auth-flows "code" "implicit" --allowed-o-auth-scopes "openid" --callback-urls "["https://example.com"]" --supported-identity-providers "["MySAMLIdP", "LoginWithAmazon"]"
    • -
    • aws --endpoint-url=http://localhost:9229 cognito-idp list-user-pool-clients --user-pool-id "user-pool-test"
    • -
    • aws --endpoint-url=http://localhost:9229 cognito-idp admin-create-user --user-pool-id "user-pool-test" --username "testuser" --temporary-password "testpassword" --user-attributes Name=email,Value=testuser@humanforce.com Name=phone_number,Value="+61455587898"
    • -
    • aws --endpoint-url=http://localhost:9229 cognito-idp admin-set-user-password --user-pool-id "user-pool-test" --username testuser --password "testpassword"--permanent
    • -
    • aws --endpoint-url=http://localhost:9229 cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --auth-parameters USERNAME=testuser,PASSWORD=testpassword --client-id 2xtkp25fbng4z7hquw2p44mzx
    • -

    Documentation

    Cloud Formation

    Commands

      -
    • awslocal lambda list-functions
    • -
    • awslocal lambda invoke --function-name helloLambda --cli-binary-format raw-in-base64-out response.json --log-type Tail
    • -
    • awslocal lambda delete-function --function-name helloLambda
    • -
    • awslocal apigatewayv2 get-apis
    • -

    .NET Lambda Tools

    Commands
    -dotnet-lambda --help

    Documentation

    Reference Material

    \ No newline at end of file diff --git a/docs/technology/azure.html b/docs/technology/azure.html deleted file mode 100644 index d7f48e027..000000000 --- a/docs/technology/azure.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - Azure - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/technology/coding-exercise.html b/docs/technology/coding-exercise.html deleted file mode 100644 index 4053e49d5..000000000 --- a/docs/technology/coding-exercise.html +++ /dev/null @@ -1,105 +0,0 @@ - - - - Coding Exercise - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    Objective

    Assess your natural approach to coding and engineering best practices.

    Pre-Requisites

      -
    1. Test the API Authentication.
    2. -
    3. Run the Code with your favorite IDE.
    4. -

    Process

      -
    1. Refactor the code following SOLID principles.
    2. -
    3. Test the code.
    4. -
    5. Make the code production-ready.
    6. -

    Code

    public class Program
    -{
    -    static void Main(string[] args)
    -    {
    -        Task.Run(async () =>
    -        {
    -            //Get Repositories
    -            await GetDetails("https://dev.azure.com/AcmeInc/ff86f2fb-5c3a-49e2-a677-c9b95d6baaef/_apis/tfvc/branches?includeParent=1&includeChildren=1&includeDeleted=1&includeLinks=1&api-version=6.0");
    -            //Get Commits
    -            await GetDetails("https://dev.azure.com/AcmeInc/ff86f2fb-5c3a-49e2-a677-c9b95d6baaef/_apis/git/repositories/4563efa9-da5d-4f54-b609-18db14479f48/commits?api-version=6.0");
    -            //Get Pull Requests
    -            await GetDetails("https://dev.azure.com/AcmeInc/ff86f2fb-5c3a-49e2-a677-c9b95d6baaef/_apis/git/repositories/4563efa9-da5d-4f54-b609-18db14479f48/pullrequests?searchCriteria.status=completed||searchCriteria.status=open?api-version=5.1");
    -        }).Wait();
    -    }
    -
    -
    -    public static async Task GetDetails(string url)
    -    {
    -        try
    -        {
    -            var personalaccesstoken = "bGVtb25hY29AYWxsaWFuei1hc3Npc3RhbmNlLmNvbS5hdTpuZXczZ3ludmRpdWJpdno0djNoc2E1enpqMmF3ZGtvbzQ3ZnZxMzZ4aWJxb2x5Y203NnNx";
    -
    -            using (HttpClient client = new HttpClient())
    -            {
    -                client.DefaultRequestHeaders.Accept.Add(
    -                    new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
    -
    -                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", personalaccesstoken);
    -
    -                using (HttpResponseMessage response = await client.GetAsync(url))
    -                {
    -                    response.EnsureSuccessStatusCode();
    -
    -                    var resultJson = await response.Content.ReadAsStringAsync();
    -                    Console.WriteLine(resultJson);
    -                }
    -            }
    -        }
    -        catch (Exception ex)
    -        {
    -            Console.WriteLine(ex.ToString());
    -        }
    -    }
    -}
    -

    API Authentication

    Documentation

    \ No newline at end of file diff --git a/docs/technology/http-3.html b/docs/technology/http-3.html deleted file mode 100644 index 0dc4167f1..000000000 --- a/docs/technology/http-3.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - HTTP 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/technology/monorepo.html b/docs/technology/monorepo.html index fc68851d9..03ecff18a 100644 --- a/docs/technology/monorepo.html +++ b/docs/technology/monorepo.html @@ -1,52 +1,20 @@ - - - + Monorepo - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
    \ No newline at end of file + + + + + + + +
    \ No newline at end of file diff --git a/docs/tools/cmd.html b/docs/tools/cmd.html index 5744076ff..2c96ee11f 100644 --- a/docs/tools/cmd.html +++ b/docs/tools/cmd.html @@ -1,50 +1,18 @@ - - - + CMD - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
    CMD

    rmdir

    The rmdir /s /q "folder_name" command is used to delete a directory and all its contents in Windows Command Prompt (CMD) without sending them to the Recycle Bin.

    Parameters:

      -
    • /s is a switch for "subdirectories" that tells the command to remove all files and directories within the specified directory/folder, including any subdirectories.
    • -
    • /q is a switch for "quiet mode" that tells the command to operate quietly without asking for confirmation from the user.
    • -
    • "folder_name" is the path of the directory/folder that you want to delete. Make sure to enclose the folder name/path in double quotes if it contains spaces or special characters.
    • -
    \ No newline at end of file + + + + + + + +

    CMD

    rmdir

    The rmdir /s /q "folder_name" command is used to delete a directory and all its contents in Windows Command Prompt (CMD) without sending them to the Recycle Bin.

    Parameters:

      +
    • /s is a switch for "subdirectories" that tells the command to remove all files and directories within the specified directory/folder, including any subdirectories.
    • +
    • /q is a switch for "quiet mode" that tells the command to operate quietly without asking for confirmation from the user.
    • +
    • "folder_name" is the path of the directory/folder that you want to delete. Make sure to enclose the folder name/path in double quotes if it contains spaces or special characters.
    • +
    \ No newline at end of file diff --git a/docs/tools/docker-desktop.html b/docs/tools/docker-desktop.html deleted file mode 100644 index 0498f3874..000000000 --- a/docs/tools/docker-desktop.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - Docker Desktop - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Docker Desktop

    Intro

    Docker Desktop for Windows provides a development environment for building, shipping, and running dockerized apps. By enabling the WSL 2 based engine, you can run both Linux and Windows containers in Docker Desktop on the same machine.

    Configuration

    -

    Warning
    -This process requires reboot

    -
      -
    1. Ensure Hyper-V has been enabled
    2. -
    3. Run winget install -e --id Docker.DockerDesktop
    4. -
    5. Click Settings
    6. -
    7. Tick the “Start Docker Desktop when you log in“ option
    8. -
    9. Run systeminfo | find "System Type" to check if your system is x64 (if so, download wsl_update_x64.msi)
    10. -
    11. Run wsl --set-default-version 2
    12. -
    13. Run wsl --install -d Ubuntu
    14. -
    15. Create a default UNIX user account
    16. -

    WSL Process

    image

    Configure WSL2

      -
    1. Run wsl --shutdown
    2. -
    3. Run notepad "$env:USERPROFILE/.wslconfig"
    4. -
    [wsl2]
    -memory=5GB   
    -processors=1 
    -

    See all configuration options

    Build and Run a Container

      -
    1. Navigate to the folder where the Dockerfile is stored
    2. -
    3. Run docker build -t angular-container:1.0 .
    4. -
    5. Search ImageID by running docker images
    6. -
    7. Run docker run -p 80:80 469b3a773ed7
    8. -

    Running Docker Windows and Linux Containers Simultaneously

    Dockerfile example

    FROM node:lts as node
    -
    -RUN npm install -g @angular/cli
    -
    -WORKDIR /usr/src/app
    -COPY src/TeamHub.UI/ ./my-app/
    -
    -WORKDIR /usr/src/app/my-app
    -RUN npm install
    -RUN npm run build
    -
    -FROM nginx:alpine
    -COPY --from=node /usr/src/app/my-app/dist/team-hub.ui /usr/share/nginx/html
    -

    Images

    docker pull jagregory/cognito-local:latest
    -docker pull localstack/localstack:latest
    -docker pull amazon/dynamodb-local:latest
    -docker pull redis:latest
    -docker pull mcr.microsoft.com/mssql/server:2022-latest
    -docker pull datalust/seq:latest
    -docker pull motoserver/moto:latest
    -docker pull jijiechen/papercut:latest
    -

    Commands

      -
    • Display containers' resource usage statistics docker stats --all --no-stream
    • -
    • Stop running containers docker kill $(docker ps -q)
    • -
    • Remove all containers docker rm $(docker ps -a -q)
    • -
    • Remove all images docker rmi $(docker images -q)
    • -

    Security

    Documentation

    \ No newline at end of file diff --git a/docs/tools/firefox.html b/docs/tools/firefox.html index 6d04ffb15..46562de1e 100644 --- a/docs/tools/firefox.html +++ b/docs/tools/firefox.html @@ -1,46 +1,14 @@ - - - + Firefox - - - - + + - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + +
    \ No newline at end of file diff --git a/docs/tools/git.html b/docs/tools/git.html index 6bd28342f..c3c511d5d 100644 --- a/docs/tools/git.html +++ b/docs/tools/git.html @@ -1,56 +1,23 @@ - - - + Git - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
    Git

    Tools

      -
    • winget install -e --id Git.Git
    • -
    • winget install -e --id GitHub.GitHubDesktop
    • -
    • winget install -e --id GitHub.cli
    • -
    • winget install -e --id GitHub.GitLFS
    • -
    • winget install -e --id Microsoft.Git
    • -
    • winget install -e --id Microsoft.VFSforGit
    • -
    • winget install -e --id Microsoft.GitCredentialManagerCore
    • -
    • winget install -e --id Atlassian.Sourcetree
    • -
    • winget install -e --id TortoiseGit.TortoiseGit
    • -

    Git Credentials Manager

    \ No newline at end of file + + + + + + + +

    Git

    Tools

      +
    • winget install -e --id Git.Git
    • +
    • winget install -e --id GitHub.GitHubDesktop
    • +
    • winget install -e --id GitHub.cli
    • +
    • winget install -e --id GitHub.GitLFS
    • +
    • winget install -e --id Microsoft.Git
    • +
    • winget install -e --id Microsoft.VFSforGit
    • +
    • winget install -e --id Atlassian.Sourcetree
    • +
    • winget install -e --id TortoiseGit.TortoiseGit
    • +

    Git Credentials Manager

    \ No newline at end of file diff --git a/docs/tools/ideas.html b/docs/tools/ideas.html index 6297b5a00..f17eb48b4 100644 --- a/docs/tools/ideas.html +++ b/docs/tools/ideas.html @@ -1,46 +1,14 @@ - - - + Ideas - - - - + + - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + +
    \ No newline at end of file diff --git a/docs/tools/infersharp.html b/docs/tools/infersharp.html index 69c4fee38..d910f3c78 100644 --- a/docs/tools/infersharp.html +++ b/docs/tools/infersharp.html @@ -1,55 +1,23 @@ - - - + InferSharp - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
    InferSharp

    Getting started with Infer

    With Infer# v1.4 you can identify Security and Performance issues with a single click, all in VS2022 and VSCode. First, make sure that Windows Subsystem for Linux (WSL) is properly installed. Then, download and install the InferSharp extension from the Visual Studio or Visual Studio Code marketplaces. In this article, we’ll show the VS experience, which is mimicked in VS Code. You can also use Infer# directly in WSL and Docker.

    The extension adds an Infer# Analysis menu item to the Tools menu. The first time it’s selected, it will complete setup by downloading and installing the Infer# custom WSL distro from Github.

      -
    • "../assets/image_1667865010674_0.png" is not created yet. Click to create.
    • -
    • -

    Analyze your code

    After waiting for setup to complete, selecting the Infer# Analysis menu item again will prompt you to provide a directory tree (defaulting to the solution directory, if it exists) containing the DLLs and PDBs you want to analyze. Your selection is automatically saved for future runs in the .infersharpconfig file created in your project directory. The analysis will then run, displaying the warnings in the Error List pane. Additionally, information about the analysis steps is shown in a pane on the right side of the editor, with clickable links to the relevant lines of code.

      -
    • "../assets/image_1667865053544_0.png" is not created yet. Click to create.
    • -

    References

    \ No newline at end of file + + + + + + + +

    InferSharp

    Getting started with Infer

    With Infer# v1.4 you can identify Security and Performance issues with a single click, all in VS2022 and VSCode. First, make sure that Windows Subsystem for Linux (WSL) is properly installed. Then, download and install the InferSharp extension from the Visual Studio or Visual Studio Code marketplaces. In this article, we’ll show the VS experience, which is mimicked in VS Code. You can also use Infer# directly in WSL and Docker.

    The extension adds an Infer# Analysis menu item to the Tools menu. The first time it’s selected, it will complete setup by downloading and installing the Infer# custom WSL distro from Github.

      +
    • “../assets/image_1667865010674_0.png” could not be found.
    • +
    • +

    Analyze your code

    After waiting for setup to complete, selecting the Infer# Analysis menu item again will prompt you to provide a directory tree (defaulting to the solution directory, if it exists) containing the DLLs and PDBs you want to analyze. Your selection is automatically saved for future runs in the .infersharpconfig file created in your project directory. The analysis will then run, displaying the warnings in the Error List pane. Additionally, information about the analysis steps is shown in a pane on the right side of the editor, with clickable links to the relevant lines of code.

      +
    • “../assets/image_1667865053544_0.png” could not be found.
    • +
    \ No newline at end of file diff --git a/docs/tools/microsoft-application-inspector.html b/docs/tools/microsoft-application-inspector.html deleted file mode 100644 index 91d0a2152..000000000 --- a/docs/tools/microsoft-application-inspector.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - Microsoft Application Inspector - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      -
    • Microsoft Application Inspector is a software source code characterization tool that helps identify coding features of first or third party software components based on well-known library/API calls and is helpful in Security and non-security use cases
    • -
    • "../assets/image_1667865747494_0.png" is not created yet. Click to create.
    • -
    • Additionally, it includes a confidence indicator (and filter) as well as the ability to drill down to the code file area where the match was found.
      -
      "../assets/image_1667865786921_0.png" is not created yet. Click to create.
    • -

    References

    \ No newline at end of file diff --git a/docs/tools/powershell.html b/docs/tools/powershell.html index 648ca50c3..8d6d6386b 100644 --- a/docs/tools/powershell.html +++ b/docs/tools/powershell.html @@ -1,53 +1,21 @@ - - - + Powershell - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
    Powershell

    Installation

      -
    • + + + + + + + +

      Powershell

      Installation

        +
      • winget search --id Microsoft.PowerShell
         winget install -e --id Microsoft.PowerShell
         winget install -e --id Microsoft.PowerShell.Preview
         
      • -
      \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/tools/redis.html b/docs/tools/redis.html index c4fff58aa..221f5b0a6 100644 --- a/docs/tools/redis.html +++ b/docs/tools/redis.html @@ -1,57 +1,25 @@ - - - + Redis - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
    Redis

    Server

      -
    • docker run --name redisserver -p 6379:6379 -v hfredisdata:/var/opt/redis -d redis:latest
    • -
    • docker run --name redisserver -p 6379:6379 -v hfredisdata:/var/opt/redis -d redis:latest --requirepass test
    • -
    • docker run -d --cap-add sys_resource --name rp -p 8443:8443 -p 9443:9443 -p 12000:12000 redislabs/redis
    • -

    Client

      -
    • docker run -it --rm redis redis-cli --verbose -h host.docker.internal
    • -
    • docker run -it --rm redis redis-cli --verbose -h host.docker.internal --tls --insecure
    • -

    Reference

    \ No newline at end of file + + + + + + + +

    Redis

    Server

      +
    • docker run --name redisserver -p 6379:6379 -v hfredisdata:/var/opt/redis -d redis:latest
    • +
    • docker run --name redisserver -p 6379:6379 -v hfredisdata:/var/opt/redis -d redis:latest --requirepass test
    • +
    • docker run -d --cap-add sys_resource --name rp -p 8443:8443 -p 9443:9443 -p 12000:12000 redislabs/redis
    • +

    Client

      +
    • docker run -it --rm redis redis-cli --verbose -h host.docker.internal
    • +
    • docker run -it --rm redis redis-cli --verbose -h host.docker.internal --tls --insecure
    • +
    \ No newline at end of file diff --git a/docs/tools/slngen.html b/docs/tools/slngen.html index 5cf874f76..2756f50f2 100644 --- a/docs/tools/slngen.html +++ b/docs/tools/slngen.html @@ -1,46 +1,14 @@ - - - + slngen - - - - + + - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + +

    slngen

    slngen "C:\Dev\Web.csproj" --devenvfullpath "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\devenv.exe"

    \ No newline at end of file diff --git a/docs/tools/sql-server.html b/docs/tools/sql-server.html deleted file mode 100644 index a832351fe..000000000 --- a/docs/tools/sql-server.html +++ /dev/null @@ -1,234 +0,0 @@ - - - - Sql Server - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Sql Server

    Installation

    Local Server Instance

    winget install -e --id Microsoft.SQLServer.2019.Express
    -winget install -e --id Microsoft.SQLServer.2019.Developer --override '/QUIET /IACCEPTSQLSERVERLICENSETERMS /CONFIGURATIONFILE="C:\Dev\SQLConfigurationFile.ini"'
    -

    SQLConfigurationFile.ini

    ; Microsoft SQL Server Configuration file  
    -[OPTIONS]  
    -; Specifies a Setup work flow, like INSTALL, UNINSTALL, or UPGRADE.  
    -; This is a required parameter.  
    -ACTION="Install"  
    -; Specifies features to install, uninstall, or upgrade.  
    -; The list of top-level features include SQL, AS, RS, IS, and Tools.  
    -; The SQL feature will install the database engine, replication, and full-text.  
    -; The Tools feature will install Management Tools, Books online,   
    -; SQL Server Data Tools, and other shared components.  
    -FEATURES=SQL,Tools
    -INSTANCENAME=SQL2019Dev
    -SQLSYSADMINACCOUNTS="[Domain]\[Username]"
    -SECURITYMODE=SQL
    -SAPWD="S4P4ssw0rd"
    -

    Docker Image

    docker pull mcr.microsoft.com/mssql/server:2019-latest
    -docker pull mcr.microsoft.com/mssql/server:2022-latest
    -

    SQL Server Management Studio

    winget install -e --id Microsoft.SQLServerManagementStudio
    -winget upgrade -e --id Microsoft.SQLServerManagementStudio
    -

    Sqlcmd Tools

    winget install -e --id Microsoft.Sqlcmd
    -winget upgrade -e --id Microsoft.Sqlcmd
    -

    Documentation

    EF vs. Stored Procedures

    SQL Performance

    Resources

    Retries

    Enable transient error resiliency by adding EnableRetryOnFailure to the UseSqlServer call on ASP.NET

    Useful Queries

    Backup

    
    ---Windows
    -BACKUP DATABASE [DbName] TO
    -DISK = N'C:\Dev\Database\DbName.bak'
    -WITH COMPRESSION, STATS = 10
    -GO
    -
    ---Linux
    -BACKUP DATABASE [DbName] TO
    -DISK = N'/var/opt/mssql/data/DbName.bak'
    -WITH COMPRESSION, STATS = 10
    -GO
    -

    Paging

    --https://learn.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql
    -SELECT *
    -FROM Employee
    -ORDER BY EmployeeId
    -OFFSET 20 ROWS
    -FETCH NEXT 5 ROWS ONLY 
    -

    Restore

    USE master;
    -GO
    -
    -ALTER DATABASE [DbName]
    -SET SINGLE_USER
    -WITH ROLLBACK IMMEDIATE;
    -GO
    -
    -RESTORE DATABASE [DbName]
    -FROM DISK = N'C:\Dev\Database\DbName.bak'
    -WITH RECOVERY
    -GO
    -
    -RESTORE DATABASE [DbName]
    -FROM DISK = N'C:\Dev\Database\DbName.bak'
    -WITH MOVE 'DbName' TO 'C:\Dev\Database\DbName.mdf',
    -   MOVE 'DbName_log' TO 'C:\Dev\Database\DbName_log.ldf',
    -RECOVERY, REPLACE
    -GO
    -
    -RESTORE DATABASE Local
    -FROM DISK = N'/var/opt/mssql/data/Local.bak'
    -WITH MOVE 'Database' TO '/var/opt/mssql/data/Local.mdf',
    -     MOVE 'Database_Log' TO '/var/opt/mssql/log/Local.ldf',
    -RECOVERY, REPLACE
    -GO
    -

    Get all linked tables by FK

    SELECT
    -OBJECT_NAME(fkeys.constraint_object_id) foreign_key_name,
    -OBJECT_NAME(fkeys.parent_object_id) referencing_table_name,
    -COL_NAME(fkeys.parent_object_id, fkeys.parent_column_id) referencing_column_name,
    -OBJECT_SCHEMA_NAME(fkeys.parent_object_id) referencing_schema_name,
    -OBJECT_NAME (fkeys.referenced_object_id) referenced_table_name,
    -COL_NAME(
    -fkeys.referenced_object_id,
    -fkeys.referenced_column_id
    -) referenced_column_name,
    -OBJECT_SCHEMA_NAME(fkeys.referenced_object_id) referenced_schema_name
    -FROM
    -sys.foreign_key_columns AS fkeys
    -ORDER BY referenced_table_name
    -

    View the compatibility level of a database

    USE AdventureWorks2019;  
    -GO  
    -SELECT compatibility_level  
    -FROM sys.databases WHERE name = 'AdventureWorks2019';  
    -GO
    -

    List table and columns with their foreign keys

    SELECT
    -schema_name(tab.schema_id) + '.' + tab.name AS [Table],
    -col.name AS 'Column Name',
    -t.name AS 'Data Type',
    -col.max_length AS 'Max Length',
    -col.precision AS 'Precision',
    -schema_name(pk_tab.schema_id) + '.' + pk_tab.name AS 'Primary Table',
    -pk_col.name AS 'PK Column Name',
    -fk.name AS 'FK Constraint Name'
    -FROM
    -sys.tables tab
    -INNER JOIN sys.columns col ON col.object_id = tab.object_id
    -LEFT OUTER JOIN sys.foreign_key_columns fk_cols ON fk_cols.parent_object_id = tab.object_id
    -AND fk_cols.parent_column_id = col.column_id
    -LEFT OUTER JOIN sys.types AS t ON col.user_type_id = t.user_type_id
    -LEFT OUTER JOIN sys.foreign_keys fk ON fk.object_id = fk_cols.constraint_object_id
    -LEFT OUTER JOIN sys.tables pk_tab ON pk_tab.object_id = fk_cols.referenced_object_id
    -LEFT OUTER JOIN sys.columns pk_col ON pk_col.column_id = fk_cols.referenced_column_id
    -AND pk_col.object_id = fk_cols.referenced_object_id
    -ORDER BY
    -schema_name(tab.schema_id) + '.' + tab.name,
    -col.column_id
    -

    List tables with no records

    SELECT
    -  t.NAME AS TableName,
    -  p.rows AS RowCounts
    -FROM
    -  sys.tables t
    -  INNER JOIN sys.partitions p ON t.object_id = p.OBJECT_ID
    -WHERE
    -  t.NAME NOT LIKE 'dt%'
    -  AND t.is_ms_shipped = 0
    -  AND p.rows = 0
    -GROUP BY
    -  t.Name,
    -  p.Rows
    -ORDER BY
    -  t.Name
    -

    Encryption by Certificate

    Encryption by Password

    1 - Create Symmetric Key (one-off)

    Encryption keys are generated by running the CREATE SYMMETRIC KEY command.

    CREATE SYMMETRIC KEY [SymKey_SomeID] WITH ALGORITHM = AES_256,
    -KEY_SOURCE = 'KEY_SOURCE_STRING',
    -IDENTITY_VALUE = 'IDENTITY_VALUE_STRING' ENCRYPTION BY PASSWORD = 'eLtGc5woM&S$n5'
    -
    --- View the newly created encryption
    -SELECT * 
    -FROM sys.symmetric_keys
    -
    --- View the actual key data. At its lowest level, a 256 bit AES key is comprised of 256 bits (32 bytes) of data.
    -SELECT * 
    -FROM sys.key_encryptions
    -

    2 - Open Symmetric Key

    A symmetric encryption key must be opened using the OPEN SYMMETRIC KEY command before it can be used.

    OPEN SYMMETRIC KEY [SymKey_SomeID] 
    -DECRYPTION BY PASSWORD = 'eLtGc5woM&S$n5'
    -

    3 - Encrypt Data

    Data can be encrypted using the SQL function ENCRYPTBYKEY.

    The authenticator value is used as an additional piece of data against which the encryption will be validated. If the same context (including authenticator) is not provided again when decrypting, then decryption will fail.

    The following SQL statement demonstrates encrypting a string using a GUID value as an authenticator:

    DECLARE @keyId UNIQUEIDENTIFIER = (SELECT key_guid FROM sys.symmetric_keys WHERE name='SymKey_SomeID')
    -DECLARE @auth VARCHAR(40) = '7AECFD07-4643-41FC-B17C-472AD71699E7'
    -DECLARE @str VARCHAR(50) = 'Super secret string data'
    -SELECT ENCRYPTBYKEY(@keyId, @str, 1, @auth)
    -

    4 - Decrypt Data

    DECLARE @encryptedData VARBINARY(200) = 0x00983DD06D6B6AC67A112F2A8866927A020000005A05FE279810FC3A75B27979324C9C81EBCE0D65AD8E2312ACBC5E23A49F135FFE44453511432DDF7C68D764865DE75C12F692E50B0B6EC5F3FD2C0E4C2C68DE5EEB8F773DA407DA32D6C79C5EF6F0BA
    -DECLARE @auth VARCHAR(40) = '7AECFD07-4643-41FC-B17C-472AD71699E7'
    -SELECT CONVERT(VARCHAR(100), DECRYPTBYKEY(@encryptedData, 1, @auth))
    -

    Troubleshooting

      -
    • Error: 'Agent XPs' component is turned off as part of the security configuration for this server. A system administrator can enable the use of 'Agent XPs' by using sp_configure. For more information about enabling 'Agent XPs', see "Surface Area Configuration" in SQL Server Books Online. (Microsoft.SqlServer.Management.MaintenancePlanWizard)
    • -
    • Solution: -
      sp_configure 'show advanced options', 1;  
      -GO  
      -RECONFIGURE;  
      -GO  
      -sp_configure 'Agent XPs', 1;  
      -GO  
      -RECONFIGURE  
      -GO
      -
      -
    • -
    • Error: SQLServerAgent is not currently running so it cannot be notified of this action. (Microsoft SQL Server, Error: 22022)
    • -
    • Solution: Open SQL Server Configuration Manager and enable SQL Server Agent Service
    • -
    • Error: Cannot execute as the database principal because the principal ‘dbo’ does not exist, this type of principal cannot be impersonated, or you do not have permission. (Microsoft SQL Server, Error: 15517)
    • -
    • Solution: -
      USE [AdventureWorks]
      -GO
      -ALTER AUTHORIZATION ON DATABASE::[AdventureWorks] TO [sa]
      -GO
      -
      -
    • -

    Performance

    \ No newline at end of file diff --git a/docs/tools/troubleshooting.html b/docs/tools/troubleshooting.html index 790981600..d8f6e02ad 100644 --- a/docs/tools/troubleshooting.html +++ b/docs/tools/troubleshooting.html @@ -1,88 +1,56 @@ - - - + Troubleshooting - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
      -
    • -

      Useful commands

      + + + + + + + +

      Troubleshooting

      My Tools

      \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/tools/tye.html b/docs/tools/tye.html deleted file mode 100644 index fc11e1a06..000000000 --- a/docs/tools/tye.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - Tye - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    References

    Installation

    dotnet tool uninstall -g Microsoft.Tye
    -dotnet tool install -g Microsoft.Tye --version "0.11.0-alpha.22111.1"
    -tye --version
    -
      -
    • -

    Create tye.yaml

      -
    • -

      Tye Schema File

      -
        -
      1. Go to the solution folder
      2. -
      3. Run tye init to generate tye.yaml
      4. -
      -
    • -

    tye.yaml Example

    extensions:

      -
    • name: seq
      -logPath: ./.logs
    • -

    name: servicetemplate
    -network: tye-network
    -ingress:
    -- name: Ingress
    -bindings:
    -- port: 50000
    -protocol: https
    -ip: '127.0.0.1'
    -rules:
    -- host: authentication-api.domain.com
    -service: authentication-api
    -services:

    - name: authentication-api
    -  project: src/Authentication.API/Authentication.API.csproj
    -  bindings:
    -  - port: 51001
    -    protocol: https
    -  #replicas: 2
    -
    -- name: servicename-api
    -  project: src/ServiceName.API/ServiceName.API.csproj
    -  bindings:
    -  - port: 51005
    -    protocol: https
    -  #replicas: 2
    -
    -- name: mock-api
    -  project: src/Mock.API/Mock.API.csproj
    -  bindings:
    -  - port: 51003
    -    protocol: https
    -  #replicas: 2
    -
    -- name: featuremanagement-api
    -  project: src/FeatureManagement.API/FeatureManagement.API.csproj
    -  bindings:
    -  - port: 51004
    -    protocol: https
    -  #replicas: 2
    -
    -- name: analytics-api
    -  project: src/Analytics.API/Analytics.API.csproj
    -  bindings:
    -  - port: 51006
    -    protocol: https
    -  #replicas: 2
    -
    -- name: SqlServer
    -  image: mcr.microsoft.com/mssql/server:2019-latest
    -  bindings:
    -  - connectionString: Data Source=localhost,1433;Initial Catalog=ServiceDB;Persist Security Info=True;User ID=sa;Password=${env:SA_PASSWORD}
    -    port: 1433
    -  env:
    -  - name: SA_PASSWORD
    -    value: secret
    -  - name: ACCEPT_EULA
    -    value: "Y"
    -
    -- name: Redis
    -  image: redis
    -  bindings:
    -  - port: 6379
    -    connectionString: "${host}:${port}"
    -  args: "--requirepass secret"
    -
    -- name: DynamoDB
    -  image: "amazon/dynamodb-local:latest"
    -  args: -jar DynamoDBLocal.jar -inMemory -sharedDb
    -  bindings:
    -  - port: 8000
    -  env:
    -  - name: AWS_ACCESS_KEY_ID
    -    value: test
    -  - name: AWS_SECRET_ACCESS_KEY
    -    value: test
    -  - name: REGION
    -    value: ap-southeast-2
    -    
    -- name: KMS
    -  image: nsmithuk/local-kms
    -  volumes:
    -     - source: "C:/"
    -       target: "/mnt/c"
    -  bindings:
    -  - port: 52002
    -  env:
    -  - name: KMS_REGION
    -    value: "ap-southeast-2"
    -  - name: KMS_SEED_PATH
    -    value: "/mnt/c/Dev/local-kms-seed.yaml"
    -
    -- name: Cognito
    -  image: jagregory/cognito-local:latest
    -  volumes:
    -     - source: "C:/Dev/.cognito"
    -       target: "/app/.cognito"
    -  bindings:
    -  - port: 9229
    -  env:
    -  - name: NODE_TLS_REJECT_UNAUTHORIZED
    -    value: "0"
    -
    -- name: LocalStack
    -  image: "localstack/localstack:latest"
    -  bindings:
    -  - port: 4566
    -  env:
    -  - name: DEBUG
    -    value: "1"
    -  - name: SERVICES
    -    value: "logs"
    -
    -- name: Zipkin
    -  image: "openzipkin/zipkin"
    -  bindings:
    -  - port: 9411
    -    protocol: http
    -
    -
    -- https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.DownloadingAndRunning.html ([[Docker]] Tab)
    -- https://docs.amazonaws.cn/en_us/amazondynamodb/latest/developerguide/DynamoDBLocal.UsageNotes.html
    --
    -- **DynamoDB Container Note**
    -- ``-inMemory`` and ``-dbPath`` cannot be set at the same time
    -- Local [[DynamoDB]] has serious performance issues when not using ``-inMemory`` parameter
    -# Run Tye
    -- 1. Run ``tye run --port 10000 --dashboard`` (where the ``tye.yaml`` file is located)
    -  2. Add ``--watch`` to watch file changes in all projects.
    -  3. Add ``--debug *`` to debug (and attach the debugger to the application process)
    --
    -- ```
    -  aws --endpoint-url=http://localhost:8000 dynamodb list-tables  
    -  aws --endpoint-url=http://localhost:8000 dynamodb create-table --table-name ServiceName_Setting --attribute-definitions AttributeName=TenantId,AttributeType=S --key-schema AttributeName=TenantId,KeyType=HASH --billing-mode PAY_PER_REQUEST  
    -
      -
    • -

    Troubleshooting

      -
    • An attempt was made to access a socket in a way forbidden by its access permissions
      -Run net stop hns and net start hns
    • -
    • -
    • Could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network -
        -
      1. Stop running containers docker kill $(docker ps -q)
      2. -
      3. Remove all containers docker rm $(docker ps -a -q)
      4. -
      5. Remove unused networks docker network prune
      6. -
      -
    • -
    \ No newline at end of file diff --git a/docs/tools/visual-studio.html b/docs/tools/visual-studio.html deleted file mode 100644 index 6161ce10d..000000000 --- a/docs/tools/visual-studio.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - Visual Studio - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Visual Studio

    <<<<<<< HEAD

    Installation

    >>>>>>> e89b33083bcb8beb793b776dec7c4eab0dce39bd
    - winget install -e --id Microsoft.VisualStudio.2019.Professional
    - winget install -e --id Microsoft.VisualStudio.2022.Enterprise
    - winget install -e --id Microsoft.VisualStudio.2022.TestController
    - winget install -e --id Microsoft.VisualStudio.2022.TestAgent
    - winget install -e --id Microsoft.VisualStudio.2022.TeamExplorer
    - winget install -e --id Microsoft.VisualStudio.2022.Professional
    - winget install -e --id Microsoft.VisualStudio.2022.Enterprise
    - winget install -e --id Microsoft.VisualStudio.2022.Community
    - winget install -e --id Microsoft.VisualStudio.2022.BuildTools
    -

    Configuration

    Extensions

    
    -#Credits: https://gist.github.com/ScottHutchinson/b22339c3d3688da5c9b477281e258400
    -#$PackageName = "AmazonWebServices.AWSToolkitforVisualStudio2022"
    -#$PackageName = "GitHub.copilotvs"
    -#$PackageName = "SteveCadwallader.CodeMaid"
    -#$PackageName = "SteveCadwallader.CodeMaidVS2022"
    -#$PackageName = "ironcev.sharpen"
    -#$PackageName = "SonarSource.SonarLintforVisualStudio2022"
    -#$PackageName = "DevExpress.CodeRushforVS2022"
    -#$PackageName = "MLNET.notebook"
    -#$PackageName = "VisualStudioProductTeam.ProjectSystemTools2022"
    -$PackageName = "snyk-security.snyk-vulnerability-scanner-vs-2022"
    -
    -$ErrorActionPreference = "Stop"
    -
    -$baseProtocol = "https:"
    -$baseHostName = "marketplace.visualstudio.com"
    -
    -$Uri = "$($baseProtocol)//$($baseHostName)/items?itemName=$($PackageName)"
    -$VsixLocation = "$($env:Temp)\$([guid]::NewGuid()).vsix"
    -
    -$VSInstallDir = "C:\Program Files (x86)\Microsoft Visual Studio\Installer\resources\app\ServiceHub\Services\Microsoft.VisualStudio.Setup.Service"
    -
    -if (-Not $VSInstallDir) {
    -Write-Error "Visual Studio InstallDir registry key missing"
    -Exit 1
    -}
    -
    -Write-Host "Grabbing VSIX extension at $($Uri)"
    -$HTML = Invoke-WebRequest -Uri $Uri -UseBasicParsing -SessionVariable session
    -
    -Write-Host "Attempting to download $($PackageName)..."
    -$anchor = $HTML.Links |
    -Where-Object { $_.class -eq 'install-button-container' } |
    -Select-Object -ExpandProperty href
    -
    -if (-Not $anchor) {
    -Write-Error "Could not find download anchor tag on the Visual Studio Extensions page"
    -Exit 1
    -}
    -Write-Host "Anchor is $($anchor)"
    -$href = "$($baseProtocol)//$($baseHostName)$($anchor)"
    -Write-Host "Href is $($href)"
    -Invoke-WebRequest $href -OutFile $VsixLocation -WebSession $session
    -
    -if (-Not (Test-Path $VsixLocation)) {
    -Write-Error "Downloaded VSIX file could not be located"
    -Exit 1
    -}
    -Write-Host "VSInstallDir is $($VSInstallDir)"
    -Write-Host "VsixLocation is $($VsixLocation)"
    -Write-Host "Installing $($PackageName)..."
    -Start-Process -Filepath "$($VSInstallDir)\VSIXInstaller" -ArgumentList "/q /a $($VsixLocation)" -Wait
    -
    -Write-Host "Cleanup..."
    -rm $VsixLocation
    -
    -Write-Host "Installation of $($PackageName) complete!"
    -

    Features

    \ No newline at end of file diff --git a/docs/tools/vscode.html b/docs/tools/vscode.html index 5b0104629..3cc89fde4 100644 --- a/docs/tools/vscode.html +++ b/docs/tools/vscode.html @@ -1,46 +1,19 @@ - - - + VSCode - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
    VSCode

    Installation

      -
    • Run winget install -e --id Microsoft.VisualStudioCode
    • -

    Extensions

    code --install-extension ms-dotnettools.csdevkit
    +		
    +		
    +		
    +		
    +		
    +		
    +		
    +		

    VSCode

    Installation

      +
    • Run winget install -e --id Microsoft.VisualStudioCode
    • +

    Extensions

    code --install-extension ms-dotnettools.csdevkit
     code --install-extension ms-vscode-remote.remote-containers
     code --install-extension amazonwebservices.aws-toolkit-vscode
     code --install-extension angular.ng-template
    @@ -74,13 +47,8 @@
     code --install-extension quicktype.quicktype
     code --install-extension ms-dotnettools.dotnet-interactive-vscode
     code --install-extension ms-vscode-remote.vscode-remote-extensionpack
    -
      -
    • -

    Documentation

    \ No newline at end of file +
      +
    • +

    Documentation

    \ No newline at end of file diff --git a/docs/tools/windows-terminal.html b/docs/tools/windows-terminal.html deleted file mode 100644 index aa94b491e..000000000 --- a/docs/tools/windows-terminal.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - Windows Terminal - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Windows Terminal

    Installation

      -
    1. Install Caskaydia Cove Nerd Font Complete Regular.otf
    2. -
    3. Run winget install --id Microsoft.WindowsTerminal
    4. -
    5. Run winget install --id Microsoft.PowerShell
    6. -
    7. Run winget install --id JanDeDobbeleer.OhMyPosh
    8. -
    9. Run Install-Module PSReadLine -AllowPrerelease -Force
    10. -
    11. Run notepad $PROFILE
    12. -
    13. Add these lines
    14. -
    oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH\jandedobbeleer.omp.json" | Invoke-Expression
    -Import-Module PSReadLine
    -Set-PSReadLineOption -PredictionSource History  
    -Set-PSReadLineOption -PredictionViewStyle ListView  
    -Set-PSReadLineOption -EditMode Windows
    -
      -
    1. Restart command prompt window
    2. -
    3. Go to Settings -> Profile -> Appearance
    4. -
    5. Check "Show all fonts"
    6. -
    7. Choose the CaskaydiaCove Nerd Font
    8. -

    Documentation

    \ No newline at end of file diff --git a/docs/tools/windows.html b/docs/tools/windows.html index 7f97e1876..58ef6a608 100644 --- a/docs/tools/windows.html +++ b/docs/tools/windows.html @@ -1,49 +1,22 @@ - - - + Windows - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
    Windows

    DISM Commands

      -
    • List All Features: DISM /online /get-features /Format:Table
    • -
    • See Feature Info: DISM /online /get-featureinfo /featurename:[feature name]
    • -
    • Disable Feature: DISM /online /disable-feature /featurename:[feature name]
    • -
    • Enable Feature: DISM /online /enable-feature /featurename:[feature name]
    • -

    Enable Windows Features (Windows 10)

    DISM /online /enable-feature /featurename:IIS-WebServerRole
    +		
    +		
    +		
    +		
    +		
    +		
    +		
    +		

    Windows

    DISM Commands

      +
    • List All Features: DISM /online /get-features /Format:Table
    • +
    • See Feature Info: DISM /online /get-featureinfo /featurename:[feature name]
    • +
    • Disable Feature: DISM /online /disable-feature /featurename:[feature name]
    • +
    • Enable Feature: DISM /online /enable-feature /featurename:[feature name]
    • +

    Enable Windows Features (Windows 10)

    DISM /online /enable-feature /featurename:IIS-WebServerRole
     DISM /online /enable-feature /featurename:IIS-WebServerManagementTools
     DISM /online /enable-feature /featurename:IIS-ManagementConsole
     DISM /online /enable-feature /featurename:IIS-NetFxExtensibility45
    @@ -66,33 +39,28 @@
     DISM /online /enable-feature /featurename:IIS-ClientCertificateMappingAuthentication
     DISM /online /enable-feature /featurename:IIS-IISCertificateMappingAuthentication   
     DISM /online /enable-feature /featurename:IIS-CertProvider
    -
      -
    • -

    Configure IP/Port Mapping

    Overview

    image

    Actions

      +
      +
    • +

    Configure IP/Port Mapping

    Overview

    image

    Actions

    1. Started my server on localhost:8081
    2. Added my "local DNS" in the hosts file as a new line (127.65.43.21 example.app). Any free address in the network 127.0.0.0/8 (127.x.x.x) can be used. You can check with netstat -a -n -p TCP | grep "LISTENING"
    3. Added the following network configuration with netsh interface portproxy add v4tov4 listenport=80 listenaddress=127.65.43.21 connectport=8081 connectaddress=127.0.0.1
    4. I can now access the server at http://example.app
    5. -

    Notes

      -
    • +

    Notes

      +
    • These commands/file modifications need to be executed with Admin rights

    • -
    • +
    • netsh portproxy needs ipv6 libraries even only to use v4tov4, typically they will also be included by default, otherwise install them using the following command: netsh interface ipv6 install

      You can see the entry you have added with the command:

      netsh interface portproxy show v4tov4

      You can remove the entry with the following command:

      netsh interface portproxy delete v4tov4 listenport=80 listenaddress=127.65.43.21

    • -

    Documentation

    \ No newline at end of file +
    \ No newline at end of file diff --git a/docs/tools/winget.html b/docs/tools/winget.html index a715aa233..f0f2fd188 100644 --- a/docs/tools/winget.html +++ b/docs/tools/winget.html @@ -1,62 +1,30 @@ - - - + WinGet - - - - + + - - - - - - - - - - - - - - - - - - - - - - -
    \ No newline at end of file + + + + + + + +
    \ No newline at end of file diff --git a/images/Pasted image 20240510085959.png b/images/Pasted image 20240510085959.png new file mode 100644 index 0000000000000000000000000000000000000000..f9466319d4ed42bcd5ea7b66ee6dcdf47b686240 GIT binary patch literal 8710 zcmbt)c|4R~-~S~kO4$k_geYXsE|P7m$(FJvNm(MhuO-Qn?0byLZU|Y+lI+YBg&{K` zhGfQ2!`O!Loaz3)UcdW({qE;^-Oua!$6Rwc*E#1p=ks~L-=FuH_^YP+$BytEfgtD@ z%s}TF1RXd7L3GlLhrpe5GTS`}5`T0~E#gzOE3nS6b#>UEK(|ErH5z=RCYwN=R zK~6p5O%h;Mq8yhQA*eP=@E`9fSB2OL!Z}H(s6f1a) zf!3U{v8gEw_WT^}zF?a8fB{Ej9IbsMV`XKf5Ies|5UNc9_UDd)^CJUJy12Nw?wX$m zph)G;>68Y#I7SWdq}F52p94Y=+Zoz;JY6v^BSN$*L#m1(Vh~YE8(OQl7FKS{AoORT z4E*^V$pdV}GMDj*3E>I2X2c~QhO2zjveu`Eop{i}vx~!{9VXx26&Y4qI6_)JCLU%3 zJ3B2K3@5f{xuFm9h+MA^_F}uFWw@XgUF2`YH?&E7kir$DoKtn#oNjp=%%J*^-EwJf zTR-!3mUS$m8sTfQdAV%4oM?<06|I4TVH=arKu&+%9_L`c_*+IiFS|h>0zhW}IF|o^qps%HS5-qlKY{p>4M`iytn*I(xXV+WeAmsjR z%0I>0|1vcHljcvKn--GE!!L##?Z+BYmvY?`fEZtPPO1WR*K(UO8ncksRN{=?+85|em+DkE5vxOpP9GY@)5a1pRF}QD6n$;KsWahigxV-1 z;(@K|K}&3L`&h!)s)QlP6<1YN^){HRD;?y7V4MmqGybs&y#_HZU|XVoGJys7A5r1& zrDx-fu6q6Y{C-6fDowMayrUoXpkoe$%~DTZD@XGAs}zNJpU}00drUM+_H%K&y}3Mq z$K!uFe!Y(lutlnNw9WsfYiMdJMgOqPt|*f1*S#$#b=*~zUssW7@yOMK7qKTHNJL3P z)Fqk{sEQCnqJSL`!I#qGZmzLP}A z*D@ER#SjGr4uT>b7TuZfa2-f9S4-&k2^QIoQ?6`K$H(csuA!LQ&YZ@at4LkFLX+-n3^uuI$X9K=_hsh^kz5wYD39}D9N zuAe`-j9E_2wmc0|-}T5Z61Qy#w#BDdspzT%1pC_C*iB?EEx8BpZoMJmq2Zi@0{()c zBwSDFi?_DMop0<<=#Tf`W>50rq~ruXFz;(i7^0*ce%iPGjSpsK@NNF}_tSSd1B*Mg zu9Q71cTTEp^Ft=`1i+p*8(Ln1t+A}=V?LOag?B3WJXDSf?p<&T@$kd1I%d!Bq6cjn zO-68qdHQL)>0{C`RrGJNLxKn|rv+RBs-xust7!r}-t{Uj=b5Q3_D0#X>s0f(YJy?M zOmU zC^T=pRg%JBEDloXr4D%Ky}dA%koEE}4?dzRZ5HNw6H-w%4(&YeUPpvo=Xbb7C7Unk zdU8p6^Zjhq$FvrzG#QOHb?mnoE!tpNRO~%axlA z1N{A&lT)xf#60a+h(pvPa~YHCQ*$K7jj?F*_vi(Ik7_w?mY2*?MH`)^HGeHgkVq)$ z*lNo9s2LMr+l}%V&$$@C5ysY($^*>le-%ZsO!+&zOFOi2^Bz3;<*>kCf-^hg%>_qw zF72&bY=3{u;(K1+oK>z`eu&N~-}R(OwEfGqA00u5=?jXvHoq$()YGaZ@|**#fobARkP#$7qeEXzA&Lxf8 zM$?_K`VCu~9O^M?BwY!B#^e0~ESKIf`23dZhF)6p<|LYE7o9ZRjV9%XNbOdsBq=p);a&jQor`0GTy#0=1}+6&<$4TPNO_LeMkb*9ELKWrACQV}!T~zr_9{@ zG6h3y8kcz%3sjn6pAX+822*E$?7Ip86rhY`hWPqZ+uJoJvDkY1lTHI_VkS{3BN4Wz zAY-0>pB^8+;9uV#f!xo1@giHVs8gNoSw2pAgc#uJ=BCfD87`S=_yqLZmx)uJYpDjo z%oePAsH3@A>~ZG@-%m0X;+e=_F9IF#hiEG7svK48whVV1PWf7eOv`b#wgQz^zG5-( zcs^HLkiaf;?+4C^&(7?B^q`h|FxXoqCyTU)DYThC`%drLCn)s4mYaVQ%d68gVmY>- zX*)@%L5+v+pwJbM#S@ndINI2t)vdXm;=@DHQpUh0YRx3{-%v`im#st@zb zcujHm-bNp}c$Oz=mLAYZammT(@(|6!827e`PJi<&s;XBsV8|mLkl@r4EqO_W}7 z#chRNHg*UVxI>-riJ;_WEeNPS#lM54l_8P}B-e~@=vyG#7sG1kwb=D8#~FkRn7UGGEgG+UovIXnAtY0= zc5Wp0l>g1M=cN<&_!<>D6`|r+dw$GFRBMjNyO+h2oW1Ek+CMHrkyY;G=!0UVAzVe} z3#ERfcq5L+p$_}&69H*E`U_l{-Wie`Y7#B}L&EJt)CKf$_hI7qZC8wxtvOohdcRXk zEpcwh2O5Z~udAEGRO{UMR?=UT2tm5t6HWA>u6QO^T4?vv`Y?0?eVw@5*x9d3ovE+rbr< z;<*g`;YqlGv9Sze6O+M5^oK$E3=9n=Ew8MUBLC4CfxcG<s79f#F%gj*k9xl%J z#B=y={c>hwdl#|){@c5U`qhpdQcB*_#`dKk`CePQ`uLbX|5WPX={ZQHhS#-OTU&n{ zyLbSCgsm#k^SxY-85I@hRRWfC?B4n6n!;5}zWtDn*iP7;IYWGT)3Wr08=#sl`k9jAkEiI(j`oiB^0yikiTBE0gG z%~|W-zo&kyqty>w_Y!RO<gK{>&8?*jRvn=L?v)lVuQ9*;kGHj(hMewv~dG;zAAUDKpCRwzf`?n9BdvMG3cbzC7!}EhuR+MgSGYS1kh(b*Eohhnrb$-nmh8&Kw)fK#vFs1)|cXBpw5b z)OR2#;t4Ijb3O56!C`v@M=mz=@MeRtblD`FdULfy4R7WP)I?M4G3=IfX(`>4p(pYQ z36<{cY4fw*3AGI{Oj5ydD2ESy&x)`AR5*(Pk7{uFk0)E%DoMhP&uwR78l@#rE@`(p zgOkKrMB@)YX#+T3a}%U>m|L9tR29P++v$qRA2)K4g%0aL0FdfBI;25-ugr8vOLy%0 zBHF-}cbka}>+g;ga)@5A`>}qVPp+(Ac)Pft2#s~>OyZA1=MJrEM=TD($AVo`V_z&a zm-2jKVmc&*_#m>S>M?iQ?h>qIP&y%`g2b37!`tX7(|(UPiU-PJCI;LDN=S2emZf5? z#RsQXNbHKS2X_KmJu{Lw9y|;DJ(>%h+6?lvbbvj{EK3jkB|9#OFF{@@Q-UpixjovS z-Q6U7moCy5@23ig>swo}h1XO|=2ojV_&5tPCByJ+o}1;N$B+C}PZxR0?Gw3Ikm*H4 z2vTjU@zeyF(MBG>8Q;;ghfCHpRrqpIS;Zfu=J>dE_&-wKIWW+sWvbf4!(+fKoW!xT zNx@(@C}G=6W)b4Nyu7&@?xRb7&*)kIkvdDW-LWGC^8DWBO!jKTKE;_`!Yi?$T;=Cwq(p5a#?7&_oe(#@+<6q%Cd0`vwFV0`IE~ zkP+kV@|ZRKBYjTeWIE{C^_q!vAcp`Z>tR0) z52KDsw+W7pj?O8Ynl?%tn(!|H7}g!j0_0EsU94Ww8F_hmxr-MwEr`n@U~`s6QhU&yyGf0(5d_ zMhv2hlm(Hzyt-;sHkt}%_UVp%KpsHUT)-yQm1ijwii<#GTpVq8XJ)cNdG~E!*}}qt z1K4ls$KD!;hTeLdlAC)9?BziLNTv@Y6PP!6J*3~`PAw25&sKx_!DgmCdBWiO>moPv zEvzr!r;i`G8A{$R&^qfa z@7J_%d<%iQItM>l$Sw{?s9U=3G#~v@go$kj9S~&IGl#P%RO|)nd?V`AAOc&5cyMx00a#?80-6|N)*BFWq*uu>56(> zo3IT=;>6r641L35L|JKFJ-*L?I$G&6*5U*QCDVSyb17=jDWYxOl@xm$`mYfJ`>fz?^ zA?fOM${om_R!T<*885FvH%+KraK^^AAICa0wv`udoY{&PyQJG#a*tx(VD_V1wuqCN zzfG%~@|{u2<_po8=?6U1DXjjSa8+2;wq7O&XHEs4+h4M<>Eh|3r}vXJJTp!eF<}vhVXRn@Xa6gtR^8$g(I;G z_UqHJ30%^bxa@Svk_=eGvI{teMc3OL7JJ@^hW0avHviH7%*=UHk)R2e7R^q@Yv{>+ z4CV8Y_v3>~_i_>ZwhIg9VLuUB{r0uSQA6sN)^S7hR#?P{UVHZ3(BlTzv$m^TXnyyk zD_LZV*G3`lE5^-k)y{T|9(VZOB^5+qtJsN8A1g=d*szh0R~x=VhqN($L$fWT+s`+mVH8}{n?GyDZ3 zOzX9IU_Vb&85U!M2wl{1dvBvs4G^ds4VJims$Bg!C2^Ujm3dylodvmX1&!TIuh-k9+xb6p@@g`OGJyaB-$RTf@YeK4&@Yp}G(g>6H zxQdYNW@}EUr!rqi`@VZ9vv!-sd`-K{p%R&Z!Zy{eTE-vk>cR-WZC|459dmUZ1n_4b zK1d;v>KbmmwmXvCa$f+=Tl35w?ppP*pw5E@qnKNTeLc|sYQP_bTwbp7@bZeOerRvA zvAMbM^Gnf)SF^rd{jLA!UCb#D$rIWFc1E(_E2OoYATAX|?BWDo5!w6j6HQ{L(gs_1 z3ng6OYZ+Fd#$CN~Ql6M216{r8FCpSP#HT-A@a?ME(O zKb=GeojBSp8}d|v&qAT(6!;3I8%Z#JiN6Cu3w>@HdKVNK0UiRutZ&W*Md||J4rwot zO9U10lAoSs(Hu|@$d{hiu;;7oqX2vY;;5J)=nMe(1Y$g-T`Dv*^vx2#MuhsNY@M=hGU6rzLWlMl#{KO9SOXdf63={UDSpz2Pi#Y54Mw~@B6WGZqly{2%AbUb zBec*ejKAxAz>%f(#5IvW2WA#zj667E8`#yhppthx;^PKh?C+N8w4eE-*bL1UgVoh0TtE-) z)|nktvhX%$A}Jo1vw2@xLPBCG;t&h4sxpDx5E7d5Qj#-?_>R=ve;5>{lppsn)=Sm8sUc`g(b0?X2wV zg|Ba1x?eqS;0CGe6cx4_I+G5v?r9vYX8t%ltSP?>*h7TLo+mf+advKgD%JQIHNIG?g$f3g4(e zPXyQOp}O&2X>JeH;A+@%xx(>^EL~!e_>72u0ye@5?uS2#_EKHg8Le=jY-1(1ng`#N zVfvjyqf0>7=mhpayFwCLgUbX-AK3s7tq>1WuiA6h4Mt!b=6tm$Z|Nj+q+Q7 zqis~TPYsE=Fj0}c;v?&RA07U)7_G5c*p#5AC%RC%aky)=w{Zgd=Y-5+z2EN+`_iG6Ope%fQ3>A-!Uvxj7x;1kJ7rby$l$9? zCW7DfTGLKQS5ot*FjxpRH~(fQ33^tepUe*fxDC1lv_M*rj!NZ$u9<5>dF`WtWXJBGU+<)@$G@pWMYVbamZ}YK0R(0#9iH+H)lY& za;BC!S_l02cvfChaOC~*#ZZE>JV3R{g z^Gr AfdBvi literal 0 HcmV?d00001 diff --git a/src/AWS KMS.org b/src/AWS/AWS KMS.md similarity index 89% rename from src/AWS KMS.org rename to src/AWS/AWS KMS.md index 92adfe248..a04c0ae31 100644 --- a/src/AWS KMS.org +++ b/src/AWS/AWS KMS.md @@ -1,8 +1,4 @@ -* Commands -:PROPERTIES: -:heading: 1 -:END: + * `aws --endpoint-url=http://localhost:52002 kms --region ap-southeast-2 create-key --key-spec RSA_2048 --key-usage SIGN_VERIFY` * `aws --endpoint-url=http://localhost:52002 kms --region ap-southeast-2 list-keys` * `aws --endpoint-url=http://localhost:52002 kms --region ap-southeast-2 get-public-key --key-id 6732c7ca-6ec9-4b96-9711-fd1c7d637c8e` -* \ No newline at end of file diff --git a/src/Email Templates/Onboarding.md b/src/Email Templates/Onboarding.md index e913958b1..576c92346 100644 --- a/src/Email Templates/Onboarding.md +++ b/src/Email Templates/Onboarding.md @@ -1,4 +1,4 @@ -- [[Management/Onboarding]] Templates +- [[src/Engineering Management/Onboarding]] Templates - - **Before Starting** - Hi [new team member], diff --git a/src/Management/.obsidian/app.json b/src/Engineering Management/.obsidian/app.json similarity index 100% rename from src/Management/.obsidian/app.json rename to src/Engineering Management/.obsidian/app.json diff --git a/src/Management/.obsidian/appearance.json b/src/Engineering Management/.obsidian/appearance.json similarity index 100% rename from src/Management/.obsidian/appearance.json rename to src/Engineering Management/.obsidian/appearance.json diff --git a/src/Management/.obsidian/core-plugins-migration.json b/src/Engineering Management/.obsidian/core-plugins-migration.json similarity index 100% rename from src/Management/.obsidian/core-plugins-migration.json rename to src/Engineering Management/.obsidian/core-plugins-migration.json diff --git a/src/Management/.obsidian/core-plugins.json b/src/Engineering Management/.obsidian/core-plugins.json similarity index 100% rename from src/Management/.obsidian/core-plugins.json rename to src/Engineering Management/.obsidian/core-plugins.json diff --git a/src/Management/.obsidian/hotkeys.json b/src/Engineering Management/.obsidian/hotkeys.json similarity index 100% rename from src/Management/.obsidian/hotkeys.json rename to src/Engineering Management/.obsidian/hotkeys.json diff --git a/src/Management/.obsidian/workspace.json b/src/Engineering Management/.obsidian/workspace.json similarity index 100% rename from src/Management/.obsidian/workspace.json rename to src/Engineering Management/.obsidian/workspace.json diff --git a/src/Management/1on1s.md b/src/Engineering Management/1on1s.md similarity index 100% rename from src/Management/1on1s.md rename to src/Engineering Management/1on1s.md diff --git a/src/Management/Agile.md b/src/Engineering Management/Agile.md similarity index 100% rename from src/Management/Agile.md rename to src/Engineering Management/Agile.md diff --git a/src/Management/Career.md b/src/Engineering Management/Career.md similarity index 100% rename from src/Management/Career.md rename to src/Engineering Management/Career.md diff --git a/src/Management/Change Management.md b/src/Engineering Management/Change Management.md similarity index 100% rename from src/Management/Change Management.md rename to src/Engineering Management/Change Management.md diff --git a/src/Management/Coaching.md b/src/Engineering Management/Coaching.md similarity index 100% rename from src/Management/Coaching.md rename to src/Engineering Management/Coaching.md diff --git a/src/Management/Code Reviews.md b/src/Engineering Management/Code Reviews.md similarity index 100% rename from src/Management/Code Reviews.md rename to src/Engineering Management/Code Reviews.md diff --git a/src/Management/Community Of Practice.md b/src/Engineering Management/Community Of Practice.md similarity index 100% rename from src/Management/Community Of Practice.md rename to src/Engineering Management/Community Of Practice.md diff --git a/src/Management/Culture.md b/src/Engineering Management/Culture.md similarity index 100% rename from src/Management/Culture.md rename to src/Engineering Management/Culture.md diff --git a/src/Management/Developer Experience.md b/src/Engineering Management/Developer Experience.md similarity index 100% rename from src/Management/Developer Experience.md rename to src/Engineering Management/Developer Experience.md diff --git a/src/Management/Effective Meetings.md b/src/Engineering Management/Effective Meetings.md similarity index 100% rename from src/Management/Effective Meetings.md rename to src/Engineering Management/Effective Meetings.md diff --git a/src/Management/Engineering Management.md b/src/Engineering Management/Engineering Management.md similarity index 100% rename from src/Management/Engineering Management.md rename to src/Engineering Management/Engineering Management.md diff --git a/src/Management/Goals.md b/src/Engineering Management/Goals.md similarity index 100% rename from src/Management/Goals.md rename to src/Engineering Management/Goals.md diff --git a/src/Management/Health Monitor.md b/src/Engineering Management/Health Monitor.md similarity index 100% rename from src/Management/Health Monitor.md rename to src/Engineering Management/Health Monitor.md diff --git a/src/Management/High Performing Teams.md b/src/Engineering Management/High Performing Teams.md similarity index 100% rename from src/Management/High Performing Teams.md rename to src/Engineering Management/High Performing Teams.md diff --git a/src/Management/Hiring.md b/src/Engineering Management/Hiring.md similarity index 68% rename from src/Management/Hiring.md rename to src/Engineering Management/Hiring.md index 51c943687..6698b2b71 100644 --- a/src/Management/Hiring.md +++ b/src/Engineering Management/Hiring.md @@ -3,4 +3,4 @@ - https://codesubmit.io/blog/test-programming-skills/ - [[Interview]] -- [[Management/Onboarding]] \ No newline at end of file +- [[src/Engineering Management/Onboarding]] \ No newline at end of file diff --git a/src/Incident Management.org b/src/Engineering Management/Incident Management.md similarity index 100% rename from src/Incident Management.org rename to src/Engineering Management/Incident Management.md diff --git a/src/Management/Index.md b/src/Engineering Management/Index.md similarity index 100% rename from src/Management/Index.md rename to src/Engineering Management/Index.md diff --git a/src/Management/Interview.md b/src/Engineering Management/Interview.md similarity index 100% rename from src/Management/Interview.md rename to src/Engineering Management/Interview.md diff --git a/src/Management/Interviewer.md b/src/Engineering Management/Interviewer.md similarity index 100% rename from src/Management/Interviewer.md rename to src/Engineering Management/Interviewer.md diff --git a/src/Management/Leadership.md b/src/Engineering Management/Leadership.md similarity index 100% rename from src/Management/Leadership.md rename to src/Engineering Management/Leadership.md diff --git a/src/Management/Manage for Better Results.md b/src/Engineering Management/Manage for Better Results.md similarity index 100% rename from src/Management/Manage for Better Results.md rename to src/Engineering Management/Manage for Better Results.md diff --git a/src/Management/Metrics.md b/src/Engineering Management/Metrics.md similarity index 100% rename from src/Management/Metrics.md rename to src/Engineering Management/Metrics.md diff --git a/src/Management/Onboarding.md b/src/Engineering Management/Onboarding.md similarity index 100% rename from src/Management/Onboarding.md rename to src/Engineering Management/Onboarding.md diff --git a/src/Management/Psychological Safety.md b/src/Engineering Management/Psychological Safety.md similarity index 100% rename from src/Management/Psychological Safety.md rename to src/Engineering Management/Psychological Safety.md diff --git a/src/Management/Reports.md b/src/Engineering Management/Reports.md similarity index 100% rename from src/Management/Reports.md rename to src/Engineering Management/Reports.md diff --git a/src/Management/Salary.md b/src/Engineering Management/Salary.md similarity index 100% rename from src/Management/Salary.md rename to src/Engineering Management/Salary.md diff --git a/src/Management/Software Development Strategy.md b/src/Engineering Management/Software Development Strategy.md similarity index 100% rename from src/Management/Software Development Strategy.md rename to src/Engineering Management/Software Development Strategy.md diff --git a/src/Management/Ways of Working.md b/src/Engineering Management/Ways of Working.md similarity index 100% rename from src/Management/Ways of Working.md rename to src/Engineering Management/Ways of Working.md diff --git a/src/Management/Wellbeing.md b/src/Engineering Management/Wellbeing.md similarity index 100% rename from src/Management/Wellbeing.md rename to src/Engineering Management/Wellbeing.md diff --git a/src/HTTP Client.org b/src/How-to/HTTP Client.md similarity index 52% rename from src/HTTP Client.org rename to src/How-to/HTTP Client.md index a4dd0a64a..7d0ae040e 100644 --- a/src/HTTP Client.org +++ b/src/How-to/HTTP Client.md @@ -1,18 +1,29 @@ -* //Program.cs - services.AddHttpClient("MyClient", client => +**Program.cs** + +```csharp +services.AddHttpClient("MyClient", client => { client.DefaultRequestHeaders.Add("authToken", "token123"); }).AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(300))); +``` + + + -Create Instance +## Option 1 - Inject IHttpClientFactory -Inject IHttpClientFactory +```csharp var httpClient = _httpClientFactory.CreateClient("MyClient"); +``` -OR - var httpClient = new HttpClient(); +## Option 2 - Create Instance -responseJson = await cmcApiClient.GetStringAsync($"https://domain.com/endpoint"); + +```csharp +var httpClient = new HttpClient(); + +responseJson = await httpClient.GetStringAsync($"https://domain.com/endpoint"); var instance = JsonSerializer.Deserialize(responseJson)!; -* \ No newline at end of file +``` + diff --git a/src/Modernization.org b/src/How-to/Modernization.md similarity index 100% rename from src/Modernization.org rename to src/How-to/Modernization.md diff --git a/src/Index.md b/src/Index.md index 2891ce88b..21b31f403 100644 --- a/src/Index.md +++ b/src/Index.md @@ -13,9 +13,12 @@ This project was inspired by this [blog post](https://github.com/readme/guides/p ## Publish -Folder: `digital-knowledge-garden\docs` (this folder is used by GitHub pages to publish https://leandromonaco.github.io/digital-knowledge-garden) - -![[Pasted image 20240510083448.png]] +1. Delete all files in `digital-knowledge-garden\docs` +2. Export `src` as HTML Documents (self-contained)![[Pasted image 20240510083448.png]]![[Pasted image 20240510085959.png]] +3. Copy `docs\src` to `docs` +4. Delete `docs\src` and `docs\lib` folders +5. Push Git changes +6. A GitHub Action will be triggered to publish https://leandromonaco.github.io/digital-knowledge-garden ### Sources - [Daily.dev](https://daily.dev/) \ No newline at end of file diff --git a/src/NuGet.org b/src/NuGet.org deleted file mode 100644 index 4491b5bb1..000000000 --- a/src/NuGet.org +++ /dev/null @@ -1,4 +0,0 @@ -* https://learn.microsoft.com/en-us/dotnet/standard/library-guidance/ -https://learn.microsoft.com/en-us/dotnet/standard/library-guidance/nuget -https://learn.microsoft.com/en-us/dotnet/standard/library-guidance/sourcelink -* \ No newline at end of file diff --git a/src/RU102N Redis for .NET Developers.org b/src/RU102N Redis for .NET Developers.org deleted file mode 100644 index 70ee130f4..000000000 --- a/src/RU102N Redis for .NET Developers.org +++ /dev/null @@ -1,14 +0,0 @@ -* # RU102N [[Redis]] for .NET Developers - -## Section 1 -* *Link:* https://university.redis.com/courses/ru102n/ -* ### 1.1 - .NET Client Ecosystem Overview -* There are different levels of abstraction that Redis clients can provide to users. It's helpful if we try to group those together for a conversation about Redis clients. Let's think of them in these groups: -* 1. Minimal Protocol Clients: These clients basically handle connection, wrap the RESP protocol (the wire protocol for Redis) and little else. They're quite minimalist and intended to provide maximum control to the user. -2. General Command Level Clients: The clients that directly expose the Redis command interface and provide some parsing for the result structures bubbling up from it. These have a more or less 1:1 mapping between commands in Redis and commands in the client. -3. Higher Level Abstract Clients: These clients are intended more to provide a friendly user interface to developers and provide some meaningful abstraction above the Redis command interface and paradigms the users are used to. -4. Framework Integrations: These clients are written to interact directly with a particular framework, often times they implement some very particular functionality in a way native to the framework. -* *StackExchange.Redis* falls somewhere between the second and third tier clients, while also leaving open a more or less minimalist ad-hoc API that we'll explore in later sections. It's best described as that second-tier General Command Level Client of Redis. -* All of the other third and fourth level libraries we'll be looking at later in this course have this Library as a dependency. -* ### 1.2 - Getting Started with StackExchange.Redis -* '' \ No newline at end of file diff --git a/src/Tools/NuGet.md b/src/Tools/NuGet.md index 22926a79b..05c5f7ed5 100644 --- a/src/Tools/NuGet.md +++ b/src/Tools/NuGet.md @@ -1 +1,4 @@ -https://devblogs.microsoft.com/nuget/announcing-nuget-6-7-keeping-you-secure/ \ No newline at end of file +- https://devblogs.microsoft.com/nuget/announcing-nuget-6-7-keeping-you-secure +* https://learn.microsoft.com/en-us/dotnet/standard/library-guidance +* https://learn.microsoft.com/en-us/dotnet/standard/library-guidance/nuget +* https://learn.microsoft.com/en-us/dotnet/standard/library-guidance/sourcelink