diff --git a/.gitignore b/.gitignore index e09a007..e6f558d 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,7 @@ main.js *.map # obsidian -data.json +.obsidian # Exclude macOS Finder (System Explorer) View States .DS_Store diff --git a/.prettierignore b/.prettierignore index e7c0c79..35349f3 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,3 +2,4 @@ node_modules .github package-lock.json main.js +src/quotes/quotes.ts diff --git a/LICENSE b/LICENSE index 03d2959..2fdc26c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ MIT License Copyright (c) 2023 Erica Xu +Copyright (c) 2023 Obsidian TTRPG Community and Collaborators Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/docs/Adding-animation-to-plugin-source.md b/docs/Adding-animation-to-plugin-source.md new file mode 100644 index 0000000..b5c0f1a --- /dev/null +++ b/docs/Adding-animation-to-plugin-source.md @@ -0,0 +1,314 @@ +# Adding your new animations to the plugin code + +This guide walks you step-by-step for adding your created animations into the source code. + +Each file where you need to add your additions will include commented templates to make the process easier. + +For this pages examples, I will use the following popular character: Pikachu. + +> 👿 Please DO NOT add a Pikachu animation to a public copy of this plugin. + +## 1. Adding quotes to QuoteManager.ts + +> ⚠ If you have not already added your new character's quote lines in [Quotes](Quotes.ts), do that first. You can find instructions in [Adding quotes to Granite](Adding-quotes-to-Granite.md). + +To have your characters say something within Granite, we need to tell the plugin to add its quotes. In [QuoteManager.ts](QuoteManager.ts), you will first want to import the quotes you created in [Quotes.ts](Quotes.ts). + +### Imports + +Underneath the import section, add your new character to the import list. + +**Before**: + +```ts +import GranitePlugin from './main'; +import { AnimationSourceType } from './Setting'; +import { GraniteMode, GraniteState } from './Granite'; +import { DRAKE_EXCLUSIVE_QUOTES, GEMMY_EXCLUSIVE_QUOTES, GRANITE_BASE_QUOTES, Quotes } from './quotes/Quotes'; +``` + +**After**: + +```ts +import GranitePlugin from './main'; +import { AnimationSourceType } from './Setting'; +import { GraniteMode, GraniteState } from './Granite'; +import { PIKACHU_EXCLUSIVE_QUOTES, DRAKE_EXCLUSIVE_QUOTES, GEMMY_EXCLUSIVE_QUOTES, GRANITE_BASE_QUOTES, Quotes } from './quotes/Quotes'; +``` + + +### Quotemap + +In the QuoteManager class, you will want to add your new character to the quote map. + +**Before**: + +```ts + constructor(plugin: GranitePlugin) { + this.plugin = plugin; + + this.quoteMap = { + [AnimationSourceType.GEMMY]: { + [GraniteMode.IDLE]: this.getIdleQuotes(GEMMY_EXCLUSIVE_QUOTES), + [GraniteMode.WRITING]: this.getWritingQuotes(GEMMY_EXCLUSIVE_QUOTES), + }, + [AnimationSourceType.DRAKE]: { + [GraniteMode.IDLE]: this.getIdleQuotes(DRAKE_EXCLUSIVE_QUOTES), + [GraniteMode.WRITING]: this.getWritingQuotes(DRAKE_EXCLUSIVE_QUOTES), + }, + }; +``` + +**After**: + +```ts + constructor(plugin: GranitePlugin) { + this.plugin = plugin; + + this.quoteMap = { + [AnimationSourceType.GEMMY]: { + [GraniteMode.IDLE]: this.getIdleQuotes(GEMMY_EXCLUSIVE_QUOTES), + [GraniteMode.WRITING]: this.getWritingQuotes(GEMMY_EXCLUSIVE_QUOTES), + }, + [AnimationSourceType.DRAKE]: { + [GraniteMode.IDLE]: this.getIdleQuotes(DRAKE_EXCLUSIVE_QUOTES), + [GraniteMode.WRITING]: this.getWritingQuotes(DRAKE_EXCLUSIVE_QUOTES), + }, + }; + [AnimationSourceType.PIKACHU]: { + [GraniteMode.IDLE]: this.getIdleQuotes(PIKACHU_EXCLUSIVE_QUOTES), + [GraniteMode.WRITING]: this.getWritingQuotes(PIKACHU_EXCLUSIVE_QUOTES), + }, + }; +``` + +## 2. Import your animations into Animations.ts + +To add your newly created animations into Granite to be rendered, we need to tell the plugin to process the gifs. + +### Imports + +Under the import section, we need to map a value to the animations. + +**Before**: +```ts +// Draconic Animations +import EMERGE_MOTION_DRAKE from '../animations/drake/drake_emerge.gif'; +import POP_MOTION_DRAKE from '../animations/drake/drake_pop.gif'; +import DISAPPEAR_MOTION_DRAKE from '../animations/drake/drake_disappear.gif'; +import ANGRY_MOTION_DRAKE from '../animations/drake/drake_angry.gif'; +import LOOK_MOTION_DRAKE from '../animations/drake/drake_lookAround.gif'; +import IDLE_MOTION_DRAKE from '../animations/drake/drake_idle.gif'; +import DISAPPOINT_IMG_DRAKE from '../animations/drake/drake_disappoint.gif'; +``` + +After: +```ts +// Draconic Animations +import EMERGE_MOTION_DRAKE from '../animations/PIKACHU/PIKACHU_emerge.gif'; +import POP_MOTION_DRAKE from '../animations/PIKACHU/PIKACHU_pop.gif'; +import DISAPPEAR_MOTION_DRAKE from '../animations/drake/drake_disappear.gif'; +import ANGRY_MOTION_DRAKE from '../animations/drake/drake_angry.gif'; +import LOOK_MOTION_DRAKE from '../animations/drake/drake_lookAround.gif'; +import IDLE_MOTION_DRAKE from '../animations/drake/drake_idle.gif'; +import DISAPPOINT_IMG_DRAKE from '../animations/drake/drake_disappoint.gif'; + +// Pikachu Animations +import EMERGE_MOTION_PIKACHU from '../animations/drake/drake_emerge.gif'; +import POP_MOTION_PIKACHU from '../animations/drake/drake_pop.gif'; +import DISAPPEAR_MOTION_PIKACHU from '../animations/drake/pikachu_disappear.gif'; +import ANGRY_MOTION_PIKACHU from '../animations/pikachu/pikachu_angry.gif'; +import LOOK_MOTION_PIKACHU from '../animations/pikachu/pikachu_lookAround.gif'; +import IDLE_MOTION_PIKACHU from '../animations/pikachu/pikachu_idle.gif'; +import DISAPPOINT_IMG_PIKACHU from '../animations/pikachu/pikachu_disappoint.gif'; +``` + +### Animations class + +Within the animations export class, you will want to add your animation map. + +**Before**: +```ts +// the mappings from an animation type to an actual image file for the drakeling +public readonly drakeAnimationMap: Record; +``` + +**After**: +```ts +// the mappings from an animation type to an actual image file for the pikachu +public readonly pikachuAnimationMap: Record; +// the mappings from an animation type to an actual image file for the drakeling +public readonly drakeAnimationMap: Record; +``` + + +### Animation Map + +Then further down, define the animation map. + +**Before**: + +```ts +constructor(plugin: GranitePlugin) { + this.plugin = plugin; + + this.drakeAnimationMap = { + [AnimationType.EMERGE]: EMERGE_MOTION_DRAKE, + [AnimationType.POP_MOTION]: POP_MOTION_DRAKE, + [AnimationType.DISAPPEAR_MOTION]: DISAPPEAR_MOTION_DRAKE, + [AnimationType.ANGRY_MOTION]: ANGRY_MOTION_DRAKE, + [AnimationType.LOOK_MOTION]: LOOK_MOTION_DRAKE, + [AnimationType.IDLE_MOTION]: IDLE_MOTION_DRAKE, + [AnimationType.DISAPPOINT_IMG]: DISAPPOINT_IMG_DRAKE, + }; +``` + + +**After**: + +```ts +constructor(plugin: GranitePlugin) { + this.plugin = plugin; + + this.pikachuAnimationMap = { + [AnimationType.EMERGE]: EMERGE_MOTION_PIKACHU, + [AnimationType.POP_MOTION]: POP_MOTION_PIKACHU, + [AnimationType.DISAPPEAR_MOTION]: DISAPPEAR_MOTION_PIKACHU, + [AnimationType.ANGRY_MOTION]: ANGRY_MOTION_PIKACHU, + [AnimationType.LOOK_MOTION]: LOOK_MOTION_PIKACHU, + [AnimationType.IDLE_MOTION]: IDLE_MOTION_PIKACHU, + [AnimationType.DISAPPOINT_IMG]: DISAPPOINT_IMG_PIKACHU, + }; + + this.drakeAnimationMap = { + [AnimationType.EMERGE]: EMERGE_MOTION_DRAKE, + [AnimationType.POP_MOTION]: POP_MOTION_DRAKE, + [AnimationType.DISAPPEAR_MOTION]: DISAPPEAR_MOTION_DRAKE, + [AnimationType.ANGRY_MOTION]: ANGRY_MOTION_DRAKE, + [AnimationType.LOOK_MOTION]: LOOK_MOTION_DRAKE, + [AnimationType.IDLE_MOTION]: IDLE_MOTION_DRAKE, + [AnimationType.DISAPPOINT_IMG]: DISAPPOINT_IMG_DRAKE, + }; +``` + +### Source Map + +And right below that, add your character to the source map. + +**Before**: + +```ts +this.animationSourceMap = { + [AnimationSourceType.DRAKE]: this.drakeAnimationMap, + [AnimationSourceType.GEMMY]: this.gemmyAnimationMap, +}; +``` + +**After**: + +```ts +this.animationSourceMap = { + [AnimationSourceType.PIKACHU]: this.pikachuAnimationMap, + [AnimationSourceType.DRAKE]: this.drakeAnimationMap, + [AnimationSourceType.GEMMY]: this.gemmyAnimationMap, +}; +``` + + +## 3. Update Settings.ts + +Now we need to make it so that you can toggle which character to use in your settings. + +### AnimationSourceType + +In the animation source type section, we need to define the name of the character for the animations we have loaded thus far. + +**Before**: + +```ts +export enum AnimationSourceType { + GEMMY = 'gemmy', + DRAKE = 'drake', +``` + +**After**: + +```ts +export enum AnimationSourceType { + GEMMY = 'gemmy', + DRAKE = 'drake', + PIKACHU = 'pikachu', +``` + +### PluginSettingsTab + +Now, we add the new character to the dropdown list. + +**Before**: + +```ts +.addDropdown(dropdown => + dropdown + .addOption(AnimationSourceType.GEMMY, 'Gemmy') + .addOption(AnimationSourceType.DRAKE, 'Drake') +``` + +**After**: + +```ts +.addDropdown(dropdown => + dropdown + .addOption(AnimationSourceType.GEMMY, 'Gemmy') + .addOption(AnimationSourceType.DRAKE, 'Drake') + .addOption(AnimationSourceType.PIKACHU, 'Pikachu') +``` + +## 4. Update Main.ts + +This last update will tell Granite what to load based on the settings provided. + +### Async loadsettings + +Before: + +```ts +async loadSettings() { + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + + // migrations + // @ts-ignore + if (this.settings.animationSource === 'dragon') { + this.settings.animationSource = AnimationSourceType.DRAKE; + } + // @ts-ignore + if (this.settings.animationSource === 'original') { + this.settings.animationSource = AnimationSourceType.GEMMY; + } + + await this.saveSettings(); +} +``` + + +```ts +async loadSettings() { + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + + // migrations + if (this.settings.animationSource === 'rat') { + this.settings.animationSource = AnimationSourceType.PIKACHU; + } + // @ts-ignore + if (this.settings.animationSource === 'dragon') { + this.settings.animationSource = AnimationSourceType.DRAKE; + } + // @ts-ignore + if (this.settings.animationSource === 'original') { + this.settings.animationSource = AnimationSourceType.GEMMY; + } + + await this.saveSettings(); +} +``` + + diff --git a/docs/Adding-animations-to-Granite.md b/docs/Adding-animations-to-Granite.md new file mode 100644 index 0000000..73fc04b --- /dev/null +++ b/docs/Adding-animations-to-Granite.md @@ -0,0 +1,47 @@ +# Adding animations to Granite Plugin + +This page gives the overall guidelines on what an animation needs to be to be successful in this plugin. + +## What format do these need to be in? + +All animations need to be in a `.gif` format. + +## Supported Emotes + +Granite supports a few different character emotes within the plugin. + +- Angry +- Disappear +- Disappoint +- Emerge +- Idle +- Look Around +- Pop + +## How long is each animation? + +- Angry is 1.92 seconds +- Disappear is 1.92 seconds +- Disappoint is 0.16 seconds +- Emerge is 3.84 seconds +- Idle is 7.3 seconds +- Look Around is 6.4 seconds +- Pop is 1.92 seconds + +## Where to place the animated gifs + +These animations are stored in `animations/name` where name is the name of the character. + +**Example**: As of writing this, Granite plugin has two characters: `gemmy` and `drake`. Gemmy's animations are located in `animations/gemmy` and Drake's animations are located in `animations/drake`. + +## What naming convention should I use? + +The animations need to be in lower case text. + +Additionally, the animations need to be named charactername_emote.gif, to match the emote they are for. + +Example: `gemmy_angry.gif` is the angry animation for Gemmy. + +## How do I add them to the plugin itself? + +See [Adding animations to plugin details](Adding-animation-to-plugin-source.md). diff --git a/docs/Adding-quotes-to-Granite.md b/docs/Adding-quotes-to-Granite.md new file mode 100644 index 0000000..f90fe39 --- /dev/null +++ b/docs/Adding-quotes-to-Granite.md @@ -0,0 +1,60 @@ + +# Adding quotes to Granite Plugin + +All quotes are handled in [Quotes,ts](src/quotes/Quotes.ts). +This file is a javascript array of objects, with each section controlling a certain character. + +Quotes are grouped under `Base Quotes`, and individual `Character Quotes`. +They are grouped further by `General`, `Idle`, and `Writing Mode` quotes. + +## Adding quotes to an existing character + +1. Open [Quotes.ts](src/quotes/Quotes.ts) and find the character you want to edit. +2. Determine if you are editing a general quote, idle quote, or writing mode quote. +3. In the section that you want to add your line to, use the following formatting to add your line: + +```json + `You are a background character in your own life.`, +``` + +How this may look in its `.json` file: + +```json + "general": [ + "You are a background character in your own life.", + ], +``` + + +Some rules of thumb: +- Every quote line needs to end with a comma `,`. +- Every quote line needs to be surrounded by double quotes `"`. + +## Adding a new character + +To add a new character into the quotes, you can add the following to the bottom of [Quotes.ts](src/quotes/Quotes.ts): + +**Before**: + +```ts +export const DRAKE_EXCLUSIVE_QUOTES: Quotes = { + general: [], + idle: [], + writingMode: [], +}; +``` + +**After**: + +```ts +export const DRAKE_EXCLUSIVE_QUOTES: Quotes = { + general: [], + idle: [], + writingMode: [], +}; +export const PIKACHU_EXCLUSIVE_QUOTES: Quotes = { + general: [], + idle: [], + writingMode: [], +}; +``` diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..01ad3f4 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,21 @@ +# Developing Granite plugin + +These documents go over the more advanced features of adding to and developing Granite. + +## Guides + +1. [Adding quotes to Granite](Adding-quotes-to-Granite.md) +2. [Adding animations to Granite](Adding-animations-to-Granite.md) +3. [Adding animation to plugin source files](Adding-animation-to-plugin-source.md) + +## Developer environment + +Granite is NPM enabled. You can retrieve the packages needed by using `npm -i D`. + +To auto-build the plugin while you are adding changes, you can use the following command in your terminal/IDE of choice: `npm run dev`. + +If you wish to specify a different output file for the built `main.js`, then add a `.env` file in the root directory of your fork, and add the following to the file: + +`OUTDIR="/absolute/path/to/your/vault/.obsidian/plugins/Granite"` + +This way, you can reload Obsidian and see your updated changes. You may also utilize the [Hot Reload](https://github.com/pjeby/hot-reload) to reload Obsidian for you. \ No newline at end of file diff --git a/main.js b/main.js index 257302c..0738544 100644 --- a/main.js +++ b/main.js @@ -132,6 +132,8 @@ var Animations = class { ["disappoint_ing" /* DISAPPOINT_IMG */]: gemmy_disappoint_default }; this.animationSourceMap = { + // Add your character to the animation source map, where name is your character name. + // [AnimationSourceType.NAME]: this.nameAnimationMap, ["drake" /* DRAKE */]: this.drakeAnimationMap, ["gemmy" /* GEMMY */]: this.gemmyAnimationMap }; @@ -175,40 +177,47 @@ var GRANITE_BASE_QUOTES = { "I slap the barrel with my member!... the 'barrel' open's its mouth!", "I'm not deprived, I'm depraved.", "You need a free hand to attempt a grapple", - `Careful how much you carry; the GM might actually ask you to calculate your inventory weight!`, - `Don't do that! Then we'll have to go look up the grapple rules!`, - `50 page backstory... NOPE`, - `It's astounding anyone can understand you, with all those Nat 1 Charisma rolls.`, - `The cheddar monks are here to save the day!`, - `You've been Gygaxed.`, - `STEP AWAY FROM THE PURCHASE MORE DICE BUTTON`, - `After thousands of years, I have attained my current state, while you struggle to complete this simple note.`, - `You are a background character in your own life.` + "Careful how much you carry; the GM might actually ask you to calculate your inventory weight!", + "Don't do that! Then we'll have to go look up the grapple rules!", + "50 page backstory... NOPE", + "It's astounding anyone can understand you, with all those Nat 1 Charisma rolls.", + "The cheddar monks are here to save the day!", + "You've been Gygaxed.", + "STEP AWAY FROM THE PURCHASE MORE DICE BUTTON", + "After thousands of years, I have attained my current state, while you struggle to complete this simple note.", + "You are a background character in your own life.", + "What... sorry Who is the Bard doing now?", + "DO NOT put the portable hole in the bag of holding!", + "DO NOT put the bag of holding in the portable hole!", + "If the shed's a'Rocking... RUN" ], writingMode: [ - `Player's dont take notes... maybe you should try that?`, - `Is that the best you can do? Keep writing!`, - `Write first, editor later.`, - `AI could probably write a better note...`, - `I love hearing your keyboard. Don't stop.`, - `How about we review some old notes today?`, - `Why not just use a template?`, - `Doesn't matter how much you plan... they will derail anyway!`, - `Maybe it's time to go get some water or coffee.`, - `That's not how rivers are in real-life...`, - `Anything is better than a blank page, even me. Write something!`, - `Have you given out Inspiration recently?`, - `Call me Jeeves. I. Dare. You.`, - `I cast 'Summon Bigger Fish`, - `Do you touch it?`, - `What would Matt Mercer do?`, - `To continue, please insert more credits`, - `Have you considered just... Not?` + "Player's dont take notes... maybe you should try that?", + "Is that the best you can do? Keep writing!", + "Write first, editor later.", + "AI could probably write a better note...", + "I love hearing your keyboard. Don't stop.", + "How about we review some old notes today?", + "Why not just use a template?", + "Doesn't matter how much you plan... they will derail anyway!", + "Maybe it's time to go get some water or coffee.", + "That's not how rivers are in real-life...", + "Anything is better than a blank page, even me. Write something!", + "Have you given out Inspiration recently?", + "Call me Jeeves. I. Dare. You.", + "I cast 'Summon Bigger Fish'", + "Do you touch it?", + "What would Matt Mercer do?", + "To continue, please insert more credits", + "Have you considered just... Not?", + "You can't just write 'I win'" ] }; var GEMMY_EXCLUSIVE_QUOTES = { general: [], - idle: [], + idle: [ + "You pooping?" + ], writingMode: [] }; var DRAKE_EXCLUSIVE_QUOTES = { @@ -230,6 +239,13 @@ var QuoteManager = class { ["IDLE" /* IDLE */]: this.getIdleQuotes(DRAKE_EXCLUSIVE_QUOTES), ["WRITING" /* WRITING */]: this.getWritingQuotes(DRAKE_EXCLUSIVE_QUOTES) } + // Copy and paste below to add your character's source here. + // Replace NAME with your new character's name + // + // [AnimationSourceType.NAME]: { + // [GraniteMode.IDLE]: this.getIdleQuotes(NAME_EXCLUSIVE_QUOTES), + // [GraniteMode.WRITING]: this.getWritingQuotes(NAME_EXCLUSIVE_QUOTES), + // }, }; console.log("granite | build quote map", this.quoteMap); } @@ -443,6 +459,11 @@ var GranitePlugin = class extends import_obsidian2.Plugin { console.log("granite | unload"); this.granite.disappear(); } + // Within the async, update your new character by adding them to the load list, + // where name is your character name and type is the type of creature it is. + // if (this.settings.animationSource === 'type') { + // this.settings.animationSource = AnimationSourceType.NAME; + // } async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); if (this.settings.animationSource === "dragon") { @@ -457,4 +478,4 @@ var GranitePlugin = class extends import_obsidian2.Plugin { await this.saveData(this.settings); } }; -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21haW4udHMiLCAic3JjL1NldHRpbmcudHMiLCAic3JjL0FuaW1hdGlvbnMudHMiLCAic3JjL3F1b3Rlcy9RdW90ZXMudHMiLCAic3JjL1F1b3RlTWFuYWdlci50cyIsICJzcmMvR3Jhbml0ZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHsgZGVib3VuY2UsIFBsdWdpbiB9IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCB7IEFuaW1hdGlvblNvdXJjZVR5cGUsIERFRkFVTFRfU0VUVElOR1MsIEdyYW5pdGVTZXR0aW5ncywgR3Jhbml0ZVNldHRpbmdzVGFiIH0gZnJvbSAnLi9TZXR0aW5nJztcbmltcG9ydCB7IEdyYW5pdGUgfSBmcm9tICcuL0dyYW5pdGUnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBHcmFuaXRlUGx1Z2luIGV4dGVuZHMgUGx1Z2luIHtcblx0c2V0dGluZ3M6IEdyYW5pdGVTZXR0aW5ncztcblx0Z3Jhbml0ZTogR3Jhbml0ZTtcblxuXHRhc3luYyBvbmxvYWQoKSB7XG5cdFx0Y29uc29sZS5sb2coJ2dyYW5pdGUgfCBsb2FkJyk7XG5cblx0XHRhd2FpdCB0aGlzLmxvYWRTZXR0aW5ncygpO1xuXG5cdFx0dGhpcy5ncmFuaXRlID0gbmV3IEdyYW5pdGUodGhpcyk7XG5cblx0XHR0aGlzLmFkZENvbW1hbmQoe1xuXHRcdFx0aWQ6ICdzaG93Jyxcblx0XHRcdG5hbWU6ICdTaG93IEdyYW5pdGUnLFxuXHRcdFx0Y2FsbGJhY2s6ICgpID0+IHtcblx0XHRcdFx0dGhpcy5ncmFuaXRlLmFwcGVhcigpO1xuXHRcdFx0fSxcblx0XHR9KTtcblxuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRpZDogJ2hpZGUnLFxuXHRcdFx0bmFtZTogJ0hpZGUgR3Jhbml0ZScsXG5cdFx0XHRjYWxsYmFjazogKCkgPT4ge1xuXHRcdFx0XHR0aGlzLmdyYW5pdGUuZGlzYXBwZWFyKCk7XG5cdFx0XHR9LFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcblx0XHRcdGlkOiAnZW50ZXItd3JpdGluZy1tb2RlJyxcblx0XHRcdG5hbWU6ICdFbnRlciB3cml0aW5nIG1vZGUnLFxuXHRcdFx0Y2FsbGJhY2s6ICgpID0+IHtcblx0XHRcdFx0dGhpcy5ncmFuaXRlLmVudGVyV3JpdGluZ01vZGUoKTtcblx0XHRcdH0sXG5cdFx0fSk7XG5cblx0XHR0aGlzLmFkZENvbW1hbmQoe1xuXHRcdFx0aWQ6ICdsZWF2ZS13cml0aW5nLW1vZGUnLFxuXHRcdFx0bmFtZTogJ0xlYXZlIHdyaXRpbmcgbW9kZScsXG5cdFx0XHRjYWxsYmFjazogKCkgPT4ge1xuXHRcdFx0XHR0aGlzLmdyYW5pdGUubGVhdmVXcml0aW5nTW9kZSgpO1xuXHRcdFx0fSxcblx0XHR9KTtcblxuXHRcdC8vIFRoaXMgYWRkcyBhIHNldHRpbmdzIHRhYiBzbyB0aGUgdXNlciBjYW4gY29uZmlndXJlIHZhcmlvdXMgYXNwZWN0cyBvZiB0aGUgcGx1Z2luXG5cdFx0dGhpcy5hZGRTZXR0aW5nVGFiKG5ldyBHcmFuaXRlU2V0dGluZ3NUYWIodGhpcy5hcHAsIHRoaXMpKTtcblxuXHRcdC8vIGRlYm91bmNlIGVkaXRvci1jaGFuZ2UgZXZlbnQgb24gd29ya3NwYWNlXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KFxuXHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLm9uKFxuXHRcdFx0XHQnZWRpdG9yLWNoYW5nZScsXG5cdFx0XHRcdGRlYm91bmNlKCgpID0+IHtcblx0XHRcdFx0XHR0aGlzLmdyYW5pdGUub25FZGl0b3JDaGFuZ2UoKTtcblx0XHRcdFx0fSwgNTAwKSxcblx0XHRcdCksXG5cdFx0KTtcblxuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS5vbkxheW91dFJlYWR5KCgpID0+IHRoaXMuZ3Jhbml0ZS5hcHBlYXIoKSk7XG5cdH1cblxuXHRvbnVubG9hZCgpIHtcblx0XHRjb25zb2xlLmxvZygnZ3Jhbml0ZSB8IHVubG9hZCcpO1xuXG5cdFx0dGhpcy5ncmFuaXRlLmRpc2FwcGVhcigpO1xuXHR9XG5cblx0YXN5bmMgbG9hZFNldHRpbmdzKCkge1xuXHRcdHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX1NFVFRJTkdTLCBhd2FpdCB0aGlzLmxvYWREYXRhKCkpO1xuXG5cdFx0Ly8gbWlncmF0aW9uc1xuXHRcdC8vIEB0cy1pZ25vcmVcblx0XHRpZiAodGhpcy5zZXR0aW5ncy5hbmltYXRpb25Tb3VyY2UgPT09ICdkcmFnb24nKSB7XG5cdFx0XHR0aGlzLnNldHRpbmdzLmFuaW1hdGlvblNvdXJjZSA9IEFuaW1hdGlvblNvdXJjZVR5cGUuRFJBS0U7XG5cdFx0fVxuXHRcdC8vIEB0cy1pZ25vcmVcblx0XHRpZiAodGhpcy5zZXR0aW5ncy5hbmltYXRpb25Tb3VyY2UgPT09ICdvcmlnaW5hbCcpIHtcblx0XHRcdHRoaXMuc2V0dGluZ3MuYW5pbWF0aW9uU291cmNlID0gQW5pbWF0aW9uU291cmNlVHlwZS5HRU1NWTtcblx0XHR9XG5cblx0XHRhd2FpdCB0aGlzLnNhdmVTZXR0aW5ncygpO1xuXHR9XG5cblx0YXN5bmMgc2F2ZVNldHRpbmdzKCkge1xuXHRcdGF3YWl0IHRoaXMuc2F2ZURhdGEodGhpcy5zZXR0aW5ncyk7XG5cdH1cbn1cbiIsICJpbXBvcnQgeyBBcHAsIFBsdWdpblNldHRpbmdUYWIsIFNldHRpbmcgfSBmcm9tICdvYnNpZGlhbic7XG5pbXBvcnQgR3Jhbml0ZVBsdWdpbiBmcm9tICcuL21haW4nO1xuXG5leHBvcnQgZW51bSBBbmltYXRpb25Tb3VyY2VUeXBlIHtcblx0R0VNTVkgPSAnZ2VtbXknLFxuXHREUkFLRSA9ICdkcmFrZScsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR3Jhbml0ZVNldHRpbmdzIHtcblx0Ly8gQWRkIHRoZSBhbmltYXRpb25Tb3VyY2UgcHJvcGVydHkgdG8gdGhlIHNldHRpbmdzIGludGVyZmFjZVxuXHRhbmltYXRpb25Tb3VyY2U6IEFuaW1hdGlvblNvdXJjZVR5cGU7XG5cdC8vIGhvdyBvZnRlbiBkb2VzIEdyYW5pdGUgdGFsayBpbiBpZGxlIG1vZGUsIGluIG1pbnV0ZXNcblx0aWRsZVRhbGtGcmVxdWVuY3k6IG51bWJlcjtcblx0Ly8gdGhlIG51bWJlciBvZiBtaW51dGVzIHlvdSBtdXN0IHdyaXRlIGJlZm9yZSBHcmFuaXRlIGFwcGVhcnMgdG8gbW9jayB5b3Vcblx0d3JpdGluZ01vZGVHcmFjZVBlcmlvZDogbnVtYmVyO1xufVxuXG5leHBvcnQgY29uc3QgREVGQVVMVF9TRVRUSU5HUzogR3Jhbml0ZVNldHRpbmdzID0ge1xuXHRhbmltYXRpb25Tb3VyY2U6IEFuaW1hdGlvblNvdXJjZVR5cGUuR0VNTVksXG5cdGlkbGVUYWxrRnJlcXVlbmN5OiAxLFxuXHR3cml0aW5nTW9kZUdyYWNlUGVyaW9kOiAxLFxufTtcblxuZXhwb3J0IGNsYXNzIEdyYW5pdGVTZXR0aW5nc1RhYiBleHRlbmRzIFBsdWdpblNldHRpbmdUYWIge1xuXHRwbHVnaW46IEdyYW5pdGVQbHVnaW47XG5cblx0Y29uc3RydWN0b3IoYXBwOiBBcHAsIHBsdWdpbjogR3Jhbml0ZVBsdWdpbikge1xuXHRcdHN1cGVyKGFwcCwgcGx1Z2luKTtcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcblx0fVxuXG5cdGRpc3BsYXkoKTogdm9pZCB7XG5cdFx0Y29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcblxuXHRcdGNvbnRhaW5lckVsLmVtcHR5KCk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKCdBbmltYXRpb24gU291cmNlJylcblx0XHRcdC5zZXREZXNjKCdDaG9vc2UgdGhlIHNvdXJjZSBvZiBHcmFuaXRlIGFuaW1hdGlvbnMuJylcblx0XHRcdC5hZGREcm9wZG93bihkcm9wZG93biA9PlxuXHRcdFx0XHRkcm9wZG93blxuXHRcdFx0XHRcdC5hZGRPcHRpb24oQW5pbWF0aW9uU291cmNlVHlwZS5HRU1NWSwgJ0dlbW15Jylcblx0XHRcdFx0XHQuYWRkT3B0aW9uKEFuaW1hdGlvblNvdXJjZVR5cGUuRFJBS0UsICdEcmFrZScpXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmFuaW1hdGlvblNvdXJjZSlcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgdmFsdWUgPT4ge1xuXHRcdFx0XHRcdFx0Ly8gRXhwbGljaXRseSBjYXN0IHRoZSB2YWx1ZSB0byB0aGUgY29ycmVjdCB0eXBlXG5cdFx0XHRcdFx0XHRjb25zdCBhbmltYXRpb25Tb3VyY2UgPSB2YWx1ZSBhcyBBbmltYXRpb25Tb3VyY2VUeXBlO1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuYW5pbWF0aW9uU291cmNlID0gYW5pbWF0aW9uU291cmNlO1xuXG5cdFx0XHRcdFx0XHQvLyBTaG93IEdyYW5pdGUgd2l0aCB0aGUgbmV3IGFuaW1hdGlvbnMgYWZ0ZXIgY2hhbmdpbmcgdGhlIHNvdXJjZVxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZ3Jhbml0ZS5yZXNldCgpO1xuXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9KSxcblx0XHRcdCk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKCdJZGxlIHRhbGsgZnJlcXVlbmN5Jylcblx0XHRcdC5zZXREZXNjKCdIb3cgb2Z0ZW4gZG9lcyBHcmFuaXRlIHNwZWFrIHdoZW4gaWRsZSwgaW4gbWludXRlcy4nKVxuXHRcdFx0LmFkZFNsaWRlcihzbGlkZXIgPT5cblx0XHRcdFx0c2xpZGVyXG5cdFx0XHRcdFx0LnNldExpbWl0cyg1LCA2MCwgNSlcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuaWRsZVRhbGtGcmVxdWVuY3kpXG5cdFx0XHRcdFx0LnNldER5bmFtaWNUb29sdGlwKClcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgdmFsdWUgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuaWRsZVRhbGtGcmVxdWVuY3kgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdH0pLFxuXHRcdFx0KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoJ1dyaXRpbmcgbW9kZSBncmFjZSBwZXJpb2QnKVxuXHRcdFx0LnNldERlc2MoJ0hvdyBzb29uIEdyYW5pdGUgc3RhcnRzIHRvIGdldCBkaXNhcHBvaW50ZWQgYWZ0ZXIgeW91IHN0b3AgdHlpbmcgaW4gd3JpdGluZyBtb2RlLCBpbiBzZWNvbmRzLicpXG5cdFx0XHQuYWRkU2xpZGVyKHNsaWRlciA9PlxuXHRcdFx0XHRzbGlkZXJcblx0XHRcdFx0XHQuc2V0TGltaXRzKDUsIDE4MCwgNSlcblx0XHRcdFx0XHQuc2V0RHluYW1pY1Rvb2x0aXAoKVxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy53cml0aW5nTW9kZUdyYWNlUGVyaW9kKVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy53cml0aW5nTW9kZUdyYWNlUGVyaW9kID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9KSxcblx0XHRcdCk7XG5cdH1cbn1cbiIsICJpbXBvcnQgR3Jhbml0ZVBsdWdpbiBmcm9tICcuL21haW4nO1xuaW1wb3J0IHsgQW5pbWF0aW9uU291cmNlVHlwZSB9IGZyb20gJy4vU2V0dGluZyc7XG5cbi8vIE9yaWdpbmFsIEFuaW1hdGlvbnNcbmltcG9ydCBFTUVSR0VfTU9USU9OX0dFTU1ZIGZyb20gJy4uL2FuaW1hdGlvbnMvZ2VtbXkvZ2VtbXlfZW1lcmdlLmdpZic7XG5pbXBvcnQgUE9QX01PVElPTl9HRU1NWSBmcm9tICcuLi9hbmltYXRpb25zL2dlbW15L2dlbW15X3BvcC5naWYnO1xuaW1wb3J0IERJU0FQUEVBUl9NT1RJT05fR0VNTVkgZnJvbSAnLi4vYW5pbWF0aW9ucy9nZW1teS9nZW1teV9kaXNhcHBlYXIuZ2lmJztcbmltcG9ydCBBTkdSWV9NT1RJT05fR0VNTVkgZnJvbSAnLi4vYW5pbWF0aW9ucy9nZW1teS9nZW1teV9hbmdyeS5naWYnO1xuaW1wb3J0IExPT0tfTU9USU9OX0dFTU1ZIGZyb20gJy4uL2FuaW1hdGlvbnMvZ2VtbXkvZ2VtbXlfbG9va0Fyb3VuZC5naWYnO1xuaW1wb3J0IElETEVfTU9USU9OX0dFTU1ZIGZyb20gJy4uL2FuaW1hdGlvbnMvZ2VtbXkvZ2VtbXlfaWRsZS5naWYnO1xuaW1wb3J0IERJU0FQUE9JTlRfSU1HX0dFTU1ZIGZyb20gJy4uL2FuaW1hdGlvbnMvZ2VtbXkvZ2VtbXlfZGlzYXBwb2ludC5naWYnO1xuXG4vLyBEcmFjb25pYyBBbmltYXRpb25zXG5pbXBvcnQgRU1FUkdFX01PVElPTl9EUkFLRSBmcm9tICcuLi9hbmltYXRpb25zL2RyYWtlL2RyYWtlX2VtZXJnZS5naWYnO1xuaW1wb3J0IFBPUF9NT1RJT05fRFJBS0UgZnJvbSAnLi4vYW5pbWF0aW9ucy9kcmFrZS9kcmFrZV9wb3AuZ2lmJztcbmltcG9ydCBESVNBUFBFQVJfTU9USU9OX0RSQUtFIGZyb20gJy4uL2FuaW1hdGlvbnMvZHJha2UvZHJha2VfZGlzYXBwZWFyLmdpZic7XG5pbXBvcnQgQU5HUllfTU9USU9OX0RSQUtFIGZyb20gJy4uL2FuaW1hdGlvbnMvZHJha2UvZHJha2VfYW5ncnkuZ2lmJztcbmltcG9ydCBMT09LX01PVElPTl9EUkFLRSBmcm9tICcuLi9hbmltYXRpb25zL2RyYWtlL2RyYWtlX2xvb2tBcm91bmQuZ2lmJztcbmltcG9ydCBJRExFX01PVElPTl9EUkFLRSBmcm9tICcuLi9hbmltYXRpb25zL2RyYWtlL2RyYWtlX2lkbGUuZ2lmJztcbmltcG9ydCBESVNBUFBPSU5UX0lNR19EUkFLRSBmcm9tICcuLi9hbmltYXRpb25zL2RyYWtlL2RyYWtlX2Rpc2FwcG9pbnQuZ2lmJztcblxuZXhwb3J0IGVudW0gQW5pbWF0aW9uVHlwZSB7XG5cdEVNRVJHRSA9ICdlbWVyZ2UnLFxuXHRQT1BfTU9USU9OID0gJ3BvcF9tb3Rpb24nLFxuXHRESVNBUFBFQVJfTU9USU9OID0gJ2Rpc2FwcGVhcl9tb3Rpb24nLFxuXHRBTkdSWV9NT1RJT04gPSAnYW5ncnlfbW90aW9uJyxcblx0TE9PS19NT1RJT04gPSAnbG9va19tb3Rpb24nLFxuXHRJRExFX01PVElPTiA9ICdpZGxlX21vdGlvbicsXG5cdERJU0FQUE9JTlRfSU1HID0gJ2Rpc2FwcG9pbnRfaW5nJyxcbn1cblxuZXhwb3J0IGNsYXNzIEFuaW1hdGlvbnMge1xuXHRwdWJsaWMgcmVhZG9ubHkgcGx1Z2luOiBHcmFuaXRlUGx1Z2luO1xuXG5cdC8vIHRoZSBtYXBwaW5ncyBmcm9tIGFuIGFuaW1hdGlvbiB0eXBlIHRvIGFuIGFjdHVhbCBpbWFnZSBmaWxlIGZvciB0aGUgZHJha2VsaW5nXG5cdHB1YmxpYyByZWFkb25seSBkcmFrZUFuaW1hdGlvbk1hcDogUmVjb3JkPEFuaW1hdGlvblR5cGUsIHN0cmluZz47XG5cdC8vIHRoZSBtYXBwaW5ncyBmcm9tIGFuIGFuaW1hdGlvbiB0eXBlIHRvIGFuIGFjdHVhbCBpbWFnZSBmaWxlIGZvciB0aGUgZ3Jhbml0ZVxuXHRwdWJsaWMgcmVhZG9ubHkgZ2VtbXlBbmltYXRpb25NYXA6IFJlY29yZDxBbmltYXRpb25UeXBlLCBzdHJpbmc+O1xuXG5cdC8vIG1hcHMgYW4gYW5pbWF0aW9uIHNvdXJjZSB0byB0aGUgY29ycmVzcG9uZGluZyBhbmltYXRpb24gbWFwXG5cdHB1YmxpYyByZWFkb25seSBhbmltYXRpb25Tb3VyY2VNYXA6IFJlY29yZDxBbmltYXRpb25Tb3VyY2VUeXBlLCBSZWNvcmQ8QW5pbWF0aW9uVHlwZSwgc3RyaW5nPj47XG5cblx0Y29uc3RydWN0b3IocGx1Z2luOiBHcmFuaXRlUGx1Z2luKSB7XG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cblx0XHR0aGlzLmRyYWtlQW5pbWF0aW9uTWFwID0ge1xuXHRcdFx0W0FuaW1hdGlvblR5cGUuRU1FUkdFXTogRU1FUkdFX01PVElPTl9EUkFLRSxcblx0XHRcdFtBbmltYXRpb25UeXBlLlBPUF9NT1RJT05dOiBQT1BfTU9USU9OX0RSQUtFLFxuXHRcdFx0W0FuaW1hdGlvblR5cGUuRElTQVBQRUFSX01PVElPTl06IERJU0FQUEVBUl9NT1RJT05fRFJBS0UsXG5cdFx0XHRbQW5pbWF0aW9uVHlwZS5BTkdSWV9NT1RJT05dOiBBTkdSWV9NT1RJT05fRFJBS0UsXG5cdFx0XHRbQW5pbWF0aW9uVHlwZS5MT09LX01PVElPTl06IExPT0tfTU9USU9OX0RSQUtFLFxuXHRcdFx0W0FuaW1hdGlvblR5cGUuSURMRV9NT1RJT05dOiBJRExFX01PVElPTl9EUkFLRSxcblx0XHRcdFtBbmltYXRpb25UeXBlLkRJU0FQUE9JTlRfSU1HXTogRElTQVBQT0lOVF9JTUdfRFJBS0UsXG5cdFx0fTtcblxuXHRcdHRoaXMuZ2VtbXlBbmltYXRpb25NYXAgPSB7XG5cdFx0XHRbQW5pbWF0aW9uVHlwZS5FTUVSR0VdOiBFTUVSR0VfTU9USU9OX0dFTU1ZLFxuXHRcdFx0W0FuaW1hdGlvblR5cGUuUE9QX01PVElPTl06IFBPUF9NT1RJT05fR0VNTVksXG5cdFx0XHRbQW5pbWF0aW9uVHlwZS5ESVNBUFBFQVJfTU9USU9OXTogRElTQVBQRUFSX01PVElPTl9HRU1NWSxcblx0XHRcdFtBbmltYXRpb25UeXBlLkFOR1JZX01PVElPTl06IEFOR1JZX01PVElPTl9HRU1NWSxcblx0XHRcdFtBbmltYXRpb25UeXBlLkxPT0tfTU9USU9OXTogTE9PS19NT1RJT05fR0VNTVksXG5cdFx0XHRbQW5pbWF0aW9uVHlwZS5JRExFX01PVElPTl06IElETEVfTU9USU9OX0dFTU1ZLFxuXHRcdFx0W0FuaW1hdGlvblR5cGUuRElTQVBQT0lOVF9JTUddOiBESVNBUFBPSU5UX0lNR19HRU1NWSxcblx0XHR9O1xuXG5cdFx0dGhpcy5hbmltYXRpb25Tb3VyY2VNYXAgPSB7XG5cdFx0XHRbQW5pbWF0aW9uU291cmNlVHlwZS5EUkFLRV06IHRoaXMuZHJha2VBbmltYXRpb25NYXAsXG5cdFx0XHRbQW5pbWF0aW9uU291cmNlVHlwZS5HRU1NWV06IHRoaXMuZ2VtbXlBbmltYXRpb25NYXAsXG5cdFx0fTtcblxuXHRcdGNvbnNvbGUubG9nKCdncmFuaXRlIHwgYnVpbGQgYW5pbWF0aW9uIG1hcCcsIHRoaXMuYW5pbWF0aW9uU291cmNlTWFwKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBQbGF5cyBhIGdyYW5pdGUgYW5pbWF0aW9uIGluIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgYW5pbWF0aW9uIHNvdXJjZSB0eXBlIGluc2lkZSBhbiBlbGVtZW50LlxuXHQgKlxuXHQgKiBAcGFyYW0gZWwgdGhlIGVsZW1lbnQgdG8gcGxheSB0aGUgYW5pbWF0aW9uIGluXG5cdCAqIEBwYXJhbSBhbmltYXRpb24gdGhlIGFuaW1hdGlvbiB0byBwbGF5XG5cdCAqL1xuXHRwdWJsaWMgcGxheShlbDogSFRNTEVsZW1lbnQsIGFuaW1hdGlvbjogQW5pbWF0aW9uVHlwZSk6IHZvaWQge1xuXHRcdGNvbnN0IGFuaW1hdGlvbkZpbGUgPSB0aGlzLmFuaW1hdGlvblNvdXJjZU1hcFt0aGlzLnBsdWdpbi5zZXR0aW5ncy5hbmltYXRpb25Tb3VyY2VdW2FuaW1hdGlvbl07XG5cblx0XHRlbC5zZXRBdHRyaWJ1dGUoJ3NyYycsIGFuaW1hdGlvbkZpbGUpO1xuXHR9XG59XG4iLCAiZXhwb3J0IGludGVyZmFjZSBRdW90ZXMge1xuXHQvLyBnZW5lcmFsIHF1b3RlcyBjYW4gYXBwZWFyIGJvdGggaW4gbm9ybWFsIGFuZCBpbiB3cml0aW5nIG1vZGVcblx0Z2VuZXJhbDogc3RyaW5nW107XG5cdC8vIGlkbGUgcXVvdGVzIGNhbiBvbmx5IGFwcGVhciBpbiBub3JtYWwgbW9kZVxuXHRpZGxlOiBzdHJpbmdbXTtcblx0Ly8gd3JpdGluZyBtb2RlIHF1b3RlcyBjYW4gb25seSBhcHBlYXIgaW4gd3JpdGluZyBtb2RlXG5cdHdyaXRpbmdNb2RlOiBzdHJpbmdbXTtcbn1cblxuLy8gdGhlc2UgcXVvdGVzIGNhbiBhcHBlYXIgaW4gZXZlcnkgYW5pbWF0aW9uIG1vZGVcbmV4cG9ydCBjb25zdCBHUkFOSVRFX0JBU0VfUVVPVEVTOiBRdW90ZXMgPSB7XG5cdGdlbmVyYWw6IFtcblxuXHRdLFxuXHRpZGxlOiBbXG5cdFx0XCJZb3UgY2FuJ3QgYXJyZXN0IHVzISBXZSBhbHJlYWR5IGF0ZSB0aGUgZXZpZGVuY2UhXCIsXG5cdFx0XCJEb24ndCBldmVyIHNwbGl0IHRoZSBwYXJ0eSFcIixcblx0XHQnSWYgeW91IGtpbGwgYSBoaXZlIG1pbmQsIGlzIHRoYXQgbXVyZGVyIG9yIGdlbm9jaWRlPycsXG5cdFx0J1JvbGwgaW5pdGlhdGl2ZSEnLFxuXHRcdCdZb3UgY2FuIHRyeSEnLFxuXHRcdFwiSSdtIG5vdCBzaG9ydCwgSSdtIGNvbmNlbnRyYXRlZCBhd2Vzb21lLlwiLFxuXHRcdFwiSSdtIG5vdCBncmVlZHksIEknbSBqdXN0IGFsbGVyZ2ljIHRvIHBvdmVydHkuXCIsXG5cdFx0XCJJIGRvbid0IGFsd2F5cyBjYXN0IHNwZWxscywgYnV0IHdoZW4gSSBkbywgaXQncyBmaXJlYmFsbC5cIixcblx0XHRcIkkgZG9uJ3QgbmVlZCBsdWNrLCBJIGhhdmUgYSBoaWdoIGNoYXJpc21hIHN0YXQuXCIsXG5cdFx0XCJJIGRvbid0IGFsd2F5cyBkcmluayBhbGUsIGJ1dCB3aGVuIEkgZG8sIGl0J3Mgd2l0aCBteSBmZWxsb3cgYWR2ZW50dXJlcnMgYWZ0ZXIgc2xheWluZyBhIGRyYWdvbi5cIixcblx0XHRcIkkgZG9uJ3QgYWx3YXlzIHJvbGwgYSBjcml0aWNhbCBoaXQsIGJ1dCB3aGVuIEkgZG8sIHRoZSBETSBmb3JnZXRzIHRvIG1ha2UgbWUgcmVyb2xsIHRoZSBkYW1hZ2UuXCIsXG5cdFx0J0kgbWF5IGJlIGNoYW90aWMgbmV1dHJhbCBvbiBwYXBlciwgYnV0IGluIHJlYWxpdHksIEkganVzdCBsaWtlIHRvIHdhdGNoIHRoZSB3b3JsZCBidXJuLicsXG5cdFx0J0l0XHUyMDE5cyBub3Qgc3RlYWxpbmcgaWYgaXQgYmVsb25ncyB0byBhIGRlYWQgZ3V5LicsXG5cdFx0J1dobyBuZWVkcyBhbiBhcm15IHdoZW4geW91IGhhdmUgYSBiYWcgb2YgaG9sZGluZyBmdWxsIG9mIHJvY2tzPycsXG5cdFx0J0xldCBtZSBzaG93IHlvdSBob3cgdG8gd2VhciBhIHNuYWtlLicsXG5cdFx0J1dIWSBXT1VMRCBZT1UgRE8gVEhBVCEnLFxuXHRcdCdUaGF0IGRpY2UgbmVlZHMgdG8gYmUgcmV0aXJlZCEnLFxuXHRcdFwiSSBkb24ndCBraWxsIHdpdGhvdXQgcmVhc29uLiBGb3J0dW5hdGVseSwgSSdtIGJvcmVkLiBSZWFzb24gZW5vdWdoIVwiLFxuXHRcdCdBaCwgbXkgZmF2b3VyZWQgZW5lbXkuIFNvbWV0aGluZyBhbGl2ZS4nLFxuXHRcdFwiSSBzbGFwIHRoZSBiYXJyZWwgd2l0aCBteSBtZW1iZXIhLi4uIHRoZSAnYmFycmVsJyBvcGVuJ3MgaXRzIG1vdXRoIVwiLFxuXHRcdFwiSSdtIG5vdCBkZXByaXZlZCwgSSdtIGRlcHJhdmVkLlwiLFxuXHRcdCdZb3UgbmVlZCBhIGZyZWUgaGFuZCB0byBhdHRlbXB0IGEgZ3JhcHBsZScsXG5cdFx0YENhcmVmdWwgaG93IG11Y2ggeW91IGNhcnJ5OyB0aGUgR00gbWlnaHQgYWN0dWFsbHkgYXNrIHlvdSB0byBjYWxjdWxhdGUgeW91ciBpbnZlbnRvcnkgd2VpZ2h0IWAsXG5cdFx0YERvbid0IGRvIHRoYXQhIFRoZW4gd2UnbGwgaGF2ZSB0byBnbyBsb29rIHVwIHRoZSBncmFwcGxlIHJ1bGVzIWAsXG5cdFx0YDUwIHBhZ2UgYmFja3N0b3J5Li4uIE5PUEVgLFxuXHRcdGBJdCdzIGFzdG91bmRpbmcgYW55b25lIGNhbiB1bmRlcnN0YW5kIHlvdSwgd2l0aCBhbGwgdGhvc2UgTmF0IDEgQ2hhcmlzbWEgcm9sbHMuYCxcblx0XHRgVGhlIGNoZWRkYXIgbW9ua3MgYXJlIGhlcmUgdG8gc2F2ZSB0aGUgZGF5IWAsXG5cdFx0YFlvdSd2ZSBiZWVuIEd5Z2F4ZWQuYCxcblx0XHRgU1RFUCBBV0FZIEZST00gVEhFIFBVUkNIQVNFIE1PUkUgRElDRSBCVVRUT05gLFxuXHRcdGBBZnRlciB0aG91c2FuZHMgb2YgeWVhcnMsIEkgaGF2ZSBhdHRhaW5lZCBteSBjdXJyZW50IHN0YXRlLCB3aGlsZSB5b3Ugc3RydWdnbGUgdG8gY29tcGxldGUgdGhpcyBzaW1wbGUgbm90ZS5gLFxuXHRcdGBZb3UgYXJlIGEgYmFja2dyb3VuZCBjaGFyYWN0ZXIgaW4geW91ciBvd24gbGlmZS5gLFxuXHRdLFxuXHR3cml0aW5nTW9kZTogW1xuXHRcdGBQbGF5ZXIncyBkb250IHRha2Ugbm90ZXMuLi4gbWF5YmUgeW91IHNob3VsZCB0cnkgdGhhdD9gLFxuXHRcdGBJcyB0aGF0IHRoZSBiZXN0IHlvdSBjYW4gZG8/IEtlZXAgd3JpdGluZyFgLFxuXHRcdGBXcml0ZSBmaXJzdCwgZWRpdG9yIGxhdGVyLmAsXG5cdFx0YEFJIGNvdWxkIHByb2JhYmx5IHdyaXRlIGEgYmV0dGVyIG5vdGUuLi5gLFxuXHRcdGBJIGxvdmUgaGVhcmluZyB5b3VyIGtleWJvYXJkLiBEb24ndCBzdG9wLmAsXG5cdFx0YEhvdyBhYm91dCB3ZSByZXZpZXcgc29tZSBvbGQgbm90ZXMgdG9kYXk/YCxcblx0XHRgV2h5IG5vdCBqdXN0IHVzZSBhIHRlbXBsYXRlP2AsXG5cdFx0YERvZXNuJ3QgbWF0dGVyIGhvdyBtdWNoIHlvdSBwbGFuLi4uIHRoZXkgd2lsbCBkZXJhaWwgYW55d2F5IWAsXG5cdFx0YE1heWJlIGl0J3MgdGltZSB0byBnbyBnZXQgc29tZSB3YXRlciBvciBjb2ZmZWUuYCxcblx0XHRgVGhhdCdzIG5vdCBob3cgcml2ZXJzIGFyZSBpbiByZWFsLWxpZmUuLi5gLFxuXHRcdGBBbnl0aGluZyBpcyBiZXR0ZXIgdGhhbiBhIGJsYW5rIHBhZ2UsIGV2ZW4gbWUuIFdyaXRlIHNvbWV0aGluZyFgLFxuXHRcdGBIYXZlIHlvdSBnaXZlbiBvdXQgSW5zcGlyYXRpb24gcmVjZW50bHk/YCxcblx0XHRgQ2FsbCBtZSBKZWV2ZXMuIEkuIERhcmUuIFlvdS5gLFxuXHRcdGBJIGNhc3QgJ1N1bW1vbiBCaWdnZXIgRmlzaGAsXG5cdFx0YERvIHlvdSB0b3VjaCBpdD9gLFxuXHRcdGBXaGF0IHdvdWxkIE1hdHQgTWVyY2VyIGRvP2AsXG5cdFx0YFRvIGNvbnRpbnVlLCBwbGVhc2UgaW5zZXJ0IG1vcmUgY3JlZGl0c2AsXG5cdFx0YEhhdmUgeW91IGNvbnNpZGVyZWQganVzdC4uLiBOb3Q/YCxcblx0XSxcbn1cblxuZXhwb3J0IGNvbnN0IEdFTU1ZX0VYQ0xVU0lWRV9RVU9URVM6IFF1b3RlcyA9IHtcblx0Z2VuZXJhbDogW10sXG5cdGlkbGU6IFtdLFxuXHR3cml0aW5nTW9kZTogW10sXG59XG5cbmV4cG9ydCBjb25zdCBEUkFLRV9FWENMVVNJVkVfUVVPVEVTOiBRdW90ZXMgPSB7XG5cdGdlbmVyYWw6IFtdLFxuXHRpZGxlOiBbXSxcblx0d3JpdGluZ01vZGU6IFtdLFxufVxuIiwgImltcG9ydCBHcmFuaXRlUGx1Z2luIGZyb20gJy4vbWFpbic7XG5pbXBvcnQgeyBBbmltYXRpb25Tb3VyY2VUeXBlIH0gZnJvbSAnLi9TZXR0aW5nJztcbmltcG9ydCB7IEdyYW5pdGVNb2RlLCBHcmFuaXRlU3RhdGUgfSBmcm9tICcuL0dyYW5pdGUnO1xuaW1wb3J0IHsgRFJBS0VfRVhDTFVTSVZFX1FVT1RFUywgR0VNTVlfRVhDTFVTSVZFX1FVT1RFUywgR1JBTklURV9CQVNFX1FVT1RFUywgUXVvdGVzIH0gZnJvbSAnLi9xdW90ZXMvUXVvdGVzJztcblxuZXhwb3J0IGNsYXNzIFF1b3RlTWFuYWdlciB7XG5cdHB1YmxpYyByZWFkb25seSBwbHVnaW46IEdyYW5pdGVQbHVnaW47XG5cdFxuXHRwdWJsaWMgcmVhZG9ubHkgcXVvdGVNYXA6IFJlY29yZDxBbmltYXRpb25Tb3VyY2VUeXBlLCBSZWNvcmQ8R3Jhbml0ZU1vZGUsIHN0cmluZ1tdPj47XG5cdFxuXHRjb25zdHJ1Y3RvcihwbHVnaW46IEdyYW5pdGVQbHVnaW4pIHtcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcblxuXHRcdHRoaXMucXVvdGVNYXAgPSB7XG5cdFx0XHRbQW5pbWF0aW9uU291cmNlVHlwZS5HRU1NWV06IHtcblx0XHRcdFx0W0dyYW5pdGVNb2RlLklETEVdOiB0aGlzLmdldElkbGVRdW90ZXMoR0VNTVlfRVhDTFVTSVZFX1FVT1RFUyksXG5cdFx0XHRcdFtHcmFuaXRlTW9kZS5XUklUSU5HXTogdGhpcy5nZXRXcml0aW5nUXVvdGVzKEdFTU1ZX0VYQ0xVU0lWRV9RVU9URVMpLFxuXHRcdFx0fSxcblx0XHRcdFtBbmltYXRpb25Tb3VyY2VUeXBlLkRSQUtFXToge1xuXHRcdFx0XHRbR3Jhbml0ZU1vZGUuSURMRV06IHRoaXMuZ2V0SWRsZVF1b3RlcyhEUkFLRV9FWENMVVNJVkVfUVVPVEVTKSxcblx0XHRcdFx0W0dyYW5pdGVNb2RlLldSSVRJTkddOiB0aGlzLmdldFdyaXRpbmdRdW90ZXMoRFJBS0VfRVhDTFVTSVZFX1FVT1RFUyksXG5cdFx0XHR9XG5cdFx0fTtcblxuXHRcdGNvbnNvbGUubG9nKCdncmFuaXRlIHwgYnVpbGQgcXVvdGUgbWFwJywgdGhpcy5xdW90ZU1hcCk7XG5cdH1cblxuXHRwcml2YXRlIGdldElkbGVRdW90ZXMoZXhjbHVzaXZlUXVvdGVzOiBRdW90ZXMpOiBzdHJpbmdbXSB7XG5cdFx0cmV0dXJuIFsuLi5HUkFOSVRFX0JBU0VfUVVPVEVTLmdlbmVyYWwsIC4uLkdSQU5JVEVfQkFTRV9RVU9URVMuaWRsZSwgLi4uZXhjbHVzaXZlUXVvdGVzLmdlbmVyYWwsIC4uLmV4Y2x1c2l2ZVF1b3Rlcy5pZGxlXTtcblx0fVxuXG5cdHByaXZhdGUgZ2V0V3JpdGluZ1F1b3RlcyhleGNsdXNpdmVRdW90ZXM6IFF1b3Rlcyk6IHN0cmluZ1tdIHtcblx0XHRyZXR1cm4gWy4uLkdSQU5JVEVfQkFTRV9RVU9URVMuZ2VuZXJhbCwgLi4uR1JBTklURV9CQVNFX1FVT1RFUy53cml0aW5nTW9kZSwgLi4uZXhjbHVzaXZlUXVvdGVzLmdlbmVyYWwsIC4uLmV4Y2x1c2l2ZVF1b3Rlcy53cml0aW5nTW9kZV07XG5cdH1cblx0XG5cdHB1YmxpYyBnZXRRdW90ZSgpOiBzdHJpbmcge1xuXHRcdGNvbnN0IHF1b3Rlczogc3RyaW5nW10gPSB0aGlzLnF1b3RlTWFwW3RoaXMucGx1Z2luLnNldHRpbmdzLmFuaW1hdGlvblNvdXJjZV1bdGhpcy5wbHVnaW4uZ3Jhbml0ZS5tb2RlXTtcblxuXHRcdHJldHVybiBxdW90ZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogcXVvdGVzLmxlbmd0aCldO1xuXHR9XG59XG4iLCAiaW1wb3J0IHsgQW5pbWF0aW9ucywgQW5pbWF0aW9uVHlwZSB9IGZyb20gJy4vQW5pbWF0aW9ucyc7XG5pbXBvcnQgR3Jhbml0ZVBsdWdpbiBmcm9tICcuL21haW4nO1xuaW1wb3J0IHsgUXVvdGVNYW5hZ2VyIH0gZnJvbSAnLi9RdW90ZU1hbmFnZXInO1xuXG5jb25zdCBCVUJCTEVfRFVSQVRJT046IG51bWJlciA9IDUwMDA7XG5cbmV4cG9ydCBlbnVtIEdyYW5pdGVNb2RlIHtcblx0SURMRSA9ICdJRExFJyxcblx0V1JJVElORyA9ICdXUklUSU5HJyxcbn1cblxuZXhwb3J0IGVudW0gR3Jhbml0ZVN0YXRlIHtcblx0VklTSUJMRSA9ICdWSVNJQkxFJyxcblx0SU5WSVNJQkxFID0gJ0lOVklTSUJMRScsXG5cdERJU0FQUEVBUklORyA9ICdESVNBUFBFQVJJTkcnLFxuXHRBUFBFQVJJTkcgPSAnQVBQRUFSSU5HJyxcbn1cblxuZXhwb3J0IGNsYXNzIEdyYW5pdGUge1xuXHRwdWJsaWMgcmVhZG9ubHkgcGx1Z2luOiBHcmFuaXRlUGx1Z2luO1xuXHRwcml2YXRlIHJlYWRvbmx5IGFuaW1hdGlvbnM6IEFuaW1hdGlvbnM7XG5cdHByaXZhdGUgcmVhZG9ubHkgcXVvdGVzOiBRdW90ZU1hbmFnZXI7XG5cblx0Z3Jhbml0ZUVsOiBIVE1MRWxlbWVudDtcblx0aW1hZ2VFbDogSFRNTEVsZW1lbnQ7XG5cblx0c3RhdGU6IEdyYW5pdGVTdGF0ZTtcblx0bW9kZTogR3Jhbml0ZU1vZGU7XG5cblx0aWRsZVRpbWVvdXQ6IG51bWJlcjtcblx0d3JpdGluZ01vZGVUaW1lb3V0OiBudW1iZXI7XG5cblx0Y29uc3RydWN0b3IocGx1Z2luOiBHcmFuaXRlUGx1Z2luKSB7XG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cblx0XHR0aGlzLmFuaW1hdGlvbnMgPSBuZXcgQW5pbWF0aW9ucyh0aGlzLnBsdWdpbik7XG5cdFx0dGhpcy5xdW90ZXMgPSBuZXcgUXVvdGVNYW5hZ2VyKHRoaXMucGx1Z2luKTtcblxuXHRcdHRoaXMuc3RhdGUgPSBHcmFuaXRlU3RhdGUuSU5WSVNJQkxFO1xuXHRcdHRoaXMubW9kZSA9IEdyYW5pdGVNb2RlLklETEU7XG5cblx0XHR0aGlzLmNyZWF0ZUdyYW5pdGVFbCgpO1xuXG5cdFx0dGhpcy5zdGFydE5leHRJZGxlVGltZW91dCgpO1xuXHR9XG5cblx0Y3JlYXRlR3Jhbml0ZUVsKCkge1xuXHRcdHRoaXMuZ3Jhbml0ZUVsID0gY3JlYXRlRGl2KCdncmFuaXRlLWNvbnRhaW5lcicpO1xuXHRcdHRoaXMuZ3Jhbml0ZUVsLnNldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbC1wb3NpdGlvbicsICd0b3AnKTtcblx0XHR0aGlzLmdyYW5pdGVFbC5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWwtZGVsYXknLCAnMCcpO1xuXHRcdHRoaXMuZ3Jhbml0ZUVsLnNldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbC1jbGFzc2VzJywgJ2dyYW5pdGUtdG9vbHRpcCcpO1xuXG5cdFx0dGhpcy5pbWFnZUVsID0gdGhpcy5ncmFuaXRlRWwuY3JlYXRlRWwoJ2ltZycsIHt9KTtcblxuXHRcdHRoaXMuZ3Jhbml0ZUVsLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCAoKSA9PiB7XG5cdFx0XHQvLyBpZ25vcmUgbW91c2UgZXZlbnRzIGluIHdyaXRpbmcgbW9kZVxuXHRcdFx0aWYgKHRoaXMubW9kZSA9PT0gR3Jhbml0ZU1vZGUuV1JJVElORykge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuc2F5U29tZXRoaW5nKHRydWUpO1xuXHRcdFx0dGhpcy5pZGxlVGltZW91dCAmJiBjbGVhclRpbWVvdXQodGhpcy5pZGxlVGltZW91dCk7XG5cdFx0fSk7XG5cblx0XHR0aGlzLmdyYW5pdGVFbC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgKCkgPT4ge1xuXHRcdFx0Ly8gaWdub3JlIG1vdXNlIGV2ZW50cyBpbiB3cml0aW5nIG1vZGVcblx0XHRcdGlmICh0aGlzLm1vZGUgPT09IEdyYW5pdGVNb2RlLldSSVRJTkcpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLmFuaW1hdGlvbnMucGxheSh0aGlzLmltYWdlRWwsIEFuaW1hdGlvblR5cGUuSURMRV9NT1RJT04pO1xuXHRcdFx0dGhpcy5zdGFydE5leHRJZGxlVGltZW91dCgpO1xuXHRcdH0pO1xuXG5cdFx0dGhpcy5ncmFuaXRlRWwuaGlkZGVuID0gdHJ1ZTtcblx0XHRkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMuZ3Jhbml0ZUVsKTtcblx0fVxuXG5cdGFzeW5jIGFwcGVhcigpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAodGhpcy5zdGF0ZSA9PT0gR3Jhbml0ZVN0YXRlLkFQUEVBUklORyB8fCB0aGlzLnN0YXRlID09PSBHcmFuaXRlU3RhdGUuVklTSUJMRSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIHNob3cgaGltXG5cdFx0dGhpcy5zdGF0ZSA9IEdyYW5pdGVTdGF0ZS5BUFBFQVJJTkc7XG5cdFx0dGhpcy5ncmFuaXRlRWwuaGlkZGVuID0gZmFsc2U7XG5cblx0XHQvLyBRdWlja2VyIGlmIHdlJ3JlIGluIHdyaXRpbmcgbW9kZVxuXHRcdGlmICh0aGlzLm1vZGUgPT09IEdyYW5pdGVNb2RlLldSSVRJTkcpIHtcblx0XHRcdHRoaXMuYW5pbWF0aW9ucy5wbGF5KHRoaXMuaW1hZ2VFbCwgQW5pbWF0aW9uVHlwZS5QT1BfTU9USU9OKTtcblxuXHRcdFx0YXdhaXQgc2xlZXAoMTgwMCk7XG5cblx0XHRcdC8vIGFub3RoZXIgYW5pbWF0aW9uIG92ZXJyb2RlIHRoaXMgYW5pbWF0aW9uLCBzbyB3ZSBxdWl0XG5cdFx0XHRpZiAodGhpcy5zdGF0ZSAhPT0gR3Jhbml0ZVN0YXRlLkFQUEVBUklORykge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuc3RhdGUgPSBHcmFuaXRlU3RhdGUuVklTSUJMRTtcblx0XHRcdHRoaXMuc2F5U29tZXRoaW5nKHRydWUpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLmFuaW1hdGlvbnMucGxheSh0aGlzLmltYWdlRWwsIEFuaW1hdGlvblR5cGUuRU1FUkdFKTtcblxuXHRcdFx0YXdhaXQgc2xlZXAoMzgwMCk7XG5cblx0XHRcdC8vIGFub3RoZXIgYW5pbWF0aW9uIG92ZXJyb2RlIHRoaXMgYW5pbWF0aW9uLCBzbyB3ZSBxdWl0XG5cdFx0XHRpZiAodGhpcy5zdGF0ZSAhPT0gR3Jhbml0ZVN0YXRlLkFQUEVBUklORykge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuc3RhdGUgPSBHcmFuaXRlU3RhdGUuVklTSUJMRTtcblx0XHRcdHRoaXMuYW5pbWF0aW9ucy5wbGF5KHRoaXMuaW1hZ2VFbCwgQW5pbWF0aW9uVHlwZS5JRExFX01PVElPTik7XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgZGlzYXBwZWFyKCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdC8vIGRvbid0IG1ha2UgZ3Jhbml0ZSBkaXNhcHBlYXIgd2hpbGUgdGhleSBhcmUgYWxyZWFkeSBsZWF2aW5nXG5cdFx0aWYgKHRoaXMuc3RhdGUgPT09IEdyYW5pdGVTdGF0ZS5ESVNBUFBFQVJJTkcgfHwgdGhpcy5zdGF0ZSA9PT0gR3Jhbml0ZVN0YXRlLklOVklTSUJMRSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRoaXMuc3RhdGUgPSBHcmFuaXRlU3RhdGUuRElTQVBQRUFSSU5HO1xuXG5cdFx0aWYgKHRoaXMuaWRsZVRpbWVvdXQpIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5pZGxlVGltZW91dCk7XG5cdFx0aWYgKHRoaXMud3JpdGluZ01vZGVUaW1lb3V0KSB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMud3JpdGluZ01vZGVUaW1lb3V0KTtcblxuXHRcdHRoaXMuYW5pbWF0aW9ucy5wbGF5KHRoaXMuaW1hZ2VFbCwgQW5pbWF0aW9uVHlwZS5ESVNBUFBFQVJfTU9USU9OKTtcblx0XHQvLyByZW1vdGUgdG9vbHRpcFxuXHRcdHRoaXMuZ3Jhbml0ZUVsLmRpc3BhdGNoRXZlbnQobmV3IE1vdXNlRXZlbnQoJ21vdXNlb3V0JywgeyBidWJibGVzOiB0cnVlLCBjbGllbnRYOiAxMCwgY2xpZW50WTogMTAgfSkpO1xuXG5cdFx0YXdhaXQgc2xlZXAoMTMwMCk7XG5cblx0XHQvLyBhbm90aGVyIGFuaW1hdGlvbiBvdmVycm9kZSB0aGlzIGFuaW1hdGlvbiwgc28gd2UgcXVpdFxuXHRcdGlmICh0aGlzLnN0YXRlICE9PSBHcmFuaXRlU3RhdGUuRElTQVBQRUFSSU5HKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dGhpcy5zdGF0ZSA9IEdyYW5pdGVTdGF0ZS5JTlZJU0lCTEU7XG5cdFx0dGhpcy5ncmFuaXRlRWwuaGlkZGVuID0gdHJ1ZTtcblx0fVxuXG5cdGFzeW5jIHJlc2V0KCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICh0aGlzLnN0YXRlID09PSBHcmFuaXRlU3RhdGUuRElTQVBQRUFSSU5HIHx8IHRoaXMuc3RhdGUgPT09IEdyYW5pdGVTdGF0ZS5JTlZJU0lCTEUpIHtcblx0XHRcdGF3YWl0IHRoaXMuYXBwZWFyKCk7XG5cdFx0fVxuXG5cdFx0dGhpcy5hbmltYXRpb25zLnBsYXkodGhpcy5pbWFnZUVsLCBBbmltYXRpb25UeXBlLklETEVfTU9USU9OKTtcblx0fVxuXG5cdG9uRWRpdG9yQ2hhbmdlKCk6IHZvaWQge1xuXHRcdGlmICh0aGlzLm1vZGUgPT09IEdyYW5pdGVNb2RlLklETEUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5zdGF0ZSAhPT0gR3Jhbml0ZVN0YXRlLkRJU0FQUEVBUklORyAmJiB0aGlzLnN0YXRlICE9PSBHcmFuaXRlU3RhdGUuSU5WSVNJQkxFKSB7XG5cdFx0XHR0aGlzLmRpc2FwcGVhcigpO1xuXHRcdH1cblx0XHR0aGlzLnNldFdyaXRpbmdNb2RlVGltZW91dCgpO1xuXHR9XG5cblx0ZW50ZXJXcml0aW5nTW9kZSgpOiB2b2lkIHtcblx0XHR0aGlzLm1vZGUgPSBHcmFuaXRlTW9kZS5XUklUSU5HO1xuXHRcdHRoaXMuZGlzYXBwZWFyKCk7XG5cblx0XHR0aGlzLnNldFdyaXRpbmdNb2RlVGltZW91dCgpO1xuXHR9XG5cblx0bGVhdmVXcml0aW5nTW9kZSgpIHtcblx0XHR0aGlzLm1vZGUgPSBHcmFuaXRlTW9kZS5JRExFO1xuXHRcdHRoaXMucmVzZXQoKTtcblxuXHRcdHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy53cml0aW5nTW9kZVRpbWVvdXQpO1xuXHR9XG5cblx0c2V0V3JpdGluZ01vZGVUaW1lb3V0KCk6IHZvaWQge1xuXHRcdGlmICh0aGlzLndyaXRpbmdNb2RlVGltZW91dCkge1xuXHRcdFx0d2luZG93LmNsZWFyVGltZW91dCh0aGlzLndyaXRpbmdNb2RlVGltZW91dCk7XG5cdFx0fVxuXG5cdFx0dGhpcy53cml0aW5nTW9kZVRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRpZiAodGhpcy5tb2RlID09PSBHcmFuaXRlTW9kZS5XUklUSU5HKSB7XG5cdFx0XHRcdHRoaXMuYXBwZWFyKCk7XG5cdFx0XHR9XG5cdFx0fSwgdGhpcy5wbHVnaW4uc2V0dGluZ3Mud3JpdGluZ01vZGVHcmFjZVBlcmlvZCAqIDEwMDApO1xuXHR9XG5cblx0c3RhcnROZXh0SWRsZVRpbWVvdXQoKTogdm9pZCB7XG5cdFx0Ly8gaWYgdGhlIHNldCB0aW1lIGlzIDUgbWludXRlcywgdGhpcyB3aWxsIHNldCB0aW1lb3V0IHRvIGJlIGEgcmFuZG9tIHRpbWUgYmV0d2VlbiA0LTYgbWludXRlc1xuXHRcdC8vIHRoZSByYW5nZSB3aWxsIGJlIDgwJSAtIDEyMCVcblx0XHRjb25zdCByYW5kb21GYWN0b3IgPSAwLjggKyAwLjQgKiBNYXRoLnJhbmRvbSgpO1xuXHRcdGNvbnN0IHJhbmRvbWl6ZWRUaW1lb3V0ID0gcmFuZG9tRmFjdG9yICogdGhpcy5wbHVnaW4uc2V0dGluZ3MuaWRsZVRhbGtGcmVxdWVuY3kgKiA2MDAwMDtcblxuXHRcdGlmICh0aGlzLmlkbGVUaW1lb3V0KSB7XG5cdFx0XHR3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMuaWRsZVRpbWVvdXQpO1xuXHRcdH1cblxuXHRcdHRoaXMuaWRsZVRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRpZiAodGhpcy5tb2RlID09PSBHcmFuaXRlTW9kZS5XUklUSU5HKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5zYXlTb21ldGhpbmcoZmFsc2UpO1xuXHRcdFx0dGhpcy5zdGFydE5leHRJZGxlVGltZW91dCgpO1xuXHRcdH0sIHJhbmRvbWl6ZWRUaW1lb3V0KTtcblx0fVxuXG5cdGFzeW5jIHNheVNvbWV0aGluZyhwZXJzaXN0ZW50OiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKHRoaXMuc3RhdGUgIT09IEdyYW5pdGVTdGF0ZS5WSVNJQkxFKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3QgcXVvdGU6IHN0cmluZyA9IHRoaXMucXVvdGVzLmdldFF1b3RlKCk7XG5cblx0XHR0aGlzLmdyYW5pdGVFbC5zZXRBdHRyKCdhcmlhLWxhYmVsJywgcXVvdGUpO1xuXHRcdHRoaXMuZ3Jhbml0ZUVsLnNldEF0dHIoJ2FyaWEtbGFiZWwtcG9zaXRpb24nLCAndG9wJyk7XG5cdFx0dGhpcy5ncmFuaXRlRWwuZGlzcGF0Y2hFdmVudChuZXcgTW91c2VFdmVudCgnbW91c2VvdmVyJywgeyBidWJibGVzOiB0cnVlLCBjbGllbnRYOiAxMCwgY2xpZW50WTogMTAgfSkpO1xuXG5cdFx0aWYgKHRoaXMubW9kZSA9PT0gR3Jhbml0ZU1vZGUuV1JJVElORykge1xuXHRcdFx0dGhpcy5hbmltYXRpb25zLnBsYXkodGhpcy5pbWFnZUVsLCBBbmltYXRpb25UeXBlLkFOR1JZX01PVElPTik7XG5cblx0XHRcdGF3YWl0IHNsZWVwKDEwMDApO1xuXG5cdFx0XHR0aGlzLmFuaW1hdGlvbnMucGxheSh0aGlzLmltYWdlRWwsIEFuaW1hdGlvblR5cGUuRElTQVBQT0lOVF9JTUcpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLmFuaW1hdGlvbnMucGxheSh0aGlzLmltYWdlRWwsIEFuaW1hdGlvblR5cGUuTE9PS19NT1RJT04pO1xuXHRcdH1cblxuXHRcdGlmICghcGVyc2lzdGVudCkge1xuXHRcdFx0YXdhaXQgc2xlZXAoQlVCQkxFX0RVUkFUSU9OKTtcblxuXHRcdFx0dGhpcy5ncmFuaXRlRWwuZGlzcGF0Y2hFdmVudChuZXcgTW91c2VFdmVudCgnbW91c2VvdXQnLCB7IGJ1YmJsZXM6IHRydWUsIGNsaWVudFg6IDEwLCBjbGllbnRZOiAxMCB9KSk7XG5cdFx0XHR0aGlzLmFuaW1hdGlvbnMucGxheSh0aGlzLmltYWdlRWwsIEFuaW1hdGlvblR5cGUuSURMRV9NT1RJT04pO1xuXHRcdH1cblx0fVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLElBQUFBLG1CQUFpQzs7O0FDQWpDLHNCQUErQztBQWlCeEMsSUFBTSxtQkFBb0M7QUFBQSxFQUNoRCxpQkFBaUI7QUFBQSxFQUNqQixtQkFBbUI7QUFBQSxFQUNuQix3QkFBd0I7QUFDekI7QUFFTyxJQUFNLHFCQUFOLGNBQWlDLGlDQUFpQjtBQUFBLEVBR3hELFlBQVksS0FBVSxRQUF1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 +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21haW4udHMiLCAic3JjL1NldHRpbmcudHMiLCAic3JjL0FuaW1hdGlvbnMudHMiLCAic3JjL3F1b3Rlcy9RdW90ZXMudHMiLCAic3JjL1F1b3RlTWFuYWdlci50cyIsICJzcmMvR3Jhbml0ZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHsgZGVib3VuY2UsIFBsdWdpbiB9IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCB7IEFuaW1hdGlvblNvdXJjZVR5cGUsIERFRkFVTFRfU0VUVElOR1MsIEdyYW5pdGVTZXR0aW5ncywgR3Jhbml0ZVNldHRpbmdzVGFiIH0gZnJvbSAnLi9TZXR0aW5nJztcbmltcG9ydCB7IEdyYW5pdGUgfSBmcm9tICcuL0dyYW5pdGUnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBHcmFuaXRlUGx1Z2luIGV4dGVuZHMgUGx1Z2luIHtcblx0c2V0dGluZ3M6IEdyYW5pdGVTZXR0aW5ncztcblx0Z3Jhbml0ZTogR3Jhbml0ZTtcblxuXHRhc3luYyBvbmxvYWQoKSB7XG5cdFx0Y29uc29sZS5sb2coJ2dyYW5pdGUgfCBsb2FkJyk7XG5cblx0XHRhd2FpdCB0aGlzLmxvYWRTZXR0aW5ncygpO1xuXG5cdFx0dGhpcy5ncmFuaXRlID0gbmV3IEdyYW5pdGUodGhpcyk7XG5cblx0XHR0aGlzLmFkZENvbW1hbmQoe1xuXHRcdFx0aWQ6ICdzaG93Jyxcblx0XHRcdG5hbWU6ICdTaG93IEdyYW5pdGUnLFxuXHRcdFx0Y2FsbGJhY2s6ICgpID0+IHtcblx0XHRcdFx0dGhpcy5ncmFuaXRlLmFwcGVhcigpO1xuXHRcdFx0fSxcblx0XHR9KTtcblxuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRpZDogJ2hpZGUnLFxuXHRcdFx0bmFtZTogJ0hpZGUgR3Jhbml0ZScsXG5cdFx0XHRjYWxsYmFjazogKCkgPT4ge1xuXHRcdFx0XHR0aGlzLmdyYW5pdGUuZGlzYXBwZWFyKCk7XG5cdFx0XHR9LFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcblx0XHRcdGlkOiAnZW50ZXItd3JpdGluZy1tb2RlJyxcblx0XHRcdG5hbWU6ICdFbnRlciB3cml0aW5nIG1vZGUnLFxuXHRcdFx0Y2FsbGJhY2s6ICgpID0+IHtcblx0XHRcdFx0dGhpcy5ncmFuaXRlLmVudGVyV3JpdGluZ01vZGUoKTtcblx0XHRcdH0sXG5cdFx0fSk7XG5cblx0XHR0aGlzLmFkZENvbW1hbmQoe1xuXHRcdFx0aWQ6ICdsZWF2ZS13cml0aW5nLW1vZGUnLFxuXHRcdFx0bmFtZTogJ0xlYXZlIHdyaXRpbmcgbW9kZScsXG5cdFx0XHRjYWxsYmFjazogKCkgPT4ge1xuXHRcdFx0XHR0aGlzLmdyYW5pdGUubGVhdmVXcml0aW5nTW9kZSgpO1xuXHRcdFx0fSxcblx0XHR9KTtcblxuXHRcdC8vIFRoaXMgYWRkcyBhIHNldHRpbmdzIHRhYiBzbyB0aGUgdXNlciBjYW4gY29uZmlndXJlIHZhcmlvdXMgYXNwZWN0cyBvZiB0aGUgcGx1Z2luXG5cdFx0dGhpcy5hZGRTZXR0aW5nVGFiKG5ldyBHcmFuaXRlU2V0dGluZ3NUYWIodGhpcy5hcHAsIHRoaXMpKTtcblxuXHRcdC8vIGRlYm91bmNlIGVkaXRvci1jaGFuZ2UgZXZlbnQgb24gd29ya3NwYWNlXG5cdFx0dGhpcy5yZWdpc3RlckV2ZW50KFxuXHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLm9uKFxuXHRcdFx0XHQnZWRpdG9yLWNoYW5nZScsXG5cdFx0XHRcdGRlYm91bmNlKCgpID0+IHtcblx0XHRcdFx0XHR0aGlzLmdyYW5pdGUub25FZGl0b3JDaGFuZ2UoKTtcblx0XHRcdFx0fSwgNTAwKSxcblx0XHRcdCksXG5cdFx0KTtcblxuXHRcdHRoaXMuYXBwLndvcmtzcGFjZS5vbkxheW91dFJlYWR5KCgpID0+IHRoaXMuZ3Jhbml0ZS5hcHBlYXIoKSk7XG5cdH1cblxuXHRvbnVubG9hZCgpIHtcblx0XHRjb25zb2xlLmxvZygnZ3Jhbml0ZSB8IHVubG9hZCcpO1xuXG5cdFx0dGhpcy5ncmFuaXRlLmRpc2FwcGVhcigpO1xuXHR9XG5cblx0Ly8gV2l0aGluIHRoZSBhc3luYywgdXBkYXRlIHlvdXIgbmV3IGNoYXJhY3RlciBieSBhZGRpbmcgdGhlbSB0byB0aGUgbG9hZCBsaXN0LFxuXHQvLyB3aGVyZSBuYW1lIGlzIHlvdXIgY2hhcmFjdGVyIG5hbWUgYW5kIHR5cGUgaXMgdGhlIHR5cGUgb2YgY3JlYXR1cmUgaXQgaXMuXG5cdC8vIFx0XHRpZiAodGhpcy5zZXR0aW5ncy5hbmltYXRpb25Tb3VyY2UgPT09ICd0eXBlJykge1xuXHQvLyBcdFx0XHR0aGlzLnNldHRpbmdzLmFuaW1hdGlvblNvdXJjZSA9IEFuaW1hdGlvblNvdXJjZVR5cGUuTkFNRTtcblx0Ly8gXHRcdH1cblxuXHRhc3luYyBsb2FkU2V0dGluZ3MoKSB7XG5cdFx0dGhpcy5zZXR0aW5ncyA9IE9iamVjdC5hc3NpZ24oe30sIERFRkFVTFRfU0VUVElOR1MsIGF3YWl0IHRoaXMubG9hZERhdGEoKSk7XG5cblx0XHQvLyBtaWdyYXRpb25zXG5cdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdGlmICh0aGlzLnNldHRpbmdzLmFuaW1hdGlvblNvdXJjZSA9PT0gJ2RyYWdvbicpIHtcblx0XHRcdHRoaXMuc2V0dGluZ3MuYW5pbWF0aW9uU291cmNlID0gQW5pbWF0aW9uU291cmNlVHlwZS5EUkFLRTtcblx0XHR9XG5cdFx0Ly8gQHRzLWlnbm9yZVxuXHRcdGlmICh0aGlzLnNldHRpbmdzLmFuaW1hdGlvblNvdXJjZSA9PT0gJ29yaWdpbmFsJykge1xuXHRcdFx0dGhpcy5zZXR0aW5ncy5hbmltYXRpb25Tb3VyY2UgPSBBbmltYXRpb25Tb3VyY2VUeXBlLkdFTU1ZO1xuXHRcdH1cblxuXHRcdGF3YWl0IHRoaXMuc2F2ZVNldHRpbmdzKCk7XG5cdH1cblxuXHRhc3luYyBzYXZlU2V0dGluZ3MoKSB7XG5cdFx0YXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcblx0fVxufVxuIiwgImltcG9ydCB7IEFwcCwgUGx1Z2luU2V0dGluZ1RhYiwgU2V0dGluZyB9IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCBHcmFuaXRlUGx1Z2luIGZyb20gJy4vbWFpbic7XG5cbmV4cG9ydCBlbnVtIEFuaW1hdGlvblNvdXJjZVR5cGUge1xuXHRHRU1NWSA9ICdnZW1teScsXG5cdERSQUtFID0gJ2RyYWtlJyxcblx0Ly8gV2hlbiB5b3UgbmVlZCB0byBhZGQgYSBuZXcgY2hhcmFjdGVyLCBhZGQgdGhlIGZvbGxvd2luZyBhYm92ZTpcblx0Ly8gTkFNRSA9ICduYW1lJyxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHcmFuaXRlU2V0dGluZ3Mge1xuXHQvLyBBZGQgdGhlIGFuaW1hdGlvblNvdXJjZSBwcm9wZXJ0eSB0byB0aGUgc2V0dGluZ3MgaW50ZXJmYWNlXG5cdGFuaW1hdGlvblNvdXJjZTogQW5pbWF0aW9uU291cmNlVHlwZTtcblx0Ly8gaG93IG9mdGVuIGRvZXMgR3Jhbml0ZSB0YWxrIGluIGlkbGUgbW9kZSwgaW4gbWludXRlc1xuXHRpZGxlVGFsa0ZyZXF1ZW5jeTogbnVtYmVyO1xuXHQvLyB0aGUgbnVtYmVyIG9mIG1pbnV0ZXMgeW91IG11c3Qgd3JpdGUgYmVmb3JlIEdyYW5pdGUgYXBwZWFycyB0byBtb2NrIHlvdVxuXHR3cml0aW5nTW9kZUdyYWNlUGVyaW9kOiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1NFVFRJTkdTOiBHcmFuaXRlU2V0dGluZ3MgPSB7XG5cdGFuaW1hdGlvblNvdXJjZTogQW5pbWF0aW9uU291cmNlVHlwZS5HRU1NWSxcblx0aWRsZVRhbGtGcmVxdWVuY3k6IDEsXG5cdHdyaXRpbmdNb2RlR3JhY2VQZXJpb2Q6IDEsXG59O1xuXG5leHBvcnQgY2xhc3MgR3Jhbml0ZVNldHRpbmdzVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XG5cdHBsdWdpbjogR3Jhbml0ZVBsdWdpbjtcblxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBHcmFuaXRlUGx1Z2luKSB7XG5cdFx0c3VwZXIoYXBwLCBwbHVnaW4pO1xuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xuXHR9XG5cblx0ZGlzcGxheSgpOiB2b2lkIHtcblx0XHRjb25zdCB7IGNvbnRhaW5lckVsIH0gPSB0aGlzO1xuXG5cdFx0Y29udGFpbmVyRWwuZW1wdHkoKTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoJ0FuaW1hdGlvbiBTb3VyY2UnKVxuXHRcdFx0LnNldERlc2MoJ0Nob29zZSB0aGUgc291cmNlIG9mIEdyYW5pdGUgYW5pbWF0aW9ucy4nKVxuXHRcdFx0LmFkZERyb3Bkb3duKGRyb3Bkb3duID0+XG5cdFx0XHRcdGRyb3Bkb3duXG5cdFx0XHRcdFx0LmFkZE9wdGlvbihBbmltYXRpb25Tb3VyY2VUeXBlLkdFTU1ZLCAnR2VtbXknKVxuXHRcdFx0XHRcdC5hZGRPcHRpb24oQW5pbWF0aW9uU291cmNlVHlwZS5EUkFLRSwgJ0RyYWtlJylcblx0XHRcdFx0XHQvLyBXaGVuIHlvdSBuZWVkIHRvIGFkZCBhIG5ldyBjaGFyYWN0ZXIsIGNvcHkgYW5kIHBhc3RlIHRoZSBmb2xsb3dpbmcgbGluZSBhYm92ZSB0aGlzIG9uZSwgYW5kIGNoYW5nZSB0aGUgTkFNRVxuXHRcdFx0XHRcdC8vIC5hZGRPcHRpb24oQW5pbWF0aW9uU291cmNlVHlwZS5OQU1FLCAnTmFtZScpXG5cdFx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmFuaW1hdGlvblNvdXJjZSlcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgdmFsdWUgPT4ge1xuXHRcdFx0XHRcdFx0Ly8gRXhwbGljaXRseSBjYXN0IHRoZSB2YWx1ZSB0byB0aGUgY29ycmVjdCB0eXBlXG5cdFx0XHRcdFx0XHRjb25zdCBhbmltYXRpb25Tb3VyY2UgPSB2YWx1ZSBhcyBBbmltYXRpb25Tb3VyY2VUeXBlO1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuYW5pbWF0aW9uU291cmNlID0gYW5pbWF0aW9uU291cmNlO1xuXG5cdFx0XHRcdFx0XHQvLyBTaG93IEdyYW5pdGUgd2l0aCB0aGUgbmV3IGFuaW1hdGlvbnMgYWZ0ZXIgY2hhbmdpbmcgdGhlIHNvdXJjZVxuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uZ3Jhbml0ZS5yZXNldCgpO1xuXG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9KSxcblx0XHRcdCk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKCdJZGxlIHRhbGsgZnJlcXVlbmN5Jylcblx0XHRcdC5zZXREZXNjKCdIb3cgb2Z0ZW4gZG9lcyBHcmFuaXRlIHNwZWFrIHdoZW4gaWRsZSwgaW4gbWludXRlcy4nKVxuXHRcdFx0LmFkZFNsaWRlcihzbGlkZXIgPT5cblx0XHRcdFx0c2xpZGVyXG5cdFx0XHRcdFx0LnNldExpbWl0cyg1LCA2MCwgNSlcblx0XHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuaWRsZVRhbGtGcmVxdWVuY3kpXG5cdFx0XHRcdFx0LnNldER5bmFtaWNUb29sdGlwKClcblx0XHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgdmFsdWUgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuaWRsZVRhbGtGcmVxdWVuY3kgPSB2YWx1ZTtcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdH0pLFxuXHRcdFx0KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoJ1dyaXRpbmcgbW9kZSBncmFjZSBwZXJpb2QnKVxuXHRcdFx0LnNldERlc2MoJ0hvdyBzb29uIEdyYW5pdGUgc3RhcnRzIHRvIGdldCBkaXNhcHBvaW50ZWQgYWZ0ZXIgeW91IHN0b3AgdHlpbmcgaW4gd3JpdGluZyBtb2RlLCBpbiBzZWNvbmRzLicpXG5cdFx0XHQuYWRkU2xpZGVyKHNsaWRlciA9PlxuXHRcdFx0XHRzbGlkZXJcblx0XHRcdFx0XHQuc2V0TGltaXRzKDUsIDE4MCwgNSlcblx0XHRcdFx0XHQuc2V0RHluYW1pY1Rvb2x0aXAoKVxuXHRcdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy53cml0aW5nTW9kZUdyYWNlUGVyaW9kKVxuXHRcdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy53cml0aW5nTW9kZUdyYWNlUGVyaW9kID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0XHR9KSxcblx0XHRcdCk7XG5cdH1cbn1cbiIsICJpbXBvcnQgR3Jhbml0ZVBsdWdpbiBmcm9tICcuL21haW4nO1xuaW1wb3J0IHsgQW5pbWF0aW9uU291cmNlVHlwZSB9IGZyb20gJy4vU2V0dGluZyc7XG5cbi8vIE9yaWdpbmFsIEFuaW1hdGlvbnNcbmltcG9ydCBFTUVSR0VfTU9USU9OX0dFTU1ZIGZyb20gJy4uL2FuaW1hdGlvbnMvZ2VtbXkvZ2VtbXlfZW1lcmdlLmdpZic7XG5pbXBvcnQgUE9QX01PVElPTl9HRU1NWSBmcm9tICcuLi9hbmltYXRpb25zL2dlbW15L2dlbW15X3BvcC5naWYnO1xuaW1wb3J0IERJU0FQUEVBUl9NT1RJT05fR0VNTVkgZnJvbSAnLi4vYW5pbWF0aW9ucy9nZW1teS9nZW1teV9kaXNhcHBlYXIuZ2lmJztcbmltcG9ydCBBTkdSWV9NT1RJT05fR0VNTVkgZnJvbSAnLi4vYW5pbWF0aW9ucy9nZW1teS9nZW1teV9hbmdyeS5naWYnO1xuaW1wb3J0IExPT0tfTU9USU9OX0dFTU1ZIGZyb20gJy4uL2FuaW1hdGlvbnMvZ2VtbXkvZ2VtbXlfbG9va0Fyb3VuZC5naWYnO1xuaW1wb3J0IElETEVfTU9USU9OX0dFTU1ZIGZyb20gJy4uL2FuaW1hdGlvbnMvZ2VtbXkvZ2VtbXlfaWRsZS5naWYnO1xuaW1wb3J0IERJU0FQUE9JTlRfSU1HX0dFTU1ZIGZyb20gJy4uL2FuaW1hdGlvbnMvZ2VtbXkvZ2VtbXlfZGlzYXBwb2ludC5naWYnO1xuXG4vLyBEcmFjb25pYyBBbmltYXRpb25zXG5pbXBvcnQgRU1FUkdFX01PVElPTl9EUkFLRSBmcm9tICcuLi9hbmltYXRpb25zL2RyYWtlL2RyYWtlX2VtZXJnZS5naWYnO1xuaW1wb3J0IFBPUF9NT1RJT05fRFJBS0UgZnJvbSAnLi4vYW5pbWF0aW9ucy9kcmFrZS9kcmFrZV9wb3AuZ2lmJztcbmltcG9ydCBESVNBUFBFQVJfTU9USU9OX0RSQUtFIGZyb20gJy4uL2FuaW1hdGlvbnMvZHJha2UvZHJha2VfZGlzYXBwZWFyLmdpZic7XG5pbXBvcnQgQU5HUllfTU9USU9OX0RSQUtFIGZyb20gJy4uL2FuaW1hdGlvbnMvZHJha2UvZHJha2VfYW5ncnkuZ2lmJztcbmltcG9ydCBMT09LX01PVElPTl9EUkFLRSBmcm9tICcuLi9hbmltYXRpb25zL2RyYWtlL2RyYWtlX2xvb2tBcm91bmQuZ2lmJztcbmltcG9ydCBJRExFX01PVElPTl9EUkFLRSBmcm9tICcuLi9hbmltYXRpb25zL2RyYWtlL2RyYWtlX2lkbGUuZ2lmJztcbmltcG9ydCBESVNBUFBPSU5UX0lNR19EUkFLRSBmcm9tICcuLi9hbmltYXRpb25zL2RyYWtlL2RyYWtlX2Rpc2FwcG9pbnQuZ2lmJztcblxuLy8gSW1wb3J0aW5nIGEgbmV3IGNoYXJhY3Rlcj8gQ29weSB0aGUgYmVsb3cgYW5kIGNoYW5nZSB0aGUgTkFNRSB3aXRoIHlvdXIgY2hhcmFjdGVyIG5hbWUuXG4vL1xuLy8gTmFtZSBBbmltYXRpb25zXG4vLyBpbXBvcnQgRU1FUkdFX01PVElPTl9OQU1FIGZyb20gJy4uL2FuaW1hdGlvbnMvbmFtZS9uYW1lX2VtZXJnZS5naWYnO1xuLy8gaW1wb3J0IFBPUF9NT1RJT05fTkFNRSBmcm9tICcuLi9hbmltYXRpb25zL25hbWUvbmFtZV9wb3AuZ2lmJztcbi8vIGltcG9ydCBESVNBUFBFQVJfTU9USU9OX05BTUUgZnJvbSAnLi4vYW5pbWF0aW9ucy9uYW1lL25hbWVfZGlzYXBwZWFyLmdpZic7XG4vLyBpbXBvcnQgQU5HUllfTU9USU9OX05BTUUgZnJvbSAnLi4vYW5pbWF0aW9ucy9uYW1lL25hbWVfYW5ncnkuZ2lmJztcbi8vIGltcG9ydCBMT09LX01PVElPTl9OQU1FIGZyb20gJy4uL2FuaW1hdGlvbnMvbmFtZS9uYW1lX2xvb2tBcm91bmQuZ2lmJztcbi8vIGltcG9ydCBJRExFX01PVElPTl9OQU1FIGZyb20gJy4uL2FuaW1hdGlvbnMvbmFtZS9uYW1lX2lkbGUuZ2lmJztcbi8vIGltcG9ydCBESVNBUFBPSU5UX0lNR19OQU1FIGZyb20gJy4uL2FuaW1hdGlvbnMvbmFtZS9uYW1lX2Rpc2FwcG9pbnQuZ2lmJztcblxuZXhwb3J0IGVudW0gQW5pbWF0aW9uVHlwZSB7XG5cdEVNRVJHRSA9ICdlbWVyZ2UnLFxuXHRQT1BfTU9USU9OID0gJ3BvcF9tb3Rpb24nLFxuXHRESVNBUFBFQVJfTU9USU9OID0gJ2Rpc2FwcGVhcl9tb3Rpb24nLFxuXHRBTkdSWV9NT1RJT04gPSAnYW5ncnlfbW90aW9uJyxcblx0TE9PS19NT1RJT04gPSAnbG9va19tb3Rpb24nLFxuXHRJRExFX01PVElPTiA9ICdpZGxlX21vdGlvbicsXG5cdERJU0FQUE9JTlRfSU1HID0gJ2Rpc2FwcG9pbnRfaW5nJyxcbn1cblxuZXhwb3J0IGNsYXNzIEFuaW1hdGlvbnMge1xuXHRwdWJsaWMgcmVhZG9ubHkgcGx1Z2luOiBHcmFuaXRlUGx1Z2luO1xuXG5cdC8vIENvcHkgYW5kIHBhc3RlIHRoaXMgYmVsb3csIHdoZXJlIG5hbWUgaXMgeW91ciBuZXcgY2hhcmFjdGVyIG5hbWUuXG5cdC8vIHRoZSBtYXBwaW5ncyBmcm9tIGFuIGFuaW1hdGlvbiB0eXBlIHRvIGFuIGFjdHVhbCBpbWFnZSBmaWxlIGZvciB0aGUgbmFtZVxuXHQvLyBwdWJsaWMgcmVhZG9ubHkgbmFtZUFuaW1hdGlvbk1hcDogUmVjb3JkPEFuaW1hdGlvblR5cGUsIHN0cmluZz47XG5cblx0Ly8gdGhlIG1hcHBpbmdzIGZyb20gYW4gYW5pbWF0aW9uIHR5cGUgdG8gYW4gYWN0dWFsIGltYWdlIGZpbGUgZm9yIHRoZSBkcmFrZWxpbmdcblx0cHVibGljIHJlYWRvbmx5IGRyYWtlQW5pbWF0aW9uTWFwOiBSZWNvcmQ8QW5pbWF0aW9uVHlwZSwgc3RyaW5nPjtcblx0Ly8gdGhlIG1hcHBpbmdzIGZyb20gYW4gYW5pbWF0aW9uIHR5cGUgdG8gYW4gYWN0dWFsIGltYWdlIGZpbGUgZm9yIHRoZSBncmFuaXRlXG5cdHB1YmxpYyByZWFkb25seSBnZW1teUFuaW1hdGlvbk1hcDogUmVjb3JkPEFuaW1hdGlvblR5cGUsIHN0cmluZz47XG5cblx0Ly8gbWFwcyBhbiBhbmltYXRpb24gc291cmNlIHRvIHRoZSBjb3JyZXNwb25kaW5nIGFuaW1hdGlvbiBtYXBcblx0cHVibGljIHJlYWRvbmx5IGFuaW1hdGlvblNvdXJjZU1hcDogUmVjb3JkPEFuaW1hdGlvblNvdXJjZVR5cGUsIFJlY29yZDxBbmltYXRpb25UeXBlLCBzdHJpbmc+PjtcblxuXHRjb25zdHJ1Y3RvcihwbHVnaW46IEdyYW5pdGVQbHVnaW4pIHtcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcblxuXHRcdC8vIEFkZCB5b3VyIGNoYXJhY3RlciB0byB0aGUgYW5pbWF0aW9uIG1hcC5cblx0XHQvLyBSZXBsYWNlIG5hbWUgd2l0aCB5b3VyIG5ldyBjaGFyYWN0ZXIncyBuYW1lLlxuXHRcdC8vXG5cdFx0Ly8gXHRcdHRoaXMubmFtZUFuaW1hdGlvbk1hcCA9IHtcblx0XHQvLyBcdFx0XHRbQW5pbWF0aW9uVHlwZS5FTUVSR0VdOiBFTUVSR0VfTU9USU9OX05BTUUsXG5cdFx0Ly8gXHRcdFx0W0FuaW1hdGlvblR5cGUuUE9QX01PVElPTl06IFBPUF9NT1RJT05fTkFNRSxcblx0XHQvLyBcdFx0XHRbQW5pbWF0aW9uVHlwZS5ESVNBUFBFQVJfTU9USU9OXTogRElTQVBQRUFSX01PVElPTl9OQU1FLFxuXHRcdC8vIFx0XHRcdFtBbmltYXRpb25UeXBlLkFOR1JZX01PVElPTl06IEFOR1JZX01PVElPTl9OQU1FLFxuXHRcdC8vIFx0XHRcdFtBbmltYXRpb25UeXBlLkxPT0tfTU9USU9OXTogTE9PS19NT1RJT05fTkFNRSxcblx0XHQvLyBcdFx0XHRbQW5pbWF0aW9uVHlwZS5JRExFX01PVElPTl06IElETEVfTU9USU9OX05BTUUsXG5cdFx0Ly8gXHRcdFx0W0FuaW1hdGlvblR5cGUuRElTQVBQT0lOVF9JTUddOiBESVNBUFBPSU5UX0lNR19OQU1FLFxuXHRcdC8vIFx0XHR9O1xuXG5cdFx0dGhpcy5kcmFrZUFuaW1hdGlvbk1hcCA9IHtcblx0XHRcdFtBbmltYXRpb25UeXBlLkVNRVJHRV06IEVNRVJHRV9NT1RJT05fRFJBS0UsXG5cdFx0XHRbQW5pbWF0aW9uVHlwZS5QT1BfTU9USU9OXTogUE9QX01PVElPTl9EUkFLRSxcblx0XHRcdFtBbmltYXRpb25UeXBlLkRJU0FQUEVBUl9NT1RJT05dOiBESVNBUFBFQVJfTU9USU9OX0RSQUtFLFxuXHRcdFx0W0FuaW1hdGlvblR5cGUuQU5HUllfTU9USU9OXTogQU5HUllfTU9USU9OX0RSQUtFLFxuXHRcdFx0W0FuaW1hdGlvblR5cGUuTE9PS19NT1RJT05dOiBMT09LX01PVElPTl9EUkFLRSxcblx0XHRcdFtBbmltYXRpb25UeXBlLklETEVfTU9USU9OXTogSURMRV9NT1RJT05fRFJBS0UsXG5cdFx0XHRbQW5pbWF0aW9uVHlwZS5ESVNBUFBPSU5UX0lNR106IERJU0FQUE9JTlRfSU1HX0RSQUtFLFxuXHRcdH07XG5cblx0XHR0aGlzLmdlbW15QW5pbWF0aW9uTWFwID0ge1xuXHRcdFx0W0FuaW1hdGlvblR5cGUuRU1FUkdFXTogRU1FUkdFX01PVElPTl9HRU1NWSxcblx0XHRcdFtBbmltYXRpb25UeXBlLlBPUF9NT1RJT05dOiBQT1BfTU9USU9OX0dFTU1ZLFxuXHRcdFx0W0FuaW1hdGlvblR5cGUuRElTQVBQRUFSX01PVElPTl06IERJU0FQUEVBUl9NT1RJT05fR0VNTVksXG5cdFx0XHRbQW5pbWF0aW9uVHlwZS5BTkdSWV9NT1RJT05dOiBBTkdSWV9NT1RJT05fR0VNTVksXG5cdFx0XHRbQW5pbWF0aW9uVHlwZS5MT09LX01PVElPTl06IExPT0tfTU9USU9OX0dFTU1ZLFxuXHRcdFx0W0FuaW1hdGlvblR5cGUuSURMRV9NT1RJT05dOiBJRExFX01PVElPTl9HRU1NWSxcblx0XHRcdFtBbmltYXRpb25UeXBlLkRJU0FQUE9JTlRfSU1HXTogRElTQVBQT0lOVF9JTUdfR0VNTVksXG5cdFx0fTtcblxuXHRcdHRoaXMuYW5pbWF0aW9uU291cmNlTWFwID0ge1xuXHRcdFx0Ly8gQWRkIHlvdXIgY2hhcmFjdGVyIHRvIHRoZSBhbmltYXRpb24gc291cmNlIG1hcCwgd2hlcmUgbmFtZSBpcyB5b3VyIGNoYXJhY3RlciBuYW1lLlxuXHRcdFx0Ly8gW0FuaW1hdGlvblNvdXJjZVR5cGUuTkFNRV06IHRoaXMubmFtZUFuaW1hdGlvbk1hcCxcblx0XHRcdFtBbmltYXRpb25Tb3VyY2VUeXBlLkRSQUtFXTogdGhpcy5kcmFrZUFuaW1hdGlvbk1hcCxcblx0XHRcdFtBbmltYXRpb25Tb3VyY2VUeXBlLkdFTU1ZXTogdGhpcy5nZW1teUFuaW1hdGlvbk1hcCxcblx0XHR9O1xuXG5cdFx0Y29uc29sZS5sb2coJ2dyYW5pdGUgfCBidWlsZCBhbmltYXRpb24gbWFwJywgdGhpcy5hbmltYXRpb25Tb3VyY2VNYXApO1xuXHR9XG5cblx0LyoqXG5cdCAqIFBsYXlzIGEgZ3Jhbml0ZSBhbmltYXRpb24gaW4gdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBhbmltYXRpb24gc291cmNlIHR5cGUgaW5zaWRlIGFuIGVsZW1lbnQuXG5cdCAqXG5cdCAqIEBwYXJhbSBlbCB0aGUgZWxlbWVudCB0byBwbGF5IHRoZSBhbmltYXRpb24gaW5cblx0ICogQHBhcmFtIGFuaW1hdGlvbiB0aGUgYW5pbWF0aW9uIHRvIHBsYXlcblx0ICovXG5cdHB1YmxpYyBwbGF5KGVsOiBIVE1MRWxlbWVudCwgYW5pbWF0aW9uOiBBbmltYXRpb25UeXBlKTogdm9pZCB7XG5cdFx0Y29uc3QgYW5pbWF0aW9uRmlsZSA9IHRoaXMuYW5pbWF0aW9uU291cmNlTWFwW3RoaXMucGx1Z2luLnNldHRpbmdzLmFuaW1hdGlvblNvdXJjZV1bYW5pbWF0aW9uXTtcblxuXHRcdGVsLnNldEF0dHJpYnV0ZSgnc3JjJywgYW5pbWF0aW9uRmlsZSk7XG5cdH1cbn1cbiIsICJleHBvcnQgaW50ZXJmYWNlIFF1b3RlcyB7XG5cdC8vIGdlbmVyYWwgcXVvdGVzIGNhbiBhcHBlYXIgYm90aCBpbiBub3JtYWwgYW5kIGluIHdyaXRpbmcgbW9kZVxuXHRnZW5lcmFsOiBzdHJpbmdbXTtcblx0Ly8gaWRsZSBxdW90ZXMgY2FuIG9ubHkgYXBwZWFyIGluIG5vcm1hbCBtb2RlXG5cdGlkbGU6IHN0cmluZ1tdO1xuXHQvLyB3cml0aW5nIG1vZGUgcXVvdGVzIGNhbiBvbmx5IGFwcGVhciBpbiB3cml0aW5nIG1vZGVcblx0d3JpdGluZ01vZGU6IHN0cmluZ1tdO1xufVxuXG4vLyB0aGVzZSBxdW90ZXMgY2FuIGFwcGVhciBpbiBldmVyeSBhbmltYXRpb24gbW9kZVxuZXhwb3J0IGNvbnN0IEdSQU5JVEVfQkFTRV9RVU9URVM6IFF1b3RlcyA9IHtcblx0Z2VuZXJhbDogW10sXG5cdGlkbGU6IFtcblx0XHRcIllvdSBjYW4ndCBhcnJlc3QgdXMhIFdlIGFscmVhZHkgYXRlIHRoZSBldmlkZW5jZSFcIixcblx0XHRcIkRvbid0IGV2ZXIgc3BsaXQgdGhlIHBhcnR5IVwiLFxuXHRcdFwiSWYgeW91IGtpbGwgYSBoaXZlIG1pbmQsIGlzIHRoYXQgbXVyZGVyIG9yIGdlbm9jaWRlP1wiLFxuXHRcdFwiUm9sbCBpbml0aWF0aXZlIVwiLFxuXHRcdFwiWW91IGNhbiB0cnkhXCIsXG5cdFx0XCJJJ20gbm90IHNob3J0LCBJJ20gY29uY2VudHJhdGVkIGF3ZXNvbWUuXCIsXG5cdFx0XCJJJ20gbm90IGdyZWVkeSwgSSdtIGp1c3QgYWxsZXJnaWMgdG8gcG92ZXJ0eS5cIixcblx0XHRcIkkgZG9uJ3QgYWx3YXlzIGNhc3Qgc3BlbGxzLCBidXQgd2hlbiBJIGRvLCBpdCdzIGZpcmViYWxsLlwiLFxuXHRcdFwiSSBkb24ndCBuZWVkIGx1Y2ssIEkgaGF2ZSBhIGhpZ2ggY2hhcmlzbWEgc3RhdC5cIixcblx0XHRcIkkgZG9uJ3QgYWx3YXlzIGRyaW5rIGFsZSwgYnV0IHdoZW4gSSBkbywgaXQncyB3aXRoIG15IGZlbGxvdyBhZHZlbnR1cmVycyBhZnRlciBzbGF5aW5nIGEgZHJhZ29uLlwiLFxuXHRcdFwiSSBkb24ndCBhbHdheXMgcm9sbCBhIGNyaXRpY2FsIGhpdCwgYnV0IHdoZW4gSSBkbywgdGhlIERNIGZvcmdldHMgdG8gbWFrZSBtZSByZXJvbGwgdGhlIGRhbWFnZS5cIixcblx0XHRcIkkgbWF5IGJlIGNoYW90aWMgbmV1dHJhbCBvbiBwYXBlciwgYnV0IGluIHJlYWxpdHksIEkganVzdCBsaWtlIHRvIHdhdGNoIHRoZSB3b3JsZCBidXJuLlwiLFxuXHRcdFwiSXRcdTIwMTlzIG5vdCBzdGVhbGluZyBpZiBpdCBiZWxvbmdzIHRvIGEgZGVhZCBndXkuXCIsXG5cdFx0XCJXaG8gbmVlZHMgYW4gYXJteSB3aGVuIHlvdSBoYXZlIGEgYmFnIG9mIGhvbGRpbmcgZnVsbCBvZiByb2Nrcz9cIixcblx0XHRcIkxldCBtZSBzaG93IHlvdSBob3cgdG8gd2VhciBhIHNuYWtlLlwiLFxuXHRcdFwiV0hZIFdPVUxEIFlPVSBETyBUSEFUIVwiLFxuXHRcdFwiVGhhdCBkaWNlIG5lZWRzIHRvIGJlIHJldGlyZWQhXCIsXG5cdFx0XCJJIGRvbid0IGtpbGwgd2l0aG91dCByZWFzb24uIEZvcnR1bmF0ZWx5LCBJJ20gYm9yZWQuIFJlYXNvbiBlbm91Z2ghXCIsXG5cdFx0XCJBaCwgbXkgZmF2b3VyZWQgZW5lbXkuIFNvbWV0aGluZyBhbGl2ZS5cIixcblx0XHRcIkkgc2xhcCB0aGUgYmFycmVsIHdpdGggbXkgbWVtYmVyIS4uLiB0aGUgJ2JhcnJlbCcgb3BlbidzIGl0cyBtb3V0aCFcIixcblx0XHRcIkknbSBub3QgZGVwcml2ZWQsIEknbSBkZXByYXZlZC5cIixcblx0XHRcIllvdSBuZWVkIGEgZnJlZSBoYW5kIHRvIGF0dGVtcHQgYSBncmFwcGxlXCIsXG5cdFx0XCJDYXJlZnVsIGhvdyBtdWNoIHlvdSBjYXJyeTsgdGhlIEdNIG1pZ2h0IGFjdHVhbGx5IGFzayB5b3UgdG8gY2FsY3VsYXRlIHlvdXIgaW52ZW50b3J5IHdlaWdodCFcIixcblx0XHRcIkRvbid0IGRvIHRoYXQhIFRoZW4gd2UnbGwgaGF2ZSB0byBnbyBsb29rIHVwIHRoZSBncmFwcGxlIHJ1bGVzIVwiLFxuXHRcdFwiNTAgcGFnZSBiYWNrc3RvcnkuLi4gTk9QRVwiLFxuXHRcdFwiSXQncyBhc3RvdW5kaW5nIGFueW9uZSBjYW4gdW5kZXJzdGFuZCB5b3UsIHdpdGggYWxsIHRob3NlIE5hdCAxIENoYXJpc21hIHJvbGxzLlwiLFxuXHRcdFwiVGhlIGNoZWRkYXIgbW9ua3MgYXJlIGhlcmUgdG8gc2F2ZSB0aGUgZGF5IVwiLFxuXHRcdFwiWW91J3ZlIGJlZW4gR3lnYXhlZC5cIixcblx0XHRcIlNURVAgQVdBWSBGUk9NIFRIRSBQVVJDSEFTRSBNT1JFIERJQ0UgQlVUVE9OXCIsXG5cdFx0XCJBZnRlciB0aG91c2FuZHMgb2YgeWVhcnMsIEkgaGF2ZSBhdHRhaW5lZCBteSBjdXJyZW50IHN0YXRlLCB3aGlsZSB5b3Ugc3RydWdnbGUgdG8gY29tcGxldGUgdGhpcyBzaW1wbGUgbm90ZS5cIixcblx0XHRcIllvdSBhcmUgYSBiYWNrZ3JvdW5kIGNoYXJhY3RlciBpbiB5b3VyIG93biBsaWZlLlwiLFxuXHRcdFwiV2hhdC4uLiBzb3JyeSBXaG8gaXMgdGhlIEJhcmQgZG9pbmcgbm93P1wiLFxuXHRcdFwiRE8gTk9UIHB1dCB0aGUgcG9ydGFibGUgaG9sZSBpbiB0aGUgYmFnIG9mIGhvbGRpbmchXCIsXG5cdFx0XCJETyBOT1QgcHV0IHRoZSBiYWcgb2YgaG9sZGluZyBpbiB0aGUgcG9ydGFibGUgaG9sZSFcIixcblx0XHRcIklmIHRoZSBzaGVkJ3MgYSdSb2NraW5nLi4uIFJVTlwiLFxuXHRdLFxuXHR3cml0aW5nTW9kZTogW1xuXHRcdFwiUGxheWVyJ3MgZG9udCB0YWtlIG5vdGVzLi4uIG1heWJlIHlvdSBzaG91bGQgdHJ5IHRoYXQ/XCIsXG5cdFx0XCJJcyB0aGF0IHRoZSBiZXN0IHlvdSBjYW4gZG8/IEtlZXAgd3JpdGluZyFcIixcblx0XHRcIldyaXRlIGZpcnN0LCBlZGl0b3IgbGF0ZXIuXCIsXG5cdFx0XCJBSSBjb3VsZCBwcm9iYWJseSB3cml0ZSBhIGJldHRlciBub3RlLi4uXCIsXG5cdFx0XCJJIGxvdmUgaGVhcmluZyB5b3VyIGtleWJvYXJkLiBEb24ndCBzdG9wLlwiLFxuXHRcdFwiSG93IGFib3V0IHdlIHJldmlldyBzb21lIG9sZCBub3RlcyB0b2RheT9cIixcblx0XHRcIldoeSBub3QganVzdCB1c2UgYSB0ZW1wbGF0ZT9cIixcblx0XHRcIkRvZXNuJ3QgbWF0dGVyIGhvdyBtdWNoIHlvdSBwbGFuLi4uIHRoZXkgd2lsbCBkZXJhaWwgYW55d2F5IVwiLFxuXHRcdFwiTWF5YmUgaXQncyB0aW1lIHRvIGdvIGdldCBzb21lIHdhdGVyIG9yIGNvZmZlZS5cIixcblx0XHRcIlRoYXQncyBub3QgaG93IHJpdmVycyBhcmUgaW4gcmVhbC1saWZlLi4uXCIsXG5cdFx0XCJBbnl0aGluZyBpcyBiZXR0ZXIgdGhhbiBhIGJsYW5rIHBhZ2UsIGV2ZW4gbWUuIFdyaXRlIHNvbWV0aGluZyFcIixcblx0XHRcIkhhdmUgeW91IGdpdmVuIG91dCBJbnNwaXJhdGlvbiByZWNlbnRseT9cIixcblx0XHRcIkNhbGwgbWUgSmVldmVzLiBJLiBEYXJlLiBZb3UuXCIsXG5cdFx0XCJJIGNhc3QgJ1N1bW1vbiBCaWdnZXIgRmlzaCdcIixcblx0XHRcIkRvIHlvdSB0b3VjaCBpdD9cIixcblx0XHRcIldoYXQgd291bGQgTWF0dCBNZXJjZXIgZG8/XCIsXG5cdFx0XCJUbyBjb250aW51ZSwgcGxlYXNlIGluc2VydCBtb3JlIGNyZWRpdHNcIixcblx0XHRcIkhhdmUgeW91IGNvbnNpZGVyZWQganVzdC4uLiBOb3Q/XCIsXG5cdFx0XCJZb3UgY2FuJ3QganVzdCB3cml0ZSAnSSB3aW4nXCIsXG5cdF0sXG59O1xuXG5leHBvcnQgY29uc3QgR0VNTVlfRVhDTFVTSVZFX1FVT1RFUzogUXVvdGVzID0ge1xuXHRnZW5lcmFsOiBbXSxcblx0aWRsZTogW1xuXHRcdFwiWW91IHBvb3Bpbmc/XCIsXG5cdF0sXG5cdHdyaXRpbmdNb2RlOiBbXSxcbn07XG5cbmV4cG9ydCBjb25zdCBEUkFLRV9FWENMVVNJVkVfUVVPVEVTOiBRdW90ZXMgPSB7XG5cdGdlbmVyYWw6IFtdLFxuXHRpZGxlOiBbXSxcblx0d3JpdGluZ01vZGU6IFtdLFxufTtcblxuLy8gQ29weSBhbmQgcGFzdGUgdGhpcyBhYm92ZS4gQ2hhbmdlIE5BTUUgd2l0aCB5b3VyIG5ldyBjaGFyYWN0ZXJcbi8vIEJlIG1pbmRmdWwgb2YgdGhlIGluZGVudGF0aW9ucyBhcyBjb21tZW50IG1vZGUgc3RyaXBzIHRoZW1cbi8vIGV4cG9ydCBjb25zdCBOQU1FX0VYQ0xVU0lWRV9RVU9URVM6IFF1b3RlcyA9IHtcbi8vIFx0Z2VuZXJhbDogW1xuLy9cbi8vIFx0XSxcbi8vXG4vLyBcdGlkbGU6IFtcblxuLy8gXHRdLFxuLy9cbi8vIFx0d3JpdGluZ01vZGU6IFtcbi8vXHRcIllvdSBjYW4ndCBqdXN0IHdyaXRlICdJIHdpbidcIixcbi8vIFx0XSxcbi8vIH07XG4iLCAiaW1wb3J0IEdyYW5pdGVQbHVnaW4gZnJvbSAnLi9tYWluJztcbmltcG9ydCB7IEFuaW1hdGlvblNvdXJjZVR5cGUgfSBmcm9tICcuL1NldHRpbmcnO1xuaW1wb3J0IHsgR3Jhbml0ZU1vZGUsIEdyYW5pdGVTdGF0ZSB9IGZyb20gJy4vR3Jhbml0ZSc7XG5pbXBvcnQgeyBEUkFLRV9FWENMVVNJVkVfUVVPVEVTLCBHRU1NWV9FWENMVVNJVkVfUVVPVEVTLCBHUkFOSVRFX0JBU0VfUVVPVEVTLCBRdW90ZXMgfSBmcm9tICcuL3F1b3Rlcy9RdW90ZXMnO1xuLy8gV2hlbiB5b3UgbmVlZCB0byBhZGQgYSBjaGFyYWN0ZXIsIGFkZCB0aGUgZm9sbG93aW5nIHRvIHRoZSBhYm92ZTogTkFNRV9FWENMVVNJVkVfUVVPVEVTLFxuLy8gRXhhbXBsZSBpbXBvcnQgeyBOQU1FX0VYQ0xVU0lWRV9RVU9URVMsIERSQUtFX0VYQ0xVU0lWRV9RVU9URVMsIEdFTU1ZX0VYQ0xVU0lWRV9RVU9URVMsIEdSQU5JVEVfQkFTRV9RVU9URVMsIFF1b3RlcyB9IGZyb20gJy4vcXVvdGVzL1F1b3Rlcyc7XG5cbmV4cG9ydCBjbGFzcyBRdW90ZU1hbmFnZXIge1xuXHRwdWJsaWMgcmVhZG9ubHkgcGx1Z2luOiBHcmFuaXRlUGx1Z2luO1xuXG5cdHB1YmxpYyByZWFkb25seSBxdW90ZU1hcDogUmVjb3JkPEFuaW1hdGlvblNvdXJjZVR5cGUsIFJlY29yZDxHcmFuaXRlTW9kZSwgc3RyaW5nW10+PjtcblxuXHRjb25zdHJ1Y3RvcihwbHVnaW46IEdyYW5pdGVQbHVnaW4pIHtcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcblxuXHRcdHRoaXMucXVvdGVNYXAgPSB7XG5cdFx0XHRbQW5pbWF0aW9uU291cmNlVHlwZS5HRU1NWV06IHtcblx0XHRcdFx0W0dyYW5pdGVNb2RlLklETEVdOiB0aGlzLmdldElkbGVRdW90ZXMoR0VNTVlfRVhDTFVTSVZFX1FVT1RFUyksXG5cdFx0XHRcdFtHcmFuaXRlTW9kZS5XUklUSU5HXTogdGhpcy5nZXRXcml0aW5nUXVvdGVzKEdFTU1ZX0VYQ0xVU0lWRV9RVU9URVMpLFxuXHRcdFx0fSxcblx0XHRcdFtBbmltYXRpb25Tb3VyY2VUeXBlLkRSQUtFXToge1xuXHRcdFx0XHRbR3Jhbml0ZU1vZGUuSURMRV06IHRoaXMuZ2V0SWRsZVF1b3RlcyhEUkFLRV9FWENMVVNJVkVfUVVPVEVTKSxcblx0XHRcdFx0W0dyYW5pdGVNb2RlLldSSVRJTkddOiB0aGlzLmdldFdyaXRpbmdRdW90ZXMoRFJBS0VfRVhDTFVTSVZFX1FVT1RFUyksXG5cdFx0XHR9LFxuXHRcdFx0Ly8gQ29weSBhbmQgcGFzdGUgYmVsb3cgdG8gYWRkIHlvdXIgY2hhcmFjdGVyJ3Mgc291cmNlIGhlcmUuXG5cdFx0XHQvLyBSZXBsYWNlIE5BTUUgd2l0aCB5b3VyIG5ldyBjaGFyYWN0ZXIncyBuYW1lXG5cdFx0XHQvL1xuXHRcdFx0Ly8gW0FuaW1hdGlvblNvdXJjZVR5cGUuTkFNRV06IHtcblx0XHRcdC8vIFx0W0dyYW5pdGVNb2RlLklETEVdOiB0aGlzLmdldElkbGVRdW90ZXMoTkFNRV9FWENMVVNJVkVfUVVPVEVTKSxcblx0XHRcdC8vIFx0W0dyYW5pdGVNb2RlLldSSVRJTkddOiB0aGlzLmdldFdyaXRpbmdRdW90ZXMoTkFNRV9FWENMVVNJVkVfUVVPVEVTKSxcblx0XHRcdC8vIH0sXG5cdFx0fTtcblxuXHRcdGNvbnNvbGUubG9nKCdncmFuaXRlIHwgYnVpbGQgcXVvdGUgbWFwJywgdGhpcy5xdW90ZU1hcCk7XG5cdH1cblxuXHRwcml2YXRlIGdldElkbGVRdW90ZXMoZXhjbHVzaXZlUXVvdGVzOiBRdW90ZXMpOiBzdHJpbmdbXSB7XG5cdFx0cmV0dXJuIFsuLi5HUkFOSVRFX0JBU0VfUVVPVEVTLmdlbmVyYWwsIC4uLkdSQU5JVEVfQkFTRV9RVU9URVMuaWRsZSwgLi4uZXhjbHVzaXZlUXVvdGVzLmdlbmVyYWwsIC4uLmV4Y2x1c2l2ZVF1b3Rlcy5pZGxlXTtcblx0fVxuXG5cdHByaXZhdGUgZ2V0V3JpdGluZ1F1b3RlcyhleGNsdXNpdmVRdW90ZXM6IFF1b3Rlcyk6IHN0cmluZ1tdIHtcblx0XHRyZXR1cm4gWy4uLkdSQU5JVEVfQkFTRV9RVU9URVMuZ2VuZXJhbCwgLi4uR1JBTklURV9CQVNFX1FVT1RFUy53cml0aW5nTW9kZSwgLi4uZXhjbHVzaXZlUXVvdGVzLmdlbmVyYWwsIC4uLmV4Y2x1c2l2ZVF1b3Rlcy53cml0aW5nTW9kZV07XG5cdH1cblxuXHRwdWJsaWMgZ2V0UXVvdGUoKTogc3RyaW5nIHtcblx0XHRjb25zdCBxdW90ZXM6IHN0cmluZ1tdID0gdGhpcy5xdW90ZU1hcFt0aGlzLnBsdWdpbi5zZXR0aW5ncy5hbmltYXRpb25Tb3VyY2VdW3RoaXMucGx1Z2luLmdyYW5pdGUubW9kZV07XG5cblx0XHRyZXR1cm4gcXVvdGVzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHF1b3Rlcy5sZW5ndGgpXTtcblx0fVxufVxuIiwgImltcG9ydCB7IEFuaW1hdGlvbnMsIEFuaW1hdGlvblR5cGUgfSBmcm9tICcuL0FuaW1hdGlvbnMnO1xuaW1wb3J0IEdyYW5pdGVQbHVnaW4gZnJvbSAnLi9tYWluJztcbmltcG9ydCB7IFF1b3RlTWFuYWdlciB9IGZyb20gJy4vUXVvdGVNYW5hZ2VyJztcblxuY29uc3QgQlVCQkxFX0RVUkFUSU9OOiBudW1iZXIgPSA1MDAwO1xuXG5leHBvcnQgZW51bSBHcmFuaXRlTW9kZSB7XG5cdElETEUgPSAnSURMRScsXG5cdFdSSVRJTkcgPSAnV1JJVElORycsXG59XG5cbmV4cG9ydCBlbnVtIEdyYW5pdGVTdGF0ZSB7XG5cdFZJU0lCTEUgPSAnVklTSUJMRScsXG5cdElOVklTSUJMRSA9ICdJTlZJU0lCTEUnLFxuXHRESVNBUFBFQVJJTkcgPSAnRElTQVBQRUFSSU5HJyxcblx0QVBQRUFSSU5HID0gJ0FQUEVBUklORycsXG59XG5cbmV4cG9ydCBjbGFzcyBHcmFuaXRlIHtcblx0cHVibGljIHJlYWRvbmx5IHBsdWdpbjogR3Jhbml0ZVBsdWdpbjtcblx0cHJpdmF0ZSByZWFkb25seSBhbmltYXRpb25zOiBBbmltYXRpb25zO1xuXHRwcml2YXRlIHJlYWRvbmx5IHF1b3RlczogUXVvdGVNYW5hZ2VyO1xuXG5cdGdyYW5pdGVFbDogSFRNTEVsZW1lbnQ7XG5cdGltYWdlRWw6IEhUTUxFbGVtZW50O1xuXG5cdHN0YXRlOiBHcmFuaXRlU3RhdGU7XG5cdG1vZGU6IEdyYW5pdGVNb2RlO1xuXG5cdGlkbGVUaW1lb3V0OiBudW1iZXI7XG5cdHdyaXRpbmdNb2RlVGltZW91dDogbnVtYmVyO1xuXG5cdGNvbnN0cnVjdG9yKHBsdWdpbjogR3Jhbml0ZVBsdWdpbikge1xuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xuXG5cdFx0dGhpcy5hbmltYXRpb25zID0gbmV3IEFuaW1hdGlvbnModGhpcy5wbHVnaW4pO1xuXHRcdHRoaXMucXVvdGVzID0gbmV3IFF1b3RlTWFuYWdlcih0aGlzLnBsdWdpbik7XG5cblx0XHR0aGlzLnN0YXRlID0gR3Jhbml0ZVN0YXRlLklOVklTSUJMRTtcblx0XHR0aGlzLm1vZGUgPSBHcmFuaXRlTW9kZS5JRExFO1xuXG5cdFx0dGhpcy5jcmVhdGVHcmFuaXRlRWwoKTtcblxuXHRcdHRoaXMuc3RhcnROZXh0SWRsZVRpbWVvdXQoKTtcblx0fVxuXG5cdGNyZWF0ZUdyYW5pdGVFbCgpIHtcblx0XHR0aGlzLmdyYW5pdGVFbCA9IGNyZWF0ZURpdignZ3Jhbml0ZS1jb250YWluZXInKTtcblx0XHR0aGlzLmdyYW5pdGVFbC5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWwtcG9zaXRpb24nLCAndG9wJyk7XG5cdFx0dGhpcy5ncmFuaXRlRWwuc2V0QXR0cmlidXRlKCdhcmlhLWxhYmVsLWRlbGF5JywgJzAnKTtcblx0XHR0aGlzLmdyYW5pdGVFbC5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWwtY2xhc3NlcycsICdncmFuaXRlLXRvb2x0aXAnKTtcblxuXHRcdHRoaXMuaW1hZ2VFbCA9IHRoaXMuZ3Jhbml0ZUVsLmNyZWF0ZUVsKCdpbWcnLCB7fSk7XG5cblx0XHR0aGlzLmdyYW5pdGVFbC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWVudGVyJywgKCkgPT4ge1xuXHRcdFx0Ly8gaWdub3JlIG1vdXNlIGV2ZW50cyBpbiB3cml0aW5nIG1vZGVcblx0XHRcdGlmICh0aGlzLm1vZGUgPT09IEdyYW5pdGVNb2RlLldSSVRJTkcpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnNheVNvbWV0aGluZyh0cnVlKTtcblx0XHRcdHRoaXMuaWRsZVRpbWVvdXQgJiYgY2xlYXJUaW1lb3V0KHRoaXMuaWRsZVRpbWVvdXQpO1xuXHRcdH0pO1xuXG5cdFx0dGhpcy5ncmFuaXRlRWwuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsICgpID0+IHtcblx0XHRcdC8vIGlnbm9yZSBtb3VzZSBldmVudHMgaW4gd3JpdGluZyBtb2RlXG5cdFx0XHRpZiAodGhpcy5tb2RlID09PSBHcmFuaXRlTW9kZS5XUklUSU5HKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5hbmltYXRpb25zLnBsYXkodGhpcy5pbWFnZUVsLCBBbmltYXRpb25UeXBlLklETEVfTU9USU9OKTtcblx0XHRcdHRoaXMuc3RhcnROZXh0SWRsZVRpbWVvdXQoKTtcblx0XHR9KTtcblxuXHRcdHRoaXMuZ3Jhbml0ZUVsLmhpZGRlbiA9IHRydWU7XG5cdFx0ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZCh0aGlzLmdyYW5pdGVFbCk7XG5cdH1cblxuXHRhc3luYyBhcHBlYXIoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKHRoaXMuc3RhdGUgPT09IEdyYW5pdGVTdGF0ZS5BUFBFQVJJTkcgfHwgdGhpcy5zdGF0ZSA9PT0gR3Jhbml0ZVN0YXRlLlZJU0lCTEUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBzaG93IGhpbVxuXHRcdHRoaXMuc3RhdGUgPSBHcmFuaXRlU3RhdGUuQVBQRUFSSU5HO1xuXHRcdHRoaXMuZ3Jhbml0ZUVsLmhpZGRlbiA9IGZhbHNlO1xuXG5cdFx0Ly8gUXVpY2tlciBpZiB3ZSdyZSBpbiB3cml0aW5nIG1vZGVcblx0XHRpZiAodGhpcy5tb2RlID09PSBHcmFuaXRlTW9kZS5XUklUSU5HKSB7XG5cdFx0XHR0aGlzLmFuaW1hdGlvbnMucGxheSh0aGlzLmltYWdlRWwsIEFuaW1hdGlvblR5cGUuUE9QX01PVElPTik7XG5cblx0XHRcdGF3YWl0IHNsZWVwKDE4MDApO1xuXG5cdFx0XHQvLyBhbm90aGVyIGFuaW1hdGlvbiBvdmVycm9kZSB0aGlzIGFuaW1hdGlvbiwgc28gd2UgcXVpdFxuXHRcdFx0aWYgKHRoaXMuc3RhdGUgIT09IEdyYW5pdGVTdGF0ZS5BUFBFQVJJTkcpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnN0YXRlID0gR3Jhbml0ZVN0YXRlLlZJU0lCTEU7XG5cdFx0XHR0aGlzLnNheVNvbWV0aGluZyh0cnVlKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5hbmltYXRpb25zLnBsYXkodGhpcy5pbWFnZUVsLCBBbmltYXRpb25UeXBlLkVNRVJHRSk7XG5cblx0XHRcdGF3YWl0IHNsZWVwKDM4MDApO1xuXG5cdFx0XHQvLyBhbm90aGVyIGFuaW1hdGlvbiBvdmVycm9kZSB0aGlzIGFuaW1hdGlvbiwgc28gd2UgcXVpdFxuXHRcdFx0aWYgKHRoaXMuc3RhdGUgIT09IEdyYW5pdGVTdGF0ZS5BUFBFQVJJTkcpIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnN0YXRlID0gR3Jhbml0ZVN0YXRlLlZJU0lCTEU7XG5cdFx0XHR0aGlzLmFuaW1hdGlvbnMucGxheSh0aGlzLmltYWdlRWwsIEFuaW1hdGlvblR5cGUuSURMRV9NT1RJT04pO1xuXHRcdH1cblx0fVxuXG5cdGFzeW5jIGRpc2FwcGVhcigpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHQvLyBkb24ndCBtYWtlIGdyYW5pdGUgZGlzYXBwZWFyIHdoaWxlIHRoZXkgYXJlIGFscmVhZHkgbGVhdmluZ1xuXHRcdGlmICh0aGlzLnN0YXRlID09PSBHcmFuaXRlU3RhdGUuRElTQVBQRUFSSU5HIHx8IHRoaXMuc3RhdGUgPT09IEdyYW5pdGVTdGF0ZS5JTlZJU0lCTEUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR0aGlzLnN0YXRlID0gR3Jhbml0ZVN0YXRlLkRJU0FQUEVBUklORztcblxuXHRcdGlmICh0aGlzLmlkbGVUaW1lb3V0KSB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMuaWRsZVRpbWVvdXQpO1xuXHRcdGlmICh0aGlzLndyaXRpbmdNb2RlVGltZW91dCkgd2luZG93LmNsZWFyVGltZW91dCh0aGlzLndyaXRpbmdNb2RlVGltZW91dCk7XG5cblx0XHR0aGlzLmFuaW1hdGlvbnMucGxheSh0aGlzLmltYWdlRWwsIEFuaW1hdGlvblR5cGUuRElTQVBQRUFSX01PVElPTik7XG5cdFx0Ly8gcmVtb3RlIHRvb2x0aXBcblx0XHR0aGlzLmdyYW5pdGVFbC5kaXNwYXRjaEV2ZW50KG5ldyBNb3VzZUV2ZW50KCdtb3VzZW91dCcsIHsgYnViYmxlczogdHJ1ZSwgY2xpZW50WDogMTAsIGNsaWVudFk6IDEwIH0pKTtcblxuXHRcdGF3YWl0IHNsZWVwKDEzMDApO1xuXG5cdFx0Ly8gYW5vdGhlciBhbmltYXRpb24gb3ZlcnJvZGUgdGhpcyBhbmltYXRpb24sIHNvIHdlIHF1aXRcblx0XHRpZiAodGhpcy5zdGF0ZSAhPT0gR3Jhbml0ZVN0YXRlLkRJU0FQUEVBUklORykge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRoaXMuc3RhdGUgPSBHcmFuaXRlU3RhdGUuSU5WSVNJQkxFO1xuXHRcdHRoaXMuZ3Jhbml0ZUVsLmhpZGRlbiA9IHRydWU7XG5cdH1cblxuXHRhc3luYyByZXNldCgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAodGhpcy5zdGF0ZSA9PT0gR3Jhbml0ZVN0YXRlLkRJU0FQUEVBUklORyB8fCB0aGlzLnN0YXRlID09PSBHcmFuaXRlU3RhdGUuSU5WSVNJQkxFKSB7XG5cdFx0XHRhd2FpdCB0aGlzLmFwcGVhcigpO1xuXHRcdH1cblxuXHRcdHRoaXMuYW5pbWF0aW9ucy5wbGF5KHRoaXMuaW1hZ2VFbCwgQW5pbWF0aW9uVHlwZS5JRExFX01PVElPTik7XG5cdH1cblxuXHRvbkVkaXRvckNoYW5nZSgpOiB2b2lkIHtcblx0XHRpZiAodGhpcy5tb2RlID09PSBHcmFuaXRlTW9kZS5JRExFKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuc3RhdGUgIT09IEdyYW5pdGVTdGF0ZS5ESVNBUFBFQVJJTkcgJiYgdGhpcy5zdGF0ZSAhPT0gR3Jhbml0ZVN0YXRlLklOVklTSUJMRSkge1xuXHRcdFx0dGhpcy5kaXNhcHBlYXIoKTtcblx0XHR9XG5cdFx0dGhpcy5zZXRXcml0aW5nTW9kZVRpbWVvdXQoKTtcblx0fVxuXG5cdGVudGVyV3JpdGluZ01vZGUoKTogdm9pZCB7XG5cdFx0dGhpcy5tb2RlID0gR3Jhbml0ZU1vZGUuV1JJVElORztcblx0XHR0aGlzLmRpc2FwcGVhcigpO1xuXG5cdFx0dGhpcy5zZXRXcml0aW5nTW9kZVRpbWVvdXQoKTtcblx0fVxuXG5cdGxlYXZlV3JpdGluZ01vZGUoKSB7XG5cdFx0dGhpcy5tb2RlID0gR3Jhbml0ZU1vZGUuSURMRTtcblx0XHR0aGlzLnJlc2V0KCk7XG5cblx0XHR3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMud3JpdGluZ01vZGVUaW1lb3V0KTtcblx0fVxuXG5cdHNldFdyaXRpbmdNb2RlVGltZW91dCgpOiB2b2lkIHtcblx0XHRpZiAodGhpcy53cml0aW5nTW9kZVRpbWVvdXQpIHtcblx0XHRcdHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy53cml0aW5nTW9kZVRpbWVvdXQpO1xuXHRcdH1cblxuXHRcdHRoaXMud3JpdGluZ01vZGVUaW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0aWYgKHRoaXMubW9kZSA9PT0gR3Jhbml0ZU1vZGUuV1JJVElORykge1xuXHRcdFx0XHR0aGlzLmFwcGVhcigpO1xuXHRcdFx0fVxuXHRcdH0sIHRoaXMucGx1Z2luLnNldHRpbmdzLndyaXRpbmdNb2RlR3JhY2VQZXJpb2QgKiAxMDAwKTtcblx0fVxuXG5cdHN0YXJ0TmV4dElkbGVUaW1lb3V0KCk6IHZvaWQge1xuXHRcdC8vIGlmIHRoZSBzZXQgdGltZSBpcyA1IG1pbnV0ZXMsIHRoaXMgd2lsbCBzZXQgdGltZW91dCB0byBiZSBhIHJhbmRvbSB0aW1lIGJldHdlZW4gNC02IG1pbnV0ZXNcblx0XHQvLyB0aGUgcmFuZ2Ugd2lsbCBiZSA4MCUgLSAxMjAlXG5cdFx0Y29uc3QgcmFuZG9tRmFjdG9yID0gMC44ICsgMC40ICogTWF0aC5yYW5kb20oKTtcblx0XHRjb25zdCByYW5kb21pemVkVGltZW91dCA9IHJhbmRvbUZhY3RvciAqIHRoaXMucGx1Z2luLnNldHRpbmdzLmlkbGVUYWxrRnJlcXVlbmN5ICogNjAwMDA7XG5cblx0XHRpZiAodGhpcy5pZGxlVGltZW91dCkge1xuXHRcdFx0d2luZG93LmNsZWFyVGltZW91dCh0aGlzLmlkbGVUaW1lb3V0KTtcblx0XHR9XG5cblx0XHR0aGlzLmlkbGVUaW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0aWYgKHRoaXMubW9kZSA9PT0gR3Jhbml0ZU1vZGUuV1JJVElORykge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuc2F5U29tZXRoaW5nKGZhbHNlKTtcblx0XHRcdHRoaXMuc3RhcnROZXh0SWRsZVRpbWVvdXQoKTtcblx0XHR9LCByYW5kb21pemVkVGltZW91dCk7XG5cdH1cblxuXHRhc3luYyBzYXlTb21ldGhpbmcocGVyc2lzdGVudDogYm9vbGVhbik6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICh0aGlzLnN0YXRlICE9PSBHcmFuaXRlU3RhdGUuVklTSUJMRSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGNvbnN0IHF1b3RlOiBzdHJpbmcgPSB0aGlzLnF1b3Rlcy5nZXRRdW90ZSgpO1xuXG5cdFx0dGhpcy5ncmFuaXRlRWwuc2V0QXR0cignYXJpYS1sYWJlbCcsIHF1b3RlKTtcblx0XHR0aGlzLmdyYW5pdGVFbC5zZXRBdHRyKCdhcmlhLWxhYmVsLXBvc2l0aW9uJywgJ3RvcCcpO1xuXHRcdHRoaXMuZ3Jhbml0ZUVsLmRpc3BhdGNoRXZlbnQobmV3IE1vdXNlRXZlbnQoJ21vdXNlb3ZlcicsIHsgYnViYmxlczogdHJ1ZSwgY2xpZW50WDogMTAsIGNsaWVudFk6IDEwIH0pKTtcblxuXHRcdGlmICh0aGlzLm1vZGUgPT09IEdyYW5pdGVNb2RlLldSSVRJTkcpIHtcblx0XHRcdHRoaXMuYW5pbWF0aW9ucy5wbGF5KHRoaXMuaW1hZ2VFbCwgQW5pbWF0aW9uVHlwZS5BTkdSWV9NT1RJT04pO1xuXG5cdFx0XHRhd2FpdCBzbGVlcCgxMDAwKTtcblxuXHRcdFx0dGhpcy5hbmltYXRpb25zLnBsYXkodGhpcy5pbWFnZUVsLCBBbmltYXRpb25UeXBlLkRJU0FQUE9JTlRfSU1HKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5hbmltYXRpb25zLnBsYXkodGhpcy5pbWFnZUVsLCBBbmltYXRpb25UeXBlLkxPT0tfTU9USU9OKTtcblx0XHR9XG5cblx0XHRpZiAoIXBlcnNpc3RlbnQpIHtcblx0XHRcdGF3YWl0IHNsZWVwKEJVQkJMRV9EVVJBVElPTik7XG5cblx0XHRcdHRoaXMuZ3Jhbml0ZUVsLmRpc3BhdGNoRXZlbnQobmV3IE1vdXNlRXZlbnQoJ21vdXNlb3V0JywgeyBidWJibGVzOiB0cnVlLCBjbGllbnRYOiAxMCwgY2xpZW50WTogMTAgfSkpO1xuXHRcdFx0dGhpcy5hbmltYXRpb25zLnBsYXkodGhpcy5pbWFnZUVsLCBBbmltYXRpb25UeXBlLklETEVfTU9USU9OKTtcblx0XHR9XG5cdH1cbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxJQUFBQSxtQkFBaUM7OztBQ0FqQyxzQkFBK0M7QUFtQnhDLElBQU0sbUJBQW9DO0FBQUEsRUFDaEQsaUJBQWlCO0FBQUEsRUFDakIsbUJBQW1CO0FBQUEsRUFDbkIsd0JBQXdCO0FBQ3pCO0FBRU8sSUFBTSxxQkFBTixjQUFpQyxpQ0FBaUI7QUFBQSxFQUd4RCxZQUFZLEtBQVUsUUFBdUI7QUFDNUMsVUFBTSxLQUFLLE1BQU07QUFDakIsU0FBSyxTQUFTO0FBQUEsRUFDZjtBQUFBLEVBRUEsVUFBZ0I7QUFDZixVQUFNLEVBQUUsWUFBWSxJQUFJO0FBRXhCLGdCQUFZLE1BQU07QUFFbEIsUUFBSSx3QkFBUSxXQUFXLEVBQ3JCLFFBQVEsa0JBQWtCLEVBQzFCLFFBQVEs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 diff --git a/manifest.json b/manifest.json index c1bf8c3..a676016 100644 --- a/manifest.json +++ b/manifest.json @@ -1,11 +1,10 @@ { "id": "granite", "name": "Granite", - "version": "0.1.1", - "minAppVersion": "0.19.0", + "version": "0.1.2", + "minAppVersion": "1.4.0", "description": "A Goal Reinforcing And Note Improving Tiny Entity", - "author": "Obsidian, and the Obsidian TTRPG Community", + "author": "Obsidian Team, and the Obsidian TTRPG Community", "authorUrl": "https://github.com/Obsidian-TTRPG-Community/gemmy_ttrpg", - "fundingUrl": "", "isDesktopOnly": false } diff --git a/package.json b/package.json index f3980fe..0ddaa3c 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "format": "prettier --write ." }, "keywords": [], - "author": "Obsidian TTRPG Community", + "author": "Obsidian, and the Obsidian TTRPG Community", "license": "MIT", "devDependencies": { "@types/node": "^16.11.6", diff --git a/src/Animations.ts b/src/Animations.ts index 7ee10d7..372cacb 100644 --- a/src/Animations.ts +++ b/src/Animations.ts @@ -19,6 +19,17 @@ import LOOK_MOTION_DRAKE from '../animations/drake/drake_lookAround.gif'; import IDLE_MOTION_DRAKE from '../animations/drake/drake_idle.gif'; import DISAPPOINT_IMG_DRAKE from '../animations/drake/drake_disappoint.gif'; +// Importing a new character? Copy the below and change the NAME with your character name. +// +// Name Animations +// import EMERGE_MOTION_NAME from '../animations/name/name_emerge.gif'; +// import POP_MOTION_NAME from '../animations/name/name_pop.gif'; +// import DISAPPEAR_MOTION_NAME from '../animations/name/name_disappear.gif'; +// import ANGRY_MOTION_NAME from '../animations/name/name_angry.gif'; +// import LOOK_MOTION_NAME from '../animations/name/name_lookAround.gif'; +// import IDLE_MOTION_NAME from '../animations/name/name_idle.gif'; +// import DISAPPOINT_IMG_NAME from '../animations/name/name_disappoint.gif'; + export enum AnimationType { EMERGE = 'emerge', POP_MOTION = 'pop_motion', @@ -32,6 +43,10 @@ export enum AnimationType { export class Animations { public readonly plugin: GranitePlugin; + // Copy and paste this below, where name is your new character name. + // the mappings from an animation type to an actual image file for the name + // public readonly nameAnimationMap: Record; + // the mappings from an animation type to an actual image file for the drakeling public readonly drakeAnimationMap: Record; // the mappings from an animation type to an actual image file for the granite @@ -43,6 +58,19 @@ export class Animations { constructor(plugin: GranitePlugin) { this.plugin = plugin; + // Add your character to the animation map. + // Replace name with your new character's name. + // + // this.nameAnimationMap = { + // [AnimationType.EMERGE]: EMERGE_MOTION_NAME, + // [AnimationType.POP_MOTION]: POP_MOTION_NAME, + // [AnimationType.DISAPPEAR_MOTION]: DISAPPEAR_MOTION_NAME, + // [AnimationType.ANGRY_MOTION]: ANGRY_MOTION_NAME, + // [AnimationType.LOOK_MOTION]: LOOK_MOTION_NAME, + // [AnimationType.IDLE_MOTION]: IDLE_MOTION_NAME, + // [AnimationType.DISAPPOINT_IMG]: DISAPPOINT_IMG_NAME, + // }; + this.drakeAnimationMap = { [AnimationType.EMERGE]: EMERGE_MOTION_DRAKE, [AnimationType.POP_MOTION]: POP_MOTION_DRAKE, @@ -64,6 +92,8 @@ export class Animations { }; this.animationSourceMap = { + // Add your character to the animation source map, where name is your character name. + // [AnimationSourceType.NAME]: this.nameAnimationMap, [AnimationSourceType.DRAKE]: this.drakeAnimationMap, [AnimationSourceType.GEMMY]: this.gemmyAnimationMap, }; diff --git a/src/QuoteManager.ts b/src/QuoteManager.ts index 269395c..e71916c 100644 --- a/src/QuoteManager.ts +++ b/src/QuoteManager.ts @@ -2,6 +2,8 @@ import GranitePlugin from './main'; import { AnimationSourceType } from './Setting'; import { GraniteMode, GraniteState } from './Granite'; import { DRAKE_EXCLUSIVE_QUOTES, GEMMY_EXCLUSIVE_QUOTES, GRANITE_BASE_QUOTES, Quotes } from './quotes/Quotes'; +// When you need to add a character, add the following to the above: NAME_EXCLUSIVE_QUOTES, +// Example import { NAME_EXCLUSIVE_QUOTES, DRAKE_EXCLUSIVE_QUOTES, GEMMY_EXCLUSIVE_QUOTES, GRANITE_BASE_QUOTES, Quotes } from './quotes/Quotes'; export class QuoteManager { public readonly plugin: GranitePlugin; @@ -20,6 +22,13 @@ export class QuoteManager { [GraniteMode.IDLE]: this.getIdleQuotes(DRAKE_EXCLUSIVE_QUOTES), [GraniteMode.WRITING]: this.getWritingQuotes(DRAKE_EXCLUSIVE_QUOTES), }, + // Copy and paste below to add your character's source here. + // Replace NAME with your new character's name + // + // [AnimationSourceType.NAME]: { + // [GraniteMode.IDLE]: this.getIdleQuotes(NAME_EXCLUSIVE_QUOTES), + // [GraniteMode.WRITING]: this.getWritingQuotes(NAME_EXCLUSIVE_QUOTES), + // }, }; console.log('granite | build quote map', this.quoteMap); diff --git a/src/Setting.ts b/src/Setting.ts index ab59e89..ccfdcb0 100644 --- a/src/Setting.ts +++ b/src/Setting.ts @@ -4,6 +4,8 @@ import GranitePlugin from './main'; export enum AnimationSourceType { GEMMY = 'gemmy', DRAKE = 'drake', + // When you need to add a new character, add the following above: + // NAME = 'name', } export interface GraniteSettings { @@ -41,6 +43,8 @@ export class GraniteSettingsTab extends PluginSettingTab { dropdown .addOption(AnimationSourceType.GEMMY, 'Gemmy') .addOption(AnimationSourceType.DRAKE, 'Drake') + // When you need to add a new character, copy and paste the following line above this one, and change the NAME + // .addOption(AnimationSourceType.NAME, 'Name') .setValue(this.plugin.settings.animationSource) .onChange(async value => { // Explicitly cast the value to the correct type diff --git a/src/main.ts b/src/main.ts index b5d39d8..f574f4a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -67,6 +67,12 @@ export default class GranitePlugin extends Plugin { this.granite.disappear(); } + // Within the async, update your new character by adding them to the load list, + // where name is your character name and type is the type of creature it is. + // if (this.settings.animationSource === 'type') { + // this.settings.animationSource = AnimationSourceType.NAME; + // } + async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); diff --git a/src/quotes/Quotes.ts b/src/quotes/Quotes.ts index c843896..84ebd0d 100644 --- a/src/quotes/Quotes.ts +++ b/src/quotes/Quotes.ts @@ -13,62 +13,67 @@ export const GRANITE_BASE_QUOTES: Quotes = { idle: [ "You can't arrest us! We already ate the evidence!", "Don't ever split the party!", - 'If you kill a hive mind, is that murder or genocide?', - 'Roll initiative!', - 'You can try!', + "If you kill a hive mind, is that murder or genocide?", + "Roll initiative!", + "You can try!", "I'm not short, I'm concentrated awesome.", "I'm not greedy, I'm just allergic to poverty.", "I don't always cast spells, but when I do, it's fireball.", "I don't need luck, I have a high charisma stat.", "I don't always drink ale, but when I do, it's with my fellow adventurers after slaying a dragon.", "I don't always roll a critical hit, but when I do, the DM forgets to make me reroll the damage.", - 'I may be chaotic neutral on paper, but in reality, I just like to watch the world burn.', - 'It’s not stealing if it belongs to a dead guy.', - 'Who needs an army when you have a bag of holding full of rocks?', - 'Let me show you how to wear a snake.', - 'WHY WOULD YOU DO THAT!', - 'That dice needs to be retired!', + "I may be chaotic neutral on paper, but in reality, I just like to watch the world burn.", + "It’s not stealing if it belongs to a dead guy.", + "Who needs an army when you have a bag of holding full of rocks?", + "Let me show you how to wear a snake.", + "WHY WOULD YOU DO THAT!", + "That dice needs to be retired!", "I don't kill without reason. Fortunately, I'm bored. Reason enough!", - 'Ah, my favoured enemy. Something alive.', + "Ah, my favoured enemy. Something alive.", "I slap the barrel with my member!... the 'barrel' open's its mouth!", "I'm not deprived, I'm depraved.", - 'You need a free hand to attempt a grapple', - `Careful how much you carry; the GM might actually ask you to calculate your inventory weight!`, - `Don't do that! Then we'll have to go look up the grapple rules!`, - `50 page backstory... NOPE`, - `It's astounding anyone can understand you, with all those Nat 1 Charisma rolls.`, - `The cheddar monks are here to save the day!`, - `You've been Gygaxed.`, - `STEP AWAY FROM THE PURCHASE MORE DICE BUTTON`, - `After thousands of years, I have attained my current state, while you struggle to complete this simple note.`, - `You are a background character in your own life.`, + "You need a free hand to attempt a grapple", + "Careful how much you carry; the GM might actually ask you to calculate your inventory weight!", + "Don't do that! Then we'll have to go look up the grapple rules!", + "50 page backstory... NOPE", + "It's astounding anyone can understand you, with all those Nat 1 Charisma rolls.", + "The cheddar monks are here to save the day!", + "You've been Gygaxed.", + "STEP AWAY FROM THE PURCHASE MORE DICE BUTTON", + "After thousands of years, I have attained my current state, while you struggle to complete this simple note.", + "You are a background character in your own life.", + "What... sorry Who is the Bard doing now?", + "DO NOT put the portable hole in the bag of holding!", + "DO NOT put the bag of holding in the portable hole!", + "If the shed's a'Rocking... RUN", ], writingMode: [ - `Player's dont take notes... maybe you should try that?`, - `Is that the best you can do? Keep writing!`, - `Write first, editor later.`, - `AI could probably write a better note...`, - `I love hearing your keyboard. Don't stop.`, - `How about we review some old notes today?`, - `Why not just use a template?`, - `Doesn't matter how much you plan... they will derail anyway!`, - `Maybe it's time to go get some water or coffee.`, - `That's not how rivers are in real-life...`, - `Anything is better than a blank page, even me. Write something!`, - `Have you given out Inspiration recently?`, - `Call me Jeeves. I. Dare. You.`, - `I cast 'Summon Bigger Fish`, - `Do you touch it?`, - `What would Matt Mercer do?`, - `To continue, please insert more credits`, - `Have you considered just... Not?`, + "Player's dont take notes... maybe you should try that?", + "Is that the best you can do? Keep writing!", + "Write first, editor later.", + "AI could probably write a better note...", + "I love hearing your keyboard. Don't stop.", + "How about we review some old notes today?", + "Why not just use a template?", + "Doesn't matter how much you plan... they will derail anyway!", + "Maybe it's time to go get some water or coffee.", + "That's not how rivers are in real-life...", + "Anything is better than a blank page, even me. Write something!", + "Have you given out Inspiration recently?", + "Call me Jeeves. I. Dare. You.", + "I cast 'Summon Bigger Fish'", + "Do you touch it?", + "What would Matt Mercer do?", + "To continue, please insert more credits", + "Have you considered just... Not?", + "You can't just write 'I win'", ], }; export const GEMMY_EXCLUSIVE_QUOTES: Quotes = { general: [], idle: [ - `You pooping?`, + "You pooping?", ], writingMode: [], }; @@ -78,3 +83,19 @@ export const DRAKE_EXCLUSIVE_QUOTES: Quotes = { idle: [], writingMode: [], }; + +// Copy and paste this above. Change NAME with your new character +// Be mindful of the indentations as comment mode strips them +// export const NAME_EXCLUSIVE_QUOTES: Quotes = { +// general: [ +// +// ], +// +// idle: [ + +// ], +// +// writingMode: [ +// "You can't just write 'I win'", +// ], +// }; diff --git a/styles.css b/styles.css index e099106..dc296f6 100644 --- a/styles.css +++ b/styles.css @@ -1,12 +1,3 @@ -/* - -This CSS file will be included with your plugin, and -available in the app when your plugin is enabled. - -If your plugin does not need CSS, delete this file. - -*/ - :root { --granite-size: 80px; }