├── .gitattributes ├── .obsidian ├── app.json ├── appearance.json ├── community-plugins.json ├── core-plugins-migration.json ├── core-plugins.json ├── hotkeys.json ├── plugins │ ├── dataview │ │ ├── main.js │ │ ├── manifest.json │ │ └── styles.css │ ├── templater-obsidian │ │ ├── data.json │ │ ├── main.js │ │ ├── manifest.json │ │ └── styles.css │ └── wikilinks-to-mdlinks-obsidian │ │ ├── main.js │ │ └── manifest.json └── workspace.json ├── PowerShell Script Example.md ├── README.md ├── TEMPLATES ├── Execute PowerShell5 Selected Text.md ├── Execute PowerShell7 Selected Text.md └── Execute cmd.exe Selected Text.md ├── attachments ├── Pasted image 20230312113439.png ├── Pasted image 20230312113550.png ├── Pasted image 20230312113743.png ├── Pasted image 20230312113952.png ├── Pasted image 20230312114222.png ├── Pasted image 20230312114606.png ├── Pasted image 20230312114655.png ├── Pasted image 20230312115546.png ├── Pasted image 20230312115849.png ├── Pasted image 20230312124148.png ├── Pasted image 20230312131658.png ├── Pasted image 20230312132859.png.md ├── Pasted image 20230312140552.png ├── Pasted image 20230312140640.png ├── Pasted image 20230312141836.png ├── Pasted image 20230312142213.png ├── Pasted image 20230312143001.png ├── Pasted image 20230312161834.png ├── Pasted image 20230312162144.png ├── ping_example.gif └── ping_example_hotkey.gif └── ping example.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.obsidian/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "spellcheck": true, 3 | "promptDelete": false, 4 | "attachmentFolderPath": "attachments", 5 | "showUnsupportedFiles": true, 6 | "newLinkFormat": "absolute", 7 | "useMarkdownLinks": true, 8 | "livePreview": true 9 | } -------------------------------------------------------------------------------- /.obsidian/appearance.json: -------------------------------------------------------------------------------- 1 | { 2 | "accentColor": "" 3 | } -------------------------------------------------------------------------------- /.obsidian/community-plugins.json: -------------------------------------------------------------------------------- 1 | [ 2 | "templater-obsidian", 3 | "dataview", 4 | "wikilinks-to-mdlinks-obsidian" 5 | ] -------------------------------------------------------------------------------- /.obsidian/core-plugins-migration.json: -------------------------------------------------------------------------------- 1 | { 2 | "file-explorer": true, 3 | "global-search": true, 4 | "switcher": true, 5 | "graph": true, 6 | "backlink": true, 7 | "canvas": true, 8 | "outgoing-link": true, 9 | "tag-pane": true, 10 | "page-preview": true, 11 | "daily-notes": true, 12 | "templates": true, 13 | "note-composer": true, 14 | "command-palette": true, 15 | "slash-command": false, 16 | "editor-status": true, 17 | "starred": true, 18 | "markdown-importer": false, 19 | "zk-prefixer": false, 20 | "random-note": false, 21 | "outline": true, 22 | "word-count": true, 23 | "slides": false, 24 | "audio-recorder": false, 25 | "workspaces": false, 26 | "file-recovery": true, 27 | "publish": false, 28 | "sync": false 29 | } -------------------------------------------------------------------------------- /.obsidian/core-plugins.json: -------------------------------------------------------------------------------- 1 | [ 2 | "file-explorer", 3 | "global-search", 4 | "switcher", 5 | "graph", 6 | "backlink", 7 | "canvas", 8 | "outgoing-link", 9 | "tag-pane", 10 | "page-preview", 11 | "daily-notes", 12 | "templates", 13 | "note-composer", 14 | "command-palette", 15 | "editor-status", 16 | "starred", 17 | "outline", 18 | "word-count", 19 | "file-recovery" 20 | ] -------------------------------------------------------------------------------- /.obsidian/hotkeys.json: -------------------------------------------------------------------------------- 1 | { 2 | "templater-obsidian:TEMPLATES/Execute PowerShell5 Selected Text.md": [ 3 | { 4 | "modifiers": [ 5 | "Mod", 6 | "Shift" 7 | ], 8 | "key": "1" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /.obsidian/plugins/dataview/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "dataview", 3 | "name": "Dataview", 4 | "version": "0.5.55", 5 | "minAppVersion": "0.13.11", 6 | "description": "Complex data views for the data-obsessed.", 7 | "author": "Michael Brenan ", 8 | "authorUrl": "https://github.com/blacksmithgu", 9 | "isDesktopOnly": false 10 | } 11 | -------------------------------------------------------------------------------- /.obsidian/plugins/dataview/styles.css: -------------------------------------------------------------------------------- 1 | /** Live Preview padding fixes, specifically for DataviewJS custom HTML elements. */ 2 | .is-live-preview .block-language-dataviewjs > p, .is-live-preview .block-language-dataviewjs > span { 3 | line-height: 1.0; 4 | } 5 | 6 | .block-language-dataview { 7 | overflow-y: auto; 8 | } 9 | 10 | /*****************/ 11 | /** Table Views **/ 12 | /*****************/ 13 | 14 | /* List View Default Styling; rendered internally as a table. */ 15 | .table-view-table { 16 | width: 100%; 17 | } 18 | 19 | .table-view-table > thead > tr, .table-view-table > tbody > tr { 20 | margin-top: 1em; 21 | margin-bottom: 1em; 22 | text-align: left; 23 | } 24 | 25 | .table-view-table > tbody > tr:hover { 26 | background-color: var(--text-selection) !important; 27 | } 28 | 29 | .table-view-table > thead > tr > th { 30 | font-weight: 700; 31 | font-size: larger; 32 | border-top: none; 33 | border-left: none; 34 | border-right: none; 35 | border-bottom: solid; 36 | 37 | max-width: 100%; 38 | } 39 | 40 | .table-view-table > tbody > tr > td { 41 | text-align: left; 42 | border: none; 43 | font-weight: 400; 44 | max-width: 100%; 45 | } 46 | 47 | .table-view-table ul, .table-view-table ol { 48 | margin-block-start: 0.2em !important; 49 | margin-block-end: 0.2em !important; 50 | } 51 | 52 | /** Rendered value styling for any view. */ 53 | .dataview-result-list-root-ul { 54 | padding: 0em !important; 55 | margin: 0em !important; 56 | } 57 | 58 | .dataview-result-list-ul { 59 | margin-block-start: 0.2em !important; 60 | margin-block-end: 0.2em !important; 61 | } 62 | 63 | /** Generic grouping styling. */ 64 | .dataview.result-group { 65 | padding-left: 8px; 66 | } 67 | 68 | /*******************/ 69 | /** Inline Fields **/ 70 | /*******************/ 71 | 72 | .dataview.inline-field-key { 73 | padding-left: 8px; 74 | padding-right: 8px; 75 | font-family: var(--font-monospace); 76 | background-color: var(--background-primary-alt); 77 | color: var(--text-nav-selected); 78 | } 79 | 80 | .dataview.inline-field-value { 81 | padding-left: 8px; 82 | padding-right: 8px; 83 | font-family: var(--font-monospace); 84 | background-color: var(--background-secondary-alt); 85 | color: var(--text-nav-selected); 86 | } 87 | 88 | .dataview.inline-field-standalone-value { 89 | padding-left: 8px; 90 | padding-right: 8px; 91 | font-family: var(--font-monospace); 92 | background-color: var(--background-secondary-alt); 93 | color: var(--text-nav-selected); 94 | } 95 | 96 | /***************/ 97 | /** Task View **/ 98 | /***************/ 99 | 100 | .dataview.task-list-item, .dataview.task-list-basic-item { 101 | margin-top: 3px; 102 | margin-bottom: 3px; 103 | transition: 0.4s; 104 | } 105 | 106 | .dataview.task-list-item:hover, .dataview.task-list-basic-item:hover { 107 | background-color: var(--text-selection); 108 | box-shadow: -40px 0 0 var(--text-selection); 109 | cursor: pointer; 110 | } 111 | 112 | /*****************/ 113 | /** Error Views **/ 114 | /*****************/ 115 | 116 | div.dataview-error-box { 117 | width: 100%; 118 | min-height: 150px; 119 | display: flex; 120 | align-items: center; 121 | justify-content: center; 122 | border: 4px dashed var(--background-secondary); 123 | } 124 | 125 | .dataview-error-message { 126 | color: var(--text-muted); 127 | text-align: center; 128 | } 129 | 130 | /*************************/ 131 | /** Additional Metadata **/ 132 | /*************************/ 133 | 134 | .dataview.small-text { 135 | font-size: smaller; 136 | color: var(--text-muted); 137 | margin-left: 3px; 138 | } 139 | 140 | .dataview.small-text::before { 141 | content: "("; 142 | } 143 | 144 | .dataview.small-text::after { 145 | content: ")"; 146 | } 147 | -------------------------------------------------------------------------------- /.obsidian/plugins/templater-obsidian/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "command_timeout": 5, 3 | "templates_folder": "TEMPLATES", 4 | "templates_pairs": [ 5 | [ 6 | "cmd_exec", 7 | "cmd /C %Cmd%" 8 | ], 9 | [ 10 | "pwsh5_exec", 11 | "PowerShell -NoProfile -Command Invoke-Expression(\"$Env:Pwsh\")" 12 | ], 13 | [ 14 | "pwsh7_exec", 15 | "pwsh -NoProfile -Command Invoke-Expression(\"$Env:Pwsh\")" 16 | ], 17 | [ 18 | "", 19 | "" 20 | ] 21 | ], 22 | "trigger_on_file_creation": false, 23 | "auto_jump_to_cursor": false, 24 | "enable_system_commands": true, 25 | "shell_path": "", 26 | "user_scripts_folder": "TEMPLATES/Functions", 27 | "enable_folder_templates": true, 28 | "folder_templates": [ 29 | { 30 | "folder": "", 31 | "template": "" 32 | } 33 | ], 34 | "syntax_highlighting": true, 35 | "enabled_templates_hotkeys": [ 36 | "TEMPLATES/Execute PowerShell5 Selected Text.md" 37 | ], 38 | "startup_templates": [ 39 | "" 40 | ], 41 | "enable_ribbon_icon": true 42 | } -------------------------------------------------------------------------------- /.obsidian/plugins/templater-obsidian/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "templater-obsidian", 3 | "name": "Templater", 4 | "version": "1.16.0", 5 | "description": "Create and use templates", 6 | "minAppVersion": "0.11.13", 7 | "author": "SilentVoid", 8 | "authorUrl": "https://github.com/SilentVoid13", 9 | "isDesktopOnly": false 10 | } 11 | -------------------------------------------------------------------------------- /.obsidian/plugins/templater-obsidian/styles.css: -------------------------------------------------------------------------------- 1 | .templater_search { 2 | width: calc(100% - 20px); 3 | } 4 | 5 | .templater_div { 6 | border-top: 1px solid var(--background-modifier-border); 7 | } 8 | 9 | .templater_div > .setting-item { 10 | border-top: none !important; 11 | align-self: center; 12 | } 13 | 14 | .templater_div > .setting-item > .setting-item-control { 15 | justify-content: space-around; 16 | padding: 0; 17 | width: 100%; 18 | } 19 | 20 | .templater_div 21 | > .setting-item 22 | > .setting-item-control 23 | > .setting-editor-extra-setting-button { 24 | align-self: center; 25 | } 26 | 27 | .templater_donating { 28 | margin: 10px; 29 | } 30 | 31 | .templater_title { 32 | margin: 0; 33 | padding: 0; 34 | margin-top: 5px; 35 | text-align: center; 36 | } 37 | 38 | .templater_template { 39 | align-self: center; 40 | margin-left: 5px; 41 | margin-right: 5px; 42 | width: 70%; 43 | } 44 | 45 | .templater_cmd { 46 | margin-left: 5px; 47 | margin-right: 5px; 48 | font-size: 14px; 49 | width: 100%; 50 | } 51 | 52 | .templater_div2 > .setting-item { 53 | align-content: center; 54 | justify-content: center; 55 | } 56 | 57 | .templater-prompt-div { 58 | display: flex; 59 | } 60 | 61 | .templater-prompt-form { 62 | display: flex; 63 | flex-grow: 1; 64 | } 65 | 66 | .templater-prompt-input { 67 | flex-grow: 1; 68 | } 69 | 70 | .templater-button-div { 71 | display: flex; 72 | flex-direction: column; 73 | align-items: center; 74 | margin-top: 1rem; 75 | } 76 | 77 | textarea.templater-prompt-input { 78 | height: 10rem; 79 | } 80 | 81 | textarea.templater-prompt-input:focus { 82 | border-color: var(--interactive-accent); 83 | } 84 | 85 | .cm-s-obsidian .templater-command-bg { 86 | left: 0px; 87 | right: 0px; 88 | background-color: var(--background-primary-alt); 89 | } 90 | 91 | .cm-s-obsidian .cm-templater-command { 92 | font-size: 0.85em; 93 | font-family: var(--font-monospace); 94 | line-height: 1.3; 95 | } 96 | 97 | .cm-s-obsidian .templater-inline .cm-templater-command { 98 | background-color: var(--background-primary-alt); 99 | } 100 | 101 | .cm-s-obsidian .cm-templater-command.cm-templater-opening-tag { 102 | font-weight: bold; 103 | } 104 | 105 | .cm-s-obsidian .cm-templater-command.cm-templater-closing-tag { 106 | font-weight: bold; 107 | } 108 | 109 | .cm-s-obsidian .cm-templater-command.cm-templater-interpolation-tag { 110 | color: #008bff; 111 | } 112 | 113 | .cm-s-obsidian .cm-templater-command.cm-templater-execution-tag { 114 | color: #c0d700; 115 | } 116 | 117 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-keyword { 118 | color: #00a7aa; 119 | font-weight: normal; 120 | } 121 | 122 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-atom { 123 | color: #f39b35; 124 | } 125 | 126 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-number { 127 | color: #a06fca; 128 | } 129 | 130 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-type { 131 | color: #a06fca; 132 | } 133 | 134 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-def { 135 | color: #98e342; 136 | } 137 | 138 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-property { 139 | color: #d4d4d4; 140 | } 141 | 142 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-variable { 143 | color: #d4d4d4; 144 | } 145 | 146 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-variable-2 { 147 | color: #da7dae; 148 | } 149 | 150 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-variable-3 { 151 | color: #a06fca; 152 | } 153 | 154 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-type.cm-def { 155 | color: #fc4384; 156 | } 157 | 158 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-property.cm-def { 159 | color: #fc4384; 160 | } 161 | 162 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-callee { 163 | color: #fc4384; 164 | } 165 | 166 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-operator { 167 | color: #fc4384; 168 | } 169 | 170 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-qualifier { 171 | color: #fc4384; 172 | } 173 | 174 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-tag { 175 | color: #fc4384; 176 | } 177 | 178 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-tag.cm-bracket { 179 | color: #d4d4d4; 180 | } 181 | 182 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-attribute { 183 | color: #a06fca; 184 | } 185 | 186 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-comment { 187 | color: #696d70; 188 | } 189 | 190 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-comment.cm-tag { 191 | color: #fc4384; 192 | } 193 | 194 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-comment.cm-attribute { 195 | color: #d4d4d4; 196 | } 197 | 198 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-string { 199 | color: #e6db74; 200 | } 201 | 202 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-string-2 { 203 | color: #f39b35; 204 | } 205 | 206 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-meta { 207 | color: #d4d4d4; 208 | background: inherit; 209 | } 210 | 211 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-builtin { 212 | color: #fc4384; 213 | } 214 | 215 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-header { 216 | color: #da7dae; 217 | } 218 | 219 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-hr { 220 | color: #98e342; 221 | } 222 | 223 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-link { 224 | color: #696d70; 225 | } 226 | 227 | .theme-dark .cm-s-obsidian .cm-templater-command.cm-error { 228 | border-bottom: 1px solid #c42412; 229 | } 230 | 231 | .theme-dark .cm-s-obsidian pre.HyperMD-codeblock .cm-keyword { 232 | font-weight: normal; 233 | } 234 | 235 | .theme-dark 236 | .cm-s-obsidian 237 | .cm-templater-command.CodeMirror-activeline-background { 238 | background: #272727; 239 | } 240 | 241 | .theme-dark .cm-s-obsidian .cm-templater-command.CodeMirror-matchingbracket { 242 | outline: 1px solid grey; 243 | color: #d4d4d4 !important; 244 | } 245 | 246 | .CodeMirror-hints { 247 | position: absolute; 248 | z-index: 10; 249 | overflow: hidden; 250 | list-style: none; 251 | 252 | margin: 0; 253 | padding: 2px; 254 | 255 | -webkit-box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2); 256 | -moz-box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2); 257 | box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.2); 258 | border-radius: 3px; 259 | border: 1px solid silver; 260 | 261 | background: white; 262 | font-size: 90%; 263 | font-family: monospace; 264 | 265 | max-height: 20em; 266 | overflow-y: auto; 267 | } 268 | 269 | .CodeMirror-hint { 270 | margin: 0; 271 | padding: 0 4px; 272 | border-radius: 2px; 273 | white-space: pre; 274 | color: black; 275 | cursor: pointer; 276 | } 277 | 278 | li.CodeMirror-hint-active { 279 | background: #08f; 280 | color: white; 281 | } 282 | -------------------------------------------------------------------------------- /.obsidian/plugins/wikilinks-to-mdlinks-obsidian/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var obsidian = require('obsidian'); 4 | 5 | /*! ***************************************************************************** 6 | Copyright (c) Microsoft Corporation. 7 | 8 | Permission to use, copy, modify, and/or distribute this software for any 9 | purpose with or without fee is hereby granted. 10 | 11 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 12 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 14 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 16 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 | PERFORMANCE OF THIS SOFTWARE. 18 | ***************************************************************************** */ 19 | /* global Reflect, Promise */ 20 | 21 | var extendStatics = function(d, b) { 22 | extendStatics = Object.setPrototypeOf || 23 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 24 | function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 25 | return extendStatics(d, b); 26 | }; 27 | 28 | function __extends(d, b) { 29 | extendStatics(d, b); 30 | function __() { this.constructor = d; } 31 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 32 | } 33 | 34 | var WikilinksToMdlinks = /** @class */ (function (_super) { 35 | __extends(WikilinksToMdlinks, _super); 36 | function WikilinksToMdlinks() { 37 | return _super !== null && _super.apply(this, arguments) || this; 38 | } 39 | WikilinksToMdlinks.prototype.onload = function () { 40 | var _this = this; 41 | console.log('loading wikilinks-to-mdlinks plugin...'); 42 | this.addCommand({ 43 | id: "toggle-wiki-md-links", 44 | name: "Toggle selected wikilink to markdown link and vice versa", 45 | checkCallback: function (checking) { 46 | var currentView = _this.app.workspace.getActiveLeafOfViewType(obsidian.MarkdownView); 47 | if ((currentView == null) || (currentView.getMode() !== 'source')) { 48 | return false; 49 | } 50 | if (!checking) { 51 | _this.toggleLink(); 52 | } 53 | return true; 54 | }, 55 | hotkeys: [{ 56 | modifiers: ["Mod", "Shift"], 57 | key: "L" 58 | }] 59 | }); 60 | }; 61 | WikilinksToMdlinks.prototype.onunload = function () { 62 | console.log('unloading wikilinks-to-mdlinks plugin'); 63 | }; 64 | WikilinksToMdlinks.prototype.toggleLink = function () { 65 | var currentView = this.app.workspace.getActiveLeafOfViewType(obsidian.MarkdownView); 66 | var editor = currentView.sourceMode.cmEditor; 67 | var cursor = editor.getCursor(); 68 | var line = editor.getDoc().getLine(cursor.line); 69 | var regexHasExtension = /^([^\\]*)\.(\w+)$/; 70 | var regexWiki = /\[\[([^\]]+)\]\]/; 71 | var regexParenthesis = /\((.*?)\)/; 72 | var regexWikiGlobal = /\[\[([^\]]*)\]\]/g; 73 | var regexMdGlobal = /\[([^\]]*)\]\(([^\(]*)\)/g; 74 | var wikiMatches = line.match(regexWikiGlobal); 75 | var mdMatches = line.match(regexMdGlobal); 76 | var ifFoundMatch = false; 77 | // If there are wikiMatches find if the cursor is inside the selected text 78 | var i = 0; 79 | if (wikiMatches) { 80 | for (var _i = 0, wikiMatches_1 = wikiMatches; _i < wikiMatches_1.length; _i++) { 81 | var item = wikiMatches_1[_i]; 82 | var temp = line.slice(i, line.length); 83 | var index = i + temp.indexOf(item); 84 | var indexEnd = index + item.length; 85 | i = indexEnd; 86 | if ((cursor.ch >= index) && (cursor.ch <= indexEnd)) { 87 | ifFoundMatch = true; 88 | var text = item.match(regexWiki)[1]; 89 | // Check if it is a markdown file 90 | var matches = text.match(regexHasExtension); 91 | var newText = text; 92 | if (matches) { 93 | var filename = matches[1]; 94 | var extension = matches[2]; 95 | } 96 | else { 97 | newText = newText + ".md"; 98 | } 99 | var encodedText = encodeURI(newText); 100 | var newItem = "[" + text + "](" + encodedText + ")"; 101 | var cursorStart = { 102 | line: cursor.line, 103 | ch: index 104 | }; 105 | var cursorEnd = { 106 | line: cursor.line, 107 | ch: indexEnd 108 | }; 109 | editor.replaceRange(newItem, cursorStart, cursorEnd); 110 | } 111 | } 112 | } 113 | i = 0; 114 | if (ifFoundMatch == false) { 115 | if (mdMatches) { 116 | for (var _a = 0, mdMatches_1 = mdMatches; _a < mdMatches_1.length; _a++) { 117 | var item = mdMatches_1[_a]; 118 | var temp = line.slice(i, line.length); 119 | var index = i + temp.indexOf(item); 120 | var indexEnd = index + item.length; 121 | i = indexEnd; 122 | if ((cursor.ch >= index) && (cursor.ch <= indexEnd)) { 123 | ifFoundMatch = true; 124 | var text = item.match(regexParenthesis)[1]; 125 | text = decodeURI(text); 126 | // Check if it is a markdown file 127 | var matches = text.match(regexHasExtension); 128 | if (matches) { 129 | var filename = matches[1]; 130 | var extension = matches[2]; 131 | if (extension == 'md') { 132 | text = filename; 133 | } 134 | } 135 | var newItem = "[[" + text + "]]"; 136 | var cursorStart = { 137 | line: cursor.line, 138 | ch: index 139 | }; 140 | var cursorEnd = { 141 | line: cursor.line, 142 | ch: indexEnd 143 | }; 144 | editor.replaceRange(newItem, cursorStart, cursorEnd); 145 | } 146 | } 147 | } 148 | } 149 | }; 150 | return WikilinksToMdlinks; 151 | }(obsidian.Plugin)); 152 | 153 | module.exports = WikilinksToMdlinks; 154 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm1haW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmFtKHBhcmFtSW5kZXgsIGRlY29yYXRvcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSkgeyBkZWNvcmF0b3IodGFyZ2V0LCBrZXksIHBhcmFtSW5kZXgpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGc7XHJcbiAgICByZXR1cm4gZyA9IHsgbmV4dDogdmVyYigwKSwgXCJ0aHJvd1wiOiB2ZXJiKDEpLCBcInJldHVyblwiOiB2ZXJiKDIpIH0sIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiAoZ1tTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzOyB9KSwgZztcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHN0ZXAoW24sIHZdKTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc3RlcChvcCkge1xyXG4gICAgICAgIGlmIChmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgZXhlY3V0aW5nLlwiKTtcclxuICAgICAgICB3aGlsZSAoXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIG1ba107IH0gfSk7XHJcbn0pIDogKGZ1bmN0aW9uKG8sIG0sIGssIGsyKSB7XHJcbiAgICBpZiAoazIgPT09IHVuZGVmaW5lZCkgazIgPSBrO1xyXG4gICAgb1trMl0gPSBtW2tdO1xyXG59KTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgbykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAocCAhPT0gXCJkZWZhdWx0XCIgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvLCBwKSkgX19jcmVhdGVCaW5kaW5nKG8sIG0sIHApO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIHMgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgU3ltYm9sLml0ZXJhdG9yLCBtID0gcyAmJiBvW3NdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgaWYgKG8gJiYgdHlwZW9mIG8ubGVuZ3RoID09PSBcIm51bWJlclwiKSByZXR1cm4ge1xyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkgbyA9IHZvaWQgMDtcclxuICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IG8gJiYgb1tpKytdLCBkb25lOiAhbyB9O1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKHMgPyBcIk9iamVjdCBpcyBub3QgaXRlcmFibGUuXCIgOiBcIlN5bWJvbC5pdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3JlYWQobywgbikge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdO1xyXG4gICAgaWYgKCFtKSByZXR1cm4gbztcclxuICAgIHZhciBpID0gbS5jYWxsKG8pLCByLCBhciA9IFtdLCBlO1xyXG4gICAgdHJ5IHtcclxuICAgICAgICB3aGlsZSAoKG4gPT09IHZvaWQgMCB8fCBuLS0gPiAwKSAmJiAhKHIgPSBpLm5leHQoKSkuZG9uZSkgYXIucHVzaChyLnZhbHVlKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChlcnJvcikgeyBlID0geyBlcnJvcjogZXJyb3IgfTsgfVxyXG4gICAgZmluYWxseSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKHIgJiYgIXIuZG9uZSAmJiAobSA9IGlbXCJyZXR1cm5cIl0pKSBtLmNhbGwoaSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZpbmFsbHkgeyBpZiAoZSkgdGhyb3cgZS5lcnJvcjsgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcclxuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxyXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgIHJldHVybiByO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBuID09PSBcInJldHVyblwiIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGspO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgcHJpdmF0ZU1hcCkge1xyXG4gICAgaWYgKCFwcml2YXRlTWFwLmhhcyhyZWNlaXZlcikpIHtcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXR0ZW1wdGVkIHRvIGdldCBwcml2YXRlIGZpZWxkIG9uIG5vbi1pbnN0YW5jZVwiKTtcclxuICAgIH1cclxuICAgIHJldHVybiBwcml2YXRlTWFwLmdldChyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHJlY2VpdmVyLCBwcml2YXRlTWFwLCB2YWx1ZSkge1xyXG4gICAgaWYgKCFwcml2YXRlTWFwLmhhcyhyZWNlaXZlcikpIHtcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXR0ZW1wdGVkIHRvIHNldCBwcml2YXRlIGZpZWxkIG9uIG5vbi1pbnN0YW5jZVwiKTtcclxuICAgIH1cclxuICAgIHByaXZhdGVNYXAuc2V0KHJlY2VpdmVyLCB2YWx1ZSk7XHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbn1cclxuIiwiaW1wb3J0IHsgc3RyaWN0IH0gZnJvbSAnYXNzZXJ0J1xyXG5pbXBvcnQgeyBBcHAsIE1vZGFsLCBOb3RpY2UsIFBsdWdpbiwgUGx1Z2luU2V0dGluZ1RhYiwgU2V0dGluZyB9IGZyb20gJ29ic2lkaWFuJ1xyXG5pbXBvcnQgeyBNYXJrZG93blZpZXcsIFRGaWxlIH0gZnJvbSAnb2JzaWRpYW4nXHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBXaWtpbGlua3NUb01kbGlua3MgZXh0ZW5kcyBQbHVnaW4ge1xyXG5cdG9ubG9hZCgpIHtcclxuXHRcdGNvbnNvbGUubG9nKCdsb2FkaW5nIHdpa2lsaW5rcy10by1tZGxpbmtzIHBsdWdpbi4uLicpXHJcblxyXG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcclxuXHRcdFx0aWQ6IFwidG9nZ2xlLXdpa2ktbWQtbGlua3NcIixcclxuXHRcdFx0bmFtZTogXCJUb2dnbGUgc2VsZWN0ZWQgd2lraWxpbmsgdG8gbWFya2Rvd24gbGluayBhbmQgdmljZSB2ZXJzYVwiLFxyXG5cdFx0XHRjaGVja0NhbGxiYWNrOiAoY2hlY2tpbmc6IGJvb2xlYW4pID0+IHtcclxuXHRcdFx0XHRjb25zdCBjdXJyZW50VmlldyA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVMZWFmT2ZWaWV3VHlwZShNYXJrZG93blZpZXcpXHJcblxyXG5cdFx0XHRcdGlmICgoY3VycmVudFZpZXcgPT0gbnVsbCkgfHwgKGN1cnJlbnRWaWV3LmdldE1vZGUoKSAhPT0gJ3NvdXJjZScpKSAge1xyXG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlXHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAoIWNoZWNraW5nKSB7XHJcblx0XHRcdFx0XHR0aGlzLnRvZ2dsZUxpbmsoKVxyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0cmV0dXJuIHRydWVcclxuXHRcdFx0fSxcclxuXHRcdFx0aG90a2V5czogW3tcclxuXHRcdFx0XHRtb2RpZmllcnM6IFtcIk1vZFwiLCBcIlNoaWZ0XCJdLFxyXG5cdFx0XHRcdGtleTogXCJMXCJcclxuXHRcdFx0fV1cclxuXHRcdH0pXHJcblxyXG5cdH1cclxuXHJcblx0b251bmxvYWQoKSB7XHJcblx0XHRjb25zb2xlLmxvZygndW5sb2FkaW5nIHdpa2lsaW5rcy10by1tZGxpbmtzIHBsdWdpbicpXHJcblx0fVxyXG5cclxuXHR0b2dnbGVMaW5rKCkge1xyXG5cdFx0Y29uc3QgY3VycmVudFZpZXcgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlTGVhZk9mVmlld1R5cGUoTWFya2Rvd25WaWV3KVxyXG5cdFx0Y29uc3QgZWRpdG9yID0gY3VycmVudFZpZXcuc291cmNlTW9kZS5jbUVkaXRvclxyXG5cclxuXHJcblx0XHRjb25zdCBjdXJzb3IgPSBlZGl0b3IuZ2V0Q3Vyc29yKClcclxuXHRcdGNvbnN0IGxpbmUgPSBlZGl0b3IuZ2V0RG9jKCkuZ2V0TGluZShjdXJzb3IubGluZSk7XHJcblxyXG5cdFx0Y29uc3QgcmVnZXhIYXNFeHRlbnNpb24gPSAvXihbXlxcXFxdKilcXC4oXFx3KykkL1xyXG5cclxuXHRcdGNvbnN0IHJlZ2V4V2lraSA9IC9cXFtcXFsoW15cXF1dKylcXF1cXF0vXHJcblx0XHRjb25zdCByZWdleFBhcmVudGhlc2lzID0gL1xcKCguKj8pXFwpL1xyXG5cdFx0Y29uc3QgcmVnZXhXaWtpR2xvYmFsID0gL1xcW1xcWyhbXlxcXV0qKVxcXVxcXS9nXHJcblx0XHRjb25zdCByZWdleE1kR2xvYmFsID0gL1xcWyhbXlxcXV0qKVxcXVxcKChbXlxcKF0qKVxcKS9nXHJcblxyXG5cdFx0bGV0IHdpa2lNYXRjaGVzID0gbGluZS5tYXRjaChyZWdleFdpa2lHbG9iYWwpXHJcblx0XHRsZXQgbWRNYXRjaGVzID0gbGluZS5tYXRjaChyZWdleE1kR2xvYmFsKVxyXG5cclxuXHRcdGxldCBpZkZvdW5kTWF0Y2ggPSBmYWxzZVxyXG5cclxuXHRcdC8vIElmIHRoZXJlIGFyZSB3aWtpTWF0Y2hlcyBmaW5kIGlmIHRoZSBjdXJzb3IgaXMgaW5zaWRlIHRoZSBzZWxlY3RlZCB0ZXh0XHJcblx0XHRsZXQgaSA9IDBcclxuXHRcdGlmICh3aWtpTWF0Y2hlcykge1xyXG5cdFx0XHRmb3IgKGNvbnN0IGl0ZW0gb2Ygd2lraU1hdGNoZXMpIHtcclxuXHJcblx0XHRcdFx0bGV0IHRlbXAgPSBsaW5lLnNsaWNlKGksIGxpbmUubGVuZ3RoKVxyXG5cclxuXHRcdFx0XHRsZXQgaW5kZXggPSBpICsgdGVtcC5pbmRleE9mKGl0ZW0pXHJcblx0XHRcdFx0bGV0IGluZGV4RW5kID0gaW5kZXggKyBpdGVtLmxlbmd0aFxyXG5cclxuXHRcdFx0XHRpID0gaW5kZXhFbmRcclxuXHRcdFx0XHRpZiAoKGN1cnNvci5jaCA+PSBpbmRleCApICYmIChjdXJzb3IuY2ggPD0gaW5kZXhFbmQgKSkge1xyXG5cdFx0XHRcdFx0aWZGb3VuZE1hdGNoID0gdHJ1ZVxyXG5cdFx0XHRcdFx0bGV0IHRleHQgPSBpdGVtLm1hdGNoKHJlZ2V4V2lraSlbMV1cclxuXHRcdFx0XHRcdC8vIENoZWNrIGlmIGl0IGlzIGEgbWFya2Rvd24gZmlsZVxyXG5cdFx0XHRcdFx0Y29uc3QgbWF0Y2hlcyA9IHRleHQubWF0Y2gocmVnZXhIYXNFeHRlbnNpb24pO1xyXG5cdFx0XHRcdFx0bGV0IG5ld1RleHQgPSB0ZXh0XHJcblx0XHRcdFx0XHRpZiAobWF0Y2hlcykge1xyXG5cdFx0XHRcdFx0XHRjb25zdCBmaWxlbmFtZSA9IG1hdGNoZXNbMV1cclxuXHRcdFx0XHRcdFx0Y29uc3QgZXh0ZW5zaW9uID0gbWF0Y2hlc1syXVxyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0bmV3VGV4dCA9IG5ld1RleHQgKyBcIi5tZFwiXHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRjb25zdCBlbmNvZGVkVGV4dCA9IGVuY29kZVVSSShuZXdUZXh0KVxyXG5cdFx0XHRcdFx0bGV0IG5ld0l0ZW0gPSBgWyR7dGV4dH1dKCR7ZW5jb2RlZFRleHR9KWBcclxuXHJcblx0XHRcdFx0XHRjb25zdCBjdXJzb3JTdGFydCA9IHtcclxuXHRcdFx0XHRcdFx0bGluZTogY3Vyc29yLmxpbmUsXHJcblx0XHRcdFx0XHRcdGNoOiBpbmRleFxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0Y29uc3QgY3Vyc29yRW5kID0ge1xyXG5cdFx0XHRcdFx0XHRsaW5lOiBjdXJzb3IubGluZSxcclxuXHRcdFx0XHRcdFx0Y2g6IGluZGV4RW5kXHJcblx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0ZWRpdG9yLnJlcGxhY2VSYW5nZShuZXdJdGVtLCBjdXJzb3JTdGFydCwgY3Vyc29yRW5kKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRpID0gMFxyXG5cdFx0aWYgKGlmRm91bmRNYXRjaCA9PSBmYWxzZSkge1xyXG5cdFx0XHRpZiAobWRNYXRjaGVzKSB7XHJcblx0XHRcdFx0Zm9yIChjb25zdCBpdGVtIG9mIG1kTWF0Y2hlcykge1xyXG5cdFx0XHRcdFx0bGV0IHRlbXAgPSBsaW5lLnNsaWNlKGksIGxpbmUubGVuZ3RoKVxyXG5cdFx0XHRcdFx0bGV0IGluZGV4ID0gaSArIHRlbXAuaW5kZXhPZihpdGVtKVxyXG5cdFx0XHRcdFx0bGV0IGluZGV4RW5kID0gaW5kZXggKyBpdGVtLmxlbmd0aFxyXG5cdFx0XHRcdFx0aSA9IGluZGV4RW5kXHJcblxyXG5cdFx0XHRcdFx0aWYgKChjdXJzb3IuY2ggPj0gaW5kZXggKSAmJiAoY3Vyc29yLmNoIDw9IGluZGV4RW5kICkpIHtcclxuXHRcdFx0XHRcdFx0aWZGb3VuZE1hdGNoID0gdHJ1ZVxyXG5cdFx0XHRcdFx0XHRsZXQgdGV4dCA9IGl0ZW0ubWF0Y2gocmVnZXhQYXJlbnRoZXNpcylbMV1cclxuXHRcdFx0XHRcdFx0dGV4dCA9IGRlY29kZVVSSSh0ZXh0KVxyXG5cclxuXHRcdFx0XHRcdFx0Ly8gQ2hlY2sgaWYgaXQgaXMgYSBtYXJrZG93biBmaWxlXHJcblx0XHRcdFx0XHRcdGNvbnN0IG1hdGNoZXMgPSB0ZXh0Lm1hdGNoKHJlZ2V4SGFzRXh0ZW5zaW9uKTtcclxuXHRcdFx0XHRcdFx0aWYgKG1hdGNoZXMpIHtcclxuXHRcdFx0XHRcdFx0XHRjb25zdCBmaWxlbmFtZSA9IG1hdGNoZXNbMV1cclxuXHRcdFx0XHRcdFx0XHRjb25zdCBleHRlbnNpb24gPSBtYXRjaGVzWzJdXHJcblxyXG5cdFx0XHRcdFx0XHRcdGlmIChleHRlbnNpb24gPT0gJ21kJykge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGV4dCA9IGZpbGVuYW1lXHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGxldCBuZXdJdGVtID0gYFtbJHt0ZXh0fV1dYFxyXG5cclxuXHRcdFx0XHRcdFx0Y29uc3QgY3Vyc29yU3RhcnQgPSB7XHJcblx0XHRcdFx0XHRcdFx0bGluZTogY3Vyc29yLmxpbmUsXHJcblx0XHRcdFx0XHRcdFx0Y2g6IGluZGV4XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0Y29uc3QgY3Vyc29yRW5kID0ge1xyXG5cdFx0XHRcdFx0XHRcdGxpbmU6IGN1cnNvci5saW5lLFxyXG5cdFx0XHRcdFx0XHRcdGNoOiBpbmRleEVuZFxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGVkaXRvci5yZXBsYWNlUmFuZ2UobmV3SXRlbSwgY3Vyc29yU3RhcnQsIGN1cnNvckVuZCk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG59XHJcbiJdLCJuYW1lcyI6WyJNYXJrZG93blZpZXciLCJQbHVnaW4iXSwibWFwcGluZ3MiOiI7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksYUFBYSxHQUFHLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNuQyxJQUFJLGFBQWEsR0FBRyxNQUFNLENBQUMsY0FBYztBQUN6QyxTQUFTLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxZQUFZLEtBQUssSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDcEYsUUFBUSxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDMUcsSUFBSSxPQUFPLGFBQWEs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 155 | -------------------------------------------------------------------------------- /.obsidian/plugins/wikilinks-to-mdlinks-obsidian/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "wikilinks-to-mdlinks-obsidian", 3 | "name": "Wikilinks to MDLinks", 4 | "version": "0.0.12", 5 | "minAppVersion": "0.9.12", 6 | "description": "A plugin that converts wikilinks to markdown links and vice versa", 7 | "author": "Agatha Uy", 8 | "authorUrl": "https://github.com/agathauy", 9 | "isDesktopOnly": false 10 | } 11 | -------------------------------------------------------------------------------- /.obsidian/workspace.json: -------------------------------------------------------------------------------- 1 | { 2 | "main": { 3 | "id": "1b0a74a337dc32bd", 4 | "type": "split", 5 | "children": [ 6 | { 7 | "id": "29a1766ef7723bd0", 8 | "type": "tabs", 9 | "children": [ 10 | { 11 | "id": "9353b986f88ba232", 12 | "type": "leaf", 13 | "state": { 14 | "type": "markdown", 15 | "state": { 16 | "file": "ping example.md", 17 | "mode": "source", 18 | "source": false 19 | } 20 | } 21 | }, 22 | { 23 | "id": "56a45af6be70493b", 24 | "type": "leaf", 25 | "state": { 26 | "type": "markdown", 27 | "state": { 28 | "file": "README.md", 29 | "mode": "source", 30 | "source": false 31 | } 32 | } 33 | } 34 | ], 35 | "currentTab": 1 36 | } 37 | ], 38 | "direction": "vertical" 39 | }, 40 | "left": { 41 | "id": "88569b557936dd60", 42 | "type": "split", 43 | "children": [ 44 | { 45 | "id": "b4c0e0b44a090aa5", 46 | "type": "tabs", 47 | "children": [ 48 | { 49 | "id": "b5914aae5de2efca", 50 | "type": "leaf", 51 | "state": { 52 | "type": "file-explorer", 53 | "state": { 54 | "sortOrder": "alphabetical" 55 | } 56 | } 57 | }, 58 | { 59 | "id": "ba35d6eab2ad0fc2", 60 | "type": "leaf", 61 | "state": { 62 | "type": "search", 63 | "state": { 64 | "query": "", 65 | "matchingCase": false, 66 | "explainSearch": false, 67 | "collapseAll": false, 68 | "extraContext": false, 69 | "sortOrder": "alphabetical" 70 | } 71 | } 72 | }, 73 | { 74 | "id": "e51e8f6466785fec", 75 | "type": "leaf", 76 | "state": { 77 | "type": "starred", 78 | "state": {} 79 | } 80 | } 81 | ] 82 | } 83 | ], 84 | "direction": "horizontal", 85 | "width": 300 86 | }, 87 | "right": { 88 | "id": "9df4606d9e9dbc5f", 89 | "type": "split", 90 | "children": [ 91 | { 92 | "id": "9514e6cc4fe57830", 93 | "type": "tabs", 94 | "children": [ 95 | { 96 | "id": "54525f7c1b493d00", 97 | "type": "leaf", 98 | "state": { 99 | "type": "backlink", 100 | "state": { 101 | "file": "README.md", 102 | "collapseAll": false, 103 | "extraContext": false, 104 | "sortOrder": "alphabetical", 105 | "showSearch": false, 106 | "searchQuery": "", 107 | "backlinkCollapsed": false, 108 | "unlinkedCollapsed": true 109 | } 110 | } 111 | }, 112 | { 113 | "id": "4836c7768fe83dc1", 114 | "type": "leaf", 115 | "state": { 116 | "type": "outgoing-link", 117 | "state": { 118 | "file": "README.md", 119 | "linksCollapsed": false, 120 | "unlinkedCollapsed": true 121 | } 122 | } 123 | }, 124 | { 125 | "id": "5532750709a44710", 126 | "type": "leaf", 127 | "state": { 128 | "type": "tag", 129 | "state": { 130 | "sortOrder": "frequency", 131 | "useHierarchy": true 132 | } 133 | } 134 | }, 135 | { 136 | "id": "f2c82eb4294aa303", 137 | "type": "leaf", 138 | "state": { 139 | "type": "outline", 140 | "state": { 141 | "file": "README.md" 142 | } 143 | } 144 | } 145 | ], 146 | "currentTab": 3 147 | } 148 | ], 149 | "direction": "horizontal", 150 | "width": 300 151 | }, 152 | "left-ribbon": { 153 | "hiddenItems": { 154 | "switcher:Open quick switcher": false, 155 | "graph:Open graph view": false, 156 | "canvas:Create new canvas": false, 157 | "daily-notes:Open today's daily note": false, 158 | "templates:Insert template": false, 159 | "command-palette:Open command palette": false, 160 | "templater-obsidian:Templater": false 161 | } 162 | }, 163 | "active": "56a45af6be70493b", 164 | "lastOpenFiles": [ 165 | "attachments/Pasted image 20230312162144.png", 166 | "PowerShell Script Example.md", 167 | "README.md", 168 | "attachments/Pasted image 20230312161834.png", 169 | "ping example.md", 170 | "Obsidian-System-Commands-Execution-Templates", 171 | "attachments/Pasted image 20230312143001.png", 172 | "attachments/Pasted image 20230312142213.png", 173 | "README.md.md", 174 | "attachments/Pasted image 20230312141836.png", 175 | "attachments/ping_example_hotkey.gif", 176 | "attachments/Pasted image 20230312140640.png", 177 | "attachments/Pasted image 20230312140552.png", 178 | "attachments/ping_example.gif", 179 | "attachments/Pasted image 20230312113439.png", 180 | "attachments", 181 | "attachments/Pasted image 20230312132859.png.md", 182 | "Pasted image 20230312132859.png", 183 | "TEMPLATES/Execute cmd.exe Selected Text.md", 184 | "TEMPLATES/Execute PowerShell5 Selected Text.md", 185 | "TEMPLATES/Execute PowerShell7 Selected Text.md", 186 | "TEMPLATES/Functions", 187 | "TEMPLATES" 188 | ] 189 | } -------------------------------------------------------------------------------- /PowerShell Script Example.md: -------------------------------------------------------------------------------- 1 | # System information 2 | ## Computer information 3 | 4 | Host Name | User Name | CMD Path (Comspec) | OS Type 5 | --- | --- | --- | --- 6 | `TESTCOMPUTER`|`SuperUser`|`C:\Windows\system32\cmd.exe`|`Windows_NT` 7 | 8 | ## Network Adapter Information 9 | 10 | Card Name | Driver Path | Driver Version 11 | --- | --- | --- 12 | `VMware Network Adapter VMnet8`|`\SystemRoot\system32\DRIVERS\vmnetadapter.sys`|`14.0.0.5` 13 | 14 | All values were produced from Get-ObsidianThings.ps1 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This vault is to showcase the power of using user defined functions and system commands created through the `Templater` plugin. 2 | 3 | ## Forewarning 4 | 5 | Keep in mind that running system commands through any application is to be considered extremely dangerous if you don't know what you're doing. In normal circumstances when applications pass user input through an `exec()` or `eval()` statement, the result can lead to remote command execution if the passed input isn't properly sanitized. Given that Obsidian is a _local_ application that isn't interacting with remote user input, I'm comfortable extending Obsidian the benefits of running local scripts and Cmdlets to have their output parsed directly into the note I'm working on. 6 | 7 | With that said, **DO NOT RUN COMMANDS POSTED ON THE INTERNET IF YOU DON'T FULLY UNDERSTAND WHAT THEY ARE DOING**. I accept 0 responsibility for what you do with the educational information provided in this repository. If you run something that wipes your entire OS of the face of the earth, that's on you. 8 | 9 | ## Steps 10 | 11 | The following are requirements to grant Obsidian access to return output of system commands into notes. 12 | 13 | 1. Enable community plugins (Disable `safe mode`) 14 | 2. Download Templater 15 | 1. Create a templates folder 16 | 2. Enable system commands 17 | 3. Create user defined shell execution functions 18 | 4. Map hotkeys to each desired shell 19 | 3. Execute system command and have output returned directly to note 20 | 21 | 22 | ### Enabling Community Plugins 23 | 24 | Open settings with `Ctrl+ ,` > `Community Plugins` > `Turn on Community Plugins` 25 | ![Pasted image 20230312113550.png](attachments/Pasted%20image%2020230312113550.png) 26 | 27 | Click `Browse` 28 | ![Pasted image 20230312113743.png](attachments/Pasted%20image%2020230312113743.png) 29 | 30 | Type `Templater` and select the plugin by `SilentVoid`. Click `Install` then `Enable`. 31 | 32 | ![Pasted image 20230312113952.png](attachments/Pasted%20image%2020230312113952.png) 33 | 34 | 35 | ### Creating Template Folder 36 | 37 | Create a template folder in your desired location within the vault. I chose the root of the vault because it's easier to navigate and create templates but the folder name or location doesn't matter. 38 | 39 | ![Pasted image 20230312114222.png](attachments/Pasted%20image%2020230312114222.png) 40 | 41 | I will also create a `Functions` folder under the `TEMPLATES` folder to hold user defined JavaScript functions (we'll go over this in a bit) which similarly extend scripting capabilities but their setup is a bit more involved. This step isn't necessary if you're only wanting to run system commands and have their output returned to the calling note. 42 | 43 | 44 | ![Pasted image 20230312114606.png](attachments/Pasted%20image%2020230312114606.png) 45 | ![Pasted image 20230312114655.png](attachments/Pasted%20image%2020230312114655.png) 46 | 47 | 48 | ### Enabling Templater System Commands 49 | 50 | Open Templater's settings menu and set the template folder to the first created folder. In my case it is the `TEMPLATES` folder. This grants Templater access to templates within the folder of our choosing. Tweak the `Timeout` seconds if you think you'll be running commands that will take longer than 5 seconds to return output. 51 | 52 | ![Pasted image 20230312115546.png](attachments/Pasted%20image%2020230312115546.png) 53 | 54 | ![Pasted image 20230312115849.png](attachments/Pasted%20image%2020230312115849.png) 55 | 56 | > [!Note] Console Differences 57 | > Windows and \*Nix systems use different shells for command execution. Tweak your `Shell binary location` to match the shell your system is using i.e. `/bin/bash`, `/usr/bin/sh`, `/bin/zsh` etc. For Windows machines this can be left blank. Windows will automatically scan the system $PATH variable to find the shells we define in the next section. 58 | 59 | 60 | 61 | ### Creating User Functions 62 | 63 | User Functions allow us to map system command strings containing variables to JS functions that can be invoked through Templater. Template variables are passed to the defined functions as arguments that are defined when invoking the function. 64 | 65 | There are two ways to create user functions via Templater: 66 | 67 | 1. Templater's `Add New User Function` option which allows us to create a user function directly in Templater's settings menu. 68 | 2. Enabling Templater's `User Script Functions` which enables supported for exported JS script modules. 69 | 70 | We'll be covering option 1 now as it is the easier of the two options. A sample `User Script Function` will be included in the [[#Appendix]] section. 71 | 72 | In `User System Command Functions` click `Add New User Function` and add the desired function names and command strings for each shell. 73 | 74 | ![Pasted image 20230312124148.png](attachments/Pasted%20image%2020230312124148.png) 75 | 76 | Function Name | System Command String | Variable Name 77 | --- | --- | --- 78 | `cmd_exec` | `cmd /C %Cmd%` | `Cmd` 79 | `pwsh5_exec` | `PowerShell -NoProfile -Command Invoke-Expression("$Env:Pwsh")` | `Pwsh` 80 | `pwsh7_exec` | `pwsh -NoProfile -Command Invoke-Expression("$Env:Pwsh")` | `Pwsh` 81 | 82 | 83 | After a function is created with this method it can be invoked via a Templater template using the syntax: 84 | 85 | ```js 86 | <% tp.user.({: }) %> 87 | ``` 88 | 89 | Lets break down an example that will convert selected note text into a PowerShell command. This command can be copied and run despite being broken into multiple lines. I personally comment my templates like this to remember exactly how the template functions. 90 | 91 | ```js 92 | <% 93 | // Templater required opening tag 94 | tp. // Templater object 95 | user. // User Functions 96 | pwsh5_exec({ // Use the "Function Name" pwsh5_exec which maps to Invoke-Expression 97 | Pwsh: // "Pwsh" part of "$Env:Pwsh" i.e. the argument expected by pwsh5_exec 98 | tp.file.selection() // The command that will be executed / What has been highlighted on the screen 99 | }) 100 | // template required closing tag stripping whitespace after inserting output 101 | _%> 102 | ``` 103 | 104 | Now that the template format is understood, we can create new templates mapping to `PowerShell5.1`, `PowerShell7`, and `Cmd.exe`. Create 3 new files under the `TEMPLATES` directory: 105 | 106 | - `Execute PowerShell5 Selected Text` 107 | - `Execute PowerShell7 Selected Text` 108 | - `Execute cmd.exe Selected Text` 109 | 110 | ![Pasted image 20230312131658.png](attachments/Pasted%20image%2020230312131658.png) 111 | 112 | Pate the following into each respective file. Note that the `variable` and `argument` have been augmented to match the functions we created in the beginning of [[#Creating User Functions]]. 113 | 114 | #### Execute PowerShell5 Selected Text 115 | ```js 116 | <% 117 | // Templater required opening tag 118 | tp. // Templater object 119 | user. // User Functions 120 | pwsh5_exec({ // Use the "Function Name" pwsh5_exec which maps to Invoke-Expression 121 | Pwsh: // "Pwsh" part of "$Env:Pwsh" i.e. the argument expected by pwsh5_exec 122 | tp.file.selection() // The command that will be executed / What has been highlighted on the screen 123 | }) 124 | // template required closing tag stripping whitespace after inserting output 125 | _%> 126 | ``` 127 | 128 | #### Execute PowerShell7 Selected Text 129 | ```js 130 | <% 131 | // Templater required opening tag 132 | tp. // Templater object 133 | user. // User Functions 134 | pwsh7_exec({ // Use the "Function Name" pwsh5_exec which maps to Invoke-Expression 135 | Pwsh: // "Pwsh" part of "$Env:Pwsh" i.e. the argument expected by pwsh7_exec 136 | tp.file.selection() // The command that will be executed / What has been highlighted on the screen 137 | }) 138 | // template required closing tag stripping whitespace after inserting output 139 | _%> 140 | ``` 141 | 142 | #### Execute cmd.exe Selected Text 143 | ```js 144 | <% 145 | // Templater required opening tag 146 | tp. // Templater object 147 | user. // User Functions 148 | cmd_exec({ // Use the "Function Name" cmd_exec which maps to cmd /C 149 | Cmd: // Argument expected by cmd_exec i.e. %Cmd% 150 | tp.file.selection() // The command that will be executed / What has been highlighted on the screen 151 | }) 152 | // template required closing tag stripping whitespace after inserting output 153 | _%> 154 | ``` 155 | 156 | 157 | ### Command Execution Example 158 | 159 | With the 3 template files added to the `TEMPLATES` directory we can now convert highlighted text into a system command. Note that note text must match the syntax of the corresponding shell. Let's look at a PowerShell example where the output of a `ping` command to Google's DNS server is returned to the note. 160 | 161 | 1. Open a new note 162 | 2. Type `ping -n 2 8.8.8.8` in the new note 163 | 3. Select the typed text 164 | 4. Click the Templater Icon 165 | 5. Select the corresponding shell to run the command 166 | 167 | ![ping_example.gif](attachments/ping_example.gif) 168 | 169 | Start to see how incredibly powerful this capability is, particularly with ingesting data into our PKMs. I run a substantial number of scripts during penetration testing whose output is eventually copy and paste into Obsidian. This functionality will significantly reduce the overhead by automating data ingestion into Obsidian. We can also execute local scripts in the same manor that might generate markdown formatted output, which in term would automatically format the note to our liking. 170 | 171 | ### Executing a PowerShell Script 172 | 173 | The following script is named "Get-ObsidianThings.ps1". It collects data about the computer and first registered ethernet card, then outputs content into a Markdown formatted table. 174 | 175 | ```powershell 176 | # Get-ObsidianThings.ps1 177 | # showcase how output can be formatted to markdown from within a script 178 | $HostName = $env:COMPUTERNAME 179 | $Accountname = $env:USERNAME 180 | $CMDPath = $env:ComSpec 181 | $OSType = $env:OS 182 | 183 | $NetAdapter = Get-NetAdapter |Select-Object -First 1 | Select-Object DriverName, Name, DriverVersion 184 | 185 | $NetCardname = $NetAdapter.Name 186 | $NetCardDriverPath = $NetAdapter.DriverName 187 | $NetCardDriverVer = $NetAdapter.DriverVersion 188 | 189 | 190 | # Format the markdown that will exist in note 191 | 192 | "# System information" | Write-Output 193 | "## Computer information`n" | Write-Output 194 | "Host Name | User Name | CMD Path (Comspec) | OS Type" | Write-Output 195 | " --- | --- | --- | --- "| Write-Output 196 | "``$HostName``|``$Accountname``|``$CMDPath``|``$OSType```n" | Write-Output 197 | "## Network Adaper Informaiton`n"| Write-Output 198 | "Card Name | Driver Path | Driver Version"| Write-Output 199 | " --- | --- | --- "| Write-Output 200 | "``$NetCardname``|``$NetCardDriverPath``|``$NetCardDriverVer```n"| Write-Output 201 | "All values were produced from Get-ObsidianThings.ps1"| Write-Output 202 | ``` 203 | 204 | To invoke this script, type the script's full path and select the text as before before running the Templater PowerShell execution template. **NOTE** when running on windows each backslash character `\` needs to be escaped with a second backslash or all slashes must be converted into forward slashes to run the command. 205 | 206 | ![](attachments/Pasted%20image%2020230312161834.png) 207 | 208 | Select the text and use the appropriate shell execution template to run the command. Output will be written directly into the note. 209 | 210 | ![](attachments/Pasted%20image%2020230312162144.png) 211 | The `ping` example was nice but this example showcases the potential of pre-emptively wrapping script output into markdown format, circumventing the need to copy and paste (and reformat) script output into our PKM systems. 212 | 213 | 214 | ### Mapping Template Hotkeys 215 | 216 | The execution templates can also be mapped to hot keys further reducing overhead. To map one of the shell executions to a hot key open `Templater settings > Template Hotkeys >` and add each shell to the hotkey of choice. 217 | 218 | ![Pasted image 20230312140552.png](attachments/Pasted%20image%2020230312140552.png) 219 | 220 | The hotkey can then be configured through the context menu. 221 | 222 | ![Pasted image 20230312140640.png](attachments/Pasted%20image%2020230312140640.png) 223 | 224 | Now to execute a system command through PowerShell5, simply highlight the text and press `Ctrl + Shift + 1` to have its output returned to the terminal. 225 | 226 | ![ping_example_hotkey.gif](attachments/ping_example_hotkey.gif) 227 | 228 | 229 | ## Appendix 230 | 231 | ### Creating CommonJS Modules (Script Modules) 232 | Documentation on a simple script module can be found on Templater's [Help Page](https://silentvoid13.github.io/Templater/) 233 | Enable script modules by specifying the module path. In my case its `TEMPLATES/Funtions`. 234 | 235 | ![Pasted image 20230312141836.png](attachments/Pasted%20image%2020230312141836.png) 236 | To extend a script module to Templater, a script must be placed in the above folder. Script modules must end in `.js`. Obsidian by default doesn't show unknown filetypes. This setting must be changed within `Files & Links`. 237 | 238 | ![Pasted image 20230312142213.png](attachments/Pasted%20image%2020230312142213.png) 239 | 240 | 241 | Open your favorite text editor and paste the following, naming the file `shell.js`. This won't be possible through Obsidian because it doesn't have a handler for `.js` files. 242 | > credits: https://forum.obsidian.md/t/templater-system-commands-file-lists-weather-and-git/36197 243 | 244 | ```js 245 | // In: cmd = a complete command to run in the command line shell. It is up 246 | // to the user to make certain the command is properly formatted 247 | // for their platform 248 | // Out: an object with two properties: 249 | // out = the trimmed content the command sent to standard out. 250 | // err = the trimmed content the command sent to standard error. 251 | async function shell(cmd) 252 | { 253 | const { promisify } = require('util'); 254 | const exec = promisify(require('child_process').exec); 255 | const result = await exec(cmd); 256 | return {out: result.stdout.trim(), err: result.stderr.trim()}; 257 | } 258 | module.exports = shell; 259 | ``` 260 | 261 | This example supposedly works on Linux based systems but it fails as it is on Windows. This example is for edification purposes to show how exporting modules works. 262 | 263 | To extend the module functionality to Templater, open settings and click the refresh button. The module should then appear in `Detected (x) User Scripts`. 264 | 265 | ![Pasted image 20230312143001.png](attachments/Pasted%20image%2020230312143001.png) 266 | - this module would then be used by calling `tp.user.shell()` the same way previous functions were called. 267 | 268 | 269 | ### Resources 270 | - https://medium.com/@gareth.stretton/obsidian-do-almost-anything-really-with-system-commands-b496ffd0679c 271 | - https://github.com/djjoa/Obsidian-System-Commands-Execution-Templates 272 | - https://silentvoid13.github.io/Templater/user-functions/script-user-functions.html 273 | - https://silentvoid13.github.io/Templater/introduction.html -------------------------------------------------------------------------------- /TEMPLATES/Execute PowerShell5 Selected Text.md: -------------------------------------------------------------------------------- 1 | <% 2 | // Templater required opening tag 3 | tp. // Templater object 4 | user. // User Functions 5 | pwsh5_exec({ // Use the "Function Name" pwsh5_exec which maps to Invoke-Expression 6 | Pwsh: // "Pwsh" part of "$Env:Pwsh" i.e. the argument expected by pwsh5_exec 7 | tp.file.selection() // The command that will be executed / What has been highlighted on the screen 8 | }) 9 | // template required closing tag stripping whitespace after inserting output 10 | _%> -------------------------------------------------------------------------------- /TEMPLATES/Execute PowerShell7 Selected Text.md: -------------------------------------------------------------------------------- 1 | <% 2 | // Templater required opening tag 3 | tp. // Templater object 4 | user. // User Functions 5 | pwsh7_exec({ // Use the "Function Name" pwsh5_exec which maps to Invoke-Expression 6 | Pwsh: // "Pwsh" part of "$Env:Pwsh" i.e. the argument expected by pwsh5_exec 7 | tp.file.selection() // The command that will be executed / What has been highlighted on the screen 8 | }) 9 | // template required closing tag stripping whitespace after inserting output 10 | _%> -------------------------------------------------------------------------------- /TEMPLATES/Execute cmd.exe Selected Text.md: -------------------------------------------------------------------------------- 1 | <% 2 | // Templater required opening tag 3 | tp. // Templater object 4 | user. // User Functions 5 | cmd_exec({ // Use the "Function Name" cmd_exec which maps to cmd /C 6 | Cmd: // Argument expected by cmd_exec i.e. %Cmd% 7 | tp.file.selection() // The command that will be executed / What has been highlighted on the screen 8 | }) 9 | // template required closing tag stripping whitespace after inserting output 10 | _%> -------------------------------------------------------------------------------- /attachments/Pasted image 20230312113439.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312113439.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312113550.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312113550.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312113743.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312113743.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312113952.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312113952.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312114222.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312114222.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312114606.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312114606.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312114655.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312114655.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312115546.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312115546.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312115849.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312115849.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312124148.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312124148.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312131658.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312131658.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312132859.png.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312132859.png.md -------------------------------------------------------------------------------- /attachments/Pasted image 20230312140552.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312140552.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312140640.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312140640.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312141836.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312141836.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312142213.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312142213.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312143001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312143001.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312161834.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312161834.png -------------------------------------------------------------------------------- /attachments/Pasted image 20230312162144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/Pasted image 20230312162144.png -------------------------------------------------------------------------------- /attachments/ping_example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/ping_example.gif -------------------------------------------------------------------------------- /attachments/ping_example_hotkey.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/attachments/ping_example_hotkey.gif -------------------------------------------------------------------------------- /ping example.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/djjoa/Obsidian-System-Commands-Execution-Templates/c4ec40c129b75772c5312940b5dec07d6da99fbc/ping example.md --------------------------------------------------------------------------------