@angular/core
Version:
Angular - the core framework
374 lines • 39.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* A static-level representation of all style or class bindings/values
* associated with a `TNode`.
*
* The `TStylingContext` unites all template styling bindings (i.e.
* `[class]` and `[style]` bindings) as well as all host-level
* styling bindings (for components and directives) together into
* a single manifest. It is used each time there are one or more
* styling bindings present for an element.
*
* The styling context is stored on a `TNode` on and there are
* two instances of it: one for classes and another for styles.
*
* ```typescript
* tNode.styles = [ ... a context only for styles ... ];
* tNode.classes = [ ... a context only for classes ... ];
* ```
*
* Due to the fact the the `TStylingContext` is stored on a `TNode`
* this means that all data within the context is static. Instead of
* storing actual styling binding values, the lView binding index values
* are stored within the context. (static nature means it is more compact.)
*
* ```typescript
* // <div [class.active]="c" // lView binding index = 20
* // [style.width]="x" // lView binding index = 21
* // [style.height]="y"> // lView binding index = 22
* tNode.stylesContext = [
* 0, // the context config value
*
* 0b001, // guard mask for width
* 2, // total entries for width
* 'width', // the property name
* 21, // the binding location for the "x" binding in the lView
* null,
*
* 0b010, // guard mask for height
* 2, // total entries for height
* 'height', // the property name
* 22, // the binding location for the "y" binding in the lView
* null,
* ];
*
* tNode.classesContext = [
* 0, // the context config value
*
* 0b001, // guard mask for active
* 2, // total entries for active
* 'active', // the property name
* 20, // the binding location for the "c" binding in the lView
* null,
* ];
* ```
*
* Entry value present in an entry (called a tuple) within the
* styling context is as follows:
*
* ```typescript
* context = [
* CONFIG, // the styling context config value
* //...
* guardMask,
* totalEntries,
* propName,
* bindingIndices...,
* defaultValue
* ];
* ```
*
* Below is a breakdown of each value:
*
* - **guardMask**:
* A numeric value where each bit represents a binding index
* location. Each binding index location is assigned based on
* a local counter value that increments each time an instruction
* is called:
*
* ```
* <div [style.width]="x" // binding index = 21 (counter index = 0)
* [style.height]="y"> // binding index = 22 (counter index = 1)
* ```
*
* In the example code above, if the `width` value where to change
* then the first bit in the local bit mask value would be flipped
* (and the second bit for when `height`).
*
* If and when there are more than 32 binding sources in the context
* (more than 32 `[style/class]` bindings) then the bit masking will
* overflow and we are left with a situation where a `-1` value will
* represent the bit mask. Due to the way that JavaScript handles
* negative values, when the bit mask is `-1` then all bits within
* that value will be automatically flipped (this is a quick and
* efficient way to flip all bits on the mask when a special kind
* of caching scenario occurs or when there are more than 32 bindings).
*
* - **totalEntries**:
* Each property present in the contains various binding sources of
* where the styling data could come from. This includes template
* level bindings, directive/component host bindings as well as the
* default value (or static value) all writing to the same property.
* This value depicts how many binding source entries exist for the
* property.
*
* The reason why the totalEntries value is needed is because the
* styling context is dynamic in size and it's not possible
* for the flushing or update algorithms to know when and where
* a property starts and ends without it.
*
* - **propName**:
* The CSS property name or class name (e.g `width` or `active`).
*
* - **bindingIndices...**:
* A series of numeric binding values that reflect where in the
* lView to find the style/class values associated with the property.
* Each value is in order in terms of priority (templates are first,
* then directives and then components). When the context is flushed
* and the style/class values are applied to the element (this happens
* inside of the `stylingApply` instruction) then the flushing code
* will keep checking each binding index against the associated lView
* to find the first style/class value that is non-null.
*
* - **defaultValue**:
* This is the default that will always be applied to the element if
* and when all other binding sources return a result that is null.
* Usually this value is null but it can also be a static value that
* is intercepted when the tNode is first constructured (e.g.
* `<div style="width:200px">` has a default value of `200px` for
* the `width` property).
*
* Each time a new binding is encountered it is registered into the
* context. The context then is continually updated until the first
* styling apply call has been called (this is triggered by the
* `stylingApply()` instruction for the active element).
*
* # How Styles/Classes are Rendered
* Each time a styling instruction (e.g. `[class.name]`, `[style.prop]`,
* etc...) is executed, the associated `lView` for the view is updated
* at the current binding location. Also, when this happens, a local
* counter value is incremented. If the binding value has changed then
* a local `bitMask` variable is updated with the specific bit based
* on the counter value.
*
* Below is a lightweight example of what happens when a single style
* property is updated (i.e. `<div [style.prop]="val">`):
*
* ```typescript
* function updateStyleProp(prop: string, value: string) {
* const lView = getLView();
* const bindingIndex = BINDING_INDEX++;
* const indexForStyle = localStylesCounter++;
* if (lView[bindingIndex] !== value) {
* lView[bindingIndex] = value;
* localBitMaskForStyles |= 1 << indexForStyle;
* }
* }
* ```
*
* ## The Apply Algorithm
* As explained above, each time a binding updates its value, the resulting
* value is stored in the `lView` array. These styling values have yet to
* be flushed to the element.
*
* Once all the styling instructions have been evaluated, then the styling
* context(s) are flushed to the element. When this happens, the context will
* be iterated over (property by property) and each binding source will be
* examined and the first non-null value will be applied to the element.
*
* Let's say that we the following template code:
*
* ```html
* <div [style.width]="w1" dir-that-set-width="w2"></div>
* ```
*
* There are two styling bindings in the code above and they both write
* to the `width` property. When styling is flushed on the element, the
* algorithm will try and figure out which one of these values to write
* to the element.
*
* In order to figure out which value to apply, the following
* binding prioritization is adhered to:
*
* 1. First template-level styling bindings are applied (if present).
* This includes things like `[style.width]` and `[class.active]`.
*
* 2. Second are styling-level host bindings present in directives.
* (if there are sub/super directives present then the sub directives
* are applied first).
*
* 3. Third are styling-level host bindings present in components.
* (if there are sub/super components present then the sub directives
* are applied first).
*
* This means that in the code above the styling binding present in the
* template is applied first and, only if its falsy, then the directive
* styling binding for width will be applied.
*
* ### What about map-based styling bindings?
* Map-based styling bindings are activated when there are one or more
* `[style]` and/or `[class]` bindings present on an element. When this
* code is activated, the apply algorithm will iterate over each map
* entry and apply each styling value to the element with the same
* prioritization rules as above.
*
* For the algorithm to apply styling values efficiently, the
* styling map entries must be applied in sync (property by property)
* with prop-based bindings. (The map-based algorithm is described
* more inside of the `render3/styling_next/map_based_bindings.ts` file.)
*
* ## Sanitization
* Sanitization is used to prevent invalid style values from being applied to
* the element.
*
* It is enabled in two cases:
*
* 1. The `styleSanitizer(sanitizerFn)` instruction was called (just before any other
* styling instructions are run).
*
* 2. The component/directive `LView` instance has a sanitizer object attached to it
* (this happens when `renderComponent` is executed with a `sanitizer` value or
* if the ngModule contains a sanitizer provider attached to it).
*
* If and when sanitization is active then all property/value entries will be evaluated
* through the active sanitizer before they are applied to the element (or the styling
* debug handler).
*
* If a `Sanitizer` object is used (via the `LView[SANITIZER]` value) then that object
* will be used for every property.
*
* If a `StyleSanitizerFn` function is used (via the `styleSanitizer`) then it will be
* called in two ways:
*
* 1. property validation mode: this will be called early to mark whether a property
* should be sanitized or not at during the flushing stage.
*
* 2. value sanitization mode: this will be called during the flushing stage and will
* run the sanitizer function against the value before applying it to the element.
*
* If sanitization returns an empty value then that empty value will be applied
* to the element.
* @record
*/
export function TStylingContext() { }
if (false) {
/* Skipping unnamed member:
[TStylingContextIndex.ConfigPosition]: TStylingConfigFlags;*/
/* Skipping unnamed member:
[TStylingContextIndex.MaxDirectiveIndexPosition]: number;*/
/* Skipping unnamed member:
[TStylingContextIndex.MapBindingsBitGuardPosition]: number;*/
/* Skipping unnamed member:
[TStylingContextIndex.MapBindingsValuesCountPosition]: number;*/
/* Skipping unnamed member:
[TStylingContextIndex.MapBindingsPropPosition]: string;*/
}
/** @enum {number} */
const TStylingConfigFlags = {
/**
* The initial state of the styling context config
*/
Initial: 0,
/**
* A flag which marks the context as being locked.
*
* The styling context is constructed across an element template
* function as well as any associated hostBindings functions. When
* this occurs, the context itself is open to mutation and only once
* it has been flushed once then it will be locked for good (no extra
* bindings can be added to it).
*/
Locked: 1,
};
export { TStylingConfigFlags };
/** @enum {number} */
const TStylingContextIndex = {
ConfigPosition: 0,
MaxDirectiveIndexPosition: 1,
// index/offset values for map-based entries (i.e. `[style]`
// and `[class] bindings).
MapBindingsPosition: 2,
MapBindingsBitGuardPosition: 2,
MapBindingsValuesCountPosition: 3,
MapBindingsPropPosition: 4,
MapBindingsBindingsStartPosition: 5,
// each tuple entry in the context
// (mask, count, prop, ...bindings||default-value)
ConfigAndGuardOffset: 0,
ValuesCountOffset: 1,
PropOffset: 2,
BindingsStartOffset: 3,
};
export { TStylingContextIndex };
/** @enum {number} */
const TStylingContextPropConfigFlags = {
Default: 0,
SanitizationRequired: 1,
TotalBits: 1,
Mask: 1,
};
export { TStylingContextPropConfigFlags };
/**
* A function used to apply or remove styling from an element for a given property.
* @record
*/
export function ApplyStylingFn() { }
/**
* Array-based representation of a key/value array.
*
* The format of the array is "property", "value", "property2",
* "value2", etc...
*
* The first value in the array is reserved to store the instance
* of the key/value array that was used to populate the property/
* value entries that take place in the remainder of the array.
* @record
*/
export function LStylingMap() { }
if (false) {
/* Skipping unnamed member:
[LStylingMapIndex.RawValuePosition]: {}|string|null;*/
}
/** @enum {number} */
const LStylingMapIndex = {
/** The location of the raw key/value map instance used last to populate the array entries */
RawValuePosition: 0,
/** Where the values start in the array */
ValuesStartPosition: 1,
/** The size of each property/value entry */
TupleSize: 2,
/** The offset for the property entry in the tuple */
PropOffset: 0,
/** The offset for the value entry in the tuple */
ValueOffset: 1,
};
export { LStylingMapIndex };
/**
* Used to apply/traverse across all map-based styling entries up to the provided `targetProp`
* value.
*
* When called, each of the map-based `LStylingMap` entries (which are stored in
* the provided `LStylingData` array) will be iterated over. Depending on the provided
* `mode` value, each prop/value entry may be applied or skipped over.
*
* If `targetProp` value is provided the iteration code will stop once it reaches
* the property (if found). Otherwise if the target property is not encountered then
* it will stop once it reaches the next value that appears alphabetically after it.
*
* If a `defaultValue` is provided then it will be applied to the element only if the
* `targetProp` property value is encountered and the value associated with the target
* property is `null`. The reason why the `defaultValue` is needed is to avoid having the
* algorithm apply a `null` value and then apply a default value afterwards (this would
* end up being two style property writes).
*
* @return whether or not the target property was reached and its value was
* applied to the element.
* @record
*/
export function SyncStylingMapsFn() { }
/** @enum {number} */
const StylingMapsSyncMode = {
/** Only traverse values (no prop/value styling entries get applied) */
TraverseValues: 0,
/** Apply every prop/value styling entry to the element */
ApplyAllValues: 1,
/** Only apply the target prop/value entry */
ApplyTargetProp: 2,
/** Skip applying the target prop/value entry */
SkipTargetProp: 4,
};
export { StylingMapsSyncMode };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3JlbmRlcjMvc3R5bGluZ19uZXh0L2ludGVyZmFjZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFzUUEscUNBcUJDOzs7Ozs7Ozs7Ozs7Ozs7SUFPQzs7T0FFRztJQUNILFVBQWE7SUFFYjs7Ozs7Ozs7T0FRRztJQUNILFNBQVk7Ozs7O0lBT1osaUJBQWtCO0lBQ2xCLDRCQUE2QjtJQUU3Qiw0REFBNEQ7SUFDNUQsMEJBQTBCO0lBQzFCLHNCQUF1QjtJQUN2Qiw4QkFBK0I7SUFDL0IsaUNBQWtDO0lBQ2xDLDBCQUEyQjtJQUMzQixtQ0FBb0M7SUFFcEMsa0NBQWtDO0lBQ2xDLGtEQUFrRDtJQUNsRCx1QkFBd0I7SUFDeEIsb0JBQXFCO0lBQ3JCLGFBQWM7SUFDZCxzQkFBdUI7Ozs7O0lBT3ZCLFVBQWE7SUFDYix1QkFBMEI7SUFDMUIsWUFBYTtJQUNiLE9BQVU7Ozs7Ozs7QUFNWixvQ0FHQzs7Ozs7Ozs7Ozs7O0FBc0JELGlDQUVDOzs7Ozs7O0lBTUMsNkZBQTZGO0lBQzdGLG1CQUFvQjtJQUVwQiwwQ0FBMEM7SUFDMUMsc0JBQXVCO0lBRXZCLDRDQUE0QztJQUM1QyxZQUFhO0lBRWIscURBQXFEO0lBQ3JELGFBQWM7SUFFZCxrREFBa0Q7SUFDbEQsY0FBZTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXdCakIsdUNBSUM7OztJQU1DLHVFQUF1RTtJQUN2RSxpQkFBc0I7SUFFdEIsMERBQTBEO0lBQzFELGlCQUFzQjtJQUV0Qiw2Q0FBNkM7SUFDN0Msa0JBQXVCO0lBRXZCLGdEQUFnRDtJQUNoRCxpQkFBc0IiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiogQGxpY2Vuc2VcbiogQ29weXJpZ2h0IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4qXG4qIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4qIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiovXG5pbXBvcnQge1N0eWxlU2FuaXRpemVGbn0gZnJvbSAnLi4vLi4vc2FuaXRpemF0aW9uL3N0eWxlX3Nhbml0aXplcic7XG5pbXBvcnQge1Byb2NlZHVyYWxSZW5kZXJlcjMsIFJFbGVtZW50LCBSZW5kZXJlcjN9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVuZGVyZXInO1xuaW1wb3J0IHtMVmlld30gZnJvbSAnLi4vaW50ZXJmYWNlcy92aWV3JztcblxuLyoqXG4gKiAtLS0tLS0tLVxuICpcbiAqIFRoaXMgZmlsZSBjb250YWlucyB0aGUgY29yZSBpbnRlcmZhY2VzIGZvciBzdHlsaW5nIGluIEFuZ3VsYXIuXG4gKlxuICogVG8gbGVhcm4gbW9yZSBhYm91dCB0aGUgYWxnb3JpdGhtIHNlZSBgVFN0eWxpbmdDb250ZXh0YC5cbiAqXG4gKiAtLS0tLS0tLVxuICovXG5cbi8qKlxuICogQSBzdGF0aWMtbGV2ZWwgcmVwcmVzZW50YXRpb24gb2YgYWxsIHN0eWxlIG9yIGNsYXNzIGJpbmRpbmdzL3ZhbHVlc1xuICogYXNzb2NpYXRlZCB3aXRoIGEgYFROb2RlYC5cbiAqXG4gKiBUaGUgYFRTdHlsaW5nQ29udGV4dGAgdW5pdGVzIGFsbCB0ZW1wbGF0ZSBzdHlsaW5nIGJpbmRpbmdzIChpLmUuXG4gKiBgW2NsYXNzXWAgYW5kIGBbc3R5bGVdYCBiaW5kaW5ncykgYXMgd2VsbCBhcyBhbGwgaG9zdC1sZXZlbFxuICogc3R5bGluZyBiaW5kaW5ncyAoZm9yIGNvbXBvbmVudHMgYW5kIGRpcmVjdGl2ZXMpIHRvZ2V0aGVyIGludG9cbiAqIGEgc2luZ2xlIG1hbmlmZXN0LiBJdCBpcyB1c2VkIGVhY2ggdGltZSB0aGVyZSBhcmUgb25lIG9yIG1vcmVcbiAqIHN0eWxpbmcgYmluZGluZ3MgcHJlc2VudCBmb3IgYW4gZWxlbWVudC5cbiAqXG4gKiBUaGUgc3R5bGluZyBjb250ZXh0IGlzIHN0b3JlZCBvbiBhIGBUTm9kZWAgb24gYW5kIHRoZXJlIGFyZVxuICogdHdvIGluc3RhbmNlcyBvZiBpdDogb25lIGZvciBjbGFzc2VzIGFuZCBhbm90aGVyIGZvciBzdHlsZXMuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogdE5vZGUuc3R5bGVzID0gWyAuLi4gYSBjb250ZXh0IG9ubHkgZm9yIHN0eWxlcyAuLi4gXTtcbiAqIHROb2RlLmNsYXNzZXMgPSBbIC4uLiBhIGNvbnRleHQgb25seSBmb3IgY2xhc3NlcyAuLi4gXTtcbiAqIGBgYFxuICpcbiAqIER1ZSB0byB0aGUgZmFjdCB0aGUgdGhlIGBUU3R5bGluZ0NvbnRleHRgIGlzIHN0b3JlZCBvbiBhIGBUTm9kZWBcbiAqIHRoaXMgbWVhbnMgdGhhdCBhbGwgZGF0YSB3aXRoaW4gdGhlIGNvbnRleHQgaXMgc3RhdGljLiBJbnN0ZWFkIG9mXG4gKiBzdG9yaW5nIGFjdHVhbCBzdHlsaW5nIGJpbmRpbmcgdmFsdWVzLCB0aGUgbFZpZXcgYmluZGluZyBpbmRleCB2YWx1ZXNcbiAqIGFyZSBzdG9yZWQgd2l0aGluIHRoZSBjb250ZXh0LiAoc3RhdGljIG5hdHVyZSBtZWFucyBpdCBpcyBtb3JlIGNvbXBhY3QuKVxuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gPGRpdiBbY2xhc3MuYWN0aXZlXT1cImNcIiAgLy8gbFZpZXcgYmluZGluZyBpbmRleCA9IDIwXG4gKiAvLyAgICAgIFtzdHlsZS53aWR0aF09XCJ4XCIgICAvLyBsVmlldyBiaW5kaW5nIGluZGV4ID0gMjFcbiAqIC8vICAgICAgW3N0eWxlLmhlaWdodF09XCJ5XCI+IC8vIGxWaWV3IGJpbmRpbmcgaW5kZXggPSAyMlxuICogdE5vZGUuc3R5bGVzQ29udGV4dCA9IFtcbiAqICAgMCwgLy8gdGhlIGNvbnRleHQgY29uZmlnIHZhbHVlXG4gKlxuICogICAwYjAwMSwgLy8gZ3VhcmQgbWFzayBmb3Igd2lkdGhcbiAqICAgMiwgLy8gdG90YWwgZW50cmllcyBmb3Igd2lkdGhcbiAqICAgJ3dpZHRoJywgLy8gdGhlIHByb3BlcnR5IG5hbWVcbiAqICAgMjEsIC8vIHRoZSBiaW5kaW5nIGxvY2F0aW9uIGZvciB0aGUgXCJ4XCIgYmluZGluZyBpbiB0aGUgbFZpZXdcbiAqICAgbnVsbCxcbiAqXG4gKiAgIDBiMDEwLCAvLyBndWFyZCBtYXNrIGZvciBoZWlnaHRcbiAqICAgMiwgLy8gdG90YWwgZW50cmllcyBmb3IgaGVpZ2h0XG4gKiAgICdoZWlnaHQnLCAvLyB0aGUgcHJvcGVydHkgbmFtZVxuICogICAyMiwgLy8gdGhlIGJpbmRpbmcgbG9jYXRpb24gZm9yIHRoZSBcInlcIiBiaW5kaW5nIGluIHRoZSBsVmlld1xuICogICBudWxsLFxuICogXTtcbiAqXG4gKiB0Tm9kZS5jbGFzc2VzQ29udGV4dCA9IFtcbiAqICAgMCwgLy8gdGhlIGNvbnRleHQgY29uZmlnIHZhbHVlXG4gKlxuICogICAwYjAwMSwgLy8gZ3VhcmQgbWFzayBmb3IgYWN0aXZlXG4gKiAgIDIsIC8vIHRvdGFsIGVudHJpZXMgZm9yIGFjdGl2ZVxuICogICAnYWN0aXZlJywgLy8gdGhlIHByb3BlcnR5IG5hbWVcbiAqICAgMjAsIC8vIHRoZSBiaW5kaW5nIGxvY2F0aW9uIGZvciB0aGUgXCJjXCIgYmluZGluZyBpbiB0aGUgbFZpZXdcbiAqICAgbnVsbCxcbiAqIF07XG4gKiBgYGBcbiAqXG4gKiBFbnRyeSB2YWx1ZSBwcmVzZW50IGluIGFuIGVudHJ5IChjYWxsZWQgYSB0dXBsZSkgd2l0aGluIHRoZVxuICogc3R5bGluZyBjb250ZXh0IGlzIGFzIGZvbGxvd3M6XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogY29udGV4dCA9IFtcbiAqICAgQ09ORklHLCAvLyB0aGUgc3R5bGluZyBjb250ZXh0IGNvbmZpZyB2YWx1ZVxuICogICAvLy4uLlxuICogICBndWFyZE1hc2ssXG4gKiAgIHRvdGFsRW50cmllcyxcbiAqICAgcHJvcE5hbWUsXG4gKiAgIGJpbmRpbmdJbmRpY2VzLi4uLFxuICogICBkZWZhdWx0VmFsdWVcbiAqIF07XG4gKiBgYGBcbiAqXG4gKiBCZWxvdyBpcyBhIGJyZWFrZG93biBvZiBlYWNoIHZhbHVlOlxuICpcbiAqIC0gKipndWFyZE1hc2sqKjpcbiAqICAgQSBudW1lcmljIHZhbHVlIHdoZXJlIGVhY2ggYml0IHJlcHJlc2VudHMgYSBiaW5kaW5nIGluZGV4XG4gKiAgIGxvY2F0aW9uLiBFYWNoIGJpbmRpbmcgaW5kZXggbG9jYXRpb24gaXMgYXNzaWduZWQgYmFzZWQgb25cbiAqICAgYSBsb2NhbCBjb3VudGVyIHZhbHVlIHRoYXQgaW5jcmVtZW50cyBlYWNoIHRpbWUgYW4gaW5zdHJ1Y3Rpb25cbiAqICAgaXMgY2FsbGVkOlxuICpcbiAqIGBgYFxuICogPGRpdiBbc3R5bGUud2lkdGhdPVwieFwiICAgLy8gYmluZGluZyBpbmRleCA9IDIxIChjb3VudGVyIGluZGV4ID0gMClcbiAqICAgICAgW3N0eWxlLmhlaWdodF09XCJ5XCI+IC8vIGJpbmRpbmcgaW5kZXggPSAyMiAoY291bnRlciBpbmRleCA9IDEpXG4gKiBgYGBcbiAqXG4gKiAgIEluIHRoZSBleGFtcGxlIGNvZGUgYWJvdmUsIGlmIHRoZSBgd2lkdGhgIHZhbHVlIHdoZXJlIHRvIGNoYW5nZVxuICogICB0aGVuIHRoZSBmaXJzdCBiaXQgaW4gdGhlIGxvY2FsIGJpdCBtYXNrIHZhbHVlIHdvdWxkIGJlIGZsaXBwZWRcbiAqICAgKGFuZCB0aGUgc2Vjb25kIGJpdCBmb3Igd2hlbiBgaGVpZ2h0YCkuXG4gKlxuICogICBJZiBhbmQgd2hlbiB0aGVyZSBhcmUgbW9yZSB0aGFuIDMyIGJpbmRpbmcgc291cmNlcyBpbiB0aGUgY29udGV4dFxuICogICAobW9yZSB0aGFuIDMyIGBbc3R5bGUvY2xhc3NdYCBiaW5kaW5ncykgdGhlbiB0aGUgYml0IG1hc2tpbmcgd2lsbFxuICogICBvdmVyZmxvdyBhbmQgd2UgYXJlIGxlZnQgd2l0aCBhIHNpdHVhdGlvbiB3aGVyZSBhIGAtMWAgdmFsdWUgd2lsbFxuICogICByZXByZXNlbnQgdGhlIGJpdCBtYXNrLiBEdWUgdG8gdGhlIHdheSB0aGF0IEphdmFTY3JpcHQgaGFuZGxlc1xuICogICBuZWdhdGl2ZSB2YWx1ZXMsIHdoZW4gdGhlIGJpdCBtYXNrIGlzIGAtMWAgdGhlbiBhbGwgYml0cyB3aXRoaW5cbiAqICAgdGhhdCB2YWx1ZSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgZmxpcHBlZCAodGhpcyBpcyBhIHF1aWNrIGFuZFxuICogICBlZmZpY2llbnQgd2F5IHRvIGZsaXAgYWxsIGJpdHMgb24gdGhlIG1hc2sgd2hlbiBhIHNwZWNpYWwga2luZFxuICogICBvZiBjYWNoaW5nIHNjZW5hcmlvIG9jY3VycyBvciB3aGVuIHRoZXJlIGFyZSBtb3JlIHRoYW4gMzIgYmluZGluZ3MpLlxuICpcbiAqIC0gKip0b3RhbEVudHJpZXMqKjpcbiAqICAgRWFjaCBwcm9wZXJ0eSBwcmVzZW50IGluIHRoZSBjb250YWlucyB2YXJpb3VzIGJpbmRpbmcgc291cmNlcyBvZlxuICogICB3aGVyZSB0aGUgc3R5bGluZyBkYXRhIGNvdWxkIGNvbWUgZnJvbS4gVGhpcyBpbmNsdWRlcyB0ZW1wbGF0ZVxuICogICBsZXZlbCBiaW5kaW5ncywgZGlyZWN0aXZlL2NvbXBvbmVudCBob3N0IGJpbmRpbmdzIGFzIHdlbGwgYXMgdGhlXG4gKiAgIGRlZmF1bHQgdmFsdWUgKG9yIHN0YXRpYyB2YWx1ZSkgYWxsIHdyaXRpbmcgdG8gdGhlIHNhbWUgcHJvcGVydHkuXG4gKiAgIFRoaXMgdmFsdWUgZGVwaWN0cyBob3cgbWFueSBiaW5kaW5nIHNvdXJjZSBlbnRyaWVzIGV4aXN0IGZvciB0aGVcbiAqICAgcHJvcGVydHkuXG4gKlxuICogICBUaGUgcmVhc29uIHdoeSB0aGUgdG90YWxFbnRyaWVzIHZhbHVlIGlzIG5lZWRlZCBpcyBiZWNhdXNlIHRoZVxuICogICBzdHlsaW5nIGNvbnRleHQgaXMgZHluYW1pYyBpbiBzaXplIGFuZCBpdCdzIG5vdCBwb3NzaWJsZVxuICogICBmb3IgdGhlIGZsdXNoaW5nIG9yIHVwZGF0ZSBhbGdvcml0aG1zIHRvIGtub3cgd2hlbiBhbmQgd2hlcmVcbiAqICAgYSBwcm9wZXJ0eSBzdGFydHMgYW5kIGVuZHMgd2l0aG91dCBpdC5cbiAqXG4gKiAtICoqcHJvcE5hbWUqKjpcbiAqICAgVGhlIENTUyBwcm9wZXJ0eSBuYW1lIG9yIGNsYXNzIG5hbWUgKGUuZyBgd2lkdGhgIG9yIGBhY3RpdmVgKS5cbiAqXG4gKiAtICoqYmluZGluZ0luZGljZXMuLi4qKjpcbiAqICAgQSBzZXJpZXMgb2YgbnVtZXJpYyBiaW5kaW5nIHZhbHVlcyB0aGF0IHJlZmxlY3Qgd2hlcmUgaW4gdGhlXG4gKiAgIGxWaWV3IHRvIGZpbmQgdGhlIHN0eWxlL2NsYXNzIHZhbHVlcyBhc3NvY2lhdGVkIHdpdGggdGhlIHByb3BlcnR5LlxuICogICBFYWNoIHZhbHVlIGlzIGluIG9yZGVyIGluIHRlcm1zIG9mIHByaW9yaXR5ICh0ZW1wbGF0ZXMgYXJlIGZpcnN0LFxuICogICB0aGVuIGRpcmVjdGl2ZXMgYW5kIHRoZW4gY29tcG9uZW50cykuIFdoZW4gdGhlIGNvbnRleHQgaXMgZmx1c2hlZFxuICogICBhbmQgdGhlIHN0eWxlL2NsYXNzIHZhbHVlcyBhcmUgYXBwbGllZCB0byB0aGUgZWxlbWVudCAodGhpcyBoYXBwZW5zXG4gKiAgIGluc2lkZSBvZiB0aGUgYHN0eWxpbmdBcHBseWAgaW5zdHJ1Y3Rpb24pIHRoZW4gdGhlIGZsdXNoaW5nIGNvZGVcbiAqICAgd2lsbCBrZWVwIGNoZWNraW5nIGVhY2ggYmluZGluZyBpbmRleCBhZ2FpbnN0IHRoZSBhc3NvY2lhdGVkIGxWaWV3XG4gKiAgIHRvIGZpbmQgdGhlIGZpcnN0IHN0eWxlL2NsYXNzIHZhbHVlIHRoYXQgaXMgbm9uLW51bGwuXG4gKlxuICogLSAqKmRlZmF1bHRWYWx1ZSoqOlxuICogICBUaGlzIGlzIHRoZSBkZWZhdWx0IHRoYXQgd2lsbCBhbHdheXMgYmUgYXBwbGllZCB0byB0aGUgZWxlbWVudCBpZlxuICogICBhbmQgd2hlbiBhbGwgb3RoZXIgYmluZGluZyBzb3VyY2VzIHJldHVybiBhIHJlc3VsdCB0aGF0IGlzIG51bGwuXG4gKiAgIFVzdWFsbHkgdGhpcyB2YWx1ZSBpcyBudWxsIGJ1dCBpdCBjYW4gYWxzbyBiZSBhIHN0YXRpYyB2YWx1ZSB0aGF0XG4gKiAgIGlzIGludGVyY2VwdGVkIHdoZW4gdGhlIHROb2RlIGlzIGZpcnN0IGNvbnN0cnVjdHVyZWQgKGUuZy5cbiAqICAgYDxkaXYgc3R5bGU9XCJ3aWR0aDoyMDBweFwiPmAgaGFzIGEgZGVmYXVsdCB2YWx1ZSBvZiBgMjAwcHhgIGZvclxuICogICB0aGUgYHdpZHRoYCBwcm9wZXJ0eSkuXG4gKlxuICogRWFjaCB0aW1lIGEgbmV3IGJpbmRpbmcgaXMgZW5jb3VudGVyZWQgaXQgaXMgcmVnaXN0ZXJlZCBpbnRvIHRoZVxuICogY29udGV4dC4gVGhlIGNvbnRleHQgdGhlbiBpcyBjb250aW51YWxseSB1cGRhdGVkIHVudGlsIHRoZSBmaXJzdFxuICogc3R5bGluZyBhcHBseSBjYWxsIGhhcyBiZWVuIGNhbGxlZCAodGhpcyBpcyB0cmlnZ2VyZWQgYnkgdGhlXG4gKiBgc3R5bGluZ0FwcGx5KClgIGluc3RydWN0aW9uIGZvciB0aGUgYWN0aXZlIGVsZW1lbnQpLlxuICpcbiAqICMgSG93IFN0eWxlcy9DbGFzc2VzIGFyZSBSZW5kZXJlZFxuICogRWFjaCB0aW1lIGEgc3R5bGluZyBpbnN0cnVjdGlvbiAoZS5nLiBgW2NsYXNzLm5hbWVdYCwgYFtzdHlsZS5wcm9wXWAsXG4gKiBldGMuLi4pIGlzIGV4ZWN1dGVkLCB0aGUgYXNzb2NpYXRlZCBgbFZpZXdgIGZvciB0aGUgdmlldyBpcyB1cGRhdGVkXG4gKiBhdCB0aGUgY3VycmVudCBiaW5kaW5nIGxvY2F0aW9uLiBBbHNvLCB3aGVuIHRoaXMgaGFwcGVucywgYSBsb2NhbFxuICogY291bnRlciB2YWx1ZSBpcyBpbmNyZW1lbnRlZC4gSWYgdGhlIGJpbmRpbmcgdmFsdWUgaGFzIGNoYW5nZWQgdGhlblxuICogYSBsb2NhbCBgYml0TWFza2AgdmFyaWFibGUgaXMgdXBkYXRlZCB3aXRoIHRoZSBzcGVjaWZpYyBiaXQgYmFzZWRcbiAqIG9uIHRoZSBjb3VudGVyIHZhbHVlLlxuICpcbiAqIEJlbG93IGlzIGEgbGlnaHR3ZWlnaHQgZXhhbXBsZSBvZiB3aGF0IGhhcHBlbnMgd2hlbiBhIHNpbmdsZSBzdHlsZVxuICogcHJvcGVydHkgaXMgdXBkYXRlZCAoaS5lLiBgPGRpdiBbc3R5bGUucHJvcF09XCJ2YWxcIj5gKTpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBmdW5jdGlvbiB1cGRhdGVTdHlsZVByb3AocHJvcDogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKSB7XG4gKiAgIGNvbnN0IGxWaWV3ID0gZ2V0TFZpZXcoKTtcbiAqICAgY29uc3QgYmluZGluZ0luZGV4ID0gQklORElOR19JTkRFWCsrO1xuICogICBjb25zdCBpbmRleEZvclN0eWxlID0gbG9jYWxTdHlsZXNDb3VudGVyKys7XG4gKiAgIGlmIChsVmlld1tiaW5kaW5nSW5kZXhdICE9PSB2YWx1ZSkge1xuICogICAgIGxWaWV3W2JpbmRpbmdJbmRleF0gPSB2YWx1ZTtcbiAqICAgICBsb2NhbEJpdE1hc2tGb3JTdHlsZXMgfD0gMSA8PCBpbmRleEZvclN0eWxlO1xuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAjIyBUaGUgQXBwbHkgQWxnb3JpdGhtXG4gKiBBcyBleHBsYWluZWQgYWJvdmUsIGVhY2ggdGltZSBhIGJpbmRpbmcgdXBkYXRlcyBpdHMgdmFsdWUsIHRoZSByZXN1bHRpbmdcbiAqIHZhbHVlIGlzIHN0b3JlZCBpbiB0aGUgYGxWaWV3YCBhcnJheS4gVGhlc2Ugc3R5bGluZyB2YWx1ZXMgaGF2ZSB5ZXQgdG9cbiAqIGJlIGZsdXNoZWQgdG8gdGhlIGVsZW1lbnQuXG4gKlxuICogT25jZSBhbGwgdGhlIHN0eWxpbmcgaW5zdHJ1Y3Rpb25zIGhhdmUgYmVlbiBldmFsdWF0ZWQsIHRoZW4gdGhlIHN0eWxpbmdcbiAqIGNvbnRleHQocykgYXJlIGZsdXNoZWQgdG8gdGhlIGVsZW1lbnQuIFdoZW4gdGhpcyBoYXBwZW5zLCB0aGUgY29udGV4dCB3aWxsXG4gKiBiZSBpdGVyYXRlZCBvdmVyIChwcm9wZXJ0eSBieSBwcm9wZXJ0eSkgYW5kIGVhY2ggYmluZGluZyBzb3VyY2Ugd2lsbCBiZVxuICogZXhhbWluZWQgYW5kIHRoZSBmaXJzdCBub24tbnVsbCB2YWx1ZSB3aWxsIGJlIGFwcGxpZWQgdG8gdGhlIGVsZW1lbnQuXG4gKlxuICogTGV0J3Mgc2F5IHRoYXQgd2UgdGhlIGZvbGxvd2luZyB0ZW1wbGF0ZSBjb2RlOlxuICpcbiAqIGBgYGh0bWxcbiAqIDxkaXYgW3N0eWxlLndpZHRoXT1cIncxXCIgZGlyLXRoYXQtc2V0LXdpZHRoPVwidzJcIj48L2Rpdj5cbiAqIGBgYFxuICpcbiAqIFRoZXJlIGFyZSB0d28gc3R5bGluZyBiaW5kaW5ncyBpbiB0aGUgY29kZSBhYm92ZSBhbmQgdGhleSBib3RoIHdyaXRlXG4gKiB0byB0aGUgYHdpZHRoYCBwcm9wZXJ0eS4gV2hlbiBzdHlsaW5nIGlzIGZsdXNoZWQgb24gdGhlIGVsZW1lbnQsIHRoZVxuICogYWxnb3JpdGhtIHdpbGwgdHJ5IGFuZCBmaWd1cmUgb3V0IHdoaWNoIG9uZSBvZiB0aGVzZSB2YWx1ZXMgdG8gd3JpdGVcbiAqIHRvIHRoZSBlbGVtZW50LlxuICpcbiAqIEluIG9yZGVyIHRvIGZpZ3VyZSBvdXQgd2hpY2ggdmFsdWUgdG8gYXBwbHksIHRoZSBmb2xsb3dpbmdcbiAqIGJpbmRpbmcgcHJpb3JpdGl6YXRpb24gaXMgYWRoZXJlZCB0bzpcbiAqXG4gKiAgIDEuIEZpcnN0IHRlbXBsYXRlLWxldmVsIHN0eWxpbmcgYmluZGluZ3MgYXJlIGFwcGxpZWQgKGlmIHByZXNlbnQpLlxuICogICAgICBUaGlzIGluY2x1ZGVzIHRoaW5ncyBsaWtlIGBbc3R5bGUud2lkdGhdYCBhbmQgYFtjbGFzcy5hY3RpdmVdYC5cbiAqXG4gKiAgIDIuIFNlY29uZCBhcmUgc3R5bGluZy1sZXZlbCBob3N0IGJpbmRpbmdzIHByZXNlbnQgaW4gZGlyZWN0aXZlcy5cbiAqICAgICAgKGlmIHRoZXJlIGFyZSBzdWIvc3VwZXIgZGlyZWN0aXZlcyBwcmVzZW50IHRoZW4gdGhlIHN1YiBkaXJlY3RpdmVzXG4gKiAgICAgIGFyZSBhcHBsaWVkIGZpcnN0KS5cbiAqXG4gKiAgIDMuIFRoaXJkIGFyZSBzdHlsaW5nLWxldmVsIGhvc3QgYmluZGluZ3MgcHJlc2VudCBpbiBjb21wb25lbnRzLlxuICogICAgICAoaWYgdGhlcmUgYXJlIHN1Yi9zdXBlciBjb21wb25lbnRzIHByZXNlbnQgdGhlbiB0aGUgc3ViIGRpcmVjdGl2ZXNcbiAqICAgICAgYXJlIGFwcGxpZWQgZmlyc3QpLlxuICpcbiAqIFRoaXMgbWVhbnMgdGhhdCBpbiB0aGUgY29kZSBhYm92ZSB0aGUgc3R5bGluZyBiaW5kaW5nIHByZXNlbnQgaW4gdGhlXG4gKiB0ZW1wbGF0ZSBpcyBhcHBsaWVkIGZpcnN0IGFuZCwgb25seSBpZiBpdHMgZmFsc3ksIHRoZW4gdGhlIGRpcmVjdGl2ZVxuICogc3R5bGluZyBiaW5kaW5nIGZvciB3aWR0aCB3aWxsIGJlIGFwcGxpZWQuXG4gKlxuICogIyMjIFdoYXQgYWJvdXQgbWFwLWJhc2VkIHN0eWxpbmcgYmluZGluZ3M/XG4gKiBNYXAtYmFzZWQgc3R5bGluZyBiaW5kaW5ncyBhcmUgYWN0aXZhdGVkIHdoZW4gdGhlcmUgYXJlIG9uZSBvciBtb3JlXG4gKiBgW3N0eWxlXWAgYW5kL29yIGBbY2xhc3NdYCBiaW5kaW5ncyBwcmVzZW50IG9uIGFuIGVsZW1lbnQuIFdoZW4gdGhpc1xuICogY29kZSBpcyBhY3RpdmF0ZWQsIHRoZSBhcHBseSBhbGdvcml0aG0gd2lsbCBpdGVyYXRlIG92ZXIgZWFjaCBtYXBcbiAqIGVudHJ5IGFuZCBhcHBseSBlYWNoIHN0eWxpbmcgdmFsdWUgdG8gdGhlIGVsZW1lbnQgd2l0aCB0aGUgc2FtZVxuICogcHJpb3JpdGl6YXRpb24gcnVsZXMgYXMgYWJvdmUuXG4gKlxuICogRm9yIHRoZSBhbGdvcml0aG0gdG8gYXBwbHkgc3R5bGluZyB2YWx1ZXMgZWZmaWNpZW50bHksIHRoZVxuICogc3R5bGluZyBtYXAgZW50cmllcyBtdXN0IGJlIGFwcGxpZWQgaW4gc3luYyAocHJvcGVydHkgYnkgcHJvcGVydHkpXG4gKiB3aXRoIHByb3AtYmFzZWQgYmluZGluZ3MuIChUaGUgbWFwLWJhc2VkIGFsZ29yaXRobSBpcyBkZXNjcmliZWRcbiAqIG1vcmUgaW5zaWRlIG9mIHRoZSBgcmVuZGVyMy9zdHlsaW5nX25leHQvbWFwX2Jhc2VkX2JpbmRpbmdzLnRzYCBmaWxlLilcbiAqXG4gKiAjIyBTYW5pdGl6YXRpb25cbiAqIFNhbml0aXphdGlvbiBpcyB1c2VkIHRvIHByZXZlbnQgaW52YWxpZCBzdHlsZSB2YWx1ZXMgZnJvbSBiZWluZyBhcHBsaWVkIHRvXG4gKiB0aGUgZWxlbWVudC5cbiAqXG4gKiBJdCBpcyBlbmFibGVkIGluIHR3byBjYXNlczpcbiAqXG4gKiAgIDEuIFRoZSBgc3R5bGVTYW5pdGl6ZXIoc2FuaXRpemVyRm4pYCBpbnN0cnVjdGlvbiB3YXMgY2FsbGVkIChqdXN0IGJlZm9yZSBhbnkgb3RoZXJcbiAqICAgICAgc3R5bGluZyBpbnN0cnVjdGlvbnMgYXJlIHJ1bikuXG4gKlxuICogICAyLiBUaGUgY29tcG9uZW50L2RpcmVjdGl2ZSBgTFZpZXdgIGluc3RhbmNlIGhhcyBhIHNhbml0aXplciBvYmplY3QgYXR0YWNoZWQgdG8gaXRcbiAqICAgICAgKHRoaXMgaGFwcGVucyB3aGVuIGByZW5kZXJDb21wb25lbnRgIGlzIGV4ZWN1dGVkIHdpdGggYSBgc2FuaXRpemVyYCB2YWx1ZSBvclxuICogICAgICBpZiB0aGUgbmdNb2R1bGUgY29udGFpbnMgYSBzYW5pdGl6ZXIgcHJvdmlkZXIgYXR0YWNoZWQgdG8gaXQpLlxuICpcbiAqIElmIGFuZCB3aGVuIHNhbml0aXphdGlvbiBpcyBhY3RpdmUgdGhlbiBhbGwgcHJvcGVydHkvdmFsdWUgZW50cmllcyB3aWxsIGJlIGV2YWx1YXRlZFxuICogdGhyb3VnaCB0aGUgYWN0aXZlIHNhbml0aXplciBiZWZvcmUgdGhleSBhcmUgYXBwbGllZCB0byB0aGUgZWxlbWVudCAob3IgdGhlIHN0eWxpbmdcbiAqIGRlYnVnIGhhbmRsZXIpLlxuICpcbiAqIElmIGEgYFNhbml0aXplcmAgb2JqZWN0IGlzIHVzZWQgKHZpYSB0aGUgYExWaWV3W1NBTklUSVpFUl1gIHZhbHVlKSB0aGVuIHRoYXQgb2JqZWN0XG4gKiB3aWxsIGJlIHVzZWQgZm9yIGV2ZXJ5IHByb3BlcnR5LlxuICpcbiAqIElmIGEgYFN0eWxlU2FuaXRpemVyRm5gIGZ1bmN0aW9uIGlzIHVzZWQgKHZpYSB0aGUgYHN0eWxlU2FuaXRpemVyYCkgdGhlbiBpdCB3aWxsIGJlXG4gKiBjYWxsZWQgaW4gdHdvIHdheXM6XG4gKlxuICogICAxLiBwcm9wZXJ0eSB2YWxpZGF0aW9uIG1vZGU6IHRoaXMgd2lsbCBiZSBjYWxsZWQgZWFybHkgdG8gbWFyayB3aGV0aGVyIGEgcHJvcGVydHlcbiAqICAgICAgc2hvdWxkIGJlIHNhbml0aXplZCBvciBub3QgYXQgZHVyaW5nIHRoZSBmbHVzaGluZyBzdGFnZS5cbiAqXG4gKiAgIDIuIHZhbHVlIHNhbml0aXphdGlvbiBtb2RlOiB0aGlzIHdpbGwgYmUgY2FsbGVkIGR1cmluZyB0aGUgZmx1c2hpbmcgc3RhZ2UgYW5kIHdpbGxcbiAqICAgICAgcnVuIHRoZSBzYW5pdGl6ZXIgZnVuY3Rpb24gYWdhaW5zdCB0aGUgdmFsdWUgYmVmb3JlIGFwcGx5aW5nIGl0IHRvIHRoZSBlbGVtZW50LlxuICpcbiAqIElmIHNhbml0aXphdGlvbiByZXR1cm5zIGFuIGVtcHR5IHZhbHVlIHRoZW4gdGhhdCBlbXB0eSB2YWx1ZSB3aWxsIGJlIGFwcGxpZWRcbiAqIHRvIHRoZSBlbGVtZW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRTdHlsaW5nQ29udGV4dCBleHRlbmRzIEFycmF5PG51bWJlcnxzdHJpbmd8bnVtYmVyfGJvb2xlYW58bnVsbHxMU3R5bGluZ01hcD4ge1xuICAvKiogQ29uZmlndXJhdGlvbiBkYXRhIGZvciB0aGUgY29udGV4dCAqL1xuICBbVFN0eWxpbmdDb250ZXh0SW5kZXguQ29uZmlnUG9zaXRpb25dOiBUU3R5bGluZ0NvbmZpZ0ZsYWdzO1xuXG4gIC8qKiBUZW1wb3JhcnkgdmFsdWUgdXNlZCB0byB0cmFjayBkaXJlY3RpdmUgaW5kZXggZW50cmllcyB1bnRpbFxuICAgICB0aGUgb2xkIHN0eWxpbmcgY29kZSBpcyBmdWxseSByZW1vdmVkLiBUaGUgcmVhc29uIHdoeSB0aGlzXG4gICAgIGlzIHJlcXVpcmVkIGlzIHRvIGZpZ3VyZSBvdXQgd2hpY2ggZGlyZWN0aXZlIGlzIGxhc3QgYW5kLFxuICAgICB3aGVuIGVuY291bnRlcmVkLCB0cmlnZ2VyIGEgc3R5bGluZyBmbHVzaCB0byBoYXBwZW4gKi9cbiAgW1RTdHlsaW5nQ29udGV4dEluZGV4Lk1heERpcmVjdGl2ZUluZGV4UG9zaXRpb25dOiBudW1iZXI7XG5cbiAgLyoqIFRoZSBiaXQgZ3VhcmQgdmFsdWUgZm9yIGFsbCBtYXAtYmFzZWQgYmluZGluZ3Mgb24gYW4gZWxlbWVudCAqL1xuICBbVFN0eWxpbmdDb250ZXh0SW5kZXguTWFwQmluZGluZ3NCaXRHdWFyZFBvc2l0aW9uXTogbnVtYmVyO1xuXG4gIC8qKiBUaGUgdG90YWwgYW1vdW50IG9mIG1hcC1iYXNlZCBiaW5kaW5ncyBwcmVzZW50IG9uIGFuIGVsZW1lbnQgKi9cbiAgW1RTdHlsaW5nQ29udGV4dEluZGV4Lk1hcEJpbmRpbmdzVmFsdWVzQ291bnRQb3NpdGlvbl06IG51bWJlcjtcblxuICAvKiogVGhlIHByb3AgdmFsdWUgZm9yIG1hcC1iYXNlZCBiaW5kaW5ncyAodGhlcmUgYWN0dWFsbHkgaXNuJ3QgYVxuICAgKiB2YWx1ZSBhdCBhbGwsIGJ1dCB0aGlzIGlzIGp1c3QgdXNlZCBpbiB0aGUgY29udGV4dCB0byBhdm9pZFxuICAgKiBoYXZpbmcgYW55IHNwZWNpYWwgY29kZSB0byB1cGRhdGUgdGhlIGJpbmRpbmcgaW5mb3JtYXRpb24gZm9yXG4gICAqIG1hcC1iYXNlZCBlbnRyaWVzKS4gKi9cbiAgW1RTdHlsaW5nQ29udGV4dEluZGV4Lk1hcEJpbmRpbmdzUHJvcFBvc2l0aW9uXTogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgc2VyaWVzIG9mIGZsYWdzIHVzZWQgdG8gY29uZmlndXJlIHRoZSBjb25maWcgdmFsdWUgcHJlc2VudCB3aXRoaW4gYVxuICogYFRTdHlsaW5nQ29udGV4dGAgdmFsdWUuXG4gKi9cbmV4cG9ydCBjb25zdCBlbnVtIFRTdHlsaW5nQ29uZmlnRmxhZ3Mge1xuICAvKipcbiAgICogVGhlIGluaXRpYWwgc3RhdGUgb2YgdGhlIHN0eWxpbmcgY29udGV4dCBjb25maWdcbiAgICovXG4gIEluaXRpYWwgPSAwYjAsXG5cbiAgLyoqXG4gICAqIEEgZmxhZyB3aGljaCBtYXJrcyB0aGUgY29udGV4dCBhcyBiZWluZyBsb2NrZWQuXG4gICAqXG4gICAqIFRoZSBzdHlsaW5nIGNvbnRleHQgaXMgY29uc3RydWN0ZWQgYWNyb3NzIGFuIGVsZW1lbnQgdGVtcGxhdGVcbiAgICogZnVuY3Rpb24gYXMgd2VsbCBhcyBhbnkgYXNzb2NpYXRlZCBob3N0QmluZGluZ3MgZnVuY3Rpb25zLiBXaGVuXG4gICAqIHRoaXMgb2NjdXJzLCB0aGUgY29udGV4dCBpdHNlbGYgaXMgb3BlbiB0byBtdXRhdGlvbiBhbmQgb25seSBvbmNlXG4gICAqIGl0IGhhcyBiZWVuIGZsdXNoZWQgb25jZSB0aGVuIGl0IHdpbGwgYmUgbG9ja2VkIGZvciBnb29kIChubyBleHRyYVxuICAgKiBiaW5kaW5ncyBjYW4gYmUgYWRkZWQgdG8gaXQpLlxuICAgKi9cbiAgTG9ja2VkID0gMGIxLFxufVxuXG4vKipcbiAqIEFuIGluZGV4IG9mIHBvc2l0aW9uIGFuZCBvZmZzZXQgdmFsdWVzIHVzZWQgdG8gbmF0aWdhdGUgdGhlIGBUU3R5bGluZ0NvbnRleHRgLlxuICovXG5leHBvcnQgY29uc3QgZW51bSBUU3R5bGluZ0NvbnRleHRJbmRleCB7XG4gIENvbmZpZ1Bvc2l0aW9uID0gMCxcbiAgTWF4RGlyZWN0aXZlSW5kZXhQb3NpdGlvbiA9IDEsXG5cbiAgLy8gaW5kZXgvb2Zmc2V0IHZhbHVlcyBmb3IgbWFwLWJhc2VkIGVudHJpZXMgKGkuZS4gYFtzdHlsZV1gXG4gIC8vIGFuZCBgW2NsYXNzXSBiaW5kaW5ncykuXG4gIE1hcEJpbmRpbmdzUG9zaXRpb24gPSAyLFxuICBNYXBCaW5kaW5nc0JpdEd1YXJkUG9zaXRpb24gPSAyLFxuICBNYXBCaW5kaW5nc1ZhbHVlc0NvdW50UG9zaXRpb24gPSAzLFxuICBNYXBCaW5kaW5nc1Byb3BQb3NpdGlvbiA9IDQsXG4gIE1hcEJpbmRpbmdzQmluZGluZ3NTdGFydFBvc2l0aW9uID0gNSxcblxuICAvLyBlYWNoIHR1cGxlIGVudHJ5IGluIHRoZSBjb250ZXh0XG4gIC8vIChtYXNrLCBjb3VudCwgcHJvcCwgLi4uYmluZGluZ3N8fGRlZmF1bHQtdmFsdWUpXG4gIENvbmZpZ0FuZEd1YXJkT2Zmc2V0ID0gMCxcbiAgVmFsdWVzQ291bnRPZmZzZXQgPSAxLFxuICBQcm9wT2Zmc2V0ID0gMixcbiAgQmluZGluZ3NTdGFydE9mZnNldCA9IDMsXG59XG5cbi8qKlxuICogQSBzZXJpZXMgb2YgZmxhZ3MgdXNlZCBmb3IgZWFjaCBwcm9wZXJ0eSBlbnRyeSB3aXRoaW4gdGhlIGBUU3R5bGluZ0NvbnRleHRgLlxuICovXG5leHBvcnQgY29uc3QgZW51bSBUU3R5bGluZ0NvbnRleHRQcm9wQ29uZmlnRmxhZ3Mge1xuICBEZWZhdWx0ID0gMGIwLFxuICBTYW5pdGl6YXRpb25SZXF1aXJlZCA9IDBiMSxcbiAgVG90YWxCaXRzID0gMSxcbiAgTWFzayA9IDBiMSxcbn1cblxuLyoqXG4gKiBBIGZ1bmN0aW9uIHVzZWQgdG8gYXBwbHkgb3IgcmVtb3ZlIHN0eWxpbmcgZnJvbSBhbiBlbGVtZW50IGZvciBhIGdpdmVuIHByb3BlcnR5LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwcGx5U3R5bGluZ0ZuIHtcbiAgKHJlbmRlcmVyOiBSZW5kZXJlcjN8UHJvY2VkdXJhbFJlbmRlcmVyM3xudWxsLCBlbGVtZW50OiBSRWxlbWVudCwgcHJvcDogc3RyaW5nLFxuICAgdmFsdWU6IHN0cmluZ3xudWxsLCBiaW5kaW5nSW5kZXg/OiBudW1iZXJ8bnVsbCk6IHZvaWQ7XG59XG5cbi8qKlxuICogUnVudGltZSBkYXRhIHR5cGUgdGhhdCBpcyB1c2VkIHRvIHN0b3JlIGJpbmRpbmcgZGF0YSByZWZlcmVuY2VkIGZyb20gdGhlIGBUU3R5bGluZ0NvbnRleHRgLlxuICpcbiAqIEJlY2F1c2UgYExWaWV3YCBpcyBqdXN0IGFuIGFycmF5IHdpdGggZGF0YSwgdGhlcmUgaXMgbm8gcmVhc29uIHRvXG4gKiBzcGVjaWFsIGNhc2UgYExWaWV3YCBldmVyeXdoZXJlIGluIHRoZSBzdHlsaW5nIGFsZ29yaXRobS4gQnkgYWxsb3dpbmdcbiAqIHRoaXMgZGF0YSB0eXBlIHRvIGJlIGFuIGFycmF5IHRoYXQgY29udGFpbnMgdmFyaW91cyBzY2FsYXIgZGF0YSB0eXBlcyxcbiAqIGFuIGluc3RhbmNlIG9mIGBMVmlld2AgZG9lc24ndCBuZWVkIHRvIGJlIGNvbnN0cnVjdGVkIGZvciB0ZXN0cy5cbiAqL1xuZXhwb3J0IHR5cGUgTFN0eWxpbmdEYXRhID0gTFZpZXcgfCAoc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IG51bGwpW107XG5cbi8qKlxuICogQXJyYXktYmFzZWQgcmVwcmVzZW50YXRpb24gb2YgYSBrZXkvdmFsdWUgYXJyYXkuXG4gKlxuICogVGhlIGZvcm1hdCBvZiB0aGUgYXJyYXkgaXMgXCJwcm9wZXJ0eVwiLCBcInZhbHVlXCIsIFwicHJvcGVydHkyXCIsXG4gKiBcInZhbHVlMlwiLCBldGMuLi5cbiAqXG4gKiBUaGUgZmlyc3QgdmFsdWUgaW4gdGhlIGFycmF5IGlzIHJlc2VydmVkIHRvIHN0b3JlIHRoZSBpbnN0YW5jZVxuICogb2YgdGhlIGtleS92YWx1ZSBhcnJheSB0aGF0IHdhcyB1c2VkIHRvIHBvcHVsYXRlIHRoZSBwcm9wZXJ0eS9cbiAqIHZhbHVlIGVudHJpZXMgdGhhdCB0YWtlIHBsYWNlIGluIHRoZSByZW1haW5kZXIgb2YgdGhlIGFycmF5LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExTdHlsaW5nTWFwIGV4dGVuZHMgQXJyYXk8e318c3RyaW5nfG51bWJlcnxudWxsPiB7XG4gIFtMU3R5bGluZ01hcEluZGV4LlJhd1ZhbHVlUG9zaXRpb25dOiB7fXxzdHJpbmd8bnVsbDtcbn1cblxuLyoqXG4gKiBBbiBpbmRleCBvZiBwb3NpdGlvbiBhbmQgb2Zmc2V0IHBvaW50cyBmb3IgYW55IGRhdGEgc3RvcmVkIHdpdGhpbiBhIGBMU3R5bGluZ01hcGAgaW5zdGFuY2UuXG4gKi9cbmV4cG9ydCBjb25zdCBlbnVtIExTdHlsaW5nTWFwSW5kZXgge1xuICAvKiogVGhlIGxvY2F0aW9uIG9mIHRoZSByYXcga2V5L3ZhbHVlIG1hcCBpbnN0YW5jZSB1c2VkIGxhc3QgdG8gcG9wdWxhdGUgdGhlIGFycmF5IGVudHJpZXMgKi9cbiAgUmF3VmFsdWVQb3NpdGlvbiA9IDAsXG5cbiAgLyoqIFdoZXJlIHRoZSB2YWx1ZXMgc3RhcnQgaW4gdGhlIGFycmF5ICovXG4gIFZhbHVlc1N0YXJ0UG9zaXRpb24gPSAxLFxuXG4gIC8qKiBUaGUgc2l6ZSBvZiBlYWNoIHByb3BlcnR5L3ZhbHVlIGVudHJ5ICovXG4gIFR1cGxlU2l6ZSA9IDIsXG5cbiAgLyoqIFRoZSBvZmZzZXQgZm9yIHRoZSBwcm9wZXJ0eSBlbnRyeSBpbiB0aGUgdHVwbGUgKi9cbiAgUHJvcE9mZnNldCA9IDAsXG5cbiAgLyoqIFRoZSBvZmZzZXQgZm9yIHRoZSB2YWx1ZSBlbnRyeSBpbiB0aGUgdHVwbGUgKi9cbiAgVmFsdWVPZmZzZXQgPSAxLFxufVxuXG4vKipcbiAqIFVzZWQgdG8gYXBwbHkvdHJhdmVyc2UgYWNyb3NzIGFsbCBtYXAtYmFzZWQgc3R5bGluZyBlbnRyaWVzIHVwIHRvIHRoZSBwcm92aWRlZCBgdGFyZ2V0UHJvcGBcbiAqIHZhbHVlLlxuICpcbiAqIFdoZW4gY2FsbGVkLCBlYWNoIG9mIHRoZSBtYXAtYmFzZWQgYExTdHlsaW5nTWFwYCBlbnRyaWVzICh3aGljaCBhcmUgc3RvcmVkIGluXG4gKiB0aGUgcHJvdmlkZWQgYExTdHlsaW5nRGF0YWAgYXJyYXkpIHdpbGwgYmUgaXRlcmF0ZWQgb3Zlci4gRGVwZW5kaW5nIG9uIHRoZSBwcm92aWRlZFxuICogYG1vZGVgIHZhbHVlLCBlYWNoIHByb3AvdmFsdWUgZW50cnkgbWF5IGJlIGFwcGxpZWQgb3Igc2tpcHBlZCBvdmVyLlxuICpcbiAqIElmIGB0YXJnZXRQcm9wYCB2YWx1ZSBpcyBwcm92aWRlZCB0aGUgaXRlcmF0aW9uIGNvZGUgd2lsbCBzdG9wIG9uY2UgaXQgcmVhY2hlc1xuICogdGhlIHByb3BlcnR5IChpZiBmb3VuZCkuIE90aGVyd2lzZSBpZiB0aGUgdGFyZ2V0IHByb3BlcnR5IGlzIG5vdCBlbmNvdW50ZXJlZCB0aGVuXG4gKiBpdCB3aWxsIHN0b3Agb25jZSBpdCByZWFjaGVzIHRoZSBuZXh0IHZhbHVlIHRoYXQgYXBwZWFycyBhbHBoYWJldGljYWxseSBhZnRlciBpdC5cbiAqXG4gKiBJZiBhIGBkZWZhdWx0VmFsdWVgIGlzIHByb3ZpZGVkIHRoZW4gaXQgd2lsbCBiZSBhcHBsaWVkIHRvIHRoZSBlbGVtZW50IG9ubHkgaWYgdGhlXG4gKiBgdGFyZ2V0UHJvcGAgcHJvcGVydHkgdmFsdWUgaXMgZW5jb3VudGVyZWQgYW5kIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHRhcmdldFxuICogcHJvcGVydHkgaXMgYG51bGxgLiBUaGUgcmVhc29uIHdoeSB0aGUgYGRlZmF1bHRWYWx1ZWAgaXMgbmVlZGVkIGlzIHRvIGF2b2lkIGhhdmluZyB0aGVcbiAqIGFsZ29yaXRobSBhcHBseSBhIGBudWxsYCB2YWx1ZSBhbmQgdGhlbiBhcHBseSBhIGRlZmF1bHQgdmFsdWUgYWZ0ZXJ3YXJkcyAodGhpcyB3b3VsZFxuICogZW5kIHVwIGJlaW5nIHR3byBzdHlsZSBwcm9wZXJ0eSB3cml0ZXMpLlxuICpcbiAqIEByZXR1cm5zIHdoZXRoZXIgb3Igbm90IHRoZSB0YXJnZXQgcHJvcGVydHkgd2FzIHJlYWNoZWQgYW5kIGl0cyB2YWx1ZSB3YXNcbiAqICBhcHBsaWVkIHRvIHRoZSBlbGVtZW50LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN5bmNTdHlsaW5nTWFwc0ZuIHtcbiAgKGNvbnRleHQ6IFRTdHlsaW5nQ29udGV4dCwgcmVuZGVyZXI6IFJlbmRlcmVyM3xQcm9jZWR1cmFsUmVuZGVyZXIzfG51bGwsIGVsZW1lbnQ6IFJFbGVtZW50LFxuICAgZGF0YTogTFN0eWxpbmdEYXRhLCBhcHBseVN0eWxpbmdGbjogQXBwbHlTdHlsaW5nRm4sIHNhbml0aXplcjogU3R5bGVTYW5pdGl6ZUZufG51bGwsXG4gICBtb2RlOiBTdHlsaW5nTWFwc1N5bmNNb2RlLCB0YXJnZXRQcm9wPzogc3RyaW5nfG51bGwsIGRlZmF1bHRWYWx1ZT86IHN0cmluZ3xudWxsKTogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBVc2VkIHRvIGRpcmVjdCBob3cgbWFwLWJhc2VkIHZhbHVlcyBhcmUgYXBwbGllZC90cmF2ZXJzZWQgd2hlbiBzdHlsaW5nIGlzIGZsdXNoZWQuXG4gKi9cbmV4cG9ydCBjb25zdCBlbnVtIFN0eWxpbmdNYXBzU3luY01vZGUge1xuICAvKiogT25seSB0cmF2ZXJzZSB2YWx1ZXMgKG5vIHByb3AvdmFsdWUgc3R5bGluZyBlbnRyaWVzIGdldCBhcHBsaWVkKSAqL1xuICBUcmF2ZXJzZVZhbHVlcyA9IDBiMDAwLFxuXG4gIC8qKiBBcHBseSBldmVyeSBwcm9wL3ZhbHVlIHN0eWxpbmcgZW50cnkgdG8gdGhlIGVsZW1lbnQgKi9cbiAgQXBwbHlBbGxWYWx1ZXMgPSAwYjAwMSxcblxuICAvKiogT25seSBhcHBseSB0aGUgdGFyZ2V0IHByb3AvdmFsdWUgZW50cnkgKi9cbiAgQXBwbHlUYXJnZXRQcm9wID0gMGIwMTAsXG5cbiAgLyoqIFNraXAgYXBwbHlpbmcgdGhlIHRhcmdldCBwcm9wL3ZhbHVlIGVudHJ5ICovXG4gIFNraXBUYXJnZXRQcm9wID0gMGIxMDAsXG59XG4iXX0=