├── manifest.json ├── tsconfig.json ├── rollup.config.js ├── package.json ├── README.md ├── main.ts └── main.js /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "shortcuts-extender", 3 | "name": "Shortcuts extender", 4 | "description": "Use shortcuts for text formatting or input special symbols without language switching", 5 | "isDesktopOnly": false, 6 | "js": "main.js", 7 | "version": "2.2.0" 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "inlineSourceMap": true, 5 | "inlineSources": true, 6 | "module": "ESNext", 7 | "target": "es5", 8 | "allowJs": true, 9 | "noImplicitAny": true, 10 | "moduleResolution": "node", 11 | "importHelpers": true, 12 | "lib": ["dom", "es5", "scripthost", "es2015"] 13 | }, 14 | "include": ["**/*.ts"] 15 | } -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from "@rollup/plugin-typescript"; 2 | import { nodeResolve } from "@rollup/plugin-node-resolve"; 3 | import commonjs from "@rollup/plugin-commonjs"; 4 | 5 | export default { 6 | input: "main.ts", 7 | output: { 8 | dir: ".", 9 | sourcemap: "inline", 10 | format: "cjs", 11 | exports: "default", 12 | }, 13 | external: ["obsidian"], 14 | plugins: [typescript(), nodeResolve({ browser: true }), commonjs()], 15 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shortcuts-extender", 3 | "version": "2.2.0", 4 | "description": "Use shortcuts for text formatting or input special symbols without language switching", 5 | "main": "main.js", 6 | "scripts": { 7 | "dev": "rollup --config rollup.config.js -w", 8 | "build": "rollup --config rollup.config.js", 9 | "release": "standard-version" 10 | }, 11 | "keywords": [], 12 | "author": "kitchenrunner", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "@rollup/plugin-commonjs": "^15.1.0", 16 | "@rollup/plugin-node-resolve": "^9.0.0", 17 | "@rollup/plugin-typescript": "^6.0.0", 18 | "@types/node": "^14.14.2", 19 | "obsidian": "https://github.com/obsidianmd/obsidian-api/tarball/master", 20 | "prettier": "2.1.2", 21 | "rollup": "^2.32.1", 22 | "standard-version": "^9.0.0", 23 | "tslib": "^2.0.3", 24 | "typescript": "^4.0.3" 25 | }, 26 | "dependencies": { 27 | "supports-color": "^7.2.0" 28 | }, 29 | "repository": { 30 | "type": "git", 31 | "url": "git+https://github.com/ryjjin/Obsidian-shortcuts-extender.git" 32 | }, 33 | "bugs": { 34 | "url": "https://github.com/ryjjin/Obsidian-shortcuts-extender/issues" 35 | }, 36 | "homepage": "https://github.com/ryjjin/Obsidian-shortcuts-extender#readme" 37 | } 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Obsidian-shortcuts-extender 2 | 3 | The three key features of the plugin so far are: 4 | - the ability to change the heading level of the text by pressing the shortcut 5 | - the ability to clearing the markup of the selected text 6 | - the ability to assign shortcuts to enter special characters - so that you can fully use the markdown markup if you write notes in a language other than English 7 | 8 | ## Сhanging the heading level 9 | 10 | To change the heading level of the text, just place the cursor on the line whose heading level we want to change. 11 | Use keyboard shortcuts to specify the heading level: 12 | - <`Ctrl` + `1`> for heading1 13 | - <`Ctrl` + `2`> for heading2 14 | - <...> 15 | - <`Ctrl` + `6`> for heading6 16 | 17 | ## Clearing the markup of the selected text 18 | 19 | Use `Ctrl` + `0` for clearing the markup of the selected text: only the initial characters of lines are cleared, such as markup characters for headings, numbered and unnumbered lists, quotes. 20 | 21 | You can in this way both clear the markup in the drain, where the pointer is at the current moment, and clear the markup of lines from all the selected text. 22 | 23 | ## Toggling code blocks 24 | 25 | Use ``Ctrl + ` (Backtick)`` to toggle code blocks. If you select a code block, you can replace the block with just the inner code. If you select code and press ``Ctrl + ` (Backtick)``, then you can create a code block. 26 | 27 | ## Assigning shortcuts to enter special characters 28 | 29 | If you are writing notes in a language other than English, you may need to switch layouts frequently to enter special markdown markup characters. This plugin lets you assign you keyboard shortcuts for the most commonly used special characters. 30 | 31 | So far, the following keyboard shortcuts have been assigned: 32 | - `Alt` + `1` - `7` for input `!`, `@`, `#`, `$`, `%`, `^`, `&` symbols 33 | - `Alt` + cyrillic `х` or `ъ` (or EN `[` and `]`) for input `[``]` 34 | - `Alt` + `Shift` + cyrillic `х` or `ъ` (or EN `{` and `}`) for input `{``}` 35 | - `Alt` + cyrillic `б` or `ю` (or EN `,` and `.`) for input `<``>` 36 | - `Alt` + cyrillic `ё` for input code fences 37 | - `Alt` + `Shift` + cyrillic `ё` (or EN `~`) for input code fences for python code 38 | - `Alt` + `Shift` + `\` for input `|` symbol 39 | 40 | If you enter brackets or comparison signs or code fences, having previously selected the text, then the text will be enclosed in brackets (in the case of square brackets, a pair will be put at once) 41 | 42 | > Notification for mac users: 43 | > 44 | > Due to mac keyboard have a lot of build-in shortcuts with `Alt` symbol, many shortcuts need to be rechanged. But also mac users don't need part of shortcuts of this plugin for effective work. 45 | 46 | ## Additional features 47 | 48 | If you enter code fences for python code via <`Alt` + `Shift` + `~`> - new strings will added and result will look as: 49 | 50 | ```py 51 | 52 | ``` 53 | 54 | Also, you can use <`Alt` + `-`> for creating list from selected text. 55 | 56 | If the selected text was already a list, the list level will increase by 1, as if you had entered a tab in front of each list item. 57 | 58 | 59 | ## Install notes 60 | 61 | You can install the plugin via the Community Plugins tab within Obsidian. 62 | For manual installation place the files `manifest.json` and `main.js` in your `/.obsidian/plugins/` folder. 63 | 64 | ## Suggestions for improvement 65 | 66 | You can open the [Issue on GitHub page](https://github.com/ryjjin/Obsidian-shortcuts-extender/issues) or contact me on [Obsidian Discord Server](https://discord.com/?utm_source=Discord%20Widget&utm_medium=Logo) via @kitchenrunner 67 | -------------------------------------------------------------------------------- /main.ts: -------------------------------------------------------------------------------- 1 | import { MarkdownView, Plugin, EditorSelection, Editor } from "obsidian"; 2 | 3 | export default class shortcutsExtender extends Plugin { 4 | async onload() { 5 | console.log(this.app); 6 | 7 | this.addCommand({ 8 | id: "shortcut-exclamation-mark", 9 | name: "Shortcut for ! symbol", 10 | callback: () => this.shortcutExclamationMark(), 11 | hotkeys: [ 12 | { 13 | modifiers: ["Alt"], 14 | key: "1", 15 | }, 16 | ], 17 | }); 18 | 19 | this.addCommand({ 20 | id: "shortcut-At", 21 | name: "Shortcut for @ symbol", 22 | callback: () => this.shortcutAt(), 23 | hotkeys: [ 24 | { 25 | modifiers: ["Alt"], 26 | key: "2", 27 | }, 28 | ], 29 | }); 30 | 31 | this.addCommand({ 32 | id: "shortcut-hash", 33 | name: "Shortcut for # symbol", 34 | callback: () => this.shortcutHash(), 35 | hotkeys: [ 36 | { 37 | modifiers: ["Alt"], 38 | key: "3", 39 | }, 40 | ], 41 | }); 42 | 43 | this.addCommand({ 44 | id: "shortcut-dollar", 45 | name: "Shortcut for $ symbol", 46 | callback: () => this.shortcutDollar(), 47 | hotkeys: [ 48 | { 49 | modifiers: ["Alt"], 50 | key: "4", 51 | }, 52 | ], 53 | }); 54 | 55 | this.addCommand({ 56 | id: "shortcut-percent", 57 | name: "Shortcut for % symbol", 58 | callback: () => this.shortcutPercent(), 59 | hotkeys: [ 60 | { 61 | modifiers: ["Alt"], 62 | key: "5", 63 | }, 64 | ], 65 | }); 66 | 67 | this.addCommand({ 68 | id: "shortcut-circumflex", 69 | name: "Shortcut for ^ symbol", 70 | callback: () => this.shortcutCircumflex(), 71 | hotkeys: [ 72 | { 73 | modifiers: ["Alt"], 74 | key: "6", 75 | }, 76 | ], 77 | }); 78 | 79 | this.addCommand({ 80 | id: "shortcut-ampersand", 81 | name: "Shortcut for & symbol", 82 | callback: () => this.shortcutAmpersand(), 83 | hotkeys: [ 84 | { 85 | modifiers: ["Alt"], 86 | key: "7", 87 | }, 88 | ], 89 | }); 90 | 91 | this.addCommand({ 92 | id: "shortcut-less-than", 93 | name: "Shortcut for < symbol", 94 | callback: () => this.shortcutLessThan(), 95 | hotkeys: [ 96 | { 97 | modifiers: ["Alt"], 98 | key: "б", 99 | }, 100 | { 101 | modifiers: ["Alt"], 102 | key: ",", 103 | }, 104 | ], 105 | }); 106 | 107 | this.addCommand({ 108 | id: "shortcut-greater-than", 109 | name: "Shortcut for > symbol", 110 | callback: () => this.shortcutGreaterThan(), 111 | hotkeys: [ 112 | { 113 | modifiers: ["Alt"], 114 | key: "ю", 115 | }, 116 | { 117 | modifiers: ["Alt"], 118 | key: ".", 119 | }, 120 | ], 121 | }); 122 | 123 | this.addCommand({ 124 | id: "shortcut-left-square-bracket", 125 | name: "Shortcut for [ symbol", 126 | callback: () => this.shortcutLeftSquareBracket(), 127 | hotkeys: [ 128 | { 129 | modifiers: ["Alt"], 130 | key: "х", 131 | }, 132 | { 133 | modifiers: ["Alt"], 134 | key: "[", 135 | }, 136 | ], 137 | }); 138 | 139 | this.addCommand({ 140 | id: "shortcut-right-square-bracket", 141 | name: "Shortcut for ] symbol", 142 | callback: () => this.shortcutRightSquareBracket(), 143 | hotkeys: [ 144 | { 145 | modifiers: ["Alt"], 146 | key: "ъ", 147 | }, 148 | { 149 | modifiers: ["Alt"], 150 | key: "]", 151 | }, 152 | ], 153 | }); 154 | 155 | this.addCommand({ 156 | id: "shortcut-python-code", 157 | name: "Shortcut for .py code fences", 158 | callback: () => this.shortcutPyCode(), 159 | hotkeys: [ 160 | { 161 | modifiers: ["Alt", "Shift"], 162 | key: "ё", 163 | }, 164 | { 165 | modifiers: ["Alt", "Shift"], 166 | key: "~", 167 | }, 168 | ], 169 | }); 170 | 171 | this.addCommand({ 172 | id: "shortcut-code", 173 | name: "Shortcut for code fences (`)", 174 | callback: () => this.shortcutCodeFences(), 175 | hotkeys: [ 176 | { 177 | modifiers: ["Alt"], 178 | key: "ё", 179 | }, 180 | { 181 | modifiers: ["Alt"], 182 | key: "`", 183 | }, 184 | ], 185 | }); 186 | 187 | this.addCommand({ 188 | id: "shortcut-code-block", 189 | name: "Shortcut for toggling a code block", 190 | callback: () => this.shortcutToggleCodeBlock(), 191 | hotkeys: [ 192 | { 193 | modifiers: ["Ctrl"], 194 | key: "`", 195 | }, 196 | ], 197 | }); 198 | 199 | this.addCommand({ 200 | id: "shortcut-left-curly-bracket", 201 | name: "Shortcut for { symbol", 202 | callback: () => this.shortcutLeftCurlyBracket(), 203 | hotkeys: [ 204 | { 205 | modifiers: ["Alt", "Shift"], 206 | key: "х", 207 | }, 208 | { 209 | modifiers: ["Alt", "Shift"], 210 | key: "{", 211 | }, 212 | ], 213 | }); 214 | 215 | this.addCommand({ 216 | id: "shortcut-right-curly-bracket", 217 | name: "Shortcut for } symbol", 218 | callback: () => this.shortcutRightCurlyBracket(), 219 | hotkeys: [ 220 | { 221 | modifiers: ["Alt", "Shift"], 222 | key: "ъ", 223 | }, 224 | { 225 | modifiers: ["Alt", "Shift"], 226 | key: "}", 227 | }, 228 | ], 229 | }); 230 | 231 | this.addCommand({ 232 | id: "shortcut-Vertical-Line", 233 | name: "Shortcut for | symbol", 234 | callback: () => this.shortcutVerticalLine(), 235 | hotkeys: [ 236 | { 237 | modifiers: ["Alt", "Shift"], 238 | key: "|", 239 | }, 240 | { 241 | modifiers: ["Alt", "Shift"], 242 | key: "\/", 243 | }, 244 | ], 245 | }); 246 | 247 | this.addCommand({ 248 | id: "shortcut-list-items", 249 | name: "Creating list item from text", 250 | callback: () => this.shortcutListItems(), 251 | hotkeys: [ 252 | { 253 | modifiers: ["Alt"], 254 | key: "-", 255 | }, 256 | ], 257 | }); 258 | 259 | this.addCommand({ 260 | id: "heading-1", 261 | name: "line into level 1 heading", 262 | callback: () => this.shortcutHeaderN(1), 263 | hotkeys: [ 264 | { 265 | modifiers: ["Ctrl"], 266 | key: "1", 267 | }, 268 | ], 269 | }); 270 | 271 | this.addCommand({ 272 | id: "heading-2", 273 | name: "line into level 2 heading", 274 | callback: () => this.shortcutHeaderN(2), 275 | hotkeys: [ 276 | { 277 | modifiers: ["Ctrl"], 278 | key: "2", 279 | }, 280 | ], 281 | }); 282 | 283 | this.addCommand({ 284 | id: "heading-3", 285 | name: "line into level 3 heading", 286 | callback: () => this.shortcutHeaderN(3), 287 | hotkeys: [ 288 | { 289 | modifiers: ["Ctrl"], 290 | key: "3", 291 | }, 292 | ], 293 | }); 294 | 295 | this.addCommand({ 296 | id: "heading-4", 297 | name: "line into level 4 heading", 298 | callback: () => this.shortcutHeaderN(4), 299 | hotkeys: [ 300 | { 301 | modifiers: ["Ctrl"], 302 | key: "4", 303 | }, 304 | ], 305 | }); 306 | 307 | this.addCommand({ 308 | id: "heading-5", 309 | name: "line into level 5 heading", 310 | callback: () => this.shortcutHeaderN(5), 311 | hotkeys: [ 312 | { 313 | modifiers: ["Ctrl"], 314 | key: "5", 315 | }, 316 | ], 317 | }); 318 | 319 | this.addCommand({ 320 | id: "heading-6", 321 | name: "line into level 6 heading", 322 | callback: () => this.shortcutHeaderN(6), 323 | hotkeys: [ 324 | { 325 | modifiers: ["Ctrl"], 326 | key: "6", 327 | }, 328 | ], 329 | }); 330 | 331 | this.addCommand({ 332 | id: "heading-0", 333 | name: "clearing of text formatting", 334 | callback: () => this.shortcutHeaderN(0), 335 | hotkeys: [ 336 | { 337 | modifiers: ["Ctrl"], 338 | key: "0", 339 | }, 340 | ], 341 | }); 342 | } 343 | 344 | getSelectedText(editor: Editor) { 345 | //thanks to user "Argentina Ortega Sáinz" from the Obsidian community for this feature 346 | //For a long time I tried to do without such an approach, which resulted in several bugs and the impossibility of fixing them with non-crutches 347 | if (editor.somethingSelected()) { 348 | let cursorStart = editor.getCursor('from'); 349 | let cursorEnd = editor.getCursor('to'); 350 | let content = editor.getRange( 351 | { line: cursorStart.line, ch: 0 }, 352 | { line: cursorEnd.line, ch: editor.getLine(cursorEnd.line).length } 353 | ); 354 | return { 355 | start: { line: cursorStart.line, ch: 0 }, 356 | end: { 357 | line: cursorEnd.line, 358 | ch: editor.getLine(cursorEnd.line).length, 359 | }, 360 | content: content, 361 | }; 362 | } else { 363 | // Toggle the todo in the line 364 | var lineNr = editor.getCursor().line; 365 | var contents = editor.getDoc().getLine(lineNr); 366 | let cursorStart = { 367 | line: lineNr, 368 | ch: 0, 369 | }; 370 | let cursorEnd = { 371 | line: lineNr, 372 | ch: contents.length, 373 | }; 374 | let content = editor.getRange(cursorStart, cursorEnd); 375 | return { start: cursorStart, end: cursorEnd, content: content }; 376 | } 377 | } 378 | 379 | shortcutExclamationMark(): void { 380 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 381 | if (editor == null) { 382 | return; 383 | } 384 | let selectedText = editor.somethingSelected() 385 | ? editor.getSelection() 386 | : false; 387 | editor.replaceSelection(`\!`); 388 | } 389 | 390 | shortcutAt(): void { 391 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 392 | if (editor == null) { 393 | return; 394 | } 395 | let selectedText = editor.somethingSelected() 396 | ? editor.getSelection() 397 | : false; 398 | editor.replaceSelection(`@`); 399 | } 400 | 401 | shortcutHash(): void { 402 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 403 | if (editor == null) { 404 | return; 405 | } 406 | let selectedText = editor.somethingSelected() 407 | ? editor.getSelection() 408 | : false; 409 | editor.replaceSelection(`#`); 410 | } 411 | 412 | shortcutDollar(): void { 413 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 414 | if (editor == null) { 415 | return; 416 | } 417 | let selectedText = editor.somethingSelected() 418 | ? editor.getSelection() 419 | : false; 420 | editor.replaceSelection(`$`); 421 | } 422 | 423 | shortcutPercent(): void { 424 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 425 | if (editor == null) { 426 | return; 427 | } 428 | let selectedText = editor.somethingSelected() 429 | ? editor.getSelection() 430 | : false; 431 | editor.replaceSelection(`\%`); 432 | } 433 | 434 | shortcutCircumflex(): void { 435 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 436 | if (editor == null) { 437 | return; 438 | } 439 | let selectedText = editor.somethingSelected() 440 | ? editor.getSelection() 441 | : false; 442 | editor.replaceSelection(`\^`); 443 | } 444 | 445 | shortcutAmpersand(): void { 446 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 447 | if (editor == null) { 448 | return; 449 | } 450 | let selectedText = editor.somethingSelected() 451 | ? editor.getSelection() 452 | : false; 453 | editor.replaceSelection(`\&`); 454 | } 455 | 456 | shortcutLessThan(): void { 457 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 458 | if (editor == null) { 459 | return; 460 | } 461 | let selectedText = editor.somethingSelected() 462 | ? editor.getSelection() 463 | : false; 464 | if (selectedText) { 465 | editor.replaceSelection(`<${selectedText}>`); 466 | } else editor.replaceSelection(`<`); 467 | } 468 | 469 | shortcutGreaterThan(): void { 470 | let activeLeaf: any = this.app.workspace.activeLeaf; 471 | let editor = activeLeaf.view.sourceMode.cmEditor; 472 | let selectedText = this.getSelectedText(editor); 473 | 474 | let resultText = "> " + selectedText.content.split('\n').join("\n> "); 475 | editor.replaceRange(resultText, selectedText.start, selectedText.end); 476 | } 477 | 478 | shortcutLeftSquareBracket(): void { 479 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 480 | if (editor == null) { 481 | return; 482 | } 483 | let selectedText = editor.somethingSelected() 484 | ? editor.getSelection() 485 | : false; 486 | if (selectedText) { 487 | editor.replaceSelection(`[[${selectedText}]]`); 488 | } else editor.replaceSelection(`[`); 489 | } 490 | 491 | shortcutRightSquareBracket(): void { 492 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 493 | if (editor == null) { 494 | return; 495 | } 496 | let selectedText = editor.somethingSelected() 497 | ? editor.getSelection() 498 | : false; 499 | editor.replaceSelection(`]`); 500 | } 501 | 502 | shortcutPyCode(): void { 503 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 504 | if (editor == null) { 505 | return; 506 | } 507 | let selectedText = editor.somethingSelected() 508 | ? editor.getSelection() 509 | : false; 510 | if (selectedText) { 511 | editor.replaceSelection(`\`\`\`py\n${selectedText}\n\`\`\``); 512 | } else editor.replaceSelection(`\``); 513 | } 514 | 515 | shortcutCodeFences(): void { 516 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 517 | if (editor == null) { 518 | return; 519 | } 520 | let selectedText = editor.somethingSelected() 521 | ? editor.getSelection() 522 | : false; 523 | if (selectedText) { 524 | editor.replaceSelection(`\`${selectedText}\``); 525 | } else editor.replaceSelection(`\``); 526 | } 527 | 528 | shortcutToggleCodeBlock(): void { 529 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 530 | if (editor == null) { 531 | return; 532 | } 533 | let selectedText = editor.somethingSelected() ? editor.getSelection() : ""; 534 | let startCursor = editor.getCursor('from'); 535 | let firstLine = editor.getLine(startCursor.line); 536 | let endCursor = editor.getCursor('to'); 537 | let lastLine = editor.getLine(endCursor.line); 538 | 539 | // If the selections starts with ```, then we should remove the code block. 540 | let isCodeBlock = firstLine.startsWith("```") && lastLine.endsWith("```") 541 | && selectedText.length >= 6; 542 | if (isCodeBlock) { 543 | // Position of first non-whitespace 544 | let textStartPos = selectedText.search("\\s\\S") + 1; 545 | if (textStartPos < 0) { 546 | textStartPos = 3; 547 | } 548 | 549 | // Remove the code block formatting. 550 | let endPos = selectedText.length - 3; 551 | let innerText = selectedText.substring(textStartPos, endPos) 552 | editor.replaceSelection(innerText) 553 | } else { 554 | editor.replaceSelection(`\`\`\`\n${selectedText}\n\`\`\``); 555 | startCursor.ch = 3; // Move cursor after ``` 556 | editor.setCursor(startCursor); 557 | } 558 | } 559 | 560 | shortcutRightCurlyBracket(): void { 561 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 562 | if (editor == null) { 563 | return; 564 | } 565 | let selectedText = editor.somethingSelected() 566 | ? editor.getSelection() 567 | : false; 568 | editor.replaceSelection(`}`); 569 | } 570 | 571 | shortcutLeftCurlyBracket(): void { 572 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 573 | if (editor == null) { 574 | return; 575 | } 576 | let selectedText = editor.somethingSelected() 577 | ? editor.getSelection() 578 | : false; 579 | if (selectedText) { 580 | editor.replaceSelection(`\{${selectedText}\}`); 581 | } else editor.replaceSelection(`\{`); 582 | } 583 | 584 | shortcutVerticalLine(): void { 585 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 586 | if (editor == null) { 587 | return; 588 | } 589 | let selectedText = editor.somethingSelected() 590 | ? editor.getSelection() 591 | : false; 592 | editor.replaceSelection(`|`); 593 | } 594 | 595 | shortcutListItems(): void { 596 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 597 | if (editor == null) { 598 | return; 599 | } 600 | let selectedText = this.getSelectedText(editor); 601 | 602 | let resultText = "- " + selectedText.content.split('\n').join("\n- "); 603 | 604 | let resultTextCheck = resultText; 605 | while (resultTextCheck.search("- - ") >= 0) { 606 | resultTextCheck = resultTextCheck.replace("- - ", " - "); 607 | } 608 | while (resultTextCheck.search("- ") >= 0) { 609 | resultTextCheck = resultTextCheck.replace("- ", " - "); 610 | } 611 | while (resultTextCheck.search("- - ") >= 0) { 612 | resultTextCheck = resultTextCheck.replace("- - ", " - "); 613 | } 614 | editor.replaceRange(resultTextCheck, selectedText.start, selectedText.end); 615 | } 616 | 617 | removeFormatSymbolsFromStr(line: string): string { 618 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 619 | if (editor == null) { 620 | return; 621 | } 622 | 623 | // Remove symbols we don't want at the beginning of the line. 624 | while (line.substring(0,2) == "##") { 625 | line = line.replace("##", "#"); 626 | } 627 | while (line.substring(0,2) == "# ") { 628 | line = line.substr(2); 629 | } 630 | while (line.substring(0,2) == "> ") { 631 | line = line.substr(2); 632 | } 633 | while (line.substring(0,2) == " ") { 634 | line = line.replace(" ", " "); 635 | } 636 | while (line.substring(0,3) == " - ") { 637 | line = line.substr(3); 638 | } 639 | while (line.substring(0,2) == "- ") { 640 | line = line.substr(2); 641 | } 642 | var re_digits = /^\d\.\s/; 643 | line = line.replace(re_digits, ""); 644 | 645 | return line; 646 | } 647 | 648 | addHeadingToStr(line: string, headingLevel: number): string { 649 | let space = " "; 650 | if (headingLevel == 0) { 651 | space = ""; 652 | } 653 | 654 | return "#".repeat(headingLevel) + space + line; 655 | } 656 | 657 | shortcutHeaderN(headingLevel: number): void { 658 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 659 | if (editor == null) { 660 | return; 661 | } 662 | 663 | // Apply heading level to each line. 664 | let selections = editor.listSelections(); 665 | for (let i = 0; i < selections.length; i++) { 666 | this.shortcutHeaderNSingleSelection(headingLevel, selections[i]) 667 | } 668 | 669 | // setSelections is called to preserve the location of each cursor relative 670 | // to the end of the line. 671 | editor.setSelections(selections); 672 | } 673 | 674 | // shortcutHeaderNSingleSelection sets all lines in the selection to the 675 | // desired heading level. selection is also updated to maintain the cursor 676 | // position relative to the end of the line. 677 | shortcutHeaderNSingleSelection(headingLevel: number, selection: EditorSelection) { 678 | let editor = this.app.workspace.getActiveViewOfType(MarkdownView)?.editor; 679 | if (editor == null) { 680 | return; 681 | } 682 | 683 | // Save anchor/head distance from end. 684 | let anchorDistFromEnd = editor.getLine(selection.anchor.line).length - selection.anchor.ch 685 | let headDistFromEnd = editor.getLine(selection.head.line).length - selection.head.ch 686 | 687 | // Get from and to line numbers. 688 | let fromLine = selection.anchor.line; 689 | let toLine = selection.head.line; 690 | let increment = fromLine <= toLine ? 1 : -1; 691 | // For each line in the selection, set the heading level. 692 | let lineNum = fromLine; 693 | while (true) { 694 | // Update the current line. 695 | let line = editor.getLine(lineNum); 696 | line = this.removeFormatSymbolsFromStr(line); 697 | line = this.addHeadingToStr(line, headingLevel); 698 | editor.setLine(lineNum, line); 699 | 700 | // Move to next line if not done. 701 | if (lineNum == toLine) { 702 | break; 703 | } 704 | lineNum += increment; 705 | } 706 | 707 | // Preserve anchor/head locations relative to line end. 708 | selection.anchor.ch = editor.getLine(selection.anchor.line).length - anchorDistFromEnd; 709 | selection.head.ch = editor.getLine(selection.head.line).length - headDistFromEnd; 710 | } 711 | } 712 | -------------------------------------------------------------------------------- /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 | if (typeof b !== "function" && b !== null) 30 | throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 31 | extendStatics(d, b); 32 | function __() { this.constructor = d; } 33 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 34 | } 35 | 36 | function __awaiter(thisArg, _arguments, P, generator) { 37 | function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 38 | return new (P || (P = Promise))(function (resolve, reject) { 39 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 40 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 41 | function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 42 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 43 | }); 44 | } 45 | 46 | function __generator(thisArg, body) { 47 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 48 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 49 | function verb(n) { return function (v) { return step([n, v]); }; } 50 | function step(op) { 51 | if (f) throw new TypeError("Generator is already executing."); 52 | while (_) try { 53 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 54 | if (y = 0, t) op = [op[0] & 2, t.value]; 55 | switch (op[0]) { 56 | case 0: case 1: t = op; break; 57 | case 4: _.label++; return { value: op[1], done: false }; 58 | case 5: _.label++; y = op[1]; op = [0]; continue; 59 | case 7: op = _.ops.pop(); _.trys.pop(); continue; 60 | default: 61 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 62 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 63 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 64 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 65 | if (t[2]) _.ops.pop(); 66 | _.trys.pop(); continue; 67 | } 68 | op = body.call(thisArg, _); 69 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 70 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 71 | } 72 | } 73 | 74 | var shortcutsExtender = /** @class */ (function (_super) { 75 | __extends(shortcutsExtender, _super); 76 | function shortcutsExtender() { 77 | return _super !== null && _super.apply(this, arguments) || this; 78 | } 79 | shortcutsExtender.prototype.onload = function () { 80 | return __awaiter(this, void 0, void 0, function () { 81 | var _this = this; 82 | return __generator(this, function (_a) { 83 | console.log(this.app); 84 | this.addCommand({ 85 | id: "shortcut-exclamation-mark", 86 | name: "Shortcut for ! symbol", 87 | callback: function () { return _this.shortcutExclamationMark(); }, 88 | hotkeys: [ 89 | { 90 | modifiers: ["Alt"], 91 | key: "1", 92 | }, 93 | ], 94 | }); 95 | this.addCommand({ 96 | id: "shortcut-At", 97 | name: "Shortcut for @ symbol", 98 | callback: function () { return _this.shortcutAt(); }, 99 | hotkeys: [ 100 | { 101 | modifiers: ["Alt"], 102 | key: "2", 103 | }, 104 | ], 105 | }); 106 | this.addCommand({ 107 | id: "shortcut-hash", 108 | name: "Shortcut for # symbol", 109 | callback: function () { return _this.shortcutHash(); }, 110 | hotkeys: [ 111 | { 112 | modifiers: ["Alt"], 113 | key: "3", 114 | }, 115 | ], 116 | }); 117 | this.addCommand({ 118 | id: "shortcut-dollar", 119 | name: "Shortcut for $ symbol", 120 | callback: function () { return _this.shortcutDollar(); }, 121 | hotkeys: [ 122 | { 123 | modifiers: ["Alt"], 124 | key: "4", 125 | }, 126 | ], 127 | }); 128 | this.addCommand({ 129 | id: "shortcut-percent", 130 | name: "Shortcut for % symbol", 131 | callback: function () { return _this.shortcutPercent(); }, 132 | hotkeys: [ 133 | { 134 | modifiers: ["Alt"], 135 | key: "5", 136 | }, 137 | ], 138 | }); 139 | this.addCommand({ 140 | id: "shortcut-circumflex", 141 | name: "Shortcut for ^ symbol", 142 | callback: function () { return _this.shortcutCircumflex(); }, 143 | hotkeys: [ 144 | { 145 | modifiers: ["Alt"], 146 | key: "6", 147 | }, 148 | ], 149 | }); 150 | this.addCommand({ 151 | id: "shortcut-ampersand", 152 | name: "Shortcut for & symbol", 153 | callback: function () { return _this.shortcutAmpersand(); }, 154 | hotkeys: [ 155 | { 156 | modifiers: ["Alt"], 157 | key: "7", 158 | }, 159 | ], 160 | }); 161 | this.addCommand({ 162 | id: "shortcut-less-than", 163 | name: "Shortcut for < symbol", 164 | callback: function () { return _this.shortcutLessThan(); }, 165 | hotkeys: [ 166 | { 167 | modifiers: ["Alt"], 168 | key: "б", 169 | }, 170 | { 171 | modifiers: ["Alt"], 172 | key: ",", 173 | }, 174 | ], 175 | }); 176 | this.addCommand({ 177 | id: "shortcut-greater-than", 178 | name: "Shortcut for > symbol", 179 | callback: function () { return _this.shortcutGreaterThan(); }, 180 | hotkeys: [ 181 | { 182 | modifiers: ["Alt"], 183 | key: "ю", 184 | }, 185 | { 186 | modifiers: ["Alt"], 187 | key: ".", 188 | }, 189 | ], 190 | }); 191 | this.addCommand({ 192 | id: "shortcut-left-square-bracket", 193 | name: "Shortcut for [ symbol", 194 | callback: function () { return _this.shortcutLeftSquareBracket(); }, 195 | hotkeys: [ 196 | { 197 | modifiers: ["Alt"], 198 | key: "х", 199 | }, 200 | { 201 | modifiers: ["Alt"], 202 | key: "[", 203 | }, 204 | ], 205 | }); 206 | this.addCommand({ 207 | id: "shortcut-right-square-bracket", 208 | name: "Shortcut for ] symbol", 209 | callback: function () { return _this.shortcutRightSquareBracket(); }, 210 | hotkeys: [ 211 | { 212 | modifiers: ["Alt"], 213 | key: "ъ", 214 | }, 215 | { 216 | modifiers: ["Alt"], 217 | key: "]", 218 | }, 219 | ], 220 | }); 221 | this.addCommand({ 222 | id: "shortcut-python-code", 223 | name: "Shortcut for .py code fences", 224 | callback: function () { return _this.shortcutPyCode(); }, 225 | hotkeys: [ 226 | { 227 | modifiers: ["Alt", "Shift"], 228 | key: "ё", 229 | }, 230 | { 231 | modifiers: ["Alt", "Shift"], 232 | key: "~", 233 | }, 234 | ], 235 | }); 236 | this.addCommand({ 237 | id: "shortcut-code", 238 | name: "Shortcut for code fences (`)", 239 | callback: function () { return _this.shortcutCodeFences(); }, 240 | hotkeys: [ 241 | { 242 | modifiers: ["Alt"], 243 | key: "ё", 244 | }, 245 | { 246 | modifiers: ["Alt"], 247 | key: "`", 248 | }, 249 | ], 250 | }); 251 | this.addCommand({ 252 | id: "shortcut-code-block", 253 | name: "Shortcut for toggling a code block", 254 | callback: function () { return _this.shortcutToggleCodeBlock(); }, 255 | hotkeys: [ 256 | { 257 | modifiers: ["Ctrl"], 258 | key: "`", 259 | }, 260 | ], 261 | }); 262 | this.addCommand({ 263 | id: "shortcut-left-curly-bracket", 264 | name: "Shortcut for { symbol", 265 | callback: function () { return _this.shortcutLeftCurlyBracket(); }, 266 | hotkeys: [ 267 | { 268 | modifiers: ["Alt", "Shift"], 269 | key: "х", 270 | }, 271 | { 272 | modifiers: ["Alt", "Shift"], 273 | key: "{", 274 | }, 275 | ], 276 | }); 277 | this.addCommand({ 278 | id: "shortcut-right-curly-bracket", 279 | name: "Shortcut for } symbol", 280 | callback: function () { return _this.shortcutRightCurlyBracket(); }, 281 | hotkeys: [ 282 | { 283 | modifiers: ["Alt", "Shift"], 284 | key: "ъ", 285 | }, 286 | { 287 | modifiers: ["Alt", "Shift"], 288 | key: "}", 289 | }, 290 | ], 291 | }); 292 | this.addCommand({ 293 | id: "shortcut-Vertical-Line", 294 | name: "Shortcut for | symbol", 295 | callback: function () { return _this.shortcutVerticalLine(); }, 296 | hotkeys: [ 297 | { 298 | modifiers: ["Alt", "Shift"], 299 | key: "|", 300 | }, 301 | { 302 | modifiers: ["Alt", "Shift"], 303 | key: "\/", 304 | }, 305 | ], 306 | }); 307 | this.addCommand({ 308 | id: "shortcut-list-items", 309 | name: "Creating list item from text", 310 | callback: function () { return _this.shortcutListItems(); }, 311 | hotkeys: [ 312 | { 313 | modifiers: ["Alt"], 314 | key: "-", 315 | }, 316 | ], 317 | }); 318 | this.addCommand({ 319 | id: "heading-1", 320 | name: "line into level 1 heading", 321 | callback: function () { return _this.shortcutHeaderN(1); }, 322 | hotkeys: [ 323 | { 324 | modifiers: ["Ctrl"], 325 | key: "1", 326 | }, 327 | ], 328 | }); 329 | this.addCommand({ 330 | id: "heading-2", 331 | name: "line into level 2 heading", 332 | callback: function () { return _this.shortcutHeaderN(2); }, 333 | hotkeys: [ 334 | { 335 | modifiers: ["Ctrl"], 336 | key: "2", 337 | }, 338 | ], 339 | }); 340 | this.addCommand({ 341 | id: "heading-3", 342 | name: "line into level 3 heading", 343 | callback: function () { return _this.shortcutHeaderN(3); }, 344 | hotkeys: [ 345 | { 346 | modifiers: ["Ctrl"], 347 | key: "3", 348 | }, 349 | ], 350 | }); 351 | this.addCommand({ 352 | id: "heading-4", 353 | name: "line into level 4 heading", 354 | callback: function () { return _this.shortcutHeaderN(4); }, 355 | hotkeys: [ 356 | { 357 | modifiers: ["Ctrl"], 358 | key: "4", 359 | }, 360 | ], 361 | }); 362 | this.addCommand({ 363 | id: "heading-5", 364 | name: "line into level 5 heading", 365 | callback: function () { return _this.shortcutHeaderN(5); }, 366 | hotkeys: [ 367 | { 368 | modifiers: ["Ctrl"], 369 | key: "5", 370 | }, 371 | ], 372 | }); 373 | this.addCommand({ 374 | id: "heading-6", 375 | name: "line into level 6 heading", 376 | callback: function () { return _this.shortcutHeaderN(6); }, 377 | hotkeys: [ 378 | { 379 | modifiers: ["Ctrl"], 380 | key: "6", 381 | }, 382 | ], 383 | }); 384 | this.addCommand({ 385 | id: "heading-0", 386 | name: "clearing of text formatting", 387 | callback: function () { return _this.shortcutHeaderN(0); }, 388 | hotkeys: [ 389 | { 390 | modifiers: ["Ctrl"], 391 | key: "0", 392 | }, 393 | ], 394 | }); 395 | return [2 /*return*/]; 396 | }); 397 | }); 398 | }; 399 | shortcutsExtender.prototype.getSelectedText = function (editor) { 400 | //thanks to user "Argentina Ortega Sáinz" from the Obsidian community for this feature 401 | //For a long time I tried to do without such an approach, which resulted in several bugs and the impossibility of fixing them with non-crutches 402 | if (editor.somethingSelected()) { 403 | var cursorStart = editor.getCursor('from'); 404 | var cursorEnd = editor.getCursor('to'); 405 | var content = editor.getRange({ line: cursorStart.line, ch: 0 }, { line: cursorEnd.line, ch: editor.getLine(cursorEnd.line).length }); 406 | return { 407 | start: { line: cursorStart.line, ch: 0 }, 408 | end: { 409 | line: cursorEnd.line, 410 | ch: editor.getLine(cursorEnd.line).length, 411 | }, 412 | content: content, 413 | }; 414 | } 415 | else { 416 | // Toggle the todo in the line 417 | var lineNr = editor.getCursor().line; 418 | var contents = editor.getDoc().getLine(lineNr); 419 | var cursorStart = { 420 | line: lineNr, 421 | ch: 0, 422 | }; 423 | var cursorEnd = { 424 | line: lineNr, 425 | ch: contents.length, 426 | }; 427 | var content = editor.getRange(cursorStart, cursorEnd); 428 | return { start: cursorStart, end: cursorEnd, content: content }; 429 | } 430 | }; 431 | shortcutsExtender.prototype.shortcutExclamationMark = function () { 432 | var _a; 433 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 434 | if (editor == null) { 435 | return; 436 | } 437 | editor.somethingSelected() 438 | ? editor.getSelection() 439 | : false; 440 | editor.replaceSelection("!"); 441 | }; 442 | shortcutsExtender.prototype.shortcutAt = function () { 443 | var _a; 444 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 445 | if (editor == null) { 446 | return; 447 | } 448 | editor.somethingSelected() 449 | ? editor.getSelection() 450 | : false; 451 | editor.replaceSelection("@"); 452 | }; 453 | shortcutsExtender.prototype.shortcutHash = function () { 454 | var _a; 455 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 456 | if (editor == null) { 457 | return; 458 | } 459 | editor.somethingSelected() 460 | ? editor.getSelection() 461 | : false; 462 | editor.replaceSelection("#"); 463 | }; 464 | shortcutsExtender.prototype.shortcutDollar = function () { 465 | var _a; 466 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 467 | if (editor == null) { 468 | return; 469 | } 470 | editor.somethingSelected() 471 | ? editor.getSelection() 472 | : false; 473 | editor.replaceSelection("$"); 474 | }; 475 | shortcutsExtender.prototype.shortcutPercent = function () { 476 | var _a; 477 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 478 | if (editor == null) { 479 | return; 480 | } 481 | editor.somethingSelected() 482 | ? editor.getSelection() 483 | : false; 484 | editor.replaceSelection("%"); 485 | }; 486 | shortcutsExtender.prototype.shortcutCircumflex = function () { 487 | var _a; 488 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 489 | if (editor == null) { 490 | return; 491 | } 492 | editor.somethingSelected() 493 | ? editor.getSelection() 494 | : false; 495 | editor.replaceSelection("^"); 496 | }; 497 | shortcutsExtender.prototype.shortcutAmpersand = function () { 498 | var _a; 499 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 500 | if (editor == null) { 501 | return; 502 | } 503 | editor.somethingSelected() 504 | ? editor.getSelection() 505 | : false; 506 | editor.replaceSelection("&"); 507 | }; 508 | shortcutsExtender.prototype.shortcutLessThan = function () { 509 | var _a; 510 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 511 | if (editor == null) { 512 | return; 513 | } 514 | var selectedText = editor.somethingSelected() 515 | ? editor.getSelection() 516 | : false; 517 | if (selectedText) { 518 | editor.replaceSelection("<".concat(selectedText, ">")); 519 | } 520 | else 521 | editor.replaceSelection("<"); 522 | }; 523 | shortcutsExtender.prototype.shortcutGreaterThan = function () { 524 | var activeLeaf = this.app.workspace.activeLeaf; 525 | var editor = activeLeaf.view.sourceMode.cmEditor; 526 | var selectedText = this.getSelectedText(editor); 527 | var resultText = "> " + selectedText.content.split('\n').join("\n> "); 528 | editor.replaceRange(resultText, selectedText.start, selectedText.end); 529 | }; 530 | shortcutsExtender.prototype.shortcutLeftSquareBracket = function () { 531 | var _a; 532 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 533 | if (editor == null) { 534 | return; 535 | } 536 | var selectedText = editor.somethingSelected() 537 | ? editor.getSelection() 538 | : false; 539 | if (selectedText) { 540 | editor.replaceSelection("[[".concat(selectedText, "]]")); 541 | } 542 | else 543 | editor.replaceSelection("["); 544 | }; 545 | shortcutsExtender.prototype.shortcutRightSquareBracket = function () { 546 | var _a; 547 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 548 | if (editor == null) { 549 | return; 550 | } 551 | editor.somethingSelected() 552 | ? editor.getSelection() 553 | : false; 554 | editor.replaceSelection("]"); 555 | }; 556 | shortcutsExtender.prototype.shortcutPyCode = function () { 557 | var _a; 558 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 559 | if (editor == null) { 560 | return; 561 | } 562 | var selectedText = editor.somethingSelected() 563 | ? editor.getSelection() 564 | : false; 565 | if (selectedText) { 566 | editor.replaceSelection("```py\n".concat(selectedText, "\n```")); 567 | } 568 | else 569 | editor.replaceSelection("`"); 570 | }; 571 | shortcutsExtender.prototype.shortcutCodeFences = function () { 572 | var _a; 573 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 574 | if (editor == null) { 575 | return; 576 | } 577 | var selectedText = editor.somethingSelected() 578 | ? editor.getSelection() 579 | : false; 580 | if (selectedText) { 581 | editor.replaceSelection("`".concat(selectedText, "`")); 582 | } 583 | else 584 | editor.replaceSelection("`"); 585 | }; 586 | shortcutsExtender.prototype.shortcutToggleCodeBlock = function () { 587 | var _a; 588 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 589 | if (editor == null) { 590 | return; 591 | } 592 | var selectedText = editor.somethingSelected() ? editor.getSelection() : ""; 593 | var startCursor = editor.getCursor('from'); 594 | var firstLine = editor.getLine(startCursor.line); 595 | var endCursor = editor.getCursor('to'); 596 | var lastLine = editor.getLine(endCursor.line); 597 | // If the selections starts with ```, then we should remove the code block. 598 | var isCodeBlock = firstLine.startsWith("```") && lastLine.endsWith("```") 599 | && selectedText.length >= 6; 600 | if (isCodeBlock) { 601 | // Position of first non-whitespace 602 | var textStartPos = selectedText.search("\\s\\S") + 1; 603 | if (textStartPos < 0) { 604 | textStartPos = 3; 605 | } 606 | // Remove the code block formatting. 607 | var endPos = selectedText.length - 3; 608 | var innerText = selectedText.substring(textStartPos, endPos); 609 | editor.replaceSelection(innerText); 610 | } 611 | else { 612 | editor.replaceSelection("```\n".concat(selectedText, "\n```")); 613 | startCursor.ch = 3; // Move cursor after ``` 614 | editor.setCursor(startCursor); 615 | } 616 | }; 617 | shortcutsExtender.prototype.shortcutRightCurlyBracket = function () { 618 | var _a; 619 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 620 | if (editor == null) { 621 | return; 622 | } 623 | editor.somethingSelected() 624 | ? editor.getSelection() 625 | : false; 626 | editor.replaceSelection("}"); 627 | }; 628 | shortcutsExtender.prototype.shortcutLeftCurlyBracket = function () { 629 | var _a; 630 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 631 | if (editor == null) { 632 | return; 633 | } 634 | var selectedText = editor.somethingSelected() 635 | ? editor.getSelection() 636 | : false; 637 | if (selectedText) { 638 | editor.replaceSelection("{".concat(selectedText, "}")); 639 | } 640 | else 641 | editor.replaceSelection("{"); 642 | }; 643 | shortcutsExtender.prototype.shortcutVerticalLine = function () { 644 | var _a; 645 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 646 | if (editor == null) { 647 | return; 648 | } 649 | editor.somethingSelected() 650 | ? editor.getSelection() 651 | : false; 652 | editor.replaceSelection("|"); 653 | }; 654 | shortcutsExtender.prototype.shortcutListItems = function () { 655 | var _a; 656 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 657 | if (editor == null) { 658 | return; 659 | } 660 | var selectedText = this.getSelectedText(editor); 661 | var resultText = "- " + selectedText.content.split('\n').join("\n- "); 662 | var resultTextCheck = resultText; 663 | while (resultTextCheck.search("- - ") >= 0) { 664 | resultTextCheck = resultTextCheck.replace("- - ", " - "); 665 | } 666 | while (resultTextCheck.search("- ") >= 0) { 667 | resultTextCheck = resultTextCheck.replace("- ", " - "); 668 | } 669 | while (resultTextCheck.search("- - ") >= 0) { 670 | resultTextCheck = resultTextCheck.replace("- - ", " - "); 671 | } 672 | editor.replaceRange(resultTextCheck, selectedText.start, selectedText.end); 673 | }; 674 | shortcutsExtender.prototype.removeFormatSymbolsFromStr = function (line) { 675 | var _a; 676 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 677 | if (editor == null) { 678 | return; 679 | } 680 | // Remove symbols we don't want at the beginning of the line. 681 | while (line.substring(0, 2) == "##") { 682 | line = line.replace("##", "#"); 683 | } 684 | while (line.substring(0, 2) == "# ") { 685 | line = line.substr(2); 686 | } 687 | while (line.substring(0, 2) == "> ") { 688 | line = line.substr(2); 689 | } 690 | while (line.substring(0, 2) == " ") { 691 | line = line.replace(" ", " "); 692 | } 693 | while (line.substring(0, 3) == " - ") { 694 | line = line.substr(3); 695 | } 696 | while (line.substring(0, 2) == "- ") { 697 | line = line.substr(2); 698 | } 699 | var re_digits = /^\d\.\s/; 700 | line = line.replace(re_digits, ""); 701 | return line; 702 | }; 703 | shortcutsExtender.prototype.addHeadingToStr = function (line, headingLevel) { 704 | var space = " "; 705 | if (headingLevel == 0) { 706 | space = ""; 707 | } 708 | return "#".repeat(headingLevel) + space + line; 709 | }; 710 | shortcutsExtender.prototype.shortcutHeaderN = function (headingLevel) { 711 | var _a; 712 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 713 | if (editor == null) { 714 | return; 715 | } 716 | // Apply heading level to each line. 717 | var selections = editor.listSelections(); 718 | for (var i = 0; i < selections.length; i++) { 719 | this.shortcutHeaderNSingleSelection(headingLevel, selections[i]); 720 | } 721 | // setSelections is called to preserve the location of each cursor relative 722 | // to the end of the line. 723 | editor.setSelections(selections); 724 | }; 725 | // shortcutHeaderNSingleSelection sets all lines in the selection to the 726 | // desired heading level. selection is also updated to maintain the cursor 727 | // position relative to the end of the line. 728 | shortcutsExtender.prototype.shortcutHeaderNSingleSelection = function (headingLevel, selection) { 729 | var _a; 730 | var editor = (_a = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView)) === null || _a === void 0 ? void 0 : _a.editor; 731 | if (editor == null) { 732 | return; 733 | } 734 | // Save anchor/head distance from end. 735 | var anchorDistFromEnd = editor.getLine(selection.anchor.line).length - selection.anchor.ch; 736 | var headDistFromEnd = editor.getLine(selection.head.line).length - selection.head.ch; 737 | // Get from and to line numbers. 738 | var fromLine = selection.anchor.line; 739 | var toLine = selection.head.line; 740 | var increment = fromLine <= toLine ? 1 : -1; 741 | // For each line in the selection, set the heading level. 742 | var lineNum = fromLine; 743 | while (true) { 744 | // Update the current line. 745 | var line = editor.getLine(lineNum); 746 | line = this.removeFormatSymbolsFromStr(line); 747 | line = this.addHeadingToStr(line, headingLevel); 748 | editor.setLine(lineNum, line); 749 | // Move to next line if not done. 750 | if (lineNum == toLine) { 751 | break; 752 | } 753 | lineNum += increment; 754 | } 755 | // Preserve anchor/head locations relative to line end. 756 | selection.anchor.ch = editor.getLine(selection.anchor.line).length - anchorDistFromEnd; 757 | selection.head.ch = editor.getLine(selection.head.line).length - headDistFromEnd; 758 | }; 759 | return shortcutsExtender; 760 | }(obsidian.Plugin)); 761 | 762 | module.exports = shortcutsExtender; 763 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm1haW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH1cclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9KTtcclxufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBvW2syXSA9IG1ba107XHJcbn0pO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheXMoKSB7XHJcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcclxuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgcltrXSA9IGFbal07XHJcbiAgICByZXR1cm4gcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20sIHBhY2spIHtcclxuICAgIGlmIChwYWNrIHx8IGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIGZvciAodmFyIGkgPSAwLCBsID0gZnJvbS5sZW5ndGgsIGFyOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKGFyIHx8ICEoaSBpbiBmcm9tKSkge1xyXG4gICAgICAgICAgICBpZiAoIWFyKSBhciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20sIDAsIGkpO1xyXG4gICAgICAgICAgICBhcltpXSA9IGZyb21baV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvLmNvbmNhdChhciB8fCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tKSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlmIChnW25dKSBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiByZXN1bWUobiwgdikgeyB0cnkgeyBzdGVwKGdbbl0odikpOyB9IGNhdGNoIChlKSB7IHNldHRsZShxWzBdWzNdLCBlKTsgfSB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKHIpIHsgci52YWx1ZSBpbnN0YW5jZW9mIF9fYXdhaXQgPyBQcm9taXNlLnJlc29sdmUoci52YWx1ZS52KS50aGVuKGZ1bGZpbGwsIHJlamVjdCkgOiBzZXR0bGUocVswXVsyXSwgcik7IH1cclxuICAgIGZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHsgcmVzdW1lKFwibmV4dFwiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHJlamVjdCh2YWx1ZSkgeyByZXN1bWUoXCJ0aHJvd1wiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShmLCB2KSB7IGlmIChmKHYpLCBxLnNoaWZ0KCksIHEubGVuZ3RoKSByZXN1bWUocVswXVswXSwgcVswXVsxXSk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNEZWxlZ2F0b3Iobykge1xyXG4gICAgdmFyIGksIHA7XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIsIGZ1bmN0aW9uIChlKSB7IHRocm93IGU7IH0pLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuLCBmKSB7IGlbbl0gPSBvW25dID8gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIChwID0gIXApID8geyB2YWx1ZTogX19hd2FpdChvW25dKHYpKSwgZG9uZTogbiA9PT0gXCJyZXR1cm5cIiB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XHJcbiAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgcmV0dXJuIGNvb2tlZDtcclxufTtcclxuXHJcbnZhciBfX3NldE1vZHVsZURlZmF1bHQgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBcImRlZmF1bHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdiB9KTtcclxufSkgOiBmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBvW1wiZGVmYXVsdFwiXSA9IHY7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChrICE9PSBcImRlZmF1bHRcIiAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgX19jcmVhdGVCaW5kaW5nKHJlc3VsdCwgbW9kLCBrKTtcclxuICAgIF9fc2V0TW9kdWxlRGVmYXVsdChyZXN1bHQsIG1vZCk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnREZWZhdWx0KG1vZCkge1xyXG4gICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBkZWZhdWx0OiBtb2QgfTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRHZXQocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcclxufVxyXG4iLCJpbXBvcnQgeyBNYXJrZG93blZpZXcsIFBsdWdpbiwgRWRpdG9yU2VsZWN0aW9uLCBFZGl0b3IgfSBmcm9tIFwib2JzaWRpYW5cIjtcclxuXHJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIHNob3J0Y3V0c0V4dGVuZGVyIGV4dGVuZHMgUGx1Z2luIHtcclxuICBhc3luYyBvbmxvYWQoKSB7XHJcbiAgICBjb25zb2xlLmxvZyh0aGlzLmFwcCk7XHJcblxyXG4gICAgdGhpcy5hZGRDb21tYW5kKHtcclxuICAgICAgaWQ6IFwic2hvcnRjdXQtZXhjbGFtYXRpb24tbWFya1wiLFxyXG4gICAgICBuYW1lOiBcIlNob3J0Y3V0IGZvciAhIHN5bWJvbFwiLFxyXG4gICAgICBjYWxsYmFjazogKCkgPT4gdGhpcy5zaG9ydGN1dEV4Y2xhbWF0aW9uTWFyaygpLFxyXG4gICAgICBob3RrZXlzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbW9kaWZpZXJzOiBbXCJBbHRcIl0sXHJcbiAgICAgICAgICBrZXk6IFwiMVwiLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIF0sXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmFkZENvbW1hbmQoe1xyXG4gICAgICBpZDogXCJzaG9ydGN1dC1BdFwiLFxyXG4gICAgICBuYW1lOiBcIlNob3J0Y3V0IGZvciBAIHN5bWJvbFwiLFxyXG4gICAgICBjYWxsYmFjazogKCkgPT4gdGhpcy5zaG9ydGN1dEF0KCksXHJcbiAgICAgIGhvdGtleXM6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiXSxcclxuICAgICAgICAgIGtleTogXCIyXCIsXHJcbiAgICAgICAgfSxcclxuICAgICAgXSxcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuYWRkQ29tbWFuZCh7XHJcbiAgICAgIGlkOiBcInNob3J0Y3V0LWhhc2hcIixcclxuICAgICAgbmFtZTogXCJTaG9ydGN1dCBmb3IgIyBzeW1ib2xcIixcclxuICAgICAgY2FsbGJhY2s6ICgpID0+IHRoaXMuc2hvcnRjdXRIYXNoKCksXHJcbiAgICAgIGhvdGtleXM6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiXSxcclxuICAgICAgICAgIGtleTogXCIzXCIsXHJcbiAgICAgICAgfSxcclxuICAgICAgXSxcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuYWRkQ29tbWFuZCh7XHJcbiAgICAgIGlkOiBcInNob3J0Y3V0LWRvbGxhclwiLFxyXG4gICAgICBuYW1lOiBcIlNob3J0Y3V0IGZvciAkIHN5bWJvbFwiLFxyXG4gICAgICBjYWxsYmFjazogKCkgPT4gdGhpcy5zaG9ydGN1dERvbGxhcigpLFxyXG4gICAgICBob3RrZXlzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbW9kaWZpZXJzOiBbXCJBbHRcIl0sXHJcbiAgICAgICAgICBrZXk6IFwiNFwiLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIF0sXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmFkZENvbW1hbmQoe1xyXG4gICAgICBpZDogXCJzaG9ydGN1dC1wZXJjZW50XCIsXHJcbiAgICAgIG5hbWU6IFwiU2hvcnRjdXQgZm9yICUgc3ltYm9sXCIsXHJcbiAgICAgIGNhbGxiYWNrOiAoKSA9PiB0aGlzLnNob3J0Y3V0UGVyY2VudCgpLFxyXG4gICAgICBob3RrZXlzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbW9kaWZpZXJzOiBbXCJBbHRcIl0sXHJcbiAgICAgICAgICBrZXk6IFwiNVwiLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIF0sXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmFkZENvbW1hbmQoe1xyXG4gICAgICBpZDogXCJzaG9ydGN1dC1jaXJjdW1mbGV4XCIsXHJcbiAgICAgIG5hbWU6IFwiU2hvcnRjdXQgZm9yIF4gc3ltYm9sXCIsXHJcbiAgICAgIGNhbGxiYWNrOiAoKSA9PiB0aGlzLnNob3J0Y3V0Q2lyY3VtZmxleCgpLFxyXG4gICAgICBob3RrZXlzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbW9kaWZpZXJzOiBbXCJBbHRcIl0sXHJcbiAgICAgICAgICBrZXk6IFwiNlwiLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIF0sXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmFkZENvbW1hbmQoe1xyXG4gICAgICBpZDogXCJzaG9ydGN1dC1hbXBlcnNhbmRcIixcclxuICAgICAgbmFtZTogXCJTaG9ydGN1dCBmb3IgJiBzeW1ib2xcIixcclxuICAgICAgY2FsbGJhY2s6ICgpID0+IHRoaXMuc2hvcnRjdXRBbXBlcnNhbmQoKSxcclxuICAgICAgaG90a2V5czogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIG1vZGlmaWVyczogW1wiQWx0XCJdLFxyXG4gICAgICAgICAga2V5OiBcIjdcIixcclxuICAgICAgICB9LFxyXG4gICAgICBdLFxyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5hZGRDb21tYW5kKHtcclxuICAgICAgaWQ6IFwic2hvcnRjdXQtbGVzcy10aGFuXCIsXHJcbiAgICAgIG5hbWU6IFwiU2hvcnRjdXQgZm9yIDwgc3ltYm9sXCIsXHJcbiAgICAgIGNhbGxiYWNrOiAoKSA9PiB0aGlzLnNob3J0Y3V0TGVzc1RoYW4oKSxcclxuICAgICAgaG90a2V5czogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIG1vZGlmaWVyczogW1wiQWx0XCJdLFxyXG4gICAgICAgICAga2V5OiBcItCxXCIsXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiXSxcclxuICAgICAgICAgIGtleTogXCIsXCIsXHJcbiAgICAgICAgfSxcclxuICAgICAgXSxcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuYWRkQ29tbWFuZCh7XHJcbiAgICAgIGlkOiBcInNob3J0Y3V0LWdyZWF0ZXItdGhhblwiLFxyXG4gICAgICBuYW1lOiBcIlNob3J0Y3V0IGZvciA+IHN5bWJvbFwiLFxyXG4gICAgICBjYWxsYmFjazogKCkgPT4gdGhpcy5zaG9ydGN1dEdyZWF0ZXJUaGFuKCksXHJcbiAgICAgIGhvdGtleXM6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiXSxcclxuICAgICAgICAgIGtleTogXCLRjlwiLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbW9kaWZpZXJzOiBbXCJBbHRcIl0sXHJcbiAgICAgICAgICBrZXk6IFwiLlwiLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIF0sXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmFkZENvbW1hbmQoe1xyXG4gICAgICBpZDogXCJzaG9ydGN1dC1sZWZ0LXNxdWFyZS1icmFja2V0XCIsXHJcbiAgICAgIG5hbWU6IFwiU2hvcnRjdXQgZm9yIFsgc3ltYm9sXCIsXHJcbiAgICAgIGNhbGxiYWNrOiAoKSA9PiB0aGlzLnNob3J0Y3V0TGVmdFNxdWFyZUJyYWNrZXQoKSxcclxuICAgICAgaG90a2V5czogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIG1vZGlmaWVyczogW1wiQWx0XCJdLFxyXG4gICAgICAgICAga2V5OiBcItGFXCIsXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiXSxcclxuICAgICAgICAgIGtleTogXCJbXCIsXHJcbiAgICAgICAgfSxcclxuICAgICAgXSxcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuYWRkQ29tbWFuZCh7XHJcbiAgICAgIGlkOiBcInNob3J0Y3V0LXJpZ2h0LXNxdWFyZS1icmFja2V0XCIsXHJcbiAgICAgIG5hbWU6IFwiU2hvcnRjdXQgZm9yIF0gc3ltYm9sXCIsXHJcbiAgICAgIGNhbGxiYWNrOiAoKSA9PiB0aGlzLnNob3J0Y3V0UmlnaHRTcXVhcmVCcmFja2V0KCksXHJcbiAgICAgIGhvdGtleXM6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiXSxcclxuICAgICAgICAgIGtleTogXCLRilwiLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbW9kaWZpZXJzOiBbXCJBbHRcIl0sXHJcbiAgICAgICAgICBrZXk6IFwiXVwiLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIF0sXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmFkZENvbW1hbmQoe1xyXG4gICAgICBpZDogXCJzaG9ydGN1dC1weXRob24tY29kZVwiLFxyXG4gICAgICBuYW1lOiBcIlNob3J0Y3V0IGZvciAucHkgY29kZSBmZW5jZXNcIixcclxuICAgICAgY2FsbGJhY2s6ICgpID0+IHRoaXMuc2hvcnRjdXRQeUNvZGUoKSxcclxuICAgICAgaG90a2V5czogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIG1vZGlmaWVyczogW1wiQWx0XCIsIFwiU2hpZnRcIl0sXHJcbiAgICAgICAgICBrZXk6IFwi0ZFcIixcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIG1vZGlmaWVyczogW1wiQWx0XCIsIFwiU2hpZnRcIl0sXHJcbiAgICAgICAgICBrZXk6IFwiflwiLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIF0sXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmFkZENvbW1hbmQoe1xyXG4gICAgICBpZDogXCJzaG9ydGN1dC1jb2RlXCIsXHJcbiAgICAgIG5hbWU6IFwiU2hvcnRjdXQgZm9yIGNvZGUgZmVuY2VzIChgKVwiLFxyXG4gICAgICBjYWxsYmFjazogKCkgPT4gdGhpcy5zaG9ydGN1dENvZGVGZW5jZXMoKSxcclxuICAgICAgaG90a2V5czogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIG1vZGlmaWVyczogW1wiQWx0XCJdLFxyXG4gICAgICAgICAga2V5OiBcItGRXCIsXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiXSxcclxuICAgICAgICAgIGtleTogXCJgXCIsXHJcbiAgICAgICAgfSxcclxuICAgICAgXSxcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuYWRkQ29tbWFuZCh7XHJcbiAgICAgIGlkOiBcInNob3J0Y3V0LWNvZGUtYmxvY2tcIixcclxuICAgICAgbmFtZTogXCJTaG9ydGN1dCBmb3IgdG9nZ2xpbmcgYSBjb2RlIGJsb2NrXCIsXHJcbiAgICAgIGNhbGxiYWNrOiAoKSA9PiB0aGlzLnNob3J0Y3V0VG9nZ2xlQ29kZUJsb2NrKCksXHJcbiAgICAgIGhvdGtleXM6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkN0cmxcIl0sXHJcbiAgICAgICAgICBrZXk6IFwiYFwiLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIF0sXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmFkZENvbW1hbmQoe1xyXG4gICAgICBpZDogXCJzaG9ydGN1dC1sZWZ0LWN1cmx5LWJyYWNrZXRcIixcclxuICAgICAgbmFtZTogXCJTaG9ydGN1dCBmb3IgeyBzeW1ib2xcIixcclxuICAgICAgY2FsbGJhY2s6ICgpID0+IHRoaXMuc2hvcnRjdXRMZWZ0Q3VybHlCcmFja2V0KCksXHJcbiAgICAgIGhvdGtleXM6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiLCBcIlNoaWZ0XCJdLFxyXG4gICAgICAgICAga2V5OiBcItGFXCIsXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiLCBcIlNoaWZ0XCJdLFxyXG4gICAgICAgICAga2V5OiBcIntcIixcclxuICAgICAgICB9LFxyXG4gICAgICBdLFxyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5hZGRDb21tYW5kKHtcclxuICAgICAgaWQ6IFwic2hvcnRjdXQtcmlnaHQtY3VybHktYnJhY2tldFwiLFxyXG4gICAgICBuYW1lOiBcIlNob3J0Y3V0IGZvciB9IHN5bWJvbFwiLFxyXG4gICAgICBjYWxsYmFjazogKCkgPT4gdGhpcy5zaG9ydGN1dFJpZ2h0Q3VybHlCcmFja2V0KCksXHJcbiAgICAgIGhvdGtleXM6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiLCBcIlNoaWZ0XCJdLFxyXG4gICAgICAgICAga2V5OiBcItGKXCIsXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiLCBcIlNoaWZ0XCJdLFxyXG4gICAgICAgICAga2V5OiBcIn1cIixcclxuICAgICAgICB9LFxyXG4gICAgICBdLFxyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5hZGRDb21tYW5kKHtcclxuICAgICAgaWQ6IFwic2hvcnRjdXQtVmVydGljYWwtTGluZVwiLFxyXG4gICAgICBuYW1lOiBcIlNob3J0Y3V0IGZvciB8IHN5bWJvbFwiLFxyXG4gICAgICBjYWxsYmFjazogKCkgPT4gdGhpcy5zaG9ydGN1dFZlcnRpY2FsTGluZSgpLFxyXG4gICAgICBob3RrZXlzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbW9kaWZpZXJzOiBbXCJBbHRcIiwgXCJTaGlmdFwiXSxcclxuICAgICAgICAgIGtleTogXCJ8XCIsXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkFsdFwiLCBcIlNoaWZ0XCJdLFxyXG4gICAgICAgICAga2V5OiBcIlxcL1wiLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIF0sXHJcbiAgICB9KTtcclxuXHJcbiAgdGhpcy5hZGRDb21tYW5kKHtcclxuICAgICAgaWQ6IFwic2hvcnRjdXQtbGlzdC1pdGVtc1wiLFxyXG4gICAgICBuYW1lOiBcIkNyZWF0aW5nIGxpc3QgaXRlbSBmcm9tIHRleHRcIixcclxuICAgICAgY2FsbGJhY2s6ICgpID0+IHRoaXMuc2hvcnRjdXRMaXN0SXRlbXMoKSxcclxuICAgICAgaG90a2V5czogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIG1vZGlmaWVyczogW1wiQWx0XCJdLFxyXG4gICAgICAgICAga2V5OiBcIi1cIixcclxuICAgICAgICB9LFxyXG4gICAgICBdLFxyXG4gICAgfSk7XHJcblxyXG4gIHRoaXMuYWRkQ29tbWFuZCh7XHJcbiAgICAgIGlkOiBcImhlYWRpbmctMVwiLFxyXG4gICAgICBuYW1lOiBcImxpbmUgaW50byBsZXZlbCAxIGhlYWRpbmdcIixcclxuICAgICAgY2FsbGJhY2s6ICgpID0+IHRoaXMuc2hvcnRjdXRIZWFkZXJOKDEpLFxyXG4gICAgICBob3RrZXlzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbW9kaWZpZXJzOiBbXCJDdHJsXCJdLFxyXG4gICAgICAgICAga2V5OiBcIjFcIixcclxuICAgICAgICB9LFxyXG4gICAgICBdLFxyXG4gICAgfSk7XHJcblxyXG4gIHRoaXMuYWRkQ29tbWFuZCh7XHJcbiAgICAgIGlkOiBcImhlYWRpbmctMlwiLFxyXG4gICAgICBuYW1lOiBcImxpbmUgaW50byBsZXZlbCAyIGhlYWRpbmdcIixcclxuICAgICAgY2FsbGJhY2s6ICgpID0+IHRoaXMuc2hvcnRjdXRIZWFkZXJOKDIpLFxyXG4gICAgICBob3RrZXlzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbW9kaWZpZXJzOiBbXCJDdHJsXCJdLFxyXG4gICAgICAgICAga2V5OiBcIjJcIixcclxuICAgICAgICB9LFxyXG4gICAgICBdLFxyXG4gICAgfSk7XHJcblxyXG4gIHRoaXMuYWRkQ29tbWFuZCh7XHJcbiAgICAgIGlkOiBcImhlYWRpbmctM1wiLFxyXG4gICAgICBuYW1lOiBcImxpbmUgaW50byBsZXZlbCAzIGhlYWRpbmdcIixcclxuICAgICAgY2FsbGJhY2s6ICgpID0+IHRoaXMuc2hvcnRjdXRIZWFkZXJOKDMpLFxyXG4gICAgICBob3RrZXlzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbW9kaWZpZXJzOiBbXCJDdHJsXCJdLFxyXG4gICAgICAgICAga2V5OiBcIjNcIixcclxuICAgICAgICB9LFxyXG4gICAgICBdLFxyXG4gICAgfSk7XHJcblxyXG4gIHRoaXMuYWRkQ29tbWFuZCh7XHJcbiAgICAgIGlkOiBcImhlYWRpbmctNFwiLFxyXG4gICAgICBuYW1lOiBcImxpbmUgaW50byBsZXZlbCA0IGhlYWRpbmdcIixcclxuICAgICAgY2FsbGJhY2s6ICgpID0+IHRoaXMuc2hvcnRjdXRIZWFkZXJOKDQpLFxyXG4gICAgICBob3RrZXlzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbW9kaWZpZXJzOiBbXCJDdHJsXCJdLFxyXG4gICAgICAgICAga2V5OiBcIjRcIixcclxuICAgICAgICB9LFxyXG4gICAgICBdLFxyXG4gICAgfSk7XHJcblxyXG4gIHRoaXMuYWRkQ29tbWFuZCh7XHJcbiAgICAgIGlkOiBcImhlYWRpbmctNVwiLFxyXG4gICAgICBuYW1lOiBcImxpbmUgaW50byBsZXZlbCA1IGhlYWRpbmdcIixcclxuICAgICAgY2FsbGJhY2s6ICgpID0+IHRoaXMuc2hvcnRjdXRIZWFkZXJOKDUpLFxyXG4gICAgICBob3RrZXlzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbW9kaWZpZXJzOiBbXCJDdHJsXCJdLFxyXG4gICAgICAgICAga2V5OiBcIjVcIixcclxuICAgICAgICB9LFxyXG4gICAgICBdLFxyXG4gICAgfSk7XHJcblxyXG4gIHRoaXMuYWRkQ29tbWFuZCh7XHJcbiAgICAgIGlkOiBcImhlYWRpbmctNlwiLFxyXG4gICAgICBuYW1lOiBcImxpbmUgaW50byBsZXZlbCA2IGhlYWRpbmdcIixcclxuICAgICAgY2FsbGJhY2s6ICgpID0+IHRoaXMuc2hvcnRjdXRIZWFkZXJOKDYpLFxyXG4gICAgICBob3RrZXlzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgbW9kaWZpZXJzOiBbXCJDdHJsXCJdLFxyXG4gICAgICAgICAga2V5OiBcIjZcIixcclxuICAgICAgICB9LFxyXG4gICAgICBdLFxyXG4gICAgfSk7XHJcblxyXG4gIHRoaXMuYWRkQ29tbWFuZCh7XHJcbiAgICAgIGlkOiBcImhlYWRpbmctMFwiLFxyXG4gICAgICBuYW1lOiBcImNsZWFyaW5nIG9mIHRleHQgZm9ybWF0dGluZ1wiLFxyXG4gICAgICBjYWxsYmFjazogKCkgPT4gdGhpcy5zaG9ydGN1dEhlYWRlck4oMCksXHJcbiAgICAgIGhvdGtleXM6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBtb2RpZmllcnM6IFtcIkN0cmxcIl0sXHJcbiAgICAgICAgICBrZXk6IFwiMFwiLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIF0sXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGdldFNlbGVjdGVkVGV4dChlZGl0b3I6IEVkaXRvcikge1xyXG4gIC8vdGhhbmtzIHRvIHVzZXIgXCJBcmdlbnRpbmEgT3J0ZWdhIFPDoWluelwiIGZyb20gdGhlIE9ic2lkaWFuIGNvbW11bml0eSBmb3IgdGhpcyBmZWF0dXJlXHJcbiAgLy9Gb3IgYSBsb25nIHRpbWUgSSB0cmllZCB0byBkbyB3aXRob3V0IHN1Y2ggYW4gYXBwcm9hY2gsIHdoaWNoIHJlc3VsdGVkIGluIHNldmVyYWwgYnVncyBhbmQgdGhlIGltcG9zc2liaWxpdHkgb2YgZml4aW5nIHRoZW0gd2l0aCBub24tY3J1dGNoZXNcclxuICAgIGlmIChlZGl0b3Iuc29tZXRoaW5nU2VsZWN0ZWQoKSkge1xyXG4gICAgICBsZXQgY3Vyc29yU3RhcnQgPSBlZGl0b3IuZ2V0Q3Vyc29yKCdmcm9tJyk7XHJcbiAgICAgIGxldCBjdXJzb3JFbmQgPSBlZGl0b3IuZ2V0Q3Vyc29yKCd0bycpO1xyXG4gICAgICBsZXQgY29udGVudCA9IGVkaXRvci5nZXRSYW5nZShcclxuICAgICAgICB7IGxpbmU6IGN1cnNvclN0YXJ0LmxpbmUsIGNoOiAwIH0sXHJcbiAgICAgICAgeyBsaW5lOiBjdXJzb3JFbmQubGluZSwgY2g6IGVkaXRvci5nZXRMaW5lKGN1cnNvckVuZC5saW5lKS5sZW5ndGggfVxyXG4gICAgICApO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHN0YXJ0OiB7IGxpbmU6IGN1cnNvclN0YXJ0LmxpbmUsIGNoOiAwIH0sXHJcbiAgICAgICAgZW5kOiB7XHJcbiAgICAgICAgICBsaW5lOiBjdXJzb3JFbmQubGluZSxcclxuICAgICAgICAgIGNoOiBlZGl0b3IuZ2V0TGluZShjdXJzb3JFbmQubGluZSkubGVuZ3RoLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgY29udGVudDogY29udGVudCxcclxuICAgICAgfTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIFRvZ2dsZSB0aGUgdG9kbyBpbiB0aGUgbGluZVxyXG4gICAgICB2YXIgbGluZU5yID0gZWRpdG9yLmdldEN1cnNvcigpLmxpbmU7XHJcbiAgICAgIHZhciBjb250ZW50cyA9IGVkaXRvci5nZXREb2MoKS5nZXRMaW5lKGxpbmVOcik7XHJcbiAgICAgIGxldCBjdXJzb3JTdGFydCA9IHtcclxuICAgICAgICBsaW5lOiBsaW5lTnIsXHJcbiAgICAgICAgY2g6IDAsXHJcbiAgICAgIH07XHJcbiAgICAgIGxldCBjdXJzb3JFbmQgPSB7XHJcbiAgICAgICAgbGluZTogbGluZU5yLFxyXG4gICAgICAgIGNoOiBjb250ZW50cy5sZW5ndGgsXHJcbiAgICAgIH07XHJcbiAgICAgIGxldCBjb250ZW50ID0gZWRpdG9yLmdldFJhbmdlKGN1cnNvclN0YXJ0LCBjdXJzb3JFbmQpO1xyXG4gICAgICByZXR1cm4geyBzdGFydDogY3Vyc29yU3RhcnQsIGVuZDogY3Vyc29yRW5kLCBjb250ZW50OiBjb250ZW50IH07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzaG9ydGN1dEV4Y2xhbWF0aW9uTWFyaygpOiB2b2lkIHtcclxuICAgIGxldCBlZGl0b3IgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpPy5lZGl0b3I7XHJcbiAgICBpZiAoZWRpdG9yID09IG51bGwpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgbGV0IHNlbGVjdGVkVGV4dCA9IGVkaXRvci5zb21ldGhpbmdTZWxlY3RlZCgpXHJcbiAgICAgID8gZWRpdG9yLmdldFNlbGVjdGlvbigpXHJcbiAgICAgIDogZmFsc2U7XHJcbiAgICBlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgXFwhYCk7XHJcbiAgfVxyXG5cclxuICBzaG9ydGN1dEF0KCk6IHZvaWQge1xyXG4gICAgbGV0IGVkaXRvciA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldyk/LmVkaXRvcjtcclxuICAgIGlmIChlZGl0b3IgPT0gbnVsbCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBsZXQgc2VsZWN0ZWRUZXh0ID0gZWRpdG9yLnNvbWV0aGluZ1NlbGVjdGVkKClcclxuICAgICAgPyBlZGl0b3IuZ2V0U2VsZWN0aW9uKClcclxuICAgICAgOiBmYWxzZTtcclxuICAgIGVkaXRvci5yZXBsYWNlU2VsZWN0aW9uKGBAYCk7XHJcbiAgfVxyXG5cclxuICBzaG9ydGN1dEhhc2goKTogdm9pZCB7XHJcbiAgICBsZXQgZWRpdG9yID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZWRpdG9yO1xyXG4gICAgaWYgKGVkaXRvciA9PSBudWxsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBzZWxlY3RlZFRleHQgPSBlZGl0b3Iuc29tZXRoaW5nU2VsZWN0ZWQoKVxyXG4gICAgICA/IGVkaXRvci5nZXRTZWxlY3Rpb24oKVxyXG4gICAgICA6IGZhbHNlO1xyXG4gICAgZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oYCNgKTtcclxuICB9XHJcblxyXG4gIHNob3J0Y3V0RG9sbGFyKCk6IHZvaWQge1xyXG4gICAgbGV0IGVkaXRvciA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldyk/LmVkaXRvcjtcclxuICAgIGlmIChlZGl0b3IgPT0gbnVsbCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBsZXQgc2VsZWN0ZWRUZXh0ID0gZWRpdG9yLnNvbWV0aGluZ1NlbGVjdGVkKClcclxuICAgICAgPyBlZGl0b3IuZ2V0U2VsZWN0aW9uKClcclxuICAgICAgOiBmYWxzZTtcclxuICAgIGVkaXRvci5yZXBsYWNlU2VsZWN0aW9uKGAkYCk7XHJcbiAgfVxyXG5cclxuICBzaG9ydGN1dFBlcmNlbnQoKTogdm9pZCB7XHJcbiAgICBsZXQgZWRpdG9yID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZWRpdG9yO1xyXG4gICAgaWYgKGVkaXRvciA9PSBudWxsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBzZWxlY3RlZFRleHQgPSBlZGl0b3Iuc29tZXRoaW5nU2VsZWN0ZWQoKVxyXG4gICAgICA/IGVkaXRvci5nZXRTZWxlY3Rpb24oKVxyXG4gICAgICA6IGZhbHNlO1xyXG4gICAgZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oYFxcJWApO1xyXG4gIH1cclxuXHJcbiAgc2hvcnRjdXRDaXJjdW1mbGV4KCk6IHZvaWQge1xyXG4gICAgbGV0IGVkaXRvciA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldyk/LmVkaXRvcjtcclxuICAgIGlmIChlZGl0b3IgPT0gbnVsbCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBsZXQgc2VsZWN0ZWRUZXh0ID0gZWRpdG9yLnNvbWV0aGluZ1NlbGVjdGVkKClcclxuICAgICAgPyBlZGl0b3IuZ2V0U2VsZWN0aW9uKClcclxuICAgICAgOiBmYWxzZTtcclxuICAgIGVkaXRvci5yZXBsYWNlU2VsZWN0aW9uKGBcXF5gKTtcclxuICB9XHJcblxyXG4gIHNob3J0Y3V0QW1wZXJzYW5kKCk6IHZvaWQge1xyXG4gICAgbGV0IGVkaXRvciA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVWaWV3T2ZUeXBlKE1hcmtkb3duVmlldyk/LmVkaXRvcjtcclxuICAgIGlmIChlZGl0b3IgPT0gbnVsbCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBsZXQgc2VsZWN0ZWRUZXh0ID0gZWRpdG9yLnNvbWV0aGluZ1NlbGVjdGVkKClcclxuICAgICAgPyBlZGl0b3IuZ2V0U2VsZWN0aW9uKClcclxuICAgICAgOiBmYWxzZTtcclxuICAgIGVkaXRvci5yZXBsYWNlU2VsZWN0aW9uKGBcXCZgKTtcclxuICB9XHJcblxyXG4gIHNob3J0Y3V0TGVzc1RoYW4oKTogdm9pZCB7XHJcbiAgICBsZXQgZWRpdG9yID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZWRpdG9yO1xyXG4gICAgaWYgKGVkaXRvciA9PSBudWxsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBzZWxlY3RlZFRleHQgPSBlZGl0b3Iuc29tZXRoaW5nU2VsZWN0ZWQoKVxyXG4gICAgICA/IGVkaXRvci5nZXRTZWxlY3Rpb24oKVxyXG4gICAgICA6IGZhbHNlO1xyXG4gICAgaWYgKHNlbGVjdGVkVGV4dCkge1xyXG4gICAgICBlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgPCR7c2VsZWN0ZWRUZXh0fT5gKTtcclxuICAgIH0gZWxzZSBlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgPGApO1xyXG4gIH1cclxuXHJcbiAgc2hvcnRjdXRHcmVhdGVyVGhhbigpOiB2b2lkIHtcclxuXHRcdGxldCBhY3RpdmVMZWFmOiBhbnkgPSB0aGlzLmFwcC53b3Jrc3BhY2UuYWN0aXZlTGVhZjtcclxuICAgIGxldCBlZGl0b3IgPSBhY3RpdmVMZWFmLnZpZXcuc291cmNlTW9kZS5jbUVkaXRvcjtcclxuICAgIGxldCBzZWxlY3RlZFRleHQgPSB0aGlzLmdldFNlbGVjdGVkVGV4dChlZGl0b3IpO1xyXG5cclxuICAgIGxldCByZXN1bHRUZXh0ID0gXCI+IFwiICsgc2VsZWN0ZWRUZXh0LmNvbnRlbnQuc3BsaXQoJ1xcbicpLmpvaW4oXCJcXG4+IFwiKTtcclxuXHRcdGVkaXRvci5yZXBsYWNlUmFuZ2UocmVzdWx0VGV4dCwgc2VsZWN0ZWRUZXh0LnN0YXJ0LCBzZWxlY3RlZFRleHQuZW5kKTtcclxuICB9XHJcblxyXG4gIHNob3J0Y3V0TGVmdFNxdWFyZUJyYWNrZXQoKTogdm9pZCB7XHJcbiAgICBsZXQgZWRpdG9yID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZWRpdG9yO1xyXG4gICAgaWYgKGVkaXRvciA9PSBudWxsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBzZWxlY3RlZFRleHQgPSBlZGl0b3Iuc29tZXRoaW5nU2VsZWN0ZWQoKVxyXG4gICAgICA/IGVkaXRvci5nZXRTZWxlY3Rpb24oKVxyXG4gICAgICA6IGZhbHNlO1xyXG4gICAgaWYgKHNlbGVjdGVkVGV4dCkge1xyXG4gICAgICBlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgW1ske3NlbGVjdGVkVGV4dH1dXWApO1xyXG4gICAgfSBlbHNlIGVkaXRvci5yZXBsYWNlU2VsZWN0aW9uKGBbYCk7XHJcbiAgfVxyXG5cclxuICBzaG9ydGN1dFJpZ2h0U3F1YXJlQnJhY2tldCgpOiB2b2lkIHtcclxuICAgIGxldCBlZGl0b3IgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpPy5lZGl0b3I7XHJcbiAgICBpZiAoZWRpdG9yID09IG51bGwpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgbGV0IHNlbGVjdGVkVGV4dCA9IGVkaXRvci5zb21ldGhpbmdTZWxlY3RlZCgpXHJcbiAgICAgID8gZWRpdG9yLmdldFNlbGVjdGlvbigpXHJcbiAgICAgIDogZmFsc2U7XHJcbiAgICBlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgXWApO1xyXG4gIH1cclxuXHJcbiAgc2hvcnRjdXRQeUNvZGUoKTogdm9pZCB7XHJcbiAgICBsZXQgZWRpdG9yID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZWRpdG9yO1xyXG4gICAgaWYgKGVkaXRvciA9PSBudWxsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBzZWxlY3RlZFRleHQgPSBlZGl0b3Iuc29tZXRoaW5nU2VsZWN0ZWQoKVxyXG4gICAgICA/IGVkaXRvci5nZXRTZWxlY3Rpb24oKVxyXG4gICAgICA6IGZhbHNlO1xyXG4gICAgaWYgKHNlbGVjdGVkVGV4dCkge1xyXG4gICAgICBlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgXFxgXFxgXFxgcHlcXG4ke3NlbGVjdGVkVGV4dH1cXG5cXGBcXGBcXGBgKTtcclxuICAgIH0gZWxzZSBlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgXFxgYCk7XHJcbiAgfVxyXG5cclxuICBzaG9ydGN1dENvZGVGZW5jZXMoKTogdm9pZCB7XHJcbiAgICBsZXQgZWRpdG9yID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZWRpdG9yO1xyXG4gICAgaWYgKGVkaXRvciA9PSBudWxsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBzZWxlY3RlZFRleHQgPSBlZGl0b3Iuc29tZXRoaW5nU2VsZWN0ZWQoKVxyXG4gICAgICA/IGVkaXRvci5nZXRTZWxlY3Rpb24oKVxyXG4gICAgICA6IGZhbHNlO1xyXG4gICAgaWYgKHNlbGVjdGVkVGV4dCkge1xyXG4gICAgICBlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgXFxgJHtzZWxlY3RlZFRleHR9XFxgYCk7XHJcbiAgICB9IGVsc2UgZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oYFxcYGApO1xyXG4gIH1cclxuXHJcbiAgc2hvcnRjdXRUb2dnbGVDb2RlQmxvY2soKTogdm9pZCB7XHJcbiAgICBsZXQgZWRpdG9yID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZWRpdG9yO1xyXG4gICAgaWYgKGVkaXRvciA9PSBudWxsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBzZWxlY3RlZFRleHQgPSBlZGl0b3Iuc29tZXRoaW5nU2VsZWN0ZWQoKSA/IGVkaXRvci5nZXRTZWxlY3Rpb24oKSA6IFwiXCI7XHJcbiAgICBsZXQgc3RhcnRDdXJzb3IgPSBlZGl0b3IuZ2V0Q3Vyc29yKCdmcm9tJyk7XHJcbiAgICBsZXQgZmlyc3RMaW5lID0gZWRpdG9yLmdldExpbmUoc3RhcnRDdXJzb3IubGluZSk7XHJcbiAgICBsZXQgZW5kQ3Vyc29yID0gZWRpdG9yLmdldEN1cnNvcigndG8nKTtcclxuICAgIGxldCBsYXN0TGluZSA9IGVkaXRvci5nZXRMaW5lKGVuZEN1cnNvci5saW5lKTtcclxuXHJcbiAgICAvLyBJZiB0aGUgc2VsZWN0aW9ucyBzdGFydHMgd2l0aCBgYGAsIHRoZW4gd2Ugc2hvdWxkIHJlbW92ZSB0aGUgY29kZSBibG9jay5cclxuICAgIGxldCBpc0NvZGVCbG9jayA9IGZpcnN0TGluZS5zdGFydHNXaXRoKFwiYGBgXCIpICYmIGxhc3RMaW5lLmVuZHNXaXRoKFwiYGBgXCIpIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAmJiBzZWxlY3RlZFRleHQubGVuZ3RoID49IDY7XHJcbiAgICBpZiAoaXNDb2RlQmxvY2spIHtcclxuICAgICAgLy8gUG9zaXRpb24gb2YgZmlyc3Qgbm9uLXdoaXRlc3BhY2VcclxuICAgICAgbGV0IHRleHRTdGFydFBvcyA9IHNlbGVjdGVkVGV4dC5zZWFyY2goXCJcXFxcc1xcXFxTXCIpICsgMTtcclxuICAgICAgaWYgKHRleHRTdGFydFBvcyA8IDApIHtcclxuICAgICAgICB0ZXh0U3RhcnRQb3MgPSAzO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBSZW1vdmUgdGhlIGNvZGUgYmxvY2sgZm9ybWF0dGluZy5cclxuICAgICAgbGV0IGVuZFBvcyA9IHNlbGVjdGVkVGV4dC5sZW5ndGggLSAzO1xyXG4gICAgICBsZXQgaW5uZXJUZXh0ID0gc2VsZWN0ZWRUZXh0LnN1YnN0cmluZyh0ZXh0U3RhcnRQb3MsIGVuZFBvcylcclxuICAgICAgZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oaW5uZXJUZXh0KVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oYFxcYFxcYFxcYFxcbiR7c2VsZWN0ZWRUZXh0fVxcblxcYFxcYFxcYGApO1xyXG4gICAgICBzdGFydEN1cnNvci5jaCA9IDM7IC8vIE1vdmUgY3Vyc29yIGFmdGVyIGBgYFxyXG4gICAgICBlZGl0b3Iuc2V0Q3Vyc29yKHN0YXJ0Q3Vyc29yKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHNob3J0Y3V0UmlnaHRDdXJseUJyYWNrZXQoKTogdm9pZCB7XHJcbiAgICBsZXQgZWRpdG9yID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZWRpdG9yO1xyXG4gICAgaWYgKGVkaXRvciA9PSBudWxsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBzZWxlY3RlZFRleHQgPSBlZGl0b3Iuc29tZXRoaW5nU2VsZWN0ZWQoKVxyXG4gICAgICA/IGVkaXRvci5nZXRTZWxlY3Rpb24oKVxyXG4gICAgICA6IGZhbHNlO1xyXG4gICAgZWRpdG9yLnJlcGxhY2VTZWxlY3Rpb24oYH1gKTtcclxuICB9XHJcblxyXG4gIHNob3J0Y3V0TGVmdEN1cmx5QnJhY2tldCgpOiB2b2lkIHtcclxuICAgIGxldCBlZGl0b3IgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpPy5lZGl0b3I7XHJcbiAgICBpZiAoZWRpdG9yID09IG51bGwpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgbGV0IHNlbGVjdGVkVGV4dCA9IGVkaXRvci5zb21ldGhpbmdTZWxlY3RlZCgpXHJcbiAgICAgID8gZWRpdG9yLmdldFNlbGVjdGlvbigpXHJcbiAgICAgIDogZmFsc2U7XHJcbiAgICBpZiAoc2VsZWN0ZWRUZXh0KSB7XHJcbiAgICAgIGVkaXRvci5yZXBsYWNlU2VsZWN0aW9uKGBcXHske3NlbGVjdGVkVGV4dH1cXH1gKTtcclxuICAgIH0gZWxzZSBlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgXFx7YCk7XHJcbiAgfVxyXG5cclxuICBzaG9ydGN1dFZlcnRpY2FsTGluZSgpOiB2b2lkIHtcclxuICAgIGxldCBlZGl0b3IgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpPy5lZGl0b3I7XHJcbiAgICBpZiAoZWRpdG9yID09IG51bGwpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgbGV0IHNlbGVjdGVkVGV4dCA9IGVkaXRvci5zb21ldGhpbmdTZWxlY3RlZCgpXHJcbiAgICAgID8gZWRpdG9yLmdldFNlbGVjdGlvbigpXHJcbiAgICAgIDogZmFsc2U7XHJcbiAgICBlZGl0b3IucmVwbGFjZVNlbGVjdGlvbihgfGApO1xyXG4gIH1cclxuXHJcbiAgc2hvcnRjdXRMaXN0SXRlbXMoKTogdm9pZCB7XHJcbiAgICBsZXQgZWRpdG9yID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZWRpdG9yO1xyXG4gICAgaWYgKGVkaXRvciA9PSBudWxsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBzZWxlY3RlZFRleHQgPSB0aGlzLmdldFNlbGVjdGVkVGV4dChlZGl0b3IpO1xyXG5cclxuICAgIGxldCByZXN1bHRUZXh0ID0gXCItIFwiICsgc2VsZWN0ZWRUZXh0LmNvbnRlbnQuc3BsaXQoJ1xcbicpLmpvaW4oXCJcXG4tIFwiKTtcclxuXHJcbiAgICBsZXQgcmVzdWx0VGV4dENoZWNrID0gcmVzdWx0VGV4dDtcclxuICAgIHdoaWxlIChyZXN1bHRUZXh0Q2hlY2suc2VhcmNoKFwiLSAtIFwiKSA+PSAwKSB7XHJcbiAgICAgIHJlc3VsdFRleHRDaGVjayA9IHJlc3VsdFRleHRDaGVjay5yZXBsYWNlKFwiLSAtIFwiLCBcIlx0LSBcIik7XHJcbiAgICB9XHJcbiAgICB3aGlsZSAocmVzdWx0VGV4dENoZWNrLnNlYXJjaChcIi0gXHRcdFwiKSA+PSAwKSB7XHJcbiAgICAgIHJlc3VsdFRleHRDaGVjayA9IHJlc3VsdFRleHRDaGVjay5yZXBsYWNlKFwiLSBcdFx0XCIsIFwiXHQtIFx0XCIpO1xyXG4gICAgfVxyXG4gICAgd2hpbGUgKHJlc3VsdFRleHRDaGVjay5zZWFyY2goXCItIFx0LSBcIikgPj0gMCkge1xyXG4gICAgICByZXN1bHRUZXh0Q2hlY2sgPSByZXN1bHRUZXh0Q2hlY2sucmVwbGFjZShcIi0gXHQtIFwiLCBcIlx0XHQtIFwiKTtcclxuICAgIH1cclxuICAgIGVkaXRvci5yZXBsYWNlUmFuZ2UocmVzdWx0VGV4dENoZWNrLCBzZWxlY3RlZFRleHQuc3RhcnQsIHNlbGVjdGVkVGV4dC5lbmQpO1xyXG4gIH1cclxuXHJcbiAgcmVtb3ZlRm9ybWF0U3ltYm9sc0Zyb21TdHIobGluZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGxldCBlZGl0b3IgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpPy5lZGl0b3I7XHJcbiAgICBpZiAoZWRpdG9yID09IG51bGwpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFJlbW92ZSBzeW1ib2xzIHdlIGRvbid0IHdhbnQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgbGluZS5cclxuICAgIHdoaWxlIChsaW5lLnN1YnN0cmluZygwLDIpID09IFwiIyNcIikge1xyXG4gICAgICBsaW5lID0gbGluZS5yZXBsYWNlKFwiIyNcIiwgXCIjXCIpO1xyXG4gICAgfVxyXG4gICAgd2hpbGUgKGxpbmUuc3Vic3RyaW5nKDAsMikgPT0gXCIjIFwiKSB7XHJcbiAgICAgIGxpbmUgPSBsaW5lLnN1YnN0cigyKTtcclxuICAgIH1cclxuICAgIHdoaWxlIChsaW5lLnN1YnN0cmluZygwLDIpID09IFwiPiBcIikge1xyXG4gICAgICBsaW5lID0gbGluZS5zdWJzdHIoMik7XHJcbiAgICB9XHJcbiAgICB3aGlsZSAobGluZS5zdWJzdHJpbmcoMCwyKSA9PSBcIlx0XHRcIikge1xyXG4gICAgICBsaW5lID0gbGluZS5yZXBsYWNlKFwiXHRcdFwiLCBcIlx0XCIpO1xyXG4gICAgfVxyXG4gICAgd2hpbGUgKGxpbmUuc3Vic3RyaW5nKDAsMykgPT0gXCJcdC0gXCIpIHtcclxuICAgICAgbGluZSA9IGxpbmUuc3Vic3RyKDMpO1xyXG4gICAgfVxyXG4gICAgd2hpbGUgKGxpbmUuc3Vic3RyaW5nKDAsMikgPT0gXCItIFwiKSB7XHJcbiAgICAgIGxpbmUgPSBsaW5lLnN1YnN0cigyKTtcclxuICAgIH1cclxuICAgIHZhciByZV9kaWdpdHMgPSAvXlxcZFxcLlxccy87XHJcbiAgICBsaW5lID0gbGluZS5yZXBsYWNlKHJlX2RpZ2l0cywgXCJcIik7XHJcblxyXG4gICAgcmV0dXJuIGxpbmU7XHJcbiAgfVxyXG5cclxuICBhZGRIZWFkaW5nVG9TdHIobGluZTogc3RyaW5nLCBoZWFkaW5nTGV2ZWw6IG51bWJlcik6IHN0cmluZyB7XHJcbiAgICBsZXQgc3BhY2UgPSBcIiBcIjtcclxuICAgIGlmIChoZWFkaW5nTGV2ZWwgPT0gMCkge1xyXG4gICAgICBzcGFjZSA9IFwiXCI7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIFwiI1wiLnJlcGVhdChoZWFkaW5nTGV2ZWwpICsgc3BhY2UgKyBsaW5lO1xyXG4gIH1cclxuXHJcbiAgc2hvcnRjdXRIZWFkZXJOKGhlYWRpbmdMZXZlbDogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBsZXQgZWRpdG9yID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZWRpdG9yO1xyXG4gICAgaWYgKGVkaXRvciA9PSBudWxsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBBcHBseSBoZWFkaW5nIGxldmVsIHRvIGVhY2ggbGluZS5cclxuICAgIGxldCBzZWxlY3Rpb25zID0gZWRpdG9yLmxpc3RTZWxlY3Rpb25zKCk7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlbGVjdGlvbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgdGhpcy5zaG9ydGN1dEhlYWRlck5TaW5nbGVTZWxlY3Rpb24oaGVhZGluZ0xldmVsLCBzZWxlY3Rpb25zW2ldKVxyXG4gICAgfVxyXG5cclxuICAgIC8vIHNldFNlbGVjdGlvbnMgaXMgY2FsbGVkIHRvIHByZXNlcnZlIHRoZSBsb2NhdGlvbiBvZiBlYWNoIGN1cnNvciByZWxhdGl2ZVxyXG4gICAgLy8gdG8gdGhlIGVuZCBvZiB0aGUgbGluZS5cclxuICAgIGVkaXRvci5zZXRTZWxlY3Rpb25zKHNlbGVjdGlvbnMpO1xyXG4gIH1cclxuXHJcbiAgLy8gc2hvcnRjdXRIZWFkZXJOU2luZ2xlU2VsZWN0aW9uIHNldHMgYWxsIGxpbmVzIGluIHRoZSBzZWxlY3Rpb24gdG8gdGhlIFxyXG4gIC8vIGRlc2lyZWQgaGVhZGluZyBsZXZlbC4gc2VsZWN0aW9uIGlzIGFsc28gdXBkYXRlZCB0byBtYWludGFpbiB0aGUgY3Vyc29yXHJcbiAgLy8gcG9zaXRpb24gcmVsYXRpdmUgdG8gdGhlIGVuZCBvZiB0aGUgbGluZS5cclxuICBzaG9ydGN1dEhlYWRlck5TaW5nbGVTZWxlY3Rpb24oaGVhZGluZ0xldmVsOiBudW1iZXIsIHNlbGVjdGlvbjogRWRpdG9yU2VsZWN0aW9uKSB7XHJcbiAgICBsZXQgZWRpdG9yID0gdGhpcy5hcHAud29ya3NwYWNlLmdldEFjdGl2ZVZpZXdPZlR5cGUoTWFya2Rvd25WaWV3KT8uZWRpdG9yO1xyXG4gICAgaWYgKGVkaXRvciA9PSBudWxsKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBTYXZlIGFuY2hvci9oZWFkIGRpc3RhbmNlIGZyb20gZW5kLlxyXG4gICAgbGV0IGFuY2hvckRpc3RGcm9tRW5kID0gZWRpdG9yLmdldExpbmUoc2VsZWN0aW9uLmFuY2hvci5saW5lKS5sZW5ndGggLSBzZWxlY3Rpb24uYW5jaG9yLmNoXHJcbiAgICBsZXQgaGVhZERpc3RGcm9tRW5kID0gZWRpdG9yLmdldExpbmUoc2VsZWN0aW9uLmhlYWQubGluZSkubGVuZ3RoIC0gc2VsZWN0aW9uLmhlYWQuY2hcclxuXHJcbiAgICAvLyBHZXQgZnJvbSBhbmQgdG8gbGluZSBudW1iZXJzLlxyXG4gICAgbGV0IGZyb21MaW5lID0gc2VsZWN0aW9uLmFuY2hvci5saW5lO1xyXG4gICAgbGV0IHRvTGluZSA9IHNlbGVjdGlvbi5oZWFkLmxpbmU7XHJcbiAgICBsZXQgaW5jcmVtZW50ID0gZnJvbUxpbmUgPD0gdG9MaW5lID8gMSA6IC0xO1xyXG4gICAgLy8gRm9yIGVhY2ggbGluZSBpbiB0aGUgc2VsZWN0aW9uLCBzZXQgdGhlIGhlYWRpbmcgbGV2ZWwuXHJcbiAgICBsZXQgbGluZU51bSA9IGZyb21MaW5lO1xyXG4gICAgd2hpbGUgKHRydWUpIHtcclxuICAgICAgLy8gVXBkYXRlIHRoZSBjdXJyZW50IGxpbmUuXHJcbiAgICAgIGxldCBsaW5lID0gZWRpdG9yLmdldExpbmUobGluZU51bSk7XHJcbiAgICAgIGxpbmUgPSB0aGlzLnJlbW92ZUZvcm1hdFN5bWJvbHNGcm9tU3RyKGxpbmUpO1xyXG4gICAgICBsaW5lID0gdGhpcy5hZGRIZWFkaW5nVG9TdHIobGluZSwgaGVhZGluZ0xldmVsKTtcclxuICAgICAgZWRpdG9yLnNldExpbmUobGluZU51bSwgbGluZSk7XHJcbiAgICAgIFxyXG4gICAgICAvLyBNb3ZlIHRvIG5leHQgbGluZSBpZiBub3QgZG9uZS5cclxuICAgICAgaWYgKGxpbmVOdW0gPT0gdG9MaW5lKSB7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuICAgICAgbGluZU51bSArPSBpbmNyZW1lbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUHJlc2VydmUgYW5jaG9yL2hlYWQgbG9jYXRpb25zIHJlbGF0aXZlIHRvIGxpbmUgZW5kLlxyXG4gICAgc2VsZWN0aW9uLmFuY2hvci5jaCA9IGVkaXRvci5nZXRMaW5lKHNlbGVjdGlvbi5hbmNob3IubGluZSkubGVuZ3RoIC0gYW5jaG9yRGlzdEZyb21FbmQ7XHJcbiAgICBzZWxlY3Rpb24uaGVhZC5jaCA9IGVkaXRvci5nZXRMaW5lKHNlbGVjdGlvbi5oZWFkLmxpbmUpLmxlbmd0aCAtIGhlYWREaXN0RnJvbUVuZDtcclxuICB9XHJcbn1cclxuIl0sIm5hbWVzIjpbIk1hcmtkb3duVmlldyIsIlBsdWdpbiJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxhQUFhLEdBQUcsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ25DLElBQUksYUFBYSxHQUFHLE1BQU0sQ0FBQyxjQUFjO0FBQ3pDLFNBQVMsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLFlBQVksS0FBSyxJQUFJLFVBQVUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNwRixRQUFRLFVBQVUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUMxRyxJQUFJLE9BQU8sYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMvQixDQUFDLENBQUM7QUFDRjtBQUNPLFNBQVMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDaEMsSUFBSSxJQUFJLE9BQU8sQ0FBQyxLQUFLLFVBQVUsSUFBSSxDQUFDLEtBQUssSUFBSTtBQUM3QyxRQUFRLE1BQU0sSUFBSSxTQUFTLENBQUMsc0JBQXNCLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLCtCQUErQixDQUFDLENBQUM7QUFDbEcsSUFBSSxhQUFhLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLElBQUksU0FBUyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxFQUFFO0FBQzNDLElBQUksQ0FBQyxDQUFDLFNBQVMsR0FBRyxDQUFDLEtBQUssSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztBQUN6RixDQUFDO0FBdUNEO0FBQ08sU0FBUyxTQUFTLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFO0FBQzdELElBQUksU0FBUyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsT0FBTyxLQUFLLFlBQVksQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxVQUFVLE9BQU8sRUFBRSxFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ2hILElBQUksT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsT0FBTyxDQUFDLEVBQUUsVUFBVSxPQUFPLEVBQUUsTUFBTSxFQUFFO0FBQy9ELFFBQVEsU0FBUyxTQUFTLENBQUMsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtBQUNuRyxRQUFRLFNBQVMsUUFBUSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtBQUN0RyxRQUFRLFNBQVMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRTtBQUN0SCxRQUFRLElBQUksQ0FBQyxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxVQUFVLElBQUksRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUM5RSxLQUFLLENBQUMsQ0FBQztBQUNQLENBQUM7QUFDRDtBQUNPLFNBQVMsV0FBVyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUU7QUFDM0MsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3JILElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLE9BQU8sTUFBTSxLQUFLLFVBQVUsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDN0osSUFBSSxTQUFTLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxPQUFPLFVBQVUsQ0FBQyxFQUFFLEVBQUUsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUN0RSxJQUFJLFNBQVMsSUFBSSxDQUFDLEVBQUUsRUFBRTtBQUN0QixRQUFRLElBQUksQ0FBQyxFQUFFLE1BQU0sSUFBSSxTQUFTLENBQUMsaUNBQWlDLENBQUMsQ0FBQztBQUN0RSxRQUFRLE9BQU8sQ0FBQyxFQUFFLElBQUk7QUFDdEIsWUFBWSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztBQUN6SyxZQUFZLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDcEQsWUFBWSxRQUFRLEVBQUUs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 764 | --------------------------------------------------------------------------------