diff --git a/.gitignore b/.gitignore index 123ae94..f647d78 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ build/Release # Dependency directory # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git node_modules +target/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..7649ca7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,13 @@ +--- +language: node_js +sudo: false +cache: + directories: + - node_modules +node_js: + - "4.1" + - "4.0" + - "0.12" + - "0.11" + - "0.10" + - "iojs" diff --git a/LICENSE b/LICENSE index 8f71f43..dc56359 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright {yyyy} {name of copyright owner} + Copyright 2016 Wave Software Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -199,4 +199,3 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - diff --git a/README.md b/README.md index deab844..62e263f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,185 @@ -# javascript-eid-exceptions -EID Runtime Exceptions and Utilities for JavaScript +# EID Runtime Exceptions and Utilities for Javascript + +[![Build Status](https://travis-ci.org/wavesoftware/javascript-eid-exceptions.svg?branch=master)](https://travis-ci.org/wavesoftware/javascript-eid-exceptions) [![Coverage Status](https://coveralls.io/repos/wavesoftware/javascript-eid-exceptions/badge.svg?branch=master&service=github)](https://coveralls.io/github/wavesoftware/javascript-eid-exceptions?branch=master) [![npm](https://img.shields.io/npm/v/eid.js.svg)](https://www.npmjs.com/package/eid.js) [![Bower](https://img.shields.io/bower/v/eid.js.svg)]() + +This small library holds a set of exceptions and utilities that implements idea of fast, reusable, error codes that can be simply thrown fast in case of unpredictable and unrecoverable application failure. It is meant to be used for application bugs. + +## Idea + +The idea is to use a set of simple runtime exceptions. They should always take the Exception ID (Eid) object in the making. This eid object will then be reported when displaying or logging that exception. It can also be viewed on the professional fatal error window of the application as a bug reference. EidRuntimeExceptions contains also additional unique ID to distinguish each single exception from others with same Eid. This approach simplifies the management of exceptions in the application and allows developers to focus on functionalities rather than coming up with the correct statement for the exception. + +This approach is best to use with tools and plugins like: + + * [EidGenerator for Netbeans IDE](http://plugins.netbeans.org/plugin/53137/exception-id-eid-generator) + * [Generating Exception Id number in Intellij IDEA with Live Templates](https://github.com/wavesoftware/java-eid-exceptions/wiki/Generating%20Exception%20Id%20number%20in%20Intellij%20IDEA%20with%20Live%20Templates) + +Example: + +```js +var cause = 'A extra message'; +throw new EidIllegalStateException("20150721:100554", cause); +``` + +Example log: + +``` +ERROR 2016-01-11T22:48:42.445 EidIllegalStateException: [20150721:100554] A extra message - Error + at http://localhost:3000/browser/toplevel/eid.min.js:1:3959 + at Object.i.3.../eid (http://localhost:3000/browser/toplevel/eid.min.js:1:4211) + at r (http://localhost:3000/browser/toplevel/eid.min.js:1:254) + at http://localhost:3000/browser/toplevel/eid.min.js:1:305 + at http://localhost:3000/browser/toplevel/eid.min.js:1:536 + at Object.i.1.../../lib/eid (http://localhost:3000/browser/toplevel/eid.min.js:1:974) + at r (http://localhost:3000/browser/toplevel/eid.min.js:1:254) + at t (http://localhost:3000/browser/toplevel/eid.min.js:1:421) + at http://localhost:3000/browser/toplevel/eid.min.js:1:438 +``` + + +## Caution + +This classes shouldn't be used in any public API or library. It is designed to be used for in-house development of end user applications which will report bugs in standardized error pages or post them to issue tracker. + +## NPM + +```bash +npm install eid.js --save +``` + +## Bower + +```bash +bower install eid.js --save +``` + +### `EidPreconditions` class + +#### General use + +`EidPreconditions` class consists static methods that help to use Eid in a method or constructor. This is solely for convenience purposes. Use them to check whether method or constructor was invoked correctly (whether its preconditions have been met). These methods generally accept a `boolean` expression which is expected to be `true` (or in the case of `checkNotNull`, an object reference which is expected to be non-null). When `false` (or `null`) is passed instead, the `EidPreconditions` method throws an unchecked exception, which helps the calling method communicate to its caller that that caller has made a mistake. + +Each method accepts a EID string or Eid object, which is designed to ease of use and provide strict ID for given exception usage. This approach speed up development of large application and helps support teams by giving both static and random ID for each possible bug that could occur. + +Each example uses static import: + +```js +// nodejs +var EidPreconditions = require('eid.js').preconditions; + +// browser using bower using toplevel version +var EidPreconditions = window.Eid.preconditions; +``` + +#### `checkArgument` method + +`checkArgument` method should be used to check argument of the method, and validate it in technical terms (not business terms). + +Example: + +```js +// [..] +function sqrt(value) { + checkArgument(value >= 0.0, "20150718:012333"); + // if ok, calculate the square root +} +``` + +In this example, `checkArgument` throws an `EidIllegalArgumentException` to indicate that developer made an error in its call to `sqrt`. + +#### `checkState` method + +`checkState` method should be used to check state of the class in given moment, and validate it in technical terms (not business terms). + +Example: + +```js +checkState(a >= 3.14 && b < 0., "20150721:115016"); +``` + +#### `checkNotNull` method + +`checkNotNull` method should be used to check if given non null argument is actually `null` + +Example: + +```js +var nonNullUserName = checkNotNull(userName, "20150721:115515"); +``` + +#### `checkElementIndex` method + +`checkElementIndex` method can be used to test parameters of an array, before being used + +```js +checkElementIndex(index, list.length, "20150721:115749"); +``` + +#### Formatted message support + +There have been added additional `message` to method descriptors for `checkArgument`, `checkState`, `checkNotNull` and `checkElementIndex` method. Those method's parameter can sometimes be used to pass additional information to exceptions that will be displayed in log files. + +For example: + +```js +checkState(transation.isValid(), "20151119:120238", "Invalid transaction: " + transaction); +``` + +Will produce output similar to; + +``` +EidIllegalStateException: [20151119:120238] => Invalid transaction: +``` + +#### Functional try to execute blocks + +You can use functional blocks to handle operations, that are intended to operate properly. This approach simplify the code and makes it more readable. It's also good way to deal with untested, uncovered `catch` blocks. It's easy and gives developers nice way of dealing with countless operations that suppose to work as intended. + +Example: + +```js +var content = EidPreconditions.tryToExecute(function() { + var fs = require('fs'); + return fs.readFileSync('project.properties'); +}, "20150718:121521"); +``` + +#### Logging + +Eid object can also be useful in logging. That are `makeLogMessage` method provided to do that. Message formatting is done using equivalent of Java's `String.format(String, Object[])` method. +For example: + +```js +log.debug(new Eid("20151119:121814").makeLogMessage("REST request received: %s", request)); +``` + +will unfold to something similar to: + +``` +2017-01-08T16:45:34,334 DEBUG [20151119:121814] REST request received: flow=ShowLastTransactions step=Confirm> +``` + +###Contributing + +Contributions are welcome! + +To contribute, follow the standard [git flow](http://danielkummer.github.io/git-flow-cheatsheet/) of: + +1. Fork it +1. Create your feature branch (`git checkout -b feature/my-new-feature`) +1. Commit your changes (`git commit -am 'Add some feature'`) +1. Push to the branch (`git push origin feature/my-new-feature`) +1. Create new Pull Request + +Even if you can't contribute code, if you have an idea for an improvement please open an [issue](https://github.com/wavesoftware/javascript-eid-exceptions/issues). + +## Requirements + +* NodeJS >= 0.10 +* Any modern browser, supported by browserify. + + +### Releases + +- 1.0.0 + - initial release + - library ported from Java version diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..93123db --- /dev/null +++ b/bower.json @@ -0,0 +1,29 @@ +{ + "name": "eid.js", + "description": "EID Runtime Exceptions and Utilities for JS", + "main": "dist/browser/toplevel/eid.min.js", + "authors": [ + "Krzysztof Suszynski " + ], + "license": "Apache-2.0", + "keywords": [ + "debug", + "expection", + "preconditions", + "quality", + "qa" + ], + "homepage": "https://github.com/wavesoftware/javascript-eid-exceptions", + "moduleType": [ + "globals" + ], + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests", + "gulp", + "target" + ] +} diff --git a/dist/browser/toplevel/eid.js b/dist/browser/toplevel/eid.js new file mode 100644 index 0000000..8478c33 --- /dev/null +++ b/dist/browser/toplevel/eid.js @@ -0,0 +1,727 @@ +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;oThis class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * Exception identifier for all Eid Runtime Exceptions. + * @constructor + * @param {string} id - the exception id, must be unique developer inserted string, from date + * @param {string} ref - an optional reference + */ +function Eid(id, ref) { + var uniq = EidInternal.uniqIdGenerator.generateUniqId(); + ref = (ref === null || ref == undefined) ? "" : ref; + + /** + * Makes a log message from this EID object + *

+ *

This method is for convenience of usage of EID in logging. You can use it like this: + *

+ *

+   * log.debug(new Eid("20151025:202129").makeLogMessage("A request: %s", request));
+   * 
+ * @param {string} logMessageFormat - a log message format as accepted by {@link String#format(String, Object...)} + * @param {Object...} parameters - a parameters for logMessageFormat to by passed to {@link String#format(String, Object...)} + * @return {string} a formatted message + */ + this.makeLogMessage = function(logMessageFormat) { + var parameters = []; + for (var i = 1; i < arguments.length; i++) { + parameters.push(arguments[i]); + } + var message = new JFormatter(logMessageFormat).format(parameters); + return new JFormatter(Eid.getMessageFormat()).format(this.toString(), message); + } + + /** + * Standard to string method + */ + this.toString = function() { + if ("" === ref) { + return new JFormatter(EidInternal.format).format(id, uniq); + } + return new JFormatter(EidInternal.refFormat).format(id, ref, uniq); + } + + /** + * Getter for constant Exception ID + * + * @return {string} ID of exception + */ + this.getId = function() { + return id; + } + + /** + * Get custom ref passed to Exception ID + * + * @return {string} ID of exception + */ + this.getRef = function() { + return ref; + } + + /** + * Gets unique generated string for this instance of Eid + * + * @return {string} a unique string + */ + this.getUniq = function() { + return uniq; + } +} + +function MathRandom() { + var LONG_MAX = Math.pow(2, 53) - 1; + var LONG_MIN = -1 * Math.pow(2, 53); + this.nextLong = function() { + return random(LONG_MIN, LONG_MAX); + }; + this.nextInt = function(max) { + return random(0, max); + }; + var random = function(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + }; +} + +function StdUniqIdGenerator() { + var BASE36 = 36; + var INTEGER_MAX_VALUE = Math.pow(2, 31); + var generator = new MathRandom(); + this.generateUniqId = function() { + var first = Math.abs(generator.nextLong() + 1); + var second = Math.abs(generator.nextInt(INTEGER_MAX_VALUE)); + var calc = first + second; + return (Math.abs(calc) % INTEGER_MAX_VALUE).toString(BASE36); + }; +} + +var DEFAULT_FORMAT = "[%s]<%s>"; +var DEFAULT_REF_FORMAT = "[%s|%s]<%s>"; +var DEFAULT_MESSAGE_FORMAT = "%s => %s"; +var DEFAULT_UNIQ_ID_GENERATOR = new StdUniqIdGenerator(); + +Object.defineProperty(Eid, "DEFAULT_FORMAT", { + get: function() { return DEFAULT_FORMAT; } +}); +Object.defineProperty(Eid, "DEFAULT_MESSAGE_FORMAT", { + get: function() { return DEFAULT_MESSAGE_FORMAT; } +}); +Object.defineProperty(Eid, "DEFAULT_REF_FORMAT", { + get: function() { return DEFAULT_REF_FORMAT; } +}); +Object.defineProperty(Eid, "DEFAULT_UNIQ_ID_GENERATOR", { + get: function() { return DEFAULT_UNIQ_ID_GENERATOR; } +}); + +var FORMAT_NUM_SPEC = 2; +var REF_FORMAT_NUM_SPEC = 3; +var MESSAGE_FORMAT_NUM_SPEC = 2; + +var EidInternal = { + messageFormat: DEFAULT_MESSAGE_FORMAT, + uniqIdGenerator: DEFAULT_UNIQ_ID_GENERATOR, + format: DEFAULT_FORMAT, + refFormat: DEFAULT_REF_FORMAT +}; + +var validateFormat = function(format, numSpecifiers) { + if (format === null || format === undefined) { + throw new TypeError("Format can't be null, but just received one"); + } + var specifiers = []; + for (var i = 0; i < numSpecifiers; i++) { + specifiers.push(i + "-test-id"); + } + var formatted = new JFormatter(format).format(specifiers); + for (var specifier in specifiers) { + if (formatted.indexOf(specifier) === -1) { + throw new TypeError("Given format contains to little format specifiers, " + + "expected " + numSpecifiers + " but given \"" + format + "\""); + } + } +}; + +/** + * Sets the actual unique ID generator that will be used to generate IDs for all Eid objects. It will return previously used + * generator. + * + * @param {UniqIdGenerator} uniqIdGenerator - new instance of unique ID generator + * @return {UniqIdGenerator} a previously used unique ID generator + * @throws {TypeError} if given generator was null + */ +Eid.setUniqIdGenerator = function(uniqIdGenerator) { + if (uniqIdGenerator === null || uniqIdGenerator === undefined) { + throw new TypeError("Unique ID generator can't be null, but given one"); + } + var previous = EidInternal.uniqIdGenerator; + EidInternal.uniqIdGenerator = uniqIdGenerator; + return previous; +}; + +/** + * Sets the actual format that will be used in {@link #toString()} method. It will return previously used format. + * + * @param {string} format - a format compliant with {@link String#format(String, Object...)} with 2 object arguments + * @return {string} a previously used format + * @throws {TypeError} if given format hasn't got two format specifiers "%s", or if given format was + * null + */ +Eid.setFormat = function(format) { + validateFormat(format, FORMAT_NUM_SPEC); + var previously = EidInternal.format; + EidInternal.format = format; + return previously; +}; + +/** + * Sets the actual format that will be used in {@link #toString()} method + * + * @param {string} refFormat - a format compliant with {@link String#format(String, Object...)} with 3 object arguments + * @return {string} a previously used format + * @throws {TypeError} if given format hasn't got tree format specifiers "%s", or if given format was + * null + */ +Eid.setRefFormat = function(refFormat) { + validateFormat(refFormat, REF_FORMAT_NUM_SPEC); + var previously = EidInternal.refFormat; + EidInternal.refFormat = refFormat; + return previously; +}; + +/** + * Sets a format that will be used for all Eid exceptions when printing a detail message. + *

+ * Format must be non-null and contain two format specifiers "%s" + * + * @param {string} format - a format that will be used, must be non-null and contain two format specifiers "%s" + * @return {string} previously used format + * @throws {TypeError} if given format hasn't got two format specifiers "%s", or if given format was + * null + */ +Eid.setMessageFormat = function(format) { + validateFormat(format, MESSAGE_FORMAT_NUM_SPEC); + var oldFormat = EidInternal.messageFormat; + EidInternal.messageFormat = format; + return oldFormat; +}; + +/** + * Gets actually set message format + * + * @return {string} actually setted message format + */ +Eid.getMessageFormat = function() { + return EidInternal.messageFormat; +}; + +module.exports = Eid; + +})(module); + +},{}],4:[function(require,module,exports){ +/* + * Copyright 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function(exports) { + 'use strict'; + + var Eid = require('./eid'); + var commonExConstructor = function(eid, message) { + if (!(eid instanceof Eid)) { + eid = new Eid(eid.toString()); + } + this.message = message !== undefined ? (eid + " " + message) : eid; + this.eid = eid; + } + + /** + * This class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * This exception class is baseline of all Eid runtime exception classes. It is designed to ease of use and provide strict ID for + * given Exception usage. This approach speed up development of large application and helps support teams to by giving the both + * static and random ID for each possible unpredicted bug. + *

+ * This is best to use with tools and plugins like + * EidGenerator for Netbeans IDE + *

+ * For convenience use {@link eid.Preconditions} + * + * @constructor + * @param {string} eid - an exception Id, should be generated + * @param {string} message - an message for the exception + * @author Krzysztof Suszyński + */ + function EidRuntimeException(eid, message) { + this.name = 'EidRuntimeException'; + commonExConstructor.apply(this, [eid, message]); + } + EidRuntimeException.prototype = new Error(); + + /** + * This class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * This id Eid version of {@link NullPointerException} + * + * @constructor + * @param {string} eid - an exception Id, should be generated + * @param {string} message - an message for the exception + * @see NullPointerException + * @see EidRuntimeException + * @author Krzysztof Suszyński + */ + function EidNullPointerException(eid, message) { + this.name = 'EidNullPointerException'; + commonExConstructor.apply(this, [eid, message]); + } + EidNullPointerException.prototype = EidRuntimeException.prototype; + + /** + * This class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * This is Eid version of {@link IllegalArgumentException} + * + * @constructor + * @param {string} eid - an exception Id, should be generated + * @param {string} message - an message for the exception + * @see IllegalArgumentException + * @see EidRuntimeException + * @author Krzysztof Suszyński + */ + function EidIllegalArgumentException(eid, message) { + this.name = 'EidIllegalArgumentException'; + commonExConstructor.apply(this, [eid, message]); + } + EidIllegalArgumentException.prototype = EidRuntimeException.prototype; + + /** + * This class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * This id Eid version of {@link IllegalStateException} + * + * @constructor + * @param {string} eid - an exception Id, should be generated + * @param {string} message - an message for the exception + * @see IllegalStateException + * @see EidRuntimeException + * @author Krzysztof Suszyński + */ + function EidIllegalStateException(eid, message) { + this.name = 'EidIllegalStateException'; + commonExConstructor.apply(this, [eid, message]); + } + EidIllegalStateException.prototype = EidRuntimeException.prototype; + + /** + * This class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * This id Eid version of {@link IndexOutOfBoundsException} + * + * @constructor + * @param {string} eid - an exception Id, should be generated + * @param {string} message - an message for the exception + * @see IndexOutOfBoundsException + * @see EidRuntimeException + * @author Krzysztof Suszyński + */ + function EidIndexOutOfBoundsException(eid, message) { + this.name = 'EidIndexOutOfBoundsException'; + commonExConstructor.apply(this, [eid, message]); + } + EidIndexOutOfBoundsException.prototype = EidRuntimeException.prototype; + + exports.EidRuntimeException = EidRuntimeException; + exports.EidNullPointerException = EidNullPointerException; + exports.EidIllegalArgumentException = EidIllegalArgumentException; + exports.EidIllegalStateException = EidIllegalStateException; + exports.EidIndexOutOfBoundsException = EidIndexOutOfBoundsException; + +})(exports); + +},{"./eid":3}],5:[function(require,module,exports){ +/* + * Copyright 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function(module) { +'use strict'; + +var Eid = require('./eid'); +var EidRuntimeException = require('./exceptions').EidRuntimeException; +var EidNullPointerException = require('./exceptions').EidNullPointerException; +var EidIllegalArgumentException = require('./exceptions').EidIllegalArgumentException; +var EidIllegalStateException = require('./exceptions').EidIllegalStateException; +var EidIndexOutOfBoundsException = require('./exceptions').EidIndexOutOfBoundsException; + +/** + * This class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * Static convenience methods that help a method or constructor check whether it was invoked correctly (whether its + * preconditions + * have been met). These methods generally accept a {@code boolean} expression which is expected to be {@code true} (or in the + * case of {@code + * checkNotNull}, an object reference which is expected to be non-null). When {@code false} (or {@code null}) is passed instead, + * the {@code EidPreconditions} method throws an unchecked exception, which helps the calling method communicate to its + * caller that + * that caller has made a mistake. + *

+ * Each method accepts a EID String or {@link Eid} object, which is designed to ease of use and provide strict ID for given + * Exception usage. This approach speed up development of large application and helps support teams to by giving the both static + * and random ID for each possible unpredicted bug. + *

+ * This is best to use with tools and plugins like + * EidGenerator for Netbeans IDE + *

+ * Example: + *

   {@code
+ *
+ *   /**
+ *    * Returns the positive square root of the given value.
+ *    *
+ *    * @throws EidIllegalArgumentException if the value is negative
+ *    *}{@code /
+ *   public static double sqrt(double value) {
+ *     EidPreconditions.checkArgument(value >= 0.0, "20150718:012333");
+ *     // calculate the square root
+ *   }
+ *
+ *   void exampleBadCaller() {
+ *     double d = sqrt(-1.0);
+ *   }
+ * }
+ *

+ * In this example, {@code checkArgument} throws an {@code EidIllegalArgumentException} to indicate that {@code exampleBadCaller} + * made an error in its call to {@code sqrt}. Exception, when it will be printed will contain user given Eid and also + * Randomly generated ID. Those fields can be displayed to user on error page on posted directly to issue tracker. + *

+ * Example: + *

+ *

+ *
+ * {@code
+ *   // Main application class for ex.: http servlet
+ *    try {
+ *        performRequest(request, response);
+ *    } catch (EidRuntimeException ex) {
+ *        issuesTracker.put(ex);
+ *        throw ex;
+ *    }
+ * }
+ *

+ *

+ *

Functional try to execute blocks

+ *

+ *

+ * Using functional blocks to handle operations, that are intended to operate properly, simplify the code and makes it more + * readable. It's also good way to deal with untested, uncovered {@code catch} blocks. It's easy and gives developers nice way of + * dealing with countless operations that suppose to work as intended. + *

+ *

+ * Example: + *


+ *
+ *     InputStream is = EidPreconditions.tryToExecute({@code new UnsafeSupplier}() {
+ *        {@literal @}Override
+ *         public InputStream get() throws IOException {
+ *             return this.getClass().getClassLoader()
+ *                 .getResourceAsStream("project.properties");
+ *         }
+ *     }, "20150718:121521");
+ * 
+ * + * @constructor + * @author Krzysztof Suszyński + * @since 0.1.0 (idea imported from Guava Library and COI code) + */ +function EidPreconditions() {} + +function isNullike(reference) { + return reference === null || reference === undefined; +} + +function checkNotNull(reference) { + if (isNullike(reference)) { + throw new TypeError("Pass not-null Eid to EidPreconditions first!"); + } + return reference; +} + +function ensureEid(candidate) { + candidate = checkNotNull(candidate); + var eid; + if (!(candidate instanceof Eid)) { + eid = new Eid(candidate + ''); + } else { + eid = candidate; + } + return eid; +} + +/** + * Ensures that an object reference passed as a parameter to the calling method is not null-like. + * + * @param {Object} reference - an object reference + * @param {string|Eid} eid - the exception ID to use if the check fails + * @param {string} message - message for produced exception + * @return {Object} the non-null reference that was validated + * @throws {EidNullPointerException} if {@code reference} is null-like + */ +EidPreconditions.checkNotNullable = function(reference, eid, message) { + var checkedEid = ensureEid(eid); + if (isNullike(reference)) { + throw new EidNullPointerException(checkedEid, message); + } + return reference; +}; + +/** + * Ensures that an object reference passed as a parameter to the calling method is not null. + * + * @param {Object} reference - an object reference + * @param {string|Eid} eid - the exception ID to use if the check fails + * @param {string} message - message for produced exception + * @return {Object} the non-null reference that was validated + * @throws {EidNullPointerException} if {@code reference} is null-like + */ +EidPreconditions.checkNotNull = function(reference, eid, message) { + var checkedEid = ensureEid(eid); + if (reference === null) { + throw new EidNullPointerException(checkedEid, message); + } + return reference; +}; + +/** + * Ensures that an object reference passed as a parameter to the calling method is not undefined. + * + * @param {Object} reference - an object reference + * @param {string|Eid} eid - the exception ID to use if the check fails + * @param {string} message - message for produced exception + * @return {Object} the non-null reference that was validated + * @throws {EidNullPointerException} if {@code reference} is null-like + */ +EidPreconditions.checkNotUndefined = function(reference, eid, message) { + var checkedEid = ensureEid(eid); + if (reference === undefined) { + throw new EidNullPointerException(checkedEid, message); + } + return reference; +}; + +/** + * Ensures the truth of an expression involving one or more parameters to the calling method. + * + * @param {boolean} expression - a boolean expression + * @param {string|Eid} eid - the exception ID to use if the check fails + * @param {string} message - optional message for generated exception + * @throws {EidIllegalArgumentException} if {@code expression} is false + * @throws {EidNullPointerException} if {@code expression} is null + */ +EidPreconditions.checkArgument = function(expression, eid, message) { + var checkedEid = ensureEid(eid); + if (!EidPreconditions.checkNotNullable(expression, checkedEid)) { + throw new EidIllegalArgumentException(checkedEid, message) + } +}; + +/** + * Ensures the truth of an expression involving the state of the calling instance, but not involving any parameters to the + * calling method. + * + * @param {boolean} expression - a boolean expression + * @param {string|Eid} eid - the exception ID to use if the check fails + * @param {string} message - optional message for generated exception + * @throws {EidIllegalStateException} if {@code expression} is false + * @throws {EidNullPointerException} if {@code expression} is null + */ +EidPreconditions.checkState = function(expression, eid, message) { + var checkedEid = ensureEid(eid); + if (!EidPreconditions.checkNotNullable(expression, checkedEid)) { + throw new EidIllegalStateException(checkedEid, message); + } +}; + +function isIndexAndSizeIllegal(index, size) { + return index < 0 || index > size; +} + +function isSizeIllegal(size) { + return size < 0; +} + +/** + * Ensures that {@code index} specifies a valid element in an array, list or string of size {@code size}. An element + * index may range from zero, inclusive, to {@code size}, exclusive. + * + * @param {number} index - a user-supplied index identifying an element of an array, list or string + * @param {numer} size - the size of that array, list or string + * @param {string|Eid} eid - the text to use to describe this index in an error message + * @param {string} message - optional message for generated exception + * @return {number} the value of {@code index} + * @throws {EidIndexOutOfBoundsException} if {@code index} is negative or is not less than {@code size} + * @throws {EidIllegalArgumentException} if {@code size} is negative + */ +EidPreconditions.checkElementIndex = function(index, size, eid, message) { + var checkedEid = ensureEid(eid); + if (isSizeIllegal(size)) { + throw new EidIllegalArgumentException(checkedEid, message); + } + if (isIndexAndSizeIllegal(index, size)) { + throw new EidIndexOutOfBoundsException(checkedEid, message); + } + return index; +}; + +/** + * Tries to execute code in given unsafe supplier code block, and if exception is thrown, it will gets rethrown as a + * {@link EidRuntimeException} with eid given as a argument. This is because this exception is threaded as a software bug! + *

+ * Example: + *


+ *
+ * Document doc = EidPreconditions.tryToExecute({@code new UnsafeSupplier}() {
+ *    {@literal @}Override
+ *     public Document get() throws IOException {
+ *          DocumentBuilder docBuilder = ...
+ *          return docBuilder.parse(new InputSource(reader));
+ *     }
+ * }, new Eid("20150718:121521"));
+ * 
+ * + * @param return type + * @param supplier unsafe supplier code to be executed within a try-catch block + * @param eid unique developer identifier from date for ex.: "20150716:123200" + * @return A block of code return type, if exception is not thrown + * @throws EidRuntimeException if code block thrown any exception, which in that case is wrapped in EidRuntimeException + */ +EidPreconditions.tryToExecute = function(supplier, eid) { + var checkedEid = ensureEid(eid); + try { + return EidPreconditions.checkNotNullable(supplier, checkedEid).apply(); + } catch (throwable) { + throw new EidRuntimeException(checkedEid, throwable); + } +}; + +module.exports = EidPreconditions; +})(module); + +},{"./eid":3,"./exceptions":4}]},{},[1]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJndWxwL2J1aWxkL3RvcGxldmVsLmpzIiwibGliL2VpZC5qcyIsImxpYi9laWQvZWlkLmpzIiwibGliL2VpZC9leGNlcHRpb25zLmpzIiwibGliL2VpZC9wcmVjb25kaXRpb25zLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9QQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiLypcbiAqIENvcHlyaWdodCAyMDE2IFdhdmUgU29mdHdhcmVcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuKGZ1bmN0aW9uKHduZCkge1xuICAndXNlIHN0cmljdCc7XG4gIHduZC5FaWQgPSByZXF1aXJlKCcuLi8uLi9saWIvZWlkJyk7XG59KSh3aW5kb3cpO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDE2IFdhdmUgU29mdHdhcmVcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuKGZ1bmN0aW9uKG1vZHVsZSkge1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgRWlkID0gcmVxdWlyZSgnLi9laWQvZWlkJyk7XG5FaWQucHJlY29uZGl0aW9ucyA9IHJlcXVpcmUoJy4vZWlkL3ByZWNvbmRpdGlvbnMnKTtcbkVpZC5leGNlcHRpb25zID0gcmVxdWlyZSgnLi9laWQvZXhjZXB0aW9ucycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEVpZDtcblxufSkobW9kdWxlKTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAxNiBXYXZlIFNvZnR3YXJlXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbihmdW5jdGlvbihtb2R1bGUpIHtcbid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gSkZvcm1hdHRlcihmb3JtYXQpIHtcbiAgdGhpcy5mb3JtYXQgPSBmdW5jdGlvbihhcnIpIHtcbiAgICB2YXIgYXJncyA9IFtdO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxICYmIHR5cGVvZihhcnIpID09PSAnb2JqZWN0Jykge1xuICAgICAgYXJncyA9IGFycjtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYXJncy5wdXNoKGFyZ3VtZW50c1tpXSk7XG4gICAgICB9XG4gICAgfVxuICAgIHZhciByZWdleCA9IC8lcy87XG4gICAgdmFyIF9yID0gZnVuY3Rpb24ocCxjKSB7IHJldHVybiBwLnJlcGxhY2UocmVnZXgsIGMpOyB9XG4gICAgcmV0dXJuIGFyZ3MucmVkdWNlKF9yLCBmb3JtYXQpO1xuICB9O1xufVxuXG4vKipcbiAqIDxzdHJvbmc+VGhpcyBjbGFzcyBzaG91bGRuJ3QgYmUgdXNlZCBpbiBhbnkgcHVibGljIEFQSSBvciBsaWJyYXJ5Ljwvc3Ryb25nPiBJdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGZvciBpbi1ob3VzZSBkZXZlbG9wbWVudFxuICogb2YgZW5kIHVzZXIgYXBwbGljYXRpb25zIHdoaWNoIHdpbGwgcmVwb3J0IEJ1Z3MgaW4gc3RhbmRhcmRpemVkIGVycm9yIHBhZ2VzIG9yIHBvc3QgdGhlbSB0byBpc3N1ZSB0cmFja2VyLlxuICogPHA+XG4gKiBFeGNlcHRpb24gaWRlbnRpZmllciBmb3IgYWxsIEVpZCBSdW50aW1lIEV4Y2VwdGlvbnMuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZCAtIHRoZSBleGNlcHRpb24gaWQsIG11c3QgYmUgdW5pcXVlIGRldmVsb3BlciBpbnNlcnRlZCBzdHJpbmcsIGZyb20gZGF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHJlZiAtIGFuIG9wdGlvbmFsIHJlZmVyZW5jZVxuICovXG5mdW5jdGlvbiBFaWQoaWQsIHJlZikge1xuICB2YXIgdW5pcSA9IEVpZEludGVybmFsLnVuaXFJZEdlbmVyYXRvci5nZW5lcmF0ZVVuaXFJZCgpO1xuICByZWYgPSAocmVmID09PSBudWxsIHx8IHJlZiA9PSB1bmRlZmluZWQpID8gXCJcIiA6IHJlZjtcblxuICAvKipcbiAgICogTWFrZXMgYSBsb2cgbWVzc2FnZSBmcm9tIHRoaXMgRUlEIG9iamVjdFxuICAgKiA8cD5cbiAgICogPHA+VGhpcyBtZXRob2QgaXMgZm9yIGNvbnZlbmllbmNlIG9mIHVzYWdlIG9mIEVJRCBpbiBsb2dnaW5nLiBZb3UgY2FuIHVzZSBpdCBsaWtlIHRoaXM6XG4gICAqIDxwPlxuICAgKiA8cHJlPlxuICAgKiBsb2cuZGVidWcobmV3IEVpZChcIjIwMTUxMDI1OjIwMjEyOVwiKS5tYWtlTG9nTWVzc2FnZShcIkEgcmVxdWVzdDogJXNcIiwgcmVxdWVzdCkpO1xuICAgKiA8L3ByZT5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGxvZ01lc3NhZ2VGb3JtYXQgLSBhIGxvZyBtZXNzYWdlIGZvcm1hdCBhcyBhY2NlcHRlZCBieSB7QGxpbmsgU3RyaW5nI2Zvcm1hdChTdHJpbmcsIE9iamVjdC4uLil9XG4gICAqIEBwYXJhbSB7T2JqZWN0Li4ufSBwYXJhbWV0ZXJzIC0gYSBwYXJhbWV0ZXJzIGZvciBsb2dNZXNzYWdlRm9ybWF0IHRvIGJ5IHBhc3NlZCB0byB7QGxpbmsgU3RyaW5nI2Zvcm1hdChTdHJpbmcsIE9iamVjdC4uLil9XG4gICAqIEByZXR1cm4ge3N0cmluZ30gYSBmb3JtYXR0ZWQgbWVzc2FnZVxuICAgKi9cbiAgdGhpcy5tYWtlTG9nTWVzc2FnZSA9IGZ1bmN0aW9uKGxvZ01lc3NhZ2VGb3JtYXQpIHtcbiAgICB2YXIgcGFyYW1ldGVycyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBwYXJhbWV0ZXJzLnB1c2goYXJndW1lbnRzW2ldKTtcbiAgICB9XG4gICAgdmFyIG1lc3NhZ2UgPSBuZXcgSkZvcm1hdHRlcihsb2dNZXNzYWdlRm9ybWF0KS5mb3JtYXQocGFyYW1ldGVycyk7XG4gICAgcmV0dXJuIG5ldyBKRm9ybWF0dGVyKEVpZC5nZXRNZXNzYWdlRm9ybWF0KCkpLmZvcm1hdCh0aGlzLnRvU3RyaW5nKCksIG1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YW5kYXJkIHRvIHN0cmluZyBtZXRob2RcbiAgICovXG4gIHRoaXMudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChcIlwiID09PSByZWYpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IEpGb3JtYXR0ZXIoRWlkSW50ZXJuYWwuZm9ybWF0KS5mb3JtYXQoaWQsIHVuaXEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBKRm9ybWF0dGVyKEVpZEludGVybmFsLnJlZkZvcm1hdCkuZm9ybWF0KGlkLCByZWYsIHVuaXEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHRlciBmb3IgY29uc3RhbnQgRXhjZXB0aW9uIElEXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZ30gSUQgb2YgZXhjZXB0aW9uXG4gICAqL1xuICB0aGlzLmdldElkID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gaWQ7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGN1c3RvbSByZWYgcGFzc2VkIHRvIEV4Y2VwdGlvbiBJRFxuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IElEIG9mIGV4Y2VwdGlvblxuICAgKi9cbiAgdGhpcy5nZXRSZWYgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiByZWY7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB1bmlxdWUgZ2VuZXJhdGVkIHN0cmluZyBmb3IgdGhpcyBpbnN0YW5jZSBvZiBFaWRcbiAgICpcbiAgICogQHJldHVybiB7c3RyaW5nfSBhIHVuaXF1ZSBzdHJpbmdcbiAgICovXG4gIHRoaXMuZ2V0VW5pcSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHVuaXE7XG4gIH1cbn1cblxuZnVuY3Rpb24gTWF0aFJhbmRvbSgpIHtcbiAgdmFyIExPTkdfTUFYID0gTWF0aC5wb3coMiwgNTMpIC0gMTtcbiAgdmFyIExPTkdfTUlOID0gLTEgKiBNYXRoLnBvdygyLCA1Myk7XG4gIHRoaXMubmV4dExvbmcgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gcmFuZG9tKExPTkdfTUlOLCBMT05HX01BWCk7XG4gIH07XG4gIHRoaXMubmV4dEludCA9IGZ1bmN0aW9uKG1heCkge1xuICAgIHJldHVybiByYW5kb20oMCwgbWF4KTtcbiAgfTtcbiAgdmFyIHJhbmRvbSA9IGZ1bmN0aW9uKG1pbiwgbWF4KSB7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIChtYXggLSBtaW4gKyAxKSkgKyBtaW47XG4gIH07XG59XG5cbmZ1bmN0aW9uIFN0ZFVuaXFJZEdlbmVyYXRvcigpIHtcbiAgdmFyIEJBU0UzNiA9IDM2O1xuICB2YXIgSU5URUdFUl9NQVhfVkFMVUUgPSBNYXRoLnBvdygyLCAzMSk7XG4gIHZhciBnZW5lcmF0b3IgPSBuZXcgTWF0aFJhbmRvbSgpO1xuICB0aGlzLmdlbmVyYXRlVW5pcUlkID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGZpcnN0ID0gTWF0aC5hYnMoZ2VuZXJhdG9yLm5leHRMb25nKCkgKyAxKTtcbiAgICB2YXIgc2Vjb25kID0gTWF0aC5hYnMoZ2VuZXJhdG9yLm5leHRJbnQoSU5URUdFUl9NQVhfVkFMVUUpKTtcbiAgICB2YXIgY2FsYyA9IGZpcnN0ICsgc2Vjb25kO1xuICAgIHJldHVybiAoTWF0aC5hYnMoY2FsYykgJSBJTlRFR0VSX01BWF9WQUxVRSkudG9TdHJpbmcoQkFTRTM2KTtcbiAgfTtcbn1cblxudmFyIERFRkFVTFRfRk9STUFUID0gXCJbJXNdPCVzPlwiO1xudmFyIERFRkFVTFRfUkVGX0ZPUk1BVCA9IFwiWyVzfCVzXTwlcz5cIjtcbnZhciBERUZBVUxUX01FU1NBR0VfRk9STUFUID0gXCIlcyA9PiAlc1wiO1xudmFyIERFRkFVTFRfVU5JUV9JRF9HRU5FUkFUT1IgPSBuZXcgU3RkVW5pcUlkR2VuZXJhdG9yKCk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShFaWQsIFwiREVGQVVMVF9GT1JNQVRcIiwge1xuICBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gREVGQVVMVF9GT1JNQVQ7IH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KEVpZCwgXCJERUZBVUxUX01FU1NBR0VfRk9STUFUXCIsIHtcbiAgZ2V0OiBmdW5jdGlvbigpIHsgcmV0dXJuIERFRkFVTFRfTUVTU0FHRV9GT1JNQVQ7IH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KEVpZCwgXCJERUZBVUxUX1JFRl9GT1JNQVRcIiwge1xuICBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gREVGQVVMVF9SRUZfRk9STUFUOyB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShFaWQsIFwiREVGQVVMVF9VTklRX0lEX0dFTkVSQVRPUlwiLCB7XG4gIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBERUZBVUxUX1VOSVFfSURfR0VORVJBVE9SOyB9XG59KTtcblxudmFyIEZPUk1BVF9OVU1fU1BFQyA9IDI7XG52YXIgUkVGX0ZPUk1BVF9OVU1fU1BFQyA9IDM7XG52YXIgTUVTU0FHRV9GT1JNQVRfTlVNX1NQRUMgPSAyO1xuXG52YXIgRWlkSW50ZXJuYWwgPSB7XG4gIG1lc3NhZ2VGb3JtYXQ6IERFRkFVTFRfTUVTU0FHRV9GT1JNQVQsXG4gIHVuaXFJZEdlbmVyYXRvcjogREVGQVVMVF9VTklRX0lEX0dFTkVSQVRPUixcbiAgZm9ybWF0OiBERUZBVUxUX0ZPUk1BVCxcbiAgcmVmRm9ybWF0OiBERUZBVUxUX1JFRl9GT1JNQVRcbn07XG5cbnZhciB2YWxpZGF0ZUZvcm1hdCA9IGZ1bmN0aW9uKGZvcm1hdCwgbnVtU3BlY2lmaWVycykge1xuICBpZiAoZm9ybWF0ID09PSBudWxsIHx8IGZvcm1hdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZvcm1hdCBjYW4ndCBiZSBudWxsLCBidXQganVzdCByZWNlaXZlZCBvbmVcIik7XG4gIH1cbiAgdmFyIHNwZWNpZmllcnMgPSBbXTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBudW1TcGVjaWZpZXJzOyBpKyspIHtcbiAgICBzcGVjaWZpZXJzLnB1c2goaSArIFwiLXRlc3QtaWRcIik7XG4gIH1cbiAgdmFyIGZvcm1hdHRlZCA9IG5ldyBKRm9ybWF0dGVyKGZvcm1hdCkuZm9ybWF0KHNwZWNpZmllcnMpO1xuICBmb3IgKHZhciBzcGVjaWZpZXIgaW4gc3BlY2lmaWVycykge1xuICAgIGlmIChmb3JtYXR0ZWQuaW5kZXhPZihzcGVjaWZpZXIpID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdpdmVuIGZvcm1hdCBjb250YWlucyB0byBsaXR0bGUgZm9ybWF0IHNwZWNpZmllcnMsIFwiICtcbiAgICAgICAgICBcImV4cGVjdGVkIFwiICsgbnVtU3BlY2lmaWVycyArIFwiIGJ1dCBnaXZlbiBcXFwiXCIgKyBmb3JtYXQgKyBcIlxcXCJcIik7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIGFjdHVhbCB1bmlxdWUgSUQgZ2VuZXJhdG9yIHRoYXQgd2lsbCBiZSB1c2VkIHRvIGdlbmVyYXRlIElEcyBmb3IgYWxsIEVpZCBvYmplY3RzLiBJdCB3aWxsIHJldHVybiBwcmV2aW91c2x5IHVzZWRcbiAqIGdlbmVyYXRvci5cbiAqXG4gKiBAcGFyYW0ge1VuaXFJZEdlbmVyYXRvcn0gdW5pcUlkR2VuZXJhdG9yIC0gbmV3IGluc3RhbmNlIG9mIHVuaXF1ZSBJRCBnZW5lcmF0b3JcbiAqIEByZXR1cm4ge1VuaXFJZEdlbmVyYXRvcn0gYSBwcmV2aW91c2x5IHVzZWQgdW5pcXVlIElEIGdlbmVyYXRvclxuICogQHRocm93cyB7VHlwZUVycm9yfSBpZiBnaXZlbiBnZW5lcmF0b3Igd2FzIG51bGxcbiAqL1xuRWlkLnNldFVuaXFJZEdlbmVyYXRvciA9IGZ1bmN0aW9uKHVuaXFJZEdlbmVyYXRvcikge1xuICBpZiAodW5pcUlkR2VuZXJhdG9yID09PSBudWxsIHx8IHVuaXFJZEdlbmVyYXRvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlVuaXF1ZSBJRCBnZW5lcmF0b3IgY2FuJ3QgYmUgbnVsbCwgYnV0IGdpdmVuIG9uZVwiKTtcbiAgfVxuICB2YXIgcHJldmlvdXMgPSBFaWRJbnRlcm5hbC51bmlxSWRHZW5lcmF0b3I7XG4gIEVpZEludGVybmFsLnVuaXFJZEdlbmVyYXRvciA9IHVuaXFJZEdlbmVyYXRvcjtcbiAgcmV0dXJuIHByZXZpb3VzO1xufTtcblxuLyoqXG4gKiBTZXRzIHRoZSBhY3R1YWwgZm9ybWF0IHRoYXQgd2lsbCBiZSB1c2VkIGluIHtAbGluayAjdG9TdHJpbmcoKX0gbWV0aG9kLiBJdCB3aWxsIHJldHVybiBwcmV2aW91c2x5IHVzZWQgZm9ybWF0LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtYXQgLSBhIGZvcm1hdCBjb21wbGlhbnQgd2l0aCB7QGxpbmsgU3RyaW5nI2Zvcm1hdChTdHJpbmcsIE9iamVjdC4uLil9IHdpdGggMiBvYmplY3QgYXJndW1lbnRzXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGEgcHJldmlvdXNseSB1c2VkIGZvcm1hdFxuICogQHRocm93cyB7VHlwZUVycm9yfSBpZiBnaXZlbiBmb3JtYXQgaGFzbid0IGdvdCB0d28gZm9ybWF0IHNwZWNpZmllcnMgPHR0PlwiJXNcIjwvdHQ+LCBvciBpZiBnaXZlbiBmb3JtYXQgd2FzXG4gKiBudWxsXG4gKi9cbkVpZC5zZXRGb3JtYXQgPSBmdW5jdGlvbihmb3JtYXQpIHtcbiAgdmFsaWRhdGVGb3JtYXQoZm9ybWF0LCBGT1JNQVRfTlVNX1NQRUMpO1xuICB2YXIgcHJldmlvdXNseSA9IEVpZEludGVybmFsLmZvcm1hdDtcbiAgRWlkSW50ZXJuYWwuZm9ybWF0ID0gZm9ybWF0O1xuICByZXR1cm4gcHJldmlvdXNseTtcbn07XG5cbi8qKlxuICogU2V0cyB0aGUgYWN0dWFsIGZvcm1hdCB0aGF0IHdpbGwgYmUgdXNlZCBpbiB7QGxpbmsgI3RvU3RyaW5nKCl9IG1ldGhvZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSByZWZGb3JtYXQgLSBhIGZvcm1hdCBjb21wbGlhbnQgd2l0aCB7QGxpbmsgU3RyaW5nI2Zvcm1hdChTdHJpbmcsIE9iamVjdC4uLil9IHdpdGggMyBvYmplY3QgYXJndW1lbnRzXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGEgcHJldmlvdXNseSB1c2VkIGZvcm1hdFxuICogQHRocm93cyB7VHlwZUVycm9yfSBpZiBnaXZlbiBmb3JtYXQgaGFzbid0IGdvdCB0cmVlIGZvcm1hdCBzcGVjaWZpZXJzIDx0dD5cIiVzXCI8L3R0Piwgb3IgaWYgZ2l2ZW4gZm9ybWF0IHdhc1xuICogbnVsbFxuICovXG5FaWQuc2V0UmVmRm9ybWF0ID0gZnVuY3Rpb24ocmVmRm9ybWF0KSB7XG4gIHZhbGlkYXRlRm9ybWF0KHJlZkZvcm1hdCwgUkVGX0ZPUk1BVF9OVU1fU1BFQyk7XG4gIHZhciBwcmV2aW91c2x5ID0gRWlkSW50ZXJuYWwucmVmRm9ybWF0O1xuICBFaWRJbnRlcm5hbC5yZWZGb3JtYXQgPSByZWZGb3JtYXQ7XG4gIHJldHVybiBwcmV2aW91c2x5O1xufTtcblxuLyoqXG4gKiBTZXRzIGEgZm9ybWF0IHRoYXQgd2lsbCBiZSB1c2VkIGZvciBhbGwgRWlkIGV4Y2VwdGlvbnMgd2hlbiBwcmludGluZyBhIGRldGFpbCBtZXNzYWdlLlxuICogPHA+XG4gKiBGb3JtYXQgbXVzdCBiZSBub24tbnVsbCBhbmQgY29udGFpbiB0d28gZm9ybWF0IHNwZWNpZmllcnMgPHR0PlwiJXNcIjwvdHQ+XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGZvcm1hdCAtIGEgZm9ybWF0IHRoYXQgd2lsbCBiZSB1c2VkLCBtdXN0IGJlIG5vbi1udWxsIGFuZCBjb250YWluIHR3byBmb3JtYXQgc3BlY2lmaWVycyA8dHQ+XCIlc1wiPC90dD5cbiAqIEByZXR1cm4ge3N0cmluZ30gcHJldmlvdXNseSB1c2VkIGZvcm1hdFxuICogQHRocm93cyB7VHlwZUVycm9yfSBpZiBnaXZlbiBmb3JtYXQgaGFzbid0IGdvdCB0d28gZm9ybWF0IHNwZWNpZmllcnMgPHR0PlwiJXNcIjwvdHQ+LCBvciBpZiBnaXZlbiBmb3JtYXQgd2FzXG4gKiBudWxsXG4gKi9cbkVpZC5zZXRNZXNzYWdlRm9ybWF0ID0gZnVuY3Rpb24oZm9ybWF0KSB7XG4gIHZhbGlkYXRlRm9ybWF0KGZvcm1hdCwgTUVTU0FHRV9GT1JNQVRfTlVNX1NQRUMpO1xuICB2YXIgb2xkRm9ybWF0ID0gRWlkSW50ZXJuYWwubWVzc2FnZUZvcm1hdDtcbiAgRWlkSW50ZXJuYWwubWVzc2FnZUZvcm1hdCA9IGZvcm1hdDtcbiAgcmV0dXJuIG9sZEZvcm1hdDtcbn07XG5cbi8qKlxuICogR2V0cyBhY3R1YWxseSBzZXQgbWVzc2FnZSBmb3JtYXRcbiAqXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGFjdHVhbGx5IHNldHRlZCBtZXNzYWdlIGZvcm1hdFxuICovXG5FaWQuZ2V0TWVzc2FnZUZvcm1hdCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gRWlkSW50ZXJuYWwubWVzc2FnZUZvcm1hdDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gRWlkO1xuXG59KShtb2R1bGUpO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDE2IFdhdmUgU29mdHdhcmVcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuKGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiAgJ3VzZSBzdHJpY3QnO1xuXG4gIHZhciBFaWQgPSByZXF1aXJlKCcuL2VpZCcpO1xuICB2YXIgY29tbW9uRXhDb25zdHJ1Y3RvciA9IGZ1bmN0aW9uKGVpZCwgbWVzc2FnZSkge1xuICAgIGlmICghKGVpZCBpbnN0YW5jZW9mIEVpZCkpIHtcbiAgICAgIGVpZCA9IG5ldyBFaWQoZWlkLnRvU3RyaW5nKCkpO1xuICAgIH1cbiAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlICE9PSB1bmRlZmluZWQgPyAoZWlkICsgXCIgXCIgKyBtZXNzYWdlKSA6IGVpZDtcbiAgICB0aGlzLmVpZCA9IGVpZDtcbiAgfVxuXG4gIC8qKlxuICAgKiA8c3Ryb25nPlRoaXMgY2xhc3Mgc2hvdWxkbid0IGJlIHVzZWQgaW4gYW55IHB1YmxpYyBBUEkgb3IgbGlicmFyeS48L3N0cm9uZz4gSXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBmb3IgaW4taG91c2UgZGV2ZWxvcG1lbnRcbiAgICogb2YgZW5kIHVzZXIgYXBwbGljYXRpb25zIHdoaWNoIHdpbGwgcmVwb3J0IEJ1Z3MgaW4gc3RhbmRhcmRpemVkIGVycm9yIHBhZ2VzIG9yIHBvc3QgdGhlbSB0byBpc3N1ZSB0cmFja2VyLlxuICAgKiA8cD5cbiAgICogVGhpcyBleGNlcHRpb24gY2xhc3MgaXMgYmFzZWxpbmUgb2YgYWxsIEVpZCBydW50aW1lIGV4Y2VwdGlvbiBjbGFzc2VzLiBJdCBpcyBkZXNpZ25lZCB0byBlYXNlIG9mIHVzZSBhbmQgcHJvdmlkZSBzdHJpY3QgSUQgZm9yXG4gICAqIGdpdmVuIEV4Y2VwdGlvbiB1c2FnZS4gVGhpcyBhcHByb2FjaCBzcGVlZCB1cCBkZXZlbG9wbWVudCBvZiBsYXJnZSBhcHBsaWNhdGlvbiBhbmQgaGVscHMgc3VwcG9ydCB0ZWFtcyB0byBieSBnaXZpbmcgdGhlIGJvdGhcbiAgICogc3RhdGljIGFuZCByYW5kb20gSUQgZm9yIGVhY2ggcG9zc2libGUgdW5wcmVkaWN0ZWQgYnVnLlxuICAgKiA8cD5cbiAgICogVGhpcyBpcyBiZXN0IHRvIHVzZSB3aXRoIHRvb2xzIGFuZCBwbHVnaW5zIGxpa2VcbiAgICogPGEgaHJlZj1cImh0dHA6Ly9wbHVnaW5zLm5ldGJlYW5zLm9yZy9wbHVnaW4vNTMxMzcvZXhjZXB0aW9uLWlkLWVpZC1nZW5lcmF0b3JcIj5FaWRHZW5lcmF0b3IgZm9yIE5ldGJlYW5zIElERTwvYT5cbiAgICogPHA+XG4gICAqIEZvciBjb252ZW5pZW5jZSB1c2Uge0BsaW5rIGVpZC5QcmVjb25kaXRpb25zfVxuICAgKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtzdHJpbmd9IGVpZCAtIGFuIGV4Y2VwdGlvbiBJZCwgc2hvdWxkIGJlIGdlbmVyYXRlZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIGFuIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb25cbiAgICogQGF1dGhvciBLcnp5c3p0b2YgU3VzennFhHNraSA8a3J6eXN6dG9mLnN1c3p5bnNraUB3YXZlc29mdHdhcmUucGw+XG4gICAqL1xuICBmdW5jdGlvbiBFaWRSdW50aW1lRXhjZXB0aW9uKGVpZCwgbWVzc2FnZSkge1xuICAgIHRoaXMubmFtZSA9ICdFaWRSdW50aW1lRXhjZXB0aW9uJztcbiAgICBjb21tb25FeENvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIFtlaWQsIG1lc3NhZ2VdKTtcbiAgfVxuICBFaWRSdW50aW1lRXhjZXB0aW9uLnByb3RvdHlwZSA9IG5ldyBFcnJvcigpO1xuXG4gIC8qKlxuICAgKiA8c3Ryb25nPlRoaXMgY2xhc3Mgc2hvdWxkbid0IGJlIHVzZWQgaW4gYW55IHB1YmxpYyBBUEkgb3IgbGlicmFyeS48L3N0cm9uZz4gSXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBmb3IgaW4taG91c2UgZGV2ZWxvcG1lbnRcbiAgICogb2YgZW5kIHVzZXIgYXBwbGljYXRpb25zIHdoaWNoIHdpbGwgcmVwb3J0IEJ1Z3MgaW4gc3RhbmRhcmRpemVkIGVycm9yIHBhZ2VzIG9yIHBvc3QgdGhlbSB0byBpc3N1ZSB0cmFja2VyLlxuICAgKiA8cD5cbiAgICogVGhpcyBpZCBFaWQgdmVyc2lvbiBvZiB7QGxpbmsgTnVsbFBvaW50ZXJFeGNlcHRpb259XG4gICAqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge3N0cmluZ30gZWlkIC0gYW4gZXhjZXB0aW9uIElkLCBzaG91bGQgYmUgZ2VuZXJhdGVkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gYW4gbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvblxuICAgKiBAc2VlIE51bGxQb2ludGVyRXhjZXB0aW9uXG4gICAqIEBzZWUgRWlkUnVudGltZUV4Y2VwdGlvblxuICAgKiBAYXV0aG9yIEtyenlzenRvZiBTdXN6ecWEc2tpIDxrcnp5c3p0b2Yuc3Vzenluc2tpQHdhdmVzb2Z0d2FyZS5wbD5cbiAgICovXG4gIGZ1bmN0aW9uIEVpZE51bGxQb2ludGVyRXhjZXB0aW9uKGVpZCwgbWVzc2FnZSkge1xuICAgIHRoaXMubmFtZSA9ICdFaWROdWxsUG9pbnRlckV4Y2VwdGlvbic7XG4gICAgY29tbW9uRXhDb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBbZWlkLCBtZXNzYWdlXSk7XG4gIH1cbiAgRWlkTnVsbFBvaW50ZXJFeGNlcHRpb24ucHJvdG90eXBlID0gRWlkUnVudGltZUV4Y2VwdGlvbi5wcm90b3R5cGU7XG5cbiAgLyoqXG4gICAqIDxzdHJvbmc+VGhpcyBjbGFzcyBzaG91bGRuJ3QgYmUgdXNlZCBpbiBhbnkgcHVibGljIEFQSSBvciBsaWJyYXJ5Ljwvc3Ryb25nPiBJdCBpcyBkZXNpZ25lZCB0byBiZSB1c2VkIGZvciBpbi1ob3VzZSBkZXZlbG9wbWVudFxuICAgKiBvZiBlbmQgdXNlciBhcHBsaWNhdGlvbnMgd2hpY2ggd2lsbCByZXBvcnQgQnVncyBpbiBzdGFuZGFyZGl6ZWQgZXJyb3IgcGFnZXMgb3IgcG9zdCB0aGVtIHRvIGlzc3VlIHRyYWNrZXIuXG4gICAqIDxwPlxuICAgKiBUaGlzIGlzIEVpZCB2ZXJzaW9uIG9mIHtAbGluayBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259XG4gICAqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge3N0cmluZ30gZWlkIC0gYW4gZXhjZXB0aW9uIElkLCBzaG91bGQgYmUgZ2VuZXJhdGVkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gYW4gbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvblxuICAgKiBAc2VlIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvblxuICAgKiBAc2VlIEVpZFJ1bnRpbWVFeGNlcHRpb25cbiAgICogQGF1dGhvciBLcnp5c3p0b2YgU3VzennFhHNraSA8a3J6eXN6dG9mLnN1c3p5bnNraUB3YXZlc29mdHdhcmUucGw+XG4gICAqL1xuICBmdW5jdGlvbiBFaWRJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oZWlkLCBtZXNzYWdlKSB7XG4gICAgdGhpcy5uYW1lID0gJ0VpZElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbic7XG4gICAgY29tbW9uRXhDb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBbZWlkLCBtZXNzYWdlXSk7XG4gIH1cbiAgRWlkSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uLnByb3RvdHlwZSA9IEVpZFJ1bnRpbWVFeGNlcHRpb24ucHJvdG90eXBlO1xuXG4gIC8qKlxuICAgKiA8c3Ryb25nPlRoaXMgY2xhc3Mgc2hvdWxkbid0IGJlIHVzZWQgaW4gYW55IHB1YmxpYyBBUEkgb3IgbGlicmFyeS48L3N0cm9uZz4gSXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBmb3IgaW4taG91c2UgZGV2ZWxvcG1lbnRcbiAgICogb2YgZW5kIHVzZXIgYXBwbGljYXRpb25zIHdoaWNoIHdpbGwgcmVwb3J0IEJ1Z3MgaW4gc3RhbmRhcmRpemVkIGVycm9yIHBhZ2VzIG9yIHBvc3QgdGhlbSB0byBpc3N1ZSB0cmFja2VyLlxuICAgKiA8cD5cbiAgICogVGhpcyBpZCBFaWQgdmVyc2lvbiBvZiB7QGxpbmsgSWxsZWdhbFN0YXRlRXhjZXB0aW9ufVxuICAgKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtzdHJpbmd9IGVpZCAtIGFuIGV4Y2VwdGlvbiBJZCwgc2hvdWxkIGJlIGdlbmVyYXRlZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIGFuIG1lc3NhZ2UgZm9yIHRoZSBleGNlcHRpb25cbiAgICogQHNlZSBJbGxlZ2FsU3RhdGVFeGNlcHRpb25cbiAgICogQHNlZSBFaWRSdW50aW1lRXhjZXB0aW9uXG4gICAqIEBhdXRob3IgS3J6eXN6dG9mIFN1c3p5xYRza2kgPGtyenlzenRvZi5zdXN6eW5za2lAd2F2ZXNvZnR3YXJlLnBsPlxuICAgKi9cbiAgZnVuY3Rpb24gRWlkSWxsZWdhbFN0YXRlRXhjZXB0aW9uKGVpZCwgbWVzc2FnZSkge1xuICAgIHRoaXMubmFtZSA9ICdFaWRJbGxlZ2FsU3RhdGVFeGNlcHRpb24nO1xuICAgIGNvbW1vbkV4Q29uc3RydWN0b3IuYXBwbHkodGhpcywgW2VpZCwgbWVzc2FnZV0pO1xuICB9XG4gIEVpZElsbGVnYWxTdGF0ZUV4Y2VwdGlvbi5wcm90b3R5cGUgPSBFaWRSdW50aW1lRXhjZXB0aW9uLnByb3RvdHlwZTtcblxuICAvKipcbiAgICogPHN0cm9uZz5UaGlzIGNsYXNzIHNob3VsZG4ndCBiZSB1c2VkIGluIGFueSBwdWJsaWMgQVBJIG9yIGxpYnJhcnkuPC9zdHJvbmc+IEl0IGlzIGRlc2lnbmVkIHRvIGJlIHVzZWQgZm9yIGluLWhvdXNlIGRldmVsb3BtZW50XG4gICAqIG9mIGVuZCB1c2VyIGFwcGxpY2F0aW9ucyB3aGljaCB3aWxsIHJlcG9ydCBCdWdzIGluIHN0YW5kYXJkaXplZCBlcnJvciBwYWdlcyBvciBwb3N0IHRoZW0gdG8gaXNzdWUgdHJhY2tlci5cbiAgICogPHA+XG4gICAqIFRoaXMgaWQgRWlkIHZlcnNpb24gb2Yge0BsaW5rIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb259XG4gICAqXG4gICAqIEBjb25zdHJ1Y3RvclxuICAgKiBAcGFyYW0ge3N0cmluZ30gZWlkIC0gYW4gZXhjZXB0aW9uIElkLCBzaG91bGQgYmUgZ2VuZXJhdGVkXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gYW4gbWVzc2FnZSBmb3IgdGhlIGV4Y2VwdGlvblxuICAgKiBAc2VlIEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb25cbiAgICogQHNlZSBFaWRSdW50aW1lRXhjZXB0aW9uXG4gICAqIEBhdXRob3IgS3J6eXN6dG9mIFN1c3p5xYRza2kgPGtyenlzenRvZi5zdXN6eW5za2lAd2F2ZXNvZnR3YXJlLnBsPlxuICAgKi9cbiAgZnVuY3Rpb24gRWlkSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbihlaWQsIG1lc3NhZ2UpIHtcbiAgICB0aGlzLm5hbWUgPSAnRWlkSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbic7XG4gICAgY29tbW9uRXhDb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBbZWlkLCBtZXNzYWdlXSk7XG4gIH1cbiAgRWlkSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbi5wcm90b3R5cGUgPSBFaWRSdW50aW1lRXhjZXB0aW9uLnByb3RvdHlwZTtcblxuICBleHBvcnRzLkVpZFJ1bnRpbWVFeGNlcHRpb24gPSBFaWRSdW50aW1lRXhjZXB0aW9uO1xuICBleHBvcnRzLkVpZE51bGxQb2ludGVyRXhjZXB0aW9uID0gRWlkTnVsbFBvaW50ZXJFeGNlcHRpb247XG4gIGV4cG9ydHMuRWlkSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uID0gRWlkSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uO1xuICBleHBvcnRzLkVpZElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiA9IEVpZElsbGVnYWxTdGF0ZUV4Y2VwdGlvbjtcbiAgZXhwb3J0cy5FaWRJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uID0gRWlkSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbjtcblxufSkoZXhwb3J0cyk7XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMTYgV2F2ZSBTb2Z0d2FyZVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG4oZnVuY3Rpb24obW9kdWxlKSB7XG4ndXNlIHN0cmljdCc7XG5cbnZhciBFaWQgPSByZXF1aXJlKCcuL2VpZCcpO1xudmFyIEVpZFJ1bnRpbWVFeGNlcHRpb24gPSByZXF1aXJlKCcuL2V4Y2VwdGlvbnMnKS5FaWRSdW50aW1lRXhjZXB0aW9uO1xudmFyIEVpZE51bGxQb2ludGVyRXhjZXB0aW9uID0gcmVxdWlyZSgnLi9leGNlcHRpb25zJykuRWlkTnVsbFBvaW50ZXJFeGNlcHRpb247XG52YXIgRWlkSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uID0gcmVxdWlyZSgnLi9leGNlcHRpb25zJykuRWlkSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uO1xudmFyIEVpZElsbGVnYWxTdGF0ZUV4Y2VwdGlvbiA9IHJlcXVpcmUoJy4vZXhjZXB0aW9ucycpLkVpZElsbGVnYWxTdGF0ZUV4Y2VwdGlvbjtcbnZhciBFaWRJbmRleE91dE9mQm91bmRzRXhjZXB0aW9uID0gcmVxdWlyZSgnLi9leGNlcHRpb25zJykuRWlkSW5kZXhPdXRPZkJvdW5kc0V4Y2VwdGlvbjtcblxuLyoqXG4gKiA8c3Ryb25nPlRoaXMgY2xhc3Mgc2hvdWxkbid0IGJlIHVzZWQgaW4gYW55IHB1YmxpYyBBUEkgb3IgbGlicmFyeS48L3N0cm9uZz4gSXQgaXMgZGVzaWduZWQgdG8gYmUgdXNlZCBmb3IgaW4taG91c2UgZGV2ZWxvcG1lbnRcbiAqIG9mIGVuZCB1c2VyIGFwcGxpY2F0aW9ucyB3aGljaCB3aWxsIHJlcG9ydCBCdWdzIGluIHN0YW5kYXJkaXplZCBlcnJvciBwYWdlcyBvciBwb3N0IHRoZW0gdG8gaXNzdWUgdHJhY2tlci5cbiAqIDxwLz5cbiAqIFN0YXRpYyBjb252ZW5pZW5jZSBtZXRob2RzIHRoYXQgaGVscCBhIG1ldGhvZCBvciBjb25zdHJ1Y3RvciBjaGVjayB3aGV0aGVyIGl0IHdhcyBpbnZva2VkIGNvcnJlY3RseSAod2hldGhlciBpdHNcbiAqIDxpPnByZWNvbmRpdGlvbnM8L2k+XG4gKiBoYXZlIGJlZW4gbWV0KS4gVGhlc2UgbWV0aG9kcyBnZW5lcmFsbHkgYWNjZXB0IGEge0Bjb2RlIGJvb2xlYW59IGV4cHJlc3Npb24gd2hpY2ggaXMgZXhwZWN0ZWQgdG8gYmUge0Bjb2RlIHRydWV9IChvciBpbiB0aGVcbiAqIGNhc2Ugb2Yge0Bjb2RlXG4gKiBjaGVja05vdE51bGx9LCBhbiBvYmplY3QgcmVmZXJlbmNlIHdoaWNoIGlzIGV4cGVjdGVkIHRvIGJlIG5vbi1udWxsKS4gV2hlbiB7QGNvZGUgZmFsc2V9IChvciB7QGNvZGUgbnVsbH0pIGlzIHBhc3NlZCBpbnN0ZWFkLFxuICogdGhlIHtAY29kZSBFaWRQcmVjb25kaXRpb25zfSBtZXRob2QgdGhyb3dzIGFuIHVuY2hlY2tlZCBleGNlcHRpb24sIHdoaWNoIGhlbHBzIHRoZSBjYWxsaW5nIG1ldGhvZCBjb21tdW5pY2F0ZSB0byA8aT5pdHM8L2k+XG4gKiBjYWxsZXIgdGhhdFxuICogPGk+dGhhdDwvaT4gY2FsbGVyIGhhcyBtYWRlIGEgbWlzdGFrZS5cbiAqIDxwLz5cbiAqIEVhY2ggbWV0aG9kIGFjY2VwdHMgYSBFSUQgU3RyaW5nIG9yIHtAbGluayBFaWR9IG9iamVjdCwgd2hpY2ggaXMgZGVzaWduZWQgdG8gZWFzZSBvZiB1c2UgYW5kIHByb3ZpZGUgc3RyaWN0IElEIGZvciBnaXZlblxuICogRXhjZXB0aW9uIHVzYWdlLiBUaGlzIGFwcHJvYWNoIHNwZWVkIHVwIGRldmVsb3BtZW50IG9mIGxhcmdlIGFwcGxpY2F0aW9uIGFuZCBoZWxwcyBzdXBwb3J0IHRlYW1zIHRvIGJ5IGdpdmluZyB0aGUgYm90aCBzdGF0aWNcbiAqIGFuZCByYW5kb20gSUQgZm9yIGVhY2ggcG9zc2libGUgdW5wcmVkaWN0ZWQgYnVnLlxuICogPHAvPlxuICogVGhpcyBpcyBiZXN0IHRvIHVzZSB3aXRoIHRvb2xzIGFuZCBwbHVnaW5zIGxpa2VcbiAqIDxhIGhyZWY9XCJodHRwOi8vcGx1Z2lucy5uZXRiZWFucy5vcmcvcGx1Z2luLzUzMTM3L2V4Y2VwdGlvbi1pZC1laWQtZ2VuZXJhdG9yXCI+RWlkR2VuZXJhdG9yIGZvciBOZXRiZWFucyBJREU8L2E+XG4gKiA8cC8+XG4gKiBFeGFtcGxlOlxuICogPHByZT4gICB7QGNvZGVcbiAqXG4gKiAgIC8qKlxuICogICAgKiBSZXR1cm5zIHRoZSBwb3NpdGl2ZSBzcXVhcmUgcm9vdCBvZiB0aGUgZ2l2ZW4gdmFsdWUuXG4gKiAgICAqXG4gKiAgICAqIEB0aHJvd3MgRWlkSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSB2YWx1ZSBpcyBuZWdhdGl2ZVxuICogICAgKn17QGNvZGUgL1xuICogICBwdWJsaWMgc3RhdGljIGRvdWJsZSBzcXJ0KGRvdWJsZSB2YWx1ZSkge1xuICogICAgIEVpZFByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudCh2YWx1ZSA+PSAwLjAsIFwiMjAxNTA3MTg6MDEyMzMzXCIpO1xuICogICAgIC8vIGNhbGN1bGF0ZSB0aGUgc3F1YXJlIHJvb3RcbiAqICAgfVxuICpcbiAqICAgdm9pZCBleGFtcGxlQmFkQ2FsbGVyKCkge1xuICogICAgIGRvdWJsZSBkID0gc3FydCgtMS4wKTtcbiAqICAgfVxuICogfTwvcHJlPlxuICogPHAvPlxuICogSW4gdGhpcyBleGFtcGxlLCB7QGNvZGUgY2hlY2tBcmd1bWVudH0gdGhyb3dzIGFuIHtAY29kZSBFaWRJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259IHRvIGluZGljYXRlIHRoYXQge0Bjb2RlIGV4YW1wbGVCYWRDYWxsZXJ9XG4gKiBtYWRlIGFuIGVycm9yIGluIDxpPml0czwvaT4gY2FsbCB0byB7QGNvZGUgc3FydH0uIEV4Y2VwdGlvbiwgd2hlbiBpdCB3aWxsIGJlIHByaW50ZWQgd2lsbCBjb250YWluIHVzZXIgZ2l2ZW4gRWlkIGFuZCBhbHNvXG4gKiBSYW5kb21seSBnZW5lcmF0ZWQgSUQuIFRob3NlIGZpZWxkcyBjYW4gYmUgZGlzcGxheWVkIHRvIHVzZXIgb24gZXJyb3IgcGFnZSBvbiBwb3N0ZWQgZGlyZWN0bHkgdG8gaXNzdWUgdHJhY2tlci5cbiAqIDxwLz5cbiAqIEV4YW1wbGU6XG4gKiA8cC8+XG4gKiA8cHJlPlxuICpcbiAqIHtAY29kZVxuICogICAvLyBNYWluIGFwcGxpY2F0aW9uIGNsYXNzIGZvciBleC46IGh0dHAgc2VydmxldFxuICogICAgdHJ5IHtcbiAqICAgICAgICBwZXJmb3JtUmVxdWVzdChyZXF1ZXN0LCByZXNwb25zZSk7XG4gKiAgICB9IGNhdGNoIChFaWRSdW50aW1lRXhjZXB0aW9uIGV4KSB7XG4gKiAgICAgICAgaXNzdWVzVHJhY2tlci5wdXQoZXgpO1xuICogICAgICAgIHRocm93IGV4O1xuICogICAgfVxuICogfTwvcHJlPlxuICogPHAvPlxuICogPHAvPlxuICogPGgzPkZ1bmN0aW9uYWwgdHJ5IHRvIGV4ZWN1dGUgYmxvY2tzPC9oMz5cbiAqIDxwLz5cbiAqIDxwLz5cbiAqIFVzaW5nIGZ1bmN0aW9uYWwgYmxvY2tzIHRvIGhhbmRsZSBvcGVyYXRpb25zLCB0aGF0IGFyZSBpbnRlbmRlZCB0byBvcGVyYXRlIHByb3Blcmx5LCBzaW1wbGlmeSB0aGUgY29kZSBhbmQgbWFrZXMgaXQgbW9yZVxuICogcmVhZGFibGUuIEl0J3MgYWxzbyBnb29kIHdheSB0byBkZWFsIHdpdGggdW50ZXN0ZWQsIHVuY292ZXJlZCB7QGNvZGUgY2F0Y2h9IGJsb2Nrcy4gSXQncyBlYXN5IGFuZCBnaXZlcyBkZXZlbG9wZXJzIG5pY2Ugd2F5IG9mXG4gKiBkZWFsaW5nIHdpdGggY291bnRsZXNzIG9wZXJhdGlvbnMgdGhhdCBzdXBwb3NlIHRvIHdvcmsgYXMgaW50ZW5kZWQuXG4gKiA8cC8+XG4gKiA8cC8+XG4gKiBFeGFtcGxlOlxuICogPHByZT48Y29kZT5cbiAqXG4gKiAgICAgSW5wdXRTdHJlYW0gaXMgPSBFaWRQcmVjb25kaXRpb25zLnRyeVRvRXhlY3V0ZSh7QGNvZGUgbmV3IFVuc2FmZVN1cHBsaWVyPElucHV0U3RyZWFtPn0oKSB7XG4gKiAgICAgICAge0BsaXRlcmFsIEB9T3ZlcnJpZGVcbiAqICAgICAgICAgcHVibGljIElucHV0U3RyZWFtIGdldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7XG4gKiAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRDbGFzcygpLmdldENsYXNzTG9hZGVyKClcbiAqICAgICAgICAgICAgICAgICAuZ2V0UmVzb3VyY2VBc1N0cmVhbShcInByb2plY3QucHJvcGVydGllc1wiKTtcbiAqICAgICAgICAgfVxuICogICAgIH0sIFwiMjAxNTA3MTg6MTIxNTIxXCIpO1xuICogPC9jb2RlPjwvcHJlPlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQGF1dGhvciBLcnp5c3p0b2YgU3VzennFhHNraSA8a3J6eXN6dG9mLnN1c3p5bnNraUB3YXZlc29mdHdhcmUucGw+XG4gKiBAc2luY2UgMC4xLjAgKGlkZWEgaW1wb3J0ZWQgZnJvbSBHdWF2YSBMaWJyYXJ5IGFuZCBDT0kgY29kZSlcbiAqL1xuZnVuY3Rpb24gRWlkUHJlY29uZGl0aW9ucygpIHt9XG5cbmZ1bmN0aW9uIGlzTnVsbGlrZShyZWZlcmVuY2UpIHtcbiAgcmV0dXJuIHJlZmVyZW5jZSA9PT0gbnVsbCB8fCByZWZlcmVuY2UgPT09IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gY2hlY2tOb3ROdWxsKHJlZmVyZW5jZSkge1xuICBpZiAoaXNOdWxsaWtlKHJlZmVyZW5jZSkpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUGFzcyBub3QtbnVsbCBFaWQgdG8gRWlkUHJlY29uZGl0aW9ucyBmaXJzdCFcIik7XG4gIH1cbiAgcmV0dXJuIHJlZmVyZW5jZTtcbn1cblxuZnVuY3Rpb24gZW5zdXJlRWlkKGNhbmRpZGF0ZSkge1xuICBjYW5kaWRhdGUgPSBjaGVja05vdE51bGwoY2FuZGlkYXRlKTtcbiAgdmFyIGVpZDtcbiAgaWYgKCEoY2FuZGlkYXRlIGluc3RhbmNlb2YgRWlkKSkge1xuICAgIGVpZCA9IG5ldyBFaWQoY2FuZGlkYXRlICsgJycpO1xuICB9IGVsc2Uge1xuICAgIGVpZCA9IGNhbmRpZGF0ZTtcbiAgfVxuICByZXR1cm4gZWlkO1xufVxuXG4vKipcbiAqIEVuc3VyZXMgdGhhdCBhbiBvYmplY3QgcmVmZXJlbmNlIHBhc3NlZCBhcyBhIHBhcmFtZXRlciB0byB0aGUgY2FsbGluZyBtZXRob2QgaXMgbm90IG51bGwtbGlrZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcmVmZXJlbmNlIC0gYW4gb2JqZWN0IHJlZmVyZW5jZVxuICogQHBhcmFtIHtzdHJpbmd8RWlkfSBlaWQgLSB0aGUgZXhjZXB0aW9uIElEIHRvIHVzZSBpZiB0aGUgY2hlY2sgZmFpbHNcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gbWVzc2FnZSBmb3IgcHJvZHVjZWQgZXhjZXB0aW9uXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRoZSBub24tbnVsbCByZWZlcmVuY2UgdGhhdCB3YXMgdmFsaWRhdGVkXG4gKiBAdGhyb3dzIHtFaWROdWxsUG9pbnRlckV4Y2VwdGlvbn0gaWYge0Bjb2RlIHJlZmVyZW5jZX0gaXMgbnVsbC1saWtlXG4gKi9cbkVpZFByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsYWJsZSA9IGZ1bmN0aW9uKHJlZmVyZW5jZSwgZWlkLCBtZXNzYWdlKSB7XG4gIHZhciBjaGVja2VkRWlkID0gZW5zdXJlRWlkKGVpZCk7XG4gIGlmIChpc051bGxpa2UocmVmZXJlbmNlKSkge1xuICAgIHRocm93IG5ldyBFaWROdWxsUG9pbnRlckV4Y2VwdGlvbihjaGVja2VkRWlkLCBtZXNzYWdlKTtcbiAgfVxuICByZXR1cm4gcmVmZXJlbmNlO1xufTtcblxuLyoqXG4gKiBFbnN1cmVzIHRoYXQgYW4gb2JqZWN0IHJlZmVyZW5jZSBwYXNzZWQgYXMgYSBwYXJhbWV0ZXIgdG8gdGhlIGNhbGxpbmcgbWV0aG9kIGlzIG5vdCBudWxsLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSByZWZlcmVuY2UgLSBhbiBvYmplY3QgcmVmZXJlbmNlXG4gKiBAcGFyYW0ge3N0cmluZ3xFaWR9IGVpZCAtIHRoZSBleGNlcHRpb24gSUQgdG8gdXNlIGlmIHRoZSBjaGVjayBmYWlsc1xuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBtZXNzYWdlIGZvciBwcm9kdWNlZCBleGNlcHRpb25cbiAqIEByZXR1cm4ge09iamVjdH0gdGhlIG5vbi1udWxsIHJlZmVyZW5jZSB0aGF0IHdhcyB2YWxpZGF0ZWRcbiAqIEB0aHJvd3Mge0VpZE51bGxQb2ludGVyRXhjZXB0aW9ufSBpZiB7QGNvZGUgcmVmZXJlbmNlfSBpcyBudWxsLWxpa2VcbiAqL1xuRWlkUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGwgPSBmdW5jdGlvbihyZWZlcmVuY2UsIGVpZCwgbWVzc2FnZSkge1xuICB2YXIgY2hlY2tlZEVpZCA9IGVuc3VyZUVpZChlaWQpO1xuICBpZiAocmVmZXJlbmNlID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVpZE51bGxQb2ludGVyRXhjZXB0aW9uKGNoZWNrZWRFaWQsIG1lc3NhZ2UpO1xuICB9XG4gIHJldHVybiByZWZlcmVuY2U7XG59O1xuXG4vKipcbiAqIEVuc3VyZXMgdGhhdCBhbiBvYmplY3QgcmVmZXJlbmNlIHBhc3NlZCBhcyBhIHBhcmFtZXRlciB0byB0aGUgY2FsbGluZyBtZXRob2QgaXMgbm90IHVuZGVmaW5lZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcmVmZXJlbmNlIC0gYW4gb2JqZWN0IHJlZmVyZW5jZVxuICogQHBhcmFtIHtzdHJpbmd8RWlkfSBlaWQgLSB0aGUgZXhjZXB0aW9uIElEIHRvIHVzZSBpZiB0aGUgY2hlY2sgZmFpbHNcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gbWVzc2FnZSBmb3IgcHJvZHVjZWQgZXhjZXB0aW9uXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRoZSBub24tbnVsbCByZWZlcmVuY2UgdGhhdCB3YXMgdmFsaWRhdGVkXG4gKiBAdGhyb3dzIHtFaWROdWxsUG9pbnRlckV4Y2VwdGlvbn0gaWYge0Bjb2RlIHJlZmVyZW5jZX0gaXMgbnVsbC1saWtlXG4gKi9cbkVpZFByZWNvbmRpdGlvbnMuY2hlY2tOb3RVbmRlZmluZWQgPSBmdW5jdGlvbihyZWZlcmVuY2UsIGVpZCwgbWVzc2FnZSkge1xuICB2YXIgY2hlY2tlZEVpZCA9IGVuc3VyZUVpZChlaWQpO1xuICBpZiAocmVmZXJlbmNlID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRWlkTnVsbFBvaW50ZXJFeGNlcHRpb24oY2hlY2tlZEVpZCwgbWVzc2FnZSk7XG4gIH1cbiAgcmV0dXJuIHJlZmVyZW5jZTtcbn07XG5cbi8qKlxuICogRW5zdXJlcyB0aGUgdHJ1dGggb2YgYW4gZXhwcmVzc2lvbiBpbnZvbHZpbmcgb25lIG9yIG1vcmUgcGFyYW1ldGVycyB0byB0aGUgY2FsbGluZyBtZXRob2QuXG4gKlxuICogQHBhcmFtIHtib29sZWFufSBleHByZXNzaW9uIC0gYSBib29sZWFuIGV4cHJlc3Npb25cbiAqIEBwYXJhbSB7c3RyaW5nfEVpZH0gZWlkIC0gdGhlIGV4Y2VwdGlvbiBJRCB0byB1c2UgaWYgdGhlIGNoZWNrIGZhaWxzXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIG9wdGlvbmFsIG1lc3NhZ2UgZm9yIGdlbmVyYXRlZCBleGNlcHRpb25cbiAqIEB0aHJvd3Mge0VpZElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbn0gaWYge0Bjb2RlIGV4cHJlc3Npb259IGlzIGZhbHNlXG4gKiBAdGhyb3dzIHtFaWROdWxsUG9pbnRlckV4Y2VwdGlvbn0gICAgIGlmIHtAY29kZSBleHByZXNzaW9ufSBpcyBudWxsXG4gKi9cbkVpZFByZWNvbmRpdGlvbnMuY2hlY2tBcmd1bWVudCA9IGZ1bmN0aW9uKGV4cHJlc3Npb24sIGVpZCwgbWVzc2FnZSkge1xuICB2YXIgY2hlY2tlZEVpZCA9IGVuc3VyZUVpZChlaWQpO1xuICBpZiAoIUVpZFByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsYWJsZShleHByZXNzaW9uLCBjaGVja2VkRWlkKSkge1xuICAgIHRocm93IG5ldyBFaWRJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oY2hlY2tlZEVpZCwgbWVzc2FnZSlcbiAgfVxufTtcblxuLyoqXG4gKiBFbnN1cmVzIHRoZSB0cnV0aCBvZiBhbiBleHByZXNzaW9uIGludm9sdmluZyB0aGUgc3RhdGUgb2YgdGhlIGNhbGxpbmcgaW5zdGFuY2UsIGJ1dCBub3QgaW52b2x2aW5nIGFueSBwYXJhbWV0ZXJzIHRvIHRoZVxuICogY2FsbGluZyBtZXRob2QuXG4gKlxuICogQHBhcmFtIHtib29sZWFufSBleHByZXNzaW9uIC0gYSBib29sZWFuIGV4cHJlc3Npb25cbiAqIEBwYXJhbSB7c3RyaW5nfEVpZH0gZWlkIC0gdGhlIGV4Y2VwdGlvbiBJRCB0byB1c2UgaWYgdGhlIGNoZWNrIGZhaWxzXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIG9wdGlvbmFsIG1lc3NhZ2UgZm9yIGdlbmVyYXRlZCBleGNlcHRpb25cbiAqIEB0aHJvd3Mge0VpZElsbGVnYWxTdGF0ZUV4Y2VwdGlvbn0gaWYge0Bjb2RlIGV4cHJlc3Npb259IGlzIGZhbHNlXG4gKiBAdGhyb3dzIHtFaWROdWxsUG9pbnRlckV4Y2VwdGlvbn0gICAgIGlmIHtAY29kZSBleHByZXNzaW9ufSBpcyBudWxsXG4gKi9cbkVpZFByZWNvbmRpdGlvbnMuY2hlY2tTdGF0ZSA9IGZ1bmN0aW9uKGV4cHJlc3Npb24sIGVpZCwgbWVzc2FnZSkge1xuICB2YXIgY2hlY2tlZEVpZCA9IGVuc3VyZUVpZChlaWQpO1xuICBpZiAoIUVpZFByZWNvbmRpdGlvbnMuY2hlY2tOb3ROdWxsYWJsZShleHByZXNzaW9uLCBjaGVja2VkRWlkKSkge1xuICAgIHRocm93IG5ldyBFaWRJbGxlZ2FsU3RhdGVFeGNlcHRpb24oY2hlY2tlZEVpZCwgbWVzc2FnZSk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGlzSW5kZXhBbmRTaXplSWxsZWdhbChpbmRleCwgc2l6ZSkge1xuICByZXR1cm4gaW5kZXggPCAwIHx8IGluZGV4ID4gc2l6ZTtcbn1cblxuZnVuY3Rpb24gaXNTaXplSWxsZWdhbChzaXplKSB7XG4gIHJldHVybiBzaXplIDwgMDtcbn1cblxuLyoqXG4gKiBFbnN1cmVzIHRoYXQge0Bjb2RlIGluZGV4fSBzcGVjaWZpZXMgYSB2YWxpZCA8aT5lbGVtZW50PC9pPiBpbiBhbiBhcnJheSwgbGlzdCBvciBzdHJpbmcgb2Ygc2l6ZSB7QGNvZGUgc2l6ZX0uIEFuIGVsZW1lbnRcbiAqIGluZGV4IG1heSByYW5nZSBmcm9tIHplcm8sIGluY2x1c2l2ZSwgdG8ge0Bjb2RlIHNpemV9LCBleGNsdXNpdmUuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IC0gYSB1c2VyLXN1cHBsaWVkIGluZGV4IGlkZW50aWZ5aW5nIGFuIGVsZW1lbnQgb2YgYW4gYXJyYXksIGxpc3Qgb3Igc3RyaW5nXG4gKiBAcGFyYW0ge251bWVyfSBzaXplIC0gdGhlIHNpemUgb2YgdGhhdCBhcnJheSwgbGlzdCBvciBzdHJpbmdcbiAqIEBwYXJhbSB7c3RyaW5nfEVpZH0gZWlkIC0gdGhlIHRleHQgdG8gdXNlIHRvIGRlc2NyaWJlIHRoaXMgaW5kZXggaW4gYW4gZXJyb3IgbWVzc2FnZVxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBvcHRpb25hbCBtZXNzYWdlIGZvciBnZW5lcmF0ZWQgZXhjZXB0aW9uXG4gKiBAcmV0dXJuIHtudW1iZXJ9IHRoZSB2YWx1ZSBvZiB7QGNvZGUgaW5kZXh9XG4gKiBAdGhyb3dzIHtFaWRJbmRleE91dE9mQm91bmRzRXhjZXB0aW9ufSBpZiB7QGNvZGUgaW5kZXh9IGlzIG5lZ2F0aXZlIG9yIGlzIG5vdCBsZXNzIHRoYW4ge0Bjb2RlIHNpemV9XG4gKiBAdGhyb3dzIHtFaWRJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb259ICBpZiB7QGNvZGUgc2l6ZX0gaXMgbmVnYXRpdmVcbiAqL1xuRWlkUHJlY29uZGl0aW9ucy5jaGVja0VsZW1lbnRJbmRleCA9IGZ1bmN0aW9uKGluZGV4LCBzaXplLCBlaWQsIG1lc3NhZ2UpIHtcbiAgdmFyIGNoZWNrZWRFaWQgPSBlbnN1cmVFaWQoZWlkKTtcbiAgaWYgKGlzU2l6ZUlsbGVnYWwoc2l6ZSkpIHtcbiAgICB0aHJvdyBuZXcgRWlkSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uKGNoZWNrZWRFaWQsIG1lc3NhZ2UpO1xuICB9XG4gIGlmIChpc0luZGV4QW5kU2l6ZUlsbGVnYWwoaW5kZXgsIHNpemUpKSB7XG4gICAgdGhyb3cgbmV3IEVpZEluZGV4T3V0T2ZCb3VuZHNFeGNlcHRpb24oY2hlY2tlZEVpZCwgbWVzc2FnZSk7XG4gIH1cbiAgcmV0dXJuIGluZGV4O1xufTtcblxuLyoqXG4gKiBUcmllcyB0byBleGVjdXRlIGNvZGUgaW4gZ2l2ZW4gdW5zYWZlIHN1cHBsaWVyIGNvZGUgYmxvY2ssIGFuZCBpZiBleGNlcHRpb24gaXMgdGhyb3duLCBpdCB3aWxsIGdldHMgcmV0aHJvd24gYXMgYVxuICoge0BsaW5rIEVpZFJ1bnRpbWVFeGNlcHRpb259IHdpdGggZWlkIGdpdmVuIGFzIGEgYXJndW1lbnQuIFRoaXMgaXMgYmVjYXVzZSB0aGlzIGV4Y2VwdGlvbiBpcyB0aHJlYWRlZCBhcyBhIHNvZnR3YXJlIGJ1ZyFcbiAqIDxwLz5cbiAqIEV4YW1wbGU6XG4gKiA8cHJlPjxjb2RlPlxuICpcbiAqIERvY3VtZW50IGRvYyA9IEVpZFByZWNvbmRpdGlvbnMudHJ5VG9FeGVjdXRlKHtAY29kZSBuZXcgVW5zYWZlU3VwcGxpZXI8RG9jdW1lbnQ+fSgpIHtcbiAqICAgIHtAbGl0ZXJhbCBAfU92ZXJyaWRlXG4gKiAgICAgcHVibGljIERvY3VtZW50IGdldCgpIHRocm93cyBJT0V4Y2VwdGlvbiB7XG4gKiAgICAgICAgICBEb2N1bWVudEJ1aWxkZXIgZG9jQnVpbGRlciA9IC4uLlxuICogICAgICAgICAgcmV0dXJuIGRvY0J1aWxkZXIucGFyc2UobmV3IElucHV0U291cmNlKHJlYWRlcikpO1xuICogICAgIH1cbiAqIH0sIG5ldyBFaWQoXCIyMDE1MDcxODoxMjE1MjFcIikpO1xuICogPC9jb2RlPjwvcHJlPlxuICpcbiAqIEBwYXJhbSA8Uj4gICAgICByZXR1cm4gdHlwZVxuICogQHBhcmFtIHN1cHBsaWVyIHVuc2FmZSBzdXBwbGllciBjb2RlIHRvIGJlIGV4ZWN1dGVkIHdpdGhpbiBhIHRyeS1jYXRjaCBibG9ja1xuICogQHBhcmFtIGVpZCAgICAgIHVuaXF1ZSBkZXZlbG9wZXIgaWRlbnRpZmllciBmcm9tIGRhdGUgZm9yIGV4LjogXCIyMDE1MDcxNjoxMjMyMDBcIlxuICogQHJldHVybiBBIGJsb2NrIG9mIGNvZGUgcmV0dXJuIHR5cGUsIGlmIGV4Y2VwdGlvbiBpcyBub3QgdGhyb3duXG4gKiBAdGhyb3dzIEVpZFJ1bnRpbWVFeGNlcHRpb24gaWYgY29kZSBibG9jayB0aHJvd24gYW55IGV4Y2VwdGlvbiwgd2hpY2ggaW4gdGhhdCBjYXNlIGlzIHdyYXBwZWQgaW4gRWlkUnVudGltZUV4Y2VwdGlvblxuICovXG5FaWRQcmVjb25kaXRpb25zLnRyeVRvRXhlY3V0ZSA9IGZ1bmN0aW9uKHN1cHBsaWVyLCBlaWQpIHtcbiAgdmFyIGNoZWNrZWRFaWQgPSBlbnN1cmVFaWQoZWlkKTtcbiAgdHJ5IHtcbiAgICByZXR1cm4gRWlkUHJlY29uZGl0aW9ucy5jaGVja05vdE51bGxhYmxlKHN1cHBsaWVyLCBjaGVja2VkRWlkKS5hcHBseSgpO1xuICB9IGNhdGNoICh0aHJvd2FibGUpIHtcbiAgICB0aHJvdyBuZXcgRWlkUnVudGltZUV4Y2VwdGlvbihjaGVja2VkRWlkLCB0aHJvd2FibGUpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEVpZFByZWNvbmRpdGlvbnM7XG59KShtb2R1bGUpO1xuIl19 diff --git a/dist/browser/toplevel/eid.min.js b/dist/browser/toplevel/eid.min.js new file mode 100644 index 0000000..8278063 --- /dev/null +++ b/dist/browser/toplevel/eid.min.js @@ -0,0 +1,2 @@ +!function t(e,n,r){function o(u,a){if(!n[u]){if(!e[u]){var c="function"==typeof require&&require;if(!a&&c)return c(u,!0);if(i)return i(u,!0);var f=new Error("Cannot find module '"+u+"'");throw f.code="MODULE_NOT_FOUND",f}var s=n[u]={exports:{}};e[u][0].call(s.exports,function(t){var n=e[u][1][t];return o(n?n:t)},s,s.exports,t,e,n,r)}return n[u].exports}for(var i="function"==typeof require&&require,u=0;uo;o++)r.push(o+"-test-id");var i=new e(t).format(r);for(var u in r)if(-1===i.indexOf(u))throw new TypeError("Given format contains to little format specifiers, expected "+n+' but given "'+t+'"')};n.setUniqIdGenerator=function(t){if(null===t||void 0===t)throw new TypeError("Unique ID generator can't be null, but given one");var e=l.uniqIdGenerator;return l.uniqIdGenerator=t,e},n.setFormat=function(t){d(t,f);var e=l.format;return l.format=t,e},n.setRefFormat=function(t){d(t,s);var e=l.refFormat;return l.refFormat=t,e},n.setMessageFormat=function(t){d(t,p);var e=l.messageFormat;return l.messageFormat=t,e},n.getMessageFormat=function(){return l.messageFormat},t.exports=n}(e)},{}],4:[function(t,e,n){!function(e){"use strict";function n(t,e){this.name="EidRuntimeException",c.apply(this,[t,e])}function r(t,e){this.name="EidNullPointerException",c.apply(this,[t,e])}function o(t,e){this.name="EidIllegalArgumentException",c.apply(this,[t,e])}function i(t,e){this.name="EidIllegalStateException",c.apply(this,[t,e])}function u(t,e){this.name="EidIndexOutOfBoundsException",c.apply(this,[t,e])}var a=t("./eid"),c=function(t,e){t instanceof a||(t=new a(t.toString())),this.message=void 0!==e?t+" "+e:t,this.eid=t};n.prototype=new Error,r.prototype=n.prototype,o.prototype=n.prototype,i.prototype=n.prototype,u.prototype=n.prototype,e.EidRuntimeException=n,e.EidNullPointerException=r,e.EidIllegalArgumentException=o,e.EidIllegalStateException=i,e.EidIndexOutOfBoundsException=u}(n)},{"./eid":3}],5:[function(t,e,n){!function(e){"use strict";function n(){}function r(t){return null===t||void 0===t}function o(t){if(r(t))throw new TypeError("Pass not-null Eid to EidPreconditions first!");return t}function i(t){t=o(t);var e;return e=t instanceof c?t:new c(t+"")}function u(t,e){return 0>t||t>e}function a(t){return 0>t}var c=t("./eid"),f=t("./exceptions").EidRuntimeException,s=t("./exceptions").EidNullPointerException,p=t("./exceptions").EidIllegalArgumentException,l=t("./exceptions").EidIllegalStateException,d=t("./exceptions").EidIndexOutOfBoundsException;n.checkNotNullable=function(t,e,n){var o=i(e);if(r(t))throw new s(o,n);return t},n.checkNotNull=function(t,e,n){var r=i(e);if(null===t)throw new s(r,n);return t},n.checkNotUndefined=function(t,e,n){var r=i(e);if(void 0===t)throw new s(r,n);return t},n.checkArgument=function(t,e,r){var o=i(e);if(!n.checkNotNullable(t,o))throw new p(o,r)},n.checkState=function(t,e,r){var o=i(e);if(!n.checkNotNullable(t,o))throw new l(o,r)},n.checkElementIndex=function(t,e,n,r){var o=i(n);if(a(e))throw new p(o,r);if(u(t,e))throw new d(o,r);return t},n.tryToExecute=function(t,e){var r=i(e);try{return n.checkNotNullable(t,r).apply()}catch(o){throw new f(r,o)}},e.exports=n}(e)},{"./eid":3,"./exceptions":4}]},{},[1]); +//# sourceMappingURL=eid.min.js.map diff --git a/dist/browser/toplevel/eid.min.js.map b/dist/browser/toplevel/eid.min.js.map new file mode 100644 index 0000000..e425da8 --- /dev/null +++ b/dist/browser/toplevel/eid.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["node_modules/browser-pack/_prelude.js","gulp/build/toplevel.js","eid.min.js","lib/eid.js","lib/eid/eid.js","lib/eid/exceptions.js","lib/eid/preconditions.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length",1,"module","wnd","Eid","window","../../lib/eid",2,"preconditions","exceptions","./eid/eid","./eid/exceptions","./eid/preconditions",3,"JFormatter","format","this","arr","args","arguments","push","regex","_r","p","c","replace","reduce","id","ref","uniq","EidInternal","uniqIdGenerator","generateUniqId","undefined","makeLogMessage","logMessageFormat","parameters","message","getMessageFormat","toString","refFormat","getId","getRef","getUniq","MathRandom","LONG_MAX","Math","pow","LONG_MIN","nextLong","random","nextInt","max","min","floor","StdUniqIdGenerator","BASE36","INTEGER_MAX_VALUE","generator","first","abs","second","calc","DEFAULT_FORMAT","DEFAULT_REF_FORMAT","DEFAULT_MESSAGE_FORMAT","DEFAULT_UNIQ_ID_GENERATOR","Object","defineProperty","get","FORMAT_NUM_SPEC","REF_FORMAT_NUM_SPEC","MESSAGE_FORMAT_NUM_SPEC","messageFormat","validateFormat","numSpecifiers","TypeError","specifiers","formatted","specifier","indexOf","setUniqIdGenerator","previous","setFormat","previously","setRefFormat","setMessageFormat","oldFormat",4,"EidRuntimeException","eid","name","commonExConstructor","apply","EidNullPointerException","EidIllegalArgumentException","EidIllegalStateException","EidIndexOutOfBoundsException","prototype","./eid",5,"EidPreconditions","isNullike","reference","checkNotNull","ensureEid","candidate","isIndexAndSizeIllegal","index","size","isSizeIllegal","checkNotNullable","checkedEid","checkNotUndefined","checkArgument","expression","checkState","checkElementIndex","tryToExecute","supplier","throwable","./exceptions"],"mappings":"CAAA,QAAAA,GAAAC,EAAAC,EAAAC,GAAA,QAAAC,GAAAC,EAAAC,GAAA,IAAAJ,EAAAG,GAAA,CAAA,IAAAJ,EAAAI,GAAA,CAAA,GAAAE,GAAA,kBAAAC,UAAAA,OAAA,KAAAF,GAAAC,EAAA,MAAAA,GAAAF,GAAA,EAAA,IAAAI,EAAA,MAAAA,GAAAJ,GAAA,EAAA,IAAAK,GAAA,GAAAC,OAAA,uBAAAN,EAAA,IAAA,MAAAK,GAAAE,KAAA,mBAAAF,EAAA,GAAAG,GAAAX,EAAAG,IAAAS,WAAAb,GAAAI,GAAA,GAAAU,KAAAF,EAAAC,QAAA,SAAAd,GAAA,GAAAE,GAAAD,EAAAI,GAAA,GAAAL,EAAA,OAAAI,GAAAF,EAAAA,EAAAF,IAAAa,EAAAA,EAAAC,QAAAd,EAAAC,EAAAC,EAAAC,GAAA,MAAAD,GAAAG,GAAAS,QAAA,IAAA,GAAAL,GAAA,kBAAAD,UAAAA,QAAAH,EAAA,EAAAA,EAAAF,EAAAa,OAAAX,IAAAD,EAAAD,EAAAE,GAAA,OAAAD,KAAAa,GAAA,SAAAT,EAAAU,EAAAJ,ICgBA,SAAAK,GACA,YACAA,GAAAC,IAAAZ,EAAA,kBACAa,UCGGC,gBAAgB,IAAIC,GAAG,SAASf,EAAQU,EAAOJ,ICNlD,SAAAI,GACA,YAEA,IAAAE,GAAAZ,EAAA,YACAY,GAAAI,cAAAhB,EAAA,uBACAY,EAAAK,WAAAjB,EAAA,oBAEAU,EAAAJ,QAAAM,GAEAF,KDyBGQ,YAAY,EAAEC,mBAAmB,EAAEC,sBAAsB,IAAIC,GAAG,SAASrB,EAAQU,EAAOJ,IElC3F,SAAAI,GACA,YAEA,SAAAY,GAAAC,GACAC,KAAAD,OAAA,SAAAE,GACA,GAAAC,KACA,IAAA,IAAAC,UAAAnB,QAAA,gBAAA,GACAkB,EAAAD,MAEA,KAAA,GAAAxB,GAAA,EAAAA,EAAA0B,UAAAnB,OAAAP,IACAyB,EAAAE,KAAAD,UAAA1B,GAGA,IAAA4B,GAAA,KACAC,EAAA,SAAAC,EAAAC,GAAA,MAAAD,GAAAE,QAAAJ,EAAAG,GACA,OAAAN,GAAAQ,OAAAJ,EAAAP,IAaA,QAAAX,GAAAuB,EAAAC,GACA,GAAAC,GAAAC,EAAAC,gBAAAC,gBACAJ,GAAA,OAAAA,GAAAK,QAAAL,EAAA,GAAAA,EAcAZ,KAAAkB,eAAA,SAAAC,GAEA,IAAA,GADAC,MACA3C,EAAA,EAAAA,EAAA0B,UAAAnB,OAAAP,IACA2C,EAAAhB,KAAAD,UAAA1B,GAEA,IAAA4C,GAAA,GAAAvB,GAAAqB,GAAApB,OAAAqB,EACA,OAAA,IAAAtB,GAAAV,EAAAkC,oBAAAvB,OAAAC,KAAAuB,WAAAF,IAMArB,KAAAuB,SAAA,WACA,MAAA,KAAAX,EACA,GAAAd,GAAAgB,EAAAf,QAAAA,OAAAY,EAAAE,GAEA,GAAAf,GAAAgB,EAAAU,WAAAzB,OAAAY,EAAAC,EAAAC,IAQAb,KAAAyB,MAAA,WACA,MAAAd,IAQAX,KAAA0B,OAAA,WACA,MAAAd,IAQAZ,KAAA2B,QAAA,WACA,MAAAd,IAIA,QAAAe,KACA,GAAAC,GAAAC,KAAAC,IAAA,EAAA,IAAA,EACAC,EAAA,GAAAF,KAAAC,IAAA,EAAA,GACA/B,MAAAiC,SAAA,WACA,MAAAC,GAAAF,EAAAH,IAEA7B,KAAAmC,QAAA,SAAAC,GACA,MAAAF,GAAA,EAAAE,GAEA,IAAAF,GAAA,SAAAG,EAAAD,GACA,MAAAN,MAAAQ,MAAAR,KAAAI,UAAAE,EAAAC,EAAA,IAAAA,GAIA,QAAAE,KACA,GAAAC,GAAA,GACAC,EAAAX,KAAAC,IAAA,EAAA,IACAW,EAAA,GAAAd,EACA5B,MAAAgB,eAAA,WACA,GAAA2B,GAAAb,KAAAc,IAAAF,EAAAT,WAAA,GACAY,EAAAf,KAAAc,IAAAF,EAAAP,QAAAM,IACAK,EAAAH,EAAAE,CACA,QAAAf,KAAAc,IAAAE,GAAAL,GAAAlB,SAAAiB,IAIA,GAAAO,GAAA,WACAC,EAAA,cACAC,EAAA,WACAC,EAAA,GAAAX,EAEAY,QAAAC,eAAAhE,EAAA,kBACAiE,IAAA,WAAA,MAAAN,MAEAI,OAAAC,eAAAhE,EAAA,0BACAiE,IAAA,WAAA,MAAAJ,MAEAE,OAAAC,eAAAhE,EAAA,sBACAiE,IAAA,WAAA,MAAAL,MAEAG,OAAAC,eAAAhE,EAAA,6BACAiE,IAAA,WAAA,MAAAH,KAGA,IAAAI,GAAA,EACAC,EAAA,EACAC,EAAA,EAEA1C,GACA2C,cAAAR,EACAlC,gBAAAmC,EACAnD,OAAAgD,EACAvB,UAAAwB,GAGAU,EAAA,SAAA3D,EAAA4D,GACA,GAAA,OAAA5D,GAAAkB,SAAAlB,EACA,KAAA,IAAA6D,WAAA,8CAGA,KAAA,GADAC,MACApF,EAAA,EAAAkF,EAAAlF,EAAAA,IACAoF,EAAAzD,KAAA3B,EAAA,WAEA,IAAAqF,GAAA,GAAAhE,GAAAC,GAAAA,OAAA8D,EACA,KAAA,GAAAE,KAAAF,GACA,GAAA,KAAAC,EAAAE,QAAAD,GACA,KAAA,IAAAH,WAAA,+DACAD,EAAA,eAAA5D,EAAA,KAaAX,GAAA6E,mBAAA,SAAAlD,GACA,GAAA,OAAAA,GAAAE,SAAAF,EACA,KAAA,IAAA6C,WAAA,mDAEA,IAAAM,GAAApD,EAAAC,eAEA,OADAD,GAAAC,gBAAAA,EACAmD,GAWA9E,EAAA+E,UAAA,SAAApE,GACA2D,EAAA3D,EAAAuD,EACA,IAAAc,GAAAtD,EAAAf,MAEA,OADAe,GAAAf,OAAAA,EACAqE,GAWAhF,EAAAiF,aAAA,SAAA7C,GACAkC,EAAAlC,EAAA+B,EACA,IAAAa,GAAAtD,EAAAU,SAEA,OADAV,GAAAU,UAAAA,EACA4C,GAaAhF,EAAAkF,iBAAA,SAAAvE,GACA2D,EAAA3D,EAAAyD,EACA,IAAAe,GAAAzD,EAAA2C,aAEA,OADA3C,GAAA2C,cAAA1D,EACAwE,GAQAnF,EAAAkC,iBAAA,WACA,MAAAR,GAAA2C,eAGAvE,EAAAJ,QAAAM,GAEAF,QFqDMsF,GAAG,SAAShG,EAAQU,EAAOJ,IGnSjC,SAAAA,GACA,YA6BA,SAAA2F,GAAAC,EAAArD,GACArB,KAAA2E,KAAA,sBACAC,EAAAC,MAAA7E,MAAA0E,EAAArD,IAiBA,QAAAyD,GAAAJ,EAAArD,GACArB,KAAA2E,KAAA,0BACAC,EAAAC,MAAA7E,MAAA0E,EAAArD,IAiBA,QAAA0D,GAAAL,EAAArD,GACArB,KAAA2E,KAAA,8BACAC,EAAAC,MAAA7E,MAAA0E,EAAArD,IAiBA,QAAA2D,GAAAN,EAAArD,GACArB,KAAA2E,KAAA,2BACAC,EAAAC,MAAA7E,MAAA0E,EAAArD,IAiBA,QAAA4D,GAAAP,EAAArD,GACArB,KAAA2E,KAAA,+BACAC,EAAAC,MAAA7E,MAAA0E,EAAArD,IAzGA,GAAAjC,GAAAZ,EAAA,SACAoG,EAAA,SAAAF,EAAArD,GACAqD,YAAAtF,KACAsF,EAAA,GAAAtF,GAAAsF,EAAAnD,aAEAvB,KAAAqB,QAAAJ,SAAAI,EAAAqD,EAAA,IAAArD,EAAAqD,EACA1E,KAAA0E,IAAAA,EAyBAD,GAAAS,UAAA,GAAAvG,OAmBAmG,EAAAI,UAAAT,EAAAS,UAmBAH,EAAAG,UAAAT,EAAAS,UAmBAF,EAAAE,UAAAT,EAAAS,UAmBAD,EAAAC,UAAAT,EAAAS,UAEApG,EAAA2F,oBAAAA,EACA3F,EAAAgG,wBAAAA,EACAhG,EAAAiG,4BAAAA,EACAjG,EAAAkG,yBAAAA,EACAlG,EAAAmG,6BAAAA,GAEAnG,KHsTGqG,QAAQ,IAAIC,GAAG,SAAS5G,EAAQU,EAAOJ,II5a1C,SAAAI,GACA,YA0FA,SAAAmG,MAEA,QAAAC,GAAAC,GACA,MAAA,QAAAA,GAAAtE,SAAAsE,EAGA,QAAAC,GAAAD,GACA,GAAAD,EAAAC,GACA,KAAA,IAAA3B,WAAA,+CAEA,OAAA2B,GAGA,QAAAE,GAAAC,GACAA,EAAAF,EAAAE,EACA,IAAAhB,EAMA,OAFAA,GAHAgB,YAAAtG,GAGAsG,EAFA,GAAAtG,GAAAsG,EAAA,IA2FA,QAAAC,GAAAC,EAAAC,GACA,MAAA,GAAAD,GAAAA,EAAAC,EAGA,QAAAC,GAAAD,GACA,MAAA,GAAAA,EAzMA,GAAAzG,GAAAZ,EAAA,SACAiG,EAAAjG,EAAA,gBAAAiG,oBACAK,EAAAtG,EAAA,gBAAAsG,wBACAC,EAAAvG,EAAA,gBAAAuG,4BACAC,EAAAxG,EAAA,gBAAAwG,yBACAC,EAAAzG,EAAA,gBAAAyG,4BAoHAI,GAAAU,iBAAA,SAAAR,EAAAb,EAAArD,GACA,GAAA2E,GAAAP,EAAAf,EACA,IAAAY,EAAAC,GACA,KAAA,IAAAT,GAAAkB,EAAA3E,EAEA,OAAAkE,IAYAF,EAAAG,aAAA,SAAAD,EAAAb,EAAArD,GACA,GAAA2E,GAAAP,EAAAf,EACA,IAAA,OAAAa,EACA,KAAA,IAAAT,GAAAkB,EAAA3E,EAEA,OAAAkE,IAYAF,EAAAY,kBAAA,SAAAV,EAAAb,EAAArD,GACA,GAAA2E,GAAAP,EAAAf,EACA,IAAAzD,SAAAsE,EACA,KAAA,IAAAT,GAAAkB,EAAA3E,EAEA,OAAAkE,IAYAF,EAAAa,cAAA,SAAAC,EAAAzB,EAAArD,GACA,GAAA2E,GAAAP,EAAAf,EACA,KAAAW,EAAAU,iBAAAI,EAAAH,GACA,KAAA,IAAAjB,GAAAiB,EAAA3E,IAcAgE,EAAAe,WAAA,SAAAD,EAAAzB,EAAArD,GACA,GAAA2E,GAAAP,EAAAf,EACA,KAAAW,EAAAU,iBAAAI,EAAAH,GACA,KAAA,IAAAhB,GAAAgB,EAAA3E,IAwBAgE,EAAAgB,kBAAA,SAAAT,EAAAC,EAAAnB,EAAArD,GACA,GAAA2E,GAAAP,EAAAf,EACA,IAAAoB,EAAAD,GACA,KAAA,IAAAd,GAAAiB,EAAA3E,EAEA,IAAAsE,EAAAC,EAAAC,GACA,KAAA,IAAAZ,GAAAe,EAAA3E,EAEA,OAAAuE,IAyBAP,EAAAiB,aAAA,SAAAC,EAAA7B,GACA,GAAAsB,GAAAP,EAAAf,EACA,KACA,MAAAW,GAAAU,iBAAAQ,EAAAP,GAAAnB,QACA,MAAA2B,GACA,KAAA,IAAA/B,GAAAuB,EAAAQ,KAIAtH,EAAAJ,QAAAuG,GACAnG,KJ+bGiG,QAAQ,EAAEsB,eAAe,SAAS","file":"eid.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;oThis class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * Exception identifier for all Eid Runtime Exceptions.\n * @constructor\n * @param {string} id - the exception id, must be unique developer inserted string, from date\n * @param {string} ref - an optional reference\n */\nfunction Eid(id, ref) {\n var uniq = EidInternal.uniqIdGenerator.generateUniqId();\n ref = (ref === null || ref == undefined) ? \"\" : ref;\n\n /**\n * Makes a log message from this EID object\n *

\n *

This method is for convenience of usage of EID in logging. You can use it like this:\n *

\n *

\n   * log.debug(new Eid(\"20151025:202129\").makeLogMessage(\"A request: %s\", request));\n   * 
\n * @param {string} logMessageFormat - a log message format as accepted by {@link String#format(String, Object...)}\n * @param {Object...} parameters - a parameters for logMessageFormat to by passed to {@link String#format(String, Object...)}\n * @return {string} a formatted message\n */\n this.makeLogMessage = function(logMessageFormat) {\n var parameters = [];\n for (var i = 1; i < arguments.length; i++) {\n parameters.push(arguments[i]);\n }\n var message = new JFormatter(logMessageFormat).format(parameters);\n return new JFormatter(Eid.getMessageFormat()).format(this.toString(), message);\n }\n\n /**\n * Standard to string method\n */\n this.toString = function() {\n if (\"\" === ref) {\n return new JFormatter(EidInternal.format).format(id, uniq);\n }\n return new JFormatter(EidInternal.refFormat).format(id, ref, uniq);\n }\n\n /**\n * Getter for constant Exception ID\n *\n * @return {string} ID of exception\n */\n this.getId = function() {\n return id;\n }\n\n /**\n * Get custom ref passed to Exception ID\n *\n * @return {string} ID of exception\n */\n this.getRef = function() {\n return ref;\n }\n\n /**\n * Gets unique generated string for this instance of Eid\n *\n * @return {string} a unique string\n */\n this.getUniq = function() {\n return uniq;\n }\n}\n\nfunction MathRandom() {\n var LONG_MAX = Math.pow(2, 53) - 1;\n var LONG_MIN = -1 * Math.pow(2, 53);\n this.nextLong = function() {\n return random(LONG_MIN, LONG_MAX);\n };\n this.nextInt = function(max) {\n return random(0, max);\n };\n var random = function(min, max) {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n };\n}\n\nfunction StdUniqIdGenerator() {\n var BASE36 = 36;\n var INTEGER_MAX_VALUE = Math.pow(2, 31);\n var generator = new MathRandom();\n this.generateUniqId = function() {\n var first = Math.abs(generator.nextLong() + 1);\n var second = Math.abs(generator.nextInt(INTEGER_MAX_VALUE));\n var calc = first + second;\n return (Math.abs(calc) % INTEGER_MAX_VALUE).toString(BASE36);\n };\n}\n\nvar DEFAULT_FORMAT = \"[%s]<%s>\";\nvar DEFAULT_REF_FORMAT = \"[%s|%s]<%s>\";\nvar DEFAULT_MESSAGE_FORMAT = \"%s => %s\";\nvar DEFAULT_UNIQ_ID_GENERATOR = new StdUniqIdGenerator();\n\nObject.defineProperty(Eid, \"DEFAULT_FORMAT\", {\n get: function() { return DEFAULT_FORMAT; }\n});\nObject.defineProperty(Eid, \"DEFAULT_MESSAGE_FORMAT\", {\n get: function() { return DEFAULT_MESSAGE_FORMAT; }\n});\nObject.defineProperty(Eid, \"DEFAULT_REF_FORMAT\", {\n get: function() { return DEFAULT_REF_FORMAT; }\n});\nObject.defineProperty(Eid, \"DEFAULT_UNIQ_ID_GENERATOR\", {\n get: function() { return DEFAULT_UNIQ_ID_GENERATOR; }\n});\n\nvar FORMAT_NUM_SPEC = 2;\nvar REF_FORMAT_NUM_SPEC = 3;\nvar MESSAGE_FORMAT_NUM_SPEC = 2;\n\nvar EidInternal = {\n messageFormat: DEFAULT_MESSAGE_FORMAT,\n uniqIdGenerator: DEFAULT_UNIQ_ID_GENERATOR,\n format: DEFAULT_FORMAT,\n refFormat: DEFAULT_REF_FORMAT\n};\n\nvar validateFormat = function(format, numSpecifiers) {\n if (format === null || format === undefined) {\n throw new TypeError(\"Format can't be null, but just received one\");\n }\n var specifiers = [];\n for (var i = 0; i < numSpecifiers; i++) {\n specifiers.push(i + \"-test-id\");\n }\n var formatted = new JFormatter(format).format(specifiers);\n for (var specifier in specifiers) {\n if (formatted.indexOf(specifier) === -1) {\n throw new TypeError(\"Given format contains to little format specifiers, \" +\n \"expected \" + numSpecifiers + \" but given \\\"\" + format + \"\\\"\");\n }\n }\n};\n\n/**\n * Sets the actual unique ID generator that will be used to generate IDs for all Eid objects. It will return previously used\n * generator.\n *\n * @param {UniqIdGenerator} uniqIdGenerator - new instance of unique ID generator\n * @return {UniqIdGenerator} a previously used unique ID generator\n * @throws {TypeError} if given generator was null\n */\nEid.setUniqIdGenerator = function(uniqIdGenerator) {\n if (uniqIdGenerator === null || uniqIdGenerator === undefined) {\n throw new TypeError(\"Unique ID generator can't be null, but given one\");\n }\n var previous = EidInternal.uniqIdGenerator;\n EidInternal.uniqIdGenerator = uniqIdGenerator;\n return previous;\n};\n\n/**\n * Sets the actual format that will be used in {@link #toString()} method. It will return previously used format.\n *\n * @param {string} format - a format compliant with {@link String#format(String, Object...)} with 2 object arguments\n * @return {string} a previously used format\n * @throws {TypeError} if given format hasn't got two format specifiers \"%s\", or if given format was\n * null\n */\nEid.setFormat = function(format) {\n validateFormat(format, FORMAT_NUM_SPEC);\n var previously = EidInternal.format;\n EidInternal.format = format;\n return previously;\n};\n\n/**\n * Sets the actual format that will be used in {@link #toString()} method\n *\n * @param {string} refFormat - a format compliant with {@link String#format(String, Object...)} with 3 object arguments\n * @return {string} a previously used format\n * @throws {TypeError} if given format hasn't got tree format specifiers \"%s\", or if given format was\n * null\n */\nEid.setRefFormat = function(refFormat) {\n validateFormat(refFormat, REF_FORMAT_NUM_SPEC);\n var previously = EidInternal.refFormat;\n EidInternal.refFormat = refFormat;\n return previously;\n};\n\n/**\n * Sets a format that will be used for all Eid exceptions when printing a detail message.\n *

\n * Format must be non-null and contain two format specifiers \"%s\"\n *\n * @param {string} format - a format that will be used, must be non-null and contain two format specifiers \"%s\"\n * @return {string} previously used format\n * @throws {TypeError} if given format hasn't got two format specifiers \"%s\", or if given format was\n * null\n */\nEid.setMessageFormat = function(format) {\n validateFormat(format, MESSAGE_FORMAT_NUM_SPEC);\n var oldFormat = EidInternal.messageFormat;\n EidInternal.messageFormat = format;\n return oldFormat;\n};\n\n/**\n * Gets actually set message format\n *\n * @return {string} actually setted message format\n */\nEid.getMessageFormat = function() {\n return EidInternal.messageFormat;\n};\n\nmodule.exports = Eid;\n\n})(module);\n\n},{}],4:[function(require,module,exports){\n/*\n * Copyright 2016 Wave Software\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n(function(exports) {\n 'use strict';\n\n var Eid = require('./eid');\n var commonExConstructor = function(eid, message) {\n if (!(eid instanceof Eid)) {\n eid = new Eid(eid.toString());\n }\n this.message = message !== undefined ? (eid + \" \" + message) : eid;\n this.eid = eid;\n }\n\n /**\n * This class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * This exception class is baseline of all Eid runtime exception classes. It is designed to ease of use and provide strict ID for\n * given Exception usage. This approach speed up development of large application and helps support teams to by giving the both\n * static and random ID for each possible unpredicted bug.\n *

\n * This is best to use with tools and plugins like\n * EidGenerator for Netbeans IDE\n *

\n * For convenience use {@link eid.Preconditions}\n *\n * @constructor\n * @param {string} eid - an exception Id, should be generated\n * @param {string} message - an message for the exception\n * @author Krzysztof Suszyński \n */\n function EidRuntimeException(eid, message) {\n this.name = 'EidRuntimeException';\n commonExConstructor.apply(this, [eid, message]);\n }\n EidRuntimeException.prototype = new Error();\n\n /**\n * This class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * This id Eid version of {@link NullPointerException}\n *\n * @constructor\n * @param {string} eid - an exception Id, should be generated\n * @param {string} message - an message for the exception\n * @see NullPointerException\n * @see EidRuntimeException\n * @author Krzysztof Suszyński \n */\n function EidNullPointerException(eid, message) {\n this.name = 'EidNullPointerException';\n commonExConstructor.apply(this, [eid, message]);\n }\n EidNullPointerException.prototype = EidRuntimeException.prototype;\n\n /**\n * This class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * This is Eid version of {@link IllegalArgumentException}\n *\n * @constructor\n * @param {string} eid - an exception Id, should be generated\n * @param {string} message - an message for the exception\n * @see IllegalArgumentException\n * @see EidRuntimeException\n * @author Krzysztof Suszyński \n */\n function EidIllegalArgumentException(eid, message) {\n this.name = 'EidIllegalArgumentException';\n commonExConstructor.apply(this, [eid, message]);\n }\n EidIllegalArgumentException.prototype = EidRuntimeException.prototype;\n\n /**\n * This class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * This id Eid version of {@link IllegalStateException}\n *\n * @constructor\n * @param {string} eid - an exception Id, should be generated\n * @param {string} message - an message for the exception\n * @see IllegalStateException\n * @see EidRuntimeException\n * @author Krzysztof Suszyński \n */\n function EidIllegalStateException(eid, message) {\n this.name = 'EidIllegalStateException';\n commonExConstructor.apply(this, [eid, message]);\n }\n EidIllegalStateException.prototype = EidRuntimeException.prototype;\n\n /**\n * This class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * This id Eid version of {@link IndexOutOfBoundsException}\n *\n * @constructor\n * @param {string} eid - an exception Id, should be generated\n * @param {string} message - an message for the exception\n * @see IndexOutOfBoundsException\n * @see EidRuntimeException\n * @author Krzysztof Suszyński \n */\n function EidIndexOutOfBoundsException(eid, message) {\n this.name = 'EidIndexOutOfBoundsException';\n commonExConstructor.apply(this, [eid, message]);\n }\n EidIndexOutOfBoundsException.prototype = EidRuntimeException.prototype;\n\n exports.EidRuntimeException = EidRuntimeException;\n exports.EidNullPointerException = EidNullPointerException;\n exports.EidIllegalArgumentException = EidIllegalArgumentException;\n exports.EidIllegalStateException = EidIllegalStateException;\n exports.EidIndexOutOfBoundsException = EidIndexOutOfBoundsException;\n\n})(exports);\n\n},{\"./eid\":3}],5:[function(require,module,exports){\n/*\n * Copyright 2016 Wave Software\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n(function(module) {\n'use strict';\n\nvar Eid = require('./eid');\nvar EidRuntimeException = require('./exceptions').EidRuntimeException;\nvar EidNullPointerException = require('./exceptions').EidNullPointerException;\nvar EidIllegalArgumentException = require('./exceptions').EidIllegalArgumentException;\nvar EidIllegalStateException = require('./exceptions').EidIllegalStateException;\nvar EidIndexOutOfBoundsException = require('./exceptions').EidIndexOutOfBoundsException;\n\n/**\n * This class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * Static convenience methods that help a method or constructor check whether it was invoked correctly (whether its\n * preconditions\n * have been met). These methods generally accept a {@code boolean} expression which is expected to be {@code true} (or in the\n * case of {@code\n * checkNotNull}, an object reference which is expected to be non-null). When {@code false} (or {@code null}) is passed instead,\n * the {@code EidPreconditions} method throws an unchecked exception, which helps the calling method communicate to its\n * caller that\n * that caller has made a mistake.\n *

\n * Each method accepts a EID String or {@link Eid} object, which is designed to ease of use and provide strict ID for given\n * Exception usage. This approach speed up development of large application and helps support teams to by giving the both static\n * and random ID for each possible unpredicted bug.\n *

\n * This is best to use with tools and plugins like\n * EidGenerator for Netbeans IDE\n *

\n * Example:\n *

   {@code\n *\n *   /**\n *    * Returns the positive square root of the given value.\n *    *\n *    * @throws EidIllegalArgumentException if the value is negative\n *    *}{@code /\n *   public static double sqrt(double value) {\n *     EidPreconditions.checkArgument(value >= 0.0, \"20150718:012333\");\n *     // calculate the square root\n *   }\n *\n *   void exampleBadCaller() {\n *     double d = sqrt(-1.0);\n *   }\n * }
\n *

\n * In this example, {@code checkArgument} throws an {@code EidIllegalArgumentException} to indicate that {@code exampleBadCaller}\n * made an error in its call to {@code sqrt}. Exception, when it will be printed will contain user given Eid and also\n * Randomly generated ID. Those fields can be displayed to user on error page on posted directly to issue tracker.\n *

\n * Example:\n *

\n *

\n *\n * {@code\n *   // Main application class for ex.: http servlet\n *    try {\n *        performRequest(request, response);\n *    } catch (EidRuntimeException ex) {\n *        issuesTracker.put(ex);\n *        throw ex;\n *    }\n * }
\n *

\n *

\n *

Functional try to execute blocks

\n *

\n *

\n * Using functional blocks to handle operations, that are intended to operate properly, simplify the code and makes it more\n * readable. It's also good way to deal with untested, uncovered {@code catch} blocks. It's easy and gives developers nice way of\n * dealing with countless operations that suppose to work as intended.\n *

\n *

\n * Example:\n *

\n *\n *     InputStream is = EidPreconditions.tryToExecute({@code new UnsafeSupplier}() {\n *        {@literal @}Override\n *         public InputStream get() throws IOException {\n *             return this.getClass().getClassLoader()\n *                 .getResourceAsStream(\"project.properties\");\n *         }\n *     }, \"20150718:121521\");\n * 
\n *\n * @constructor\n * @author Krzysztof Suszyński \n * @since 0.1.0 (idea imported from Guava Library and COI code)\n */\nfunction EidPreconditions() {}\n\nfunction isNullike(reference) {\n return reference === null || reference === undefined;\n}\n\nfunction checkNotNull(reference) {\n if (isNullike(reference)) {\n throw new TypeError(\"Pass not-null Eid to EidPreconditions first!\");\n }\n return reference;\n}\n\nfunction ensureEid(candidate) {\n candidate = checkNotNull(candidate);\n var eid;\n if (!(candidate instanceof Eid)) {\n eid = new Eid(candidate + '');\n } else {\n eid = candidate;\n }\n return eid;\n}\n\n/**\n * Ensures that an object reference passed as a parameter to the calling method is not null-like.\n *\n * @param {Object} reference - an object reference\n * @param {string|Eid} eid - the exception ID to use if the check fails\n * @param {string} message - message for produced exception\n * @return {Object} the non-null reference that was validated\n * @throws {EidNullPointerException} if {@code reference} is null-like\n */\nEidPreconditions.checkNotNullable = function(reference, eid, message) {\n var checkedEid = ensureEid(eid);\n if (isNullike(reference)) {\n throw new EidNullPointerException(checkedEid, message);\n }\n return reference;\n};\n\n/**\n * Ensures that an object reference passed as a parameter to the calling method is not null.\n *\n * @param {Object} reference - an object reference\n * @param {string|Eid} eid - the exception ID to use if the check fails\n * @param {string} message - message for produced exception\n * @return {Object} the non-null reference that was validated\n * @throws {EidNullPointerException} if {@code reference} is null-like\n */\nEidPreconditions.checkNotNull = function(reference, eid, message) {\n var checkedEid = ensureEid(eid);\n if (reference === null) {\n throw new EidNullPointerException(checkedEid, message);\n }\n return reference;\n};\n\n/**\n * Ensures that an object reference passed as a parameter to the calling method is not undefined.\n *\n * @param {Object} reference - an object reference\n * @param {string|Eid} eid - the exception ID to use if the check fails\n * @param {string} message - message for produced exception\n * @return {Object} the non-null reference that was validated\n * @throws {EidNullPointerException} if {@code reference} is null-like\n */\nEidPreconditions.checkNotUndefined = function(reference, eid, message) {\n var checkedEid = ensureEid(eid);\n if (reference === undefined) {\n throw new EidNullPointerException(checkedEid, message);\n }\n return reference;\n};\n\n/**\n * Ensures the truth of an expression involving one or more parameters to the calling method.\n *\n * @param {boolean} expression - a boolean expression\n * @param {string|Eid} eid - the exception ID to use if the check fails\n * @param {string} message - optional message for generated exception\n * @throws {EidIllegalArgumentException} if {@code expression} is false\n * @throws {EidNullPointerException} if {@code expression} is null\n */\nEidPreconditions.checkArgument = function(expression, eid, message) {\n var checkedEid = ensureEid(eid);\n if (!EidPreconditions.checkNotNullable(expression, checkedEid)) {\n throw new EidIllegalArgumentException(checkedEid, message)\n }\n};\n\n/**\n * Ensures the truth of an expression involving the state of the calling instance, but not involving any parameters to the\n * calling method.\n *\n * @param {boolean} expression - a boolean expression\n * @param {string|Eid} eid - the exception ID to use if the check fails\n * @param {string} message - optional message for generated exception\n * @throws {EidIllegalStateException} if {@code expression} is false\n * @throws {EidNullPointerException} if {@code expression} is null\n */\nEidPreconditions.checkState = function(expression, eid, message) {\n var checkedEid = ensureEid(eid);\n if (!EidPreconditions.checkNotNullable(expression, checkedEid)) {\n throw new EidIllegalStateException(checkedEid, message);\n }\n};\n\nfunction isIndexAndSizeIllegal(index, size) {\n return index < 0 || index > size;\n}\n\nfunction isSizeIllegal(size) {\n return size < 0;\n}\n\n/**\n * Ensures that {@code index} specifies a valid element in an array, list or string of size {@code size}. An element\n * index may range from zero, inclusive, to {@code size}, exclusive.\n *\n * @param {number} index - a user-supplied index identifying an element of an array, list or string\n * @param {numer} size - the size of that array, list or string\n * @param {string|Eid} eid - the text to use to describe this index in an error message\n * @param {string} message - optional message for generated exception\n * @return {number} the value of {@code index}\n * @throws {EidIndexOutOfBoundsException} if {@code index} is negative or is not less than {@code size}\n * @throws {EidIllegalArgumentException} if {@code size} is negative\n */\nEidPreconditions.checkElementIndex = function(index, size, eid, message) {\n var checkedEid = ensureEid(eid);\n if (isSizeIllegal(size)) {\n throw new EidIllegalArgumentException(checkedEid, message);\n }\n if (isIndexAndSizeIllegal(index, size)) {\n throw new EidIndexOutOfBoundsException(checkedEid, message);\n }\n return index;\n};\n\n/**\n * Tries to execute code in given unsafe supplier code block, and if exception is thrown, it will gets rethrown as a\n * {@link EidRuntimeException} with eid given as a argument. This is because this exception is threaded as a software bug!\n *

\n * Example:\n *

\n *\n * Document doc = EidPreconditions.tryToExecute({@code new UnsafeSupplier}() {\n *    {@literal @}Override\n *     public Document get() throws IOException {\n *          DocumentBuilder docBuilder = ...\n *          return docBuilder.parse(new InputSource(reader));\n *     }\n * }, new Eid(\"20150718:121521\"));\n * 
\n *\n * @param return type\n * @param supplier unsafe supplier code to be executed within a try-catch block\n * @param eid unique developer identifier from date for ex.: \"20150716:123200\"\n * @return A block of code return type, if exception is not thrown\n * @throws EidRuntimeException if code block thrown any exception, which in that case is wrapped in EidRuntimeException\n */\nEidPreconditions.tryToExecute = function(supplier, eid) {\n var checkedEid = ensureEid(eid);\n try {\n return EidPreconditions.checkNotNullable(supplier, checkedEid).apply();\n } catch (throwable) {\n throw new EidRuntimeException(checkedEid, throwable);\n }\n};\n\nmodule.exports = EidPreconditions;\n})(module);\n\n},{\"./eid\":3,\"./exceptions\":4}]},{},[1])\n\n","/*\n * Copyright 2016 Wave Software\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n(function(module) {\n'use strict';\n\nvar Eid = require('./eid/eid');\nEid.preconditions = require('./eid/preconditions');\nEid.exceptions = require('./eid/exceptions');\n\nmodule.exports = Eid;\n\n})(module);\n","/*\n * Copyright 2016 Wave Software\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n(function(module) {\n'use strict';\n\nfunction JFormatter(format) {\n this.format = function(arr) {\n var args = [];\n if (arguments.length === 1 && typeof(arr) === 'object') {\n args = arr;\n } else {\n for (var i = 0; i < arguments.length; i++) {\n args.push(arguments[i]);\n }\n }\n var regex = /%s/;\n var _r = function(p,c) { return p.replace(regex, c); }\n return args.reduce(_r, format);\n };\n}\n\n/**\n * This class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * Exception identifier for all Eid Runtime Exceptions.\n * @constructor\n * @param {string} id - the exception id, must be unique developer inserted string, from date\n * @param {string} ref - an optional reference\n */\nfunction Eid(id, ref) {\n var uniq = EidInternal.uniqIdGenerator.generateUniqId();\n ref = (ref === null || ref == undefined) ? \"\" : ref;\n\n /**\n * Makes a log message from this EID object\n *

\n *

This method is for convenience of usage of EID in logging. You can use it like this:\n *

\n *

\n   * log.debug(new Eid(\"20151025:202129\").makeLogMessage(\"A request: %s\", request));\n   * 
\n * @param {string} logMessageFormat - a log message format as accepted by {@link String#format(String, Object...)}\n * @param {Object...} parameters - a parameters for logMessageFormat to by passed to {@link String#format(String, Object...)}\n * @return {string} a formatted message\n */\n this.makeLogMessage = function(logMessageFormat) {\n var parameters = [];\n for (var i = 1; i < arguments.length; i++) {\n parameters.push(arguments[i]);\n }\n var message = new JFormatter(logMessageFormat).format(parameters);\n return new JFormatter(Eid.getMessageFormat()).format(this.toString(), message);\n }\n\n /**\n * Standard to string method\n */\n this.toString = function() {\n if (\"\" === ref) {\n return new JFormatter(EidInternal.format).format(id, uniq);\n }\n return new JFormatter(EidInternal.refFormat).format(id, ref, uniq);\n }\n\n /**\n * Getter for constant Exception ID\n *\n * @return {string} ID of exception\n */\n this.getId = function() {\n return id;\n }\n\n /**\n * Get custom ref passed to Exception ID\n *\n * @return {string} ID of exception\n */\n this.getRef = function() {\n return ref;\n }\n\n /**\n * Gets unique generated string for this instance of Eid\n *\n * @return {string} a unique string\n */\n this.getUniq = function() {\n return uniq;\n }\n}\n\nfunction MathRandom() {\n var LONG_MAX = Math.pow(2, 53) - 1;\n var LONG_MIN = -1 * Math.pow(2, 53);\n this.nextLong = function() {\n return random(LONG_MIN, LONG_MAX);\n };\n this.nextInt = function(max) {\n return random(0, max);\n };\n var random = function(min, max) {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n };\n}\n\nfunction StdUniqIdGenerator() {\n var BASE36 = 36;\n var INTEGER_MAX_VALUE = Math.pow(2, 31);\n var generator = new MathRandom();\n this.generateUniqId = function() {\n var first = Math.abs(generator.nextLong() + 1);\n var second = Math.abs(generator.nextInt(INTEGER_MAX_VALUE));\n var calc = first + second;\n return (Math.abs(calc) % INTEGER_MAX_VALUE).toString(BASE36);\n };\n}\n\nvar DEFAULT_FORMAT = \"[%s]<%s>\";\nvar DEFAULT_REF_FORMAT = \"[%s|%s]<%s>\";\nvar DEFAULT_MESSAGE_FORMAT = \"%s => %s\";\nvar DEFAULT_UNIQ_ID_GENERATOR = new StdUniqIdGenerator();\n\nObject.defineProperty(Eid, \"DEFAULT_FORMAT\", {\n get: function() { return DEFAULT_FORMAT; }\n});\nObject.defineProperty(Eid, \"DEFAULT_MESSAGE_FORMAT\", {\n get: function() { return DEFAULT_MESSAGE_FORMAT; }\n});\nObject.defineProperty(Eid, \"DEFAULT_REF_FORMAT\", {\n get: function() { return DEFAULT_REF_FORMAT; }\n});\nObject.defineProperty(Eid, \"DEFAULT_UNIQ_ID_GENERATOR\", {\n get: function() { return DEFAULT_UNIQ_ID_GENERATOR; }\n});\n\nvar FORMAT_NUM_SPEC = 2;\nvar REF_FORMAT_NUM_SPEC = 3;\nvar MESSAGE_FORMAT_NUM_SPEC = 2;\n\nvar EidInternal = {\n messageFormat: DEFAULT_MESSAGE_FORMAT,\n uniqIdGenerator: DEFAULT_UNIQ_ID_GENERATOR,\n format: DEFAULT_FORMAT,\n refFormat: DEFAULT_REF_FORMAT\n};\n\nvar validateFormat = function(format, numSpecifiers) {\n if (format === null || format === undefined) {\n throw new TypeError(\"Format can't be null, but just received one\");\n }\n var specifiers = [];\n for (var i = 0; i < numSpecifiers; i++) {\n specifiers.push(i + \"-test-id\");\n }\n var formatted = new JFormatter(format).format(specifiers);\n for (var specifier in specifiers) {\n if (formatted.indexOf(specifier) === -1) {\n throw new TypeError(\"Given format contains to little format specifiers, \" +\n \"expected \" + numSpecifiers + \" but given \\\"\" + format + \"\\\"\");\n }\n }\n};\n\n/**\n * Sets the actual unique ID generator that will be used to generate IDs for all Eid objects. It will return previously used\n * generator.\n *\n * @param {UniqIdGenerator} uniqIdGenerator - new instance of unique ID generator\n * @return {UniqIdGenerator} a previously used unique ID generator\n * @throws {TypeError} if given generator was null\n */\nEid.setUniqIdGenerator = function(uniqIdGenerator) {\n if (uniqIdGenerator === null || uniqIdGenerator === undefined) {\n throw new TypeError(\"Unique ID generator can't be null, but given one\");\n }\n var previous = EidInternal.uniqIdGenerator;\n EidInternal.uniqIdGenerator = uniqIdGenerator;\n return previous;\n};\n\n/**\n * Sets the actual format that will be used in {@link #toString()} method. It will return previously used format.\n *\n * @param {string} format - a format compliant with {@link String#format(String, Object...)} with 2 object arguments\n * @return {string} a previously used format\n * @throws {TypeError} if given format hasn't got two format specifiers \"%s\", or if given format was\n * null\n */\nEid.setFormat = function(format) {\n validateFormat(format, FORMAT_NUM_SPEC);\n var previously = EidInternal.format;\n EidInternal.format = format;\n return previously;\n};\n\n/**\n * Sets the actual format that will be used in {@link #toString()} method\n *\n * @param {string} refFormat - a format compliant with {@link String#format(String, Object...)} with 3 object arguments\n * @return {string} a previously used format\n * @throws {TypeError} if given format hasn't got tree format specifiers \"%s\", or if given format was\n * null\n */\nEid.setRefFormat = function(refFormat) {\n validateFormat(refFormat, REF_FORMAT_NUM_SPEC);\n var previously = EidInternal.refFormat;\n EidInternal.refFormat = refFormat;\n return previously;\n};\n\n/**\n * Sets a format that will be used for all Eid exceptions when printing a detail message.\n *

\n * Format must be non-null and contain two format specifiers \"%s\"\n *\n * @param {string} format - a format that will be used, must be non-null and contain two format specifiers \"%s\"\n * @return {string} previously used format\n * @throws {TypeError} if given format hasn't got two format specifiers \"%s\", or if given format was\n * null\n */\nEid.setMessageFormat = function(format) {\n validateFormat(format, MESSAGE_FORMAT_NUM_SPEC);\n var oldFormat = EidInternal.messageFormat;\n EidInternal.messageFormat = format;\n return oldFormat;\n};\n\n/**\n * Gets actually set message format\n *\n * @return {string} actually setted message format\n */\nEid.getMessageFormat = function() {\n return EidInternal.messageFormat;\n};\n\nmodule.exports = Eid;\n\n})(module);\n","/*\n * Copyright 2016 Wave Software\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n(function(exports) {\n 'use strict';\n\n var Eid = require('./eid');\n var commonExConstructor = function(eid, message) {\n if (!(eid instanceof Eid)) {\n eid = new Eid(eid.toString());\n }\n this.message = message !== undefined ? (eid + \" \" + message) : eid;\n this.eid = eid;\n }\n\n /**\n * This class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * This exception class is baseline of all Eid runtime exception classes. It is designed to ease of use and provide strict ID for\n * given Exception usage. This approach speed up development of large application and helps support teams to by giving the both\n * static and random ID for each possible unpredicted bug.\n *

\n * This is best to use with tools and plugins like\n * EidGenerator for Netbeans IDE\n *

\n * For convenience use {@link eid.Preconditions}\n *\n * @constructor\n * @param {string} eid - an exception Id, should be generated\n * @param {string} message - an message for the exception\n * @author Krzysztof Suszyński \n */\n function EidRuntimeException(eid, message) {\n this.name = 'EidRuntimeException';\n commonExConstructor.apply(this, [eid, message]);\n }\n EidRuntimeException.prototype = new Error();\n\n /**\n * This class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * This id Eid version of {@link NullPointerException}\n *\n * @constructor\n * @param {string} eid - an exception Id, should be generated\n * @param {string} message - an message for the exception\n * @see NullPointerException\n * @see EidRuntimeException\n * @author Krzysztof Suszyński \n */\n function EidNullPointerException(eid, message) {\n this.name = 'EidNullPointerException';\n commonExConstructor.apply(this, [eid, message]);\n }\n EidNullPointerException.prototype = EidRuntimeException.prototype;\n\n /**\n * This class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * This is Eid version of {@link IllegalArgumentException}\n *\n * @constructor\n * @param {string} eid - an exception Id, should be generated\n * @param {string} message - an message for the exception\n * @see IllegalArgumentException\n * @see EidRuntimeException\n * @author Krzysztof Suszyński \n */\n function EidIllegalArgumentException(eid, message) {\n this.name = 'EidIllegalArgumentException';\n commonExConstructor.apply(this, [eid, message]);\n }\n EidIllegalArgumentException.prototype = EidRuntimeException.prototype;\n\n /**\n * This class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * This id Eid version of {@link IllegalStateException}\n *\n * @constructor\n * @param {string} eid - an exception Id, should be generated\n * @param {string} message - an message for the exception\n * @see IllegalStateException\n * @see EidRuntimeException\n * @author Krzysztof Suszyński \n */\n function EidIllegalStateException(eid, message) {\n this.name = 'EidIllegalStateException';\n commonExConstructor.apply(this, [eid, message]);\n }\n EidIllegalStateException.prototype = EidRuntimeException.prototype;\n\n /**\n * This class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * This id Eid version of {@link IndexOutOfBoundsException}\n *\n * @constructor\n * @param {string} eid - an exception Id, should be generated\n * @param {string} message - an message for the exception\n * @see IndexOutOfBoundsException\n * @see EidRuntimeException\n * @author Krzysztof Suszyński \n */\n function EidIndexOutOfBoundsException(eid, message) {\n this.name = 'EidIndexOutOfBoundsException';\n commonExConstructor.apply(this, [eid, message]);\n }\n EidIndexOutOfBoundsException.prototype = EidRuntimeException.prototype;\n\n exports.EidRuntimeException = EidRuntimeException;\n exports.EidNullPointerException = EidNullPointerException;\n exports.EidIllegalArgumentException = EidIllegalArgumentException;\n exports.EidIllegalStateException = EidIllegalStateException;\n exports.EidIndexOutOfBoundsException = EidIndexOutOfBoundsException;\n\n})(exports);\n","/*\n * Copyright 2016 Wave Software\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n(function(module) {\n'use strict';\n\nvar Eid = require('./eid');\nvar EidRuntimeException = require('./exceptions').EidRuntimeException;\nvar EidNullPointerException = require('./exceptions').EidNullPointerException;\nvar EidIllegalArgumentException = require('./exceptions').EidIllegalArgumentException;\nvar EidIllegalStateException = require('./exceptions').EidIllegalStateException;\nvar EidIndexOutOfBoundsException = require('./exceptions').EidIndexOutOfBoundsException;\n\n/**\n * This class shouldn't be used in any public API or library. It is designed to be used for in-house development\n * of end user applications which will report Bugs in standardized error pages or post them to issue tracker.\n *

\n * Static convenience methods that help a method or constructor check whether it was invoked correctly (whether its\n * preconditions\n * have been met). These methods generally accept a {@code boolean} expression which is expected to be {@code true} (or in the\n * case of {@code\n * checkNotNull}, an object reference which is expected to be non-null). When {@code false} (or {@code null}) is passed instead,\n * the {@code EidPreconditions} method throws an unchecked exception, which helps the calling method communicate to its\n * caller that\n * that caller has made a mistake.\n *

\n * Each method accepts a EID String or {@link Eid} object, which is designed to ease of use and provide strict ID for given\n * Exception usage. This approach speed up development of large application and helps support teams to by giving the both static\n * and random ID for each possible unpredicted bug.\n *

\n * This is best to use with tools and plugins like\n * EidGenerator for Netbeans IDE\n *

\n * Example:\n *

   {@code\n *\n *   /**\n *    * Returns the positive square root of the given value.\n *    *\n *    * @throws EidIllegalArgumentException if the value is negative\n *    *}{@code /\n *   public static double sqrt(double value) {\n *     EidPreconditions.checkArgument(value >= 0.0, \"20150718:012333\");\n *     // calculate the square root\n *   }\n *\n *   void exampleBadCaller() {\n *     double d = sqrt(-1.0);\n *   }\n * }
\n *

\n * In this example, {@code checkArgument} throws an {@code EidIllegalArgumentException} to indicate that {@code exampleBadCaller}\n * made an error in its call to {@code sqrt}. Exception, when it will be printed will contain user given Eid and also\n * Randomly generated ID. Those fields can be displayed to user on error page on posted directly to issue tracker.\n *

\n * Example:\n *

\n *

\n *\n * {@code\n *   // Main application class for ex.: http servlet\n *    try {\n *        performRequest(request, response);\n *    } catch (EidRuntimeException ex) {\n *        issuesTracker.put(ex);\n *        throw ex;\n *    }\n * }
\n *

\n *

\n *

Functional try to execute blocks

\n *

\n *

\n * Using functional blocks to handle operations, that are intended to operate properly, simplify the code and makes it more\n * readable. It's also good way to deal with untested, uncovered {@code catch} blocks. It's easy and gives developers nice way of\n * dealing with countless operations that suppose to work as intended.\n *

\n *

\n * Example:\n *

\n *\n *     InputStream is = EidPreconditions.tryToExecute({@code new UnsafeSupplier}() {\n *        {@literal @}Override\n *         public InputStream get() throws IOException {\n *             return this.getClass().getClassLoader()\n *                 .getResourceAsStream(\"project.properties\");\n *         }\n *     }, \"20150718:121521\");\n * 
\n *\n * @constructor\n * @author Krzysztof Suszyński \n * @since 0.1.0 (idea imported from Guava Library and COI code)\n */\nfunction EidPreconditions() {}\n\nfunction isNullike(reference) {\n return reference === null || reference === undefined;\n}\n\nfunction checkNotNull(reference) {\n if (isNullike(reference)) {\n throw new TypeError(\"Pass not-null Eid to EidPreconditions first!\");\n }\n return reference;\n}\n\nfunction ensureEid(candidate) {\n candidate = checkNotNull(candidate);\n var eid;\n if (!(candidate instanceof Eid)) {\n eid = new Eid(candidate + '');\n } else {\n eid = candidate;\n }\n return eid;\n}\n\n/**\n * Ensures that an object reference passed as a parameter to the calling method is not null-like.\n *\n * @param {Object} reference - an object reference\n * @param {string|Eid} eid - the exception ID to use if the check fails\n * @param {string} message - message for produced exception\n * @return {Object} the non-null reference that was validated\n * @throws {EidNullPointerException} if {@code reference} is null-like\n */\nEidPreconditions.checkNotNullable = function(reference, eid, message) {\n var checkedEid = ensureEid(eid);\n if (isNullike(reference)) {\n throw new EidNullPointerException(checkedEid, message);\n }\n return reference;\n};\n\n/**\n * Ensures that an object reference passed as a parameter to the calling method is not null.\n *\n * @param {Object} reference - an object reference\n * @param {string|Eid} eid - the exception ID to use if the check fails\n * @param {string} message - message for produced exception\n * @return {Object} the non-null reference that was validated\n * @throws {EidNullPointerException} if {@code reference} is null-like\n */\nEidPreconditions.checkNotNull = function(reference, eid, message) {\n var checkedEid = ensureEid(eid);\n if (reference === null) {\n throw new EidNullPointerException(checkedEid, message);\n }\n return reference;\n};\n\n/**\n * Ensures that an object reference passed as a parameter to the calling method is not undefined.\n *\n * @param {Object} reference - an object reference\n * @param {string|Eid} eid - the exception ID to use if the check fails\n * @param {string} message - message for produced exception\n * @return {Object} the non-null reference that was validated\n * @throws {EidNullPointerException} if {@code reference} is null-like\n */\nEidPreconditions.checkNotUndefined = function(reference, eid, message) {\n var checkedEid = ensureEid(eid);\n if (reference === undefined) {\n throw new EidNullPointerException(checkedEid, message);\n }\n return reference;\n};\n\n/**\n * Ensures the truth of an expression involving one or more parameters to the calling method.\n *\n * @param {boolean} expression - a boolean expression\n * @param {string|Eid} eid - the exception ID to use if the check fails\n * @param {string} message - optional message for generated exception\n * @throws {EidIllegalArgumentException} if {@code expression} is false\n * @throws {EidNullPointerException} if {@code expression} is null\n */\nEidPreconditions.checkArgument = function(expression, eid, message) {\n var checkedEid = ensureEid(eid);\n if (!EidPreconditions.checkNotNullable(expression, checkedEid)) {\n throw new EidIllegalArgumentException(checkedEid, message)\n }\n};\n\n/**\n * Ensures the truth of an expression involving the state of the calling instance, but not involving any parameters to the\n * calling method.\n *\n * @param {boolean} expression - a boolean expression\n * @param {string|Eid} eid - the exception ID to use if the check fails\n * @param {string} message - optional message for generated exception\n * @throws {EidIllegalStateException} if {@code expression} is false\n * @throws {EidNullPointerException} if {@code expression} is null\n */\nEidPreconditions.checkState = function(expression, eid, message) {\n var checkedEid = ensureEid(eid);\n if (!EidPreconditions.checkNotNullable(expression, checkedEid)) {\n throw new EidIllegalStateException(checkedEid, message);\n }\n};\n\nfunction isIndexAndSizeIllegal(index, size) {\n return index < 0 || index > size;\n}\n\nfunction isSizeIllegal(size) {\n return size < 0;\n}\n\n/**\n * Ensures that {@code index} specifies a valid element in an array, list or string of size {@code size}. An element\n * index may range from zero, inclusive, to {@code size}, exclusive.\n *\n * @param {number} index - a user-supplied index identifying an element of an array, list or string\n * @param {numer} size - the size of that array, list or string\n * @param {string|Eid} eid - the text to use to describe this index in an error message\n * @param {string} message - optional message for generated exception\n * @return {number} the value of {@code index}\n * @throws {EidIndexOutOfBoundsException} if {@code index} is negative or is not less than {@code size}\n * @throws {EidIllegalArgumentException} if {@code size} is negative\n */\nEidPreconditions.checkElementIndex = function(index, size, eid, message) {\n var checkedEid = ensureEid(eid);\n if (isSizeIllegal(size)) {\n throw new EidIllegalArgumentException(checkedEid, message);\n }\n if (isIndexAndSizeIllegal(index, size)) {\n throw new EidIndexOutOfBoundsException(checkedEid, message);\n }\n return index;\n};\n\n/**\n * Tries to execute code in given unsafe supplier code block, and if exception is thrown, it will gets rethrown as a\n * {@link EidRuntimeException} with eid given as a argument. This is because this exception is threaded as a software bug!\n *

\n * Example:\n *

\n *\n * Document doc = EidPreconditions.tryToExecute({@code new UnsafeSupplier}() {\n *    {@literal @}Override\n *     public Document get() throws IOException {\n *          DocumentBuilder docBuilder = ...\n *          return docBuilder.parse(new InputSource(reader));\n *     }\n * }, new Eid(\"20150718:121521\"));\n * 
\n *\n * @param return type\n * @param supplier unsafe supplier code to be executed within a try-catch block\n * @param eid unique developer identifier from date for ex.: \"20150716:123200\"\n * @return A block of code return type, if exception is not thrown\n * @throws EidRuntimeException if code block thrown any exception, which in that case is wrapped in EidRuntimeException\n */\nEidPreconditions.tryToExecute = function(supplier, eid) {\n var checkedEid = ensureEid(eid);\n try {\n return EidPreconditions.checkNotNullable(supplier, checkedEid).apply();\n } catch (throwable) {\n throw new EidRuntimeException(checkedEid, throwable);\n }\n};\n\nmodule.exports = EidPreconditions;\n})(module);\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/gulp/build.js b/gulp/build.js new file mode 100644 index 0000000..00ef952 --- /dev/null +++ b/gulp/build.js @@ -0,0 +1,46 @@ +/* eslint-disable no-var, strict, prefer-arrow-callback */ +'use strict'; + +var gulp = require('gulp'); +var browserify = require('browserify'); +var source = require('vinyl-source-stream'); +var buffer = require('vinyl-buffer'); +var uglify = require('gulp-uglify'); +var sourcemaps = require('gulp-sourcemaps'); +var gutil = require('gulp-util'); +var config = require('./config'); + +var toplevel = 'gulp/build/toplevel.js'; + +module.exports = { + browserify: function() { + // set up the browserify instance on a task basis + var b = browserify({ + entries: toplevel, + debug: true + }); + + return b.bundle() + .pipe(source('eid.js')) + .pipe(buffer()) + .on('error', gutil.log) + .pipe(gulp.dest(config.dist + '/browser/toplevel')); + }, + minified: function() { + // set up the browserify instance on a task basis + var b = browserify({ + entries: toplevel, + debug: true + }); + + return b.bundle() + .pipe(source('eid.min.js')) + .pipe(buffer()) + .pipe(sourcemaps.init({loadMaps: true})) + // Add transformation tasks to the pipeline here. + .pipe(uglify()) + .on('error', gutil.log) + .pipe(sourcemaps.write('./')) + .pipe(gulp.dest(config.dist + '/browser/toplevel')); + } +}; diff --git a/gulp/build/toplevel.js b/gulp/build/toplevel.js new file mode 100644 index 0000000..2f7474b --- /dev/null +++ b/gulp/build/toplevel.js @@ -0,0 +1,20 @@ +/* + * Copyright 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function(wnd) { + 'use strict'; + wnd.Eid = require('../../lib/eid'); +})(window); diff --git a/gulp/clean.js b/gulp/clean.js new file mode 100644 index 0000000..a7cd7f9 --- /dev/null +++ b/gulp/clean.js @@ -0,0 +1,25 @@ +/* eslint-disable no-var, strict, prefer-arrow-callback */ +'use strict'; + +var fs = require('fs'); +var config = require('./config'); + +var deleteFolderRecursive = function(path) { + var files = []; + if( fs.existsSync(path) ) { + files = fs.readdirSync(path); + files.forEach(function(file,index){ + var curPath = path + "/" + file; + if(fs.lstatSync(curPath).isDirectory()) { // recurse + deleteFolderRecursive(curPath); + } else { // delete file + fs.unlinkSync(curPath); + } + }); + fs.rmdirSync(path); + } +}; + +module.exports = function() { + deleteFolderRecursive(config.target); +}; diff --git a/gulp/config.js b/gulp/config.js new file mode 100644 index 0000000..1ed0e07 --- /dev/null +++ b/gulp/config.js @@ -0,0 +1,19 @@ +/* eslint-disable no-var, strict, prefer-arrow-callback */ +'use strict'; + +var directory = { + lib: 'lib', + test: 'test', + target: 'target', + dist: 'dist' +}; + +module.exports = { + sources: [ directory.lib + '/**/*.js' ], + testSources: [ directory.test + '/**/*.js' ], + lib: directory.lib, + test: directory.test, + target: directory.target, + dist: directory.dist, + ceverageMin: 98 +}; diff --git a/gulp/serve.js b/gulp/serve.js new file mode 100644 index 0000000..8e1ebe0 --- /dev/null +++ b/gulp/serve.js @@ -0,0 +1,7 @@ +/* eslint-disable no-var, strict, prefer-arrow-callback */ +'use strict'; + +var serve = require('gulp-serve'); +var config = require('./config'); + +module.exports = serve([ config.test, config.dist ]); diff --git a/gulp/tests.js b/gulp/tests.js new file mode 100644 index 0000000..7a1c034 --- /dev/null +++ b/gulp/tests.js @@ -0,0 +1,75 @@ +/* eslint-disable no-var, strict, prefer-arrow-callback */ +'use strict'; + +var gulp = require('gulp'); +var eslint = require('gulp-eslint'); +var mocha = require('gulp-mocha'); +var cover = require('gulp-coverage'); +var coveralls = require('gulp-coveralls'); +var config = require('./config'); + +module.exports = { + lint: function () { + return gulp.src(config.sources) + .pipe(eslint({ + extends: 'eslint:recommended', + rules: { + strict: 2 + }, + env: { + node: true, + browser: true + } + })) + .pipe(eslint.format()) + .pipe(eslint.failAfterError()); + }, + specs: function (done) { + var prependToAll = function(path, globs) { + var ret = []; + for (var i = 0; i < globs.length; i++) { + var value = globs[i]; + ret.push(path + '/' + value); + } + return ret; + }; + var fs = require('fs'); + var target = config.target; + if (!fs.existsSync(target)) { + fs.mkdirSync(target); + } + var pwd = process.cwd(); + process.chdir(target); + var testSrc = prependToAll('..', config.testSources); + var src = prependToAll('..', config.sources); + var stream = gulp.src(testSrc, { read: false }) + .pipe(cover.instrument({ + pattern: src, + debugDirectory: 'debug' + })) + .pipe(mocha()) + .pipe(cover.gather()); + + if (process.env.TRAVIS == 'true') { + stream = stream.pipe(cover.format([ + { reporter: 'lcov' } + ])) + .pipe(coveralls()); + } else { + stream = stream.pipe(cover.format([ + { reporter: 'html' }, + { reporter: 'json' }, + { reporter: 'lcov' } + ])) + .pipe(gulp.dest('reports')); + } + return stream.pipe(cover.enforce({ + statements: config.ceverageMin, + blocks: config.ceverageMin, + lines: config.ceverageMin, + })) + .on('end', function() { + process.chdir(pwd); + }); + } +}; diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..beedc28 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,22 @@ +/* eslint-disable no-var, strict, prefer-arrow-callback */ +'use strict'; + +var gulp = require('gulp'); + +var tests = require('./gulp/tests'); +var build = require('./gulp/build'); +var clean = require('./gulp/clean'); +var serve = require('./gulp/serve'); + +gulp.task('clean', clean); +gulp.task('lint', tests.lint); +gulp.task('specs', ['lint'], tests.specs); +gulp.task('test', ['lint', 'specs']); +gulp.task('watch', function() { + gulp.watch(sources.concat(testSources), ['test']); +}); +gulp.task('build-browser', ['test'], build.browserify); +gulp.task('build-minified', ['test'], build.minified); +gulp.task('serve', serve); +gulp.task('build', ['build-browser', 'build-minified']); +gulp.task('default', ['test', 'build']); diff --git a/lib/eid.js b/lib/eid.js new file mode 100644 index 0000000..eaad486 --- /dev/null +++ b/lib/eid.js @@ -0,0 +1,26 @@ +/* + * Copyright 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function(module) { +'use strict'; + +var Eid = require('./eid/eid'); +Eid.preconditions = require('./eid/preconditions'); +Eid.exceptions = require('./eid/exceptions'); + +module.exports = Eid; + +})(module); diff --git a/lib/eid/eid.js b/lib/eid/eid.js new file mode 100644 index 0000000..ce37312 --- /dev/null +++ b/lib/eid/eid.js @@ -0,0 +1,255 @@ +/* + * Copyright 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function(module) { +'use strict'; + +function JFormatter(format) { + this.format = function(arr) { + var args = []; + if (arguments.length === 1 && typeof(arr) === 'object') { + args = arr; + } else { + for (var i = 0; i < arguments.length; i++) { + args.push(arguments[i]); + } + } + var regex = /%s/; + var _r = function(p,c) { return p.replace(regex, c); } + return args.reduce(_r, format); + }; +} + +/** + * This class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * Exception identifier for all Eid Runtime Exceptions. + * @constructor + * @param {string} id - the exception id, must be unique developer inserted string, from date + * @param {string} ref - an optional reference + */ +function Eid(id, ref) { + var uniq = EidInternal.uniqIdGenerator.generateUniqId(); + ref = (ref === null || ref == undefined) ? "" : ref; + + /** + * Makes a log message from this EID object + *

+ *

This method is for convenience of usage of EID in logging. You can use it like this: + *

+ *

+   * log.debug(new Eid("20151025:202129").makeLogMessage("A request: %s", request));
+   * 
+ * @param {string} logMessageFormat - a log message format as accepted by {@link String#format(String, Object...)} + * @param {Object...} parameters - a parameters for logMessageFormat to by passed to {@link String#format(String, Object...)} + * @return {string} a formatted message + */ + this.makeLogMessage = function(logMessageFormat) { + var parameters = []; + for (var i = 1; i < arguments.length; i++) { + parameters.push(arguments[i]); + } + var message = new JFormatter(logMessageFormat).format(parameters); + return new JFormatter(Eid.getMessageFormat()).format(this.toString(), message); + } + + /** + * Standard to string method + */ + this.toString = function() { + if ("" === ref) { + return new JFormatter(EidInternal.format).format(id, uniq); + } + return new JFormatter(EidInternal.refFormat).format(id, ref, uniq); + } + + /** + * Getter for constant Exception ID + * + * @return {string} ID of exception + */ + this.getId = function() { + return id; + } + + /** + * Get custom ref passed to Exception ID + * + * @return {string} ID of exception + */ + this.getRef = function() { + return ref; + } + + /** + * Gets unique generated string for this instance of Eid + * + * @return {string} a unique string + */ + this.getUniq = function() { + return uniq; + } +} + +function MathRandom() { + var LONG_MAX = Math.pow(2, 53) - 1; + var LONG_MIN = -1 * Math.pow(2, 53); + this.nextLong = function() { + return random(LONG_MIN, LONG_MAX); + }; + this.nextInt = function(max) { + return random(0, max); + }; + var random = function(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min; + }; +} + +function StdUniqIdGenerator() { + var BASE36 = 36; + var INTEGER_MAX_VALUE = Math.pow(2, 31); + var generator = new MathRandom(); + this.generateUniqId = function() { + var first = Math.abs(generator.nextLong() + 1); + var second = Math.abs(generator.nextInt(INTEGER_MAX_VALUE)); + var calc = first + second; + return (Math.abs(calc) % INTEGER_MAX_VALUE).toString(BASE36); + }; +} + +var DEFAULT_FORMAT = "[%s]<%s>"; +var DEFAULT_REF_FORMAT = "[%s|%s]<%s>"; +var DEFAULT_MESSAGE_FORMAT = "%s => %s"; +var DEFAULT_UNIQ_ID_GENERATOR = new StdUniqIdGenerator(); + +Object.defineProperty(Eid, "DEFAULT_FORMAT", { + get: function() { return DEFAULT_FORMAT; } +}); +Object.defineProperty(Eid, "DEFAULT_MESSAGE_FORMAT", { + get: function() { return DEFAULT_MESSAGE_FORMAT; } +}); +Object.defineProperty(Eid, "DEFAULT_REF_FORMAT", { + get: function() { return DEFAULT_REF_FORMAT; } +}); +Object.defineProperty(Eid, "DEFAULT_UNIQ_ID_GENERATOR", { + get: function() { return DEFAULT_UNIQ_ID_GENERATOR; } +}); + +var FORMAT_NUM_SPEC = 2; +var REF_FORMAT_NUM_SPEC = 3; +var MESSAGE_FORMAT_NUM_SPEC = 2; + +var EidInternal = { + messageFormat: DEFAULT_MESSAGE_FORMAT, + uniqIdGenerator: DEFAULT_UNIQ_ID_GENERATOR, + format: DEFAULT_FORMAT, + refFormat: DEFAULT_REF_FORMAT +}; + +var validateFormat = function(format, numSpecifiers) { + if (format === null || format === undefined) { + throw new TypeError("Format can't be null, but just received one"); + } + var specifiers = []; + for (var i = 0; i < numSpecifiers; i++) { + specifiers.push(i + "-test-id"); + } + var formatted = new JFormatter(format).format(specifiers); + for (var specifier in specifiers) { + if (formatted.indexOf(specifier) === -1) { + throw new TypeError("Given format contains to little format specifiers, " + + "expected " + numSpecifiers + " but given \"" + format + "\""); + } + } +}; + +/** + * Sets the actual unique ID generator that will be used to generate IDs for all Eid objects. It will return previously used + * generator. + * + * @param {UniqIdGenerator} uniqIdGenerator - new instance of unique ID generator + * @return {UniqIdGenerator} a previously used unique ID generator + * @throws {TypeError} if given generator was null + */ +Eid.setUniqIdGenerator = function(uniqIdGenerator) { + if (uniqIdGenerator === null || uniqIdGenerator === undefined) { + throw new TypeError("Unique ID generator can't be null, but given one"); + } + var previous = EidInternal.uniqIdGenerator; + EidInternal.uniqIdGenerator = uniqIdGenerator; + return previous; +}; + +/** + * Sets the actual format that will be used in {@link #toString()} method. It will return previously used format. + * + * @param {string} format - a format compliant with {@link String#format(String, Object...)} with 2 object arguments + * @return {string} a previously used format + * @throws {TypeError} if given format hasn't got two format specifiers "%s", or if given format was + * null + */ +Eid.setFormat = function(format) { + validateFormat(format, FORMAT_NUM_SPEC); + var previously = EidInternal.format; + EidInternal.format = format; + return previously; +}; + +/** + * Sets the actual format that will be used in {@link #toString()} method + * + * @param {string} refFormat - a format compliant with {@link String#format(String, Object...)} with 3 object arguments + * @return {string} a previously used format + * @throws {TypeError} if given format hasn't got tree format specifiers "%s", or if given format was + * null + */ +Eid.setRefFormat = function(refFormat) { + validateFormat(refFormat, REF_FORMAT_NUM_SPEC); + var previously = EidInternal.refFormat; + EidInternal.refFormat = refFormat; + return previously; +}; + +/** + * Sets a format that will be used for all Eid exceptions when printing a detail message. + *

+ * Format must be non-null and contain two format specifiers "%s" + * + * @param {string} format - a format that will be used, must be non-null and contain two format specifiers "%s" + * @return {string} previously used format + * @throws {TypeError} if given format hasn't got two format specifiers "%s", or if given format was + * null + */ +Eid.setMessageFormat = function(format) { + validateFormat(format, MESSAGE_FORMAT_NUM_SPEC); + var oldFormat = EidInternal.messageFormat; + EidInternal.messageFormat = format; + return oldFormat; +}; + +/** + * Gets actually set message format + * + * @return {string} actually setted message format + */ +Eid.getMessageFormat = function() { + return EidInternal.messageFormat; +}; + +module.exports = Eid; + +})(module); diff --git a/lib/eid/exceptions.js b/lib/eid/exceptions.js new file mode 100644 index 0000000..9ce95bd --- /dev/null +++ b/lib/eid/exceptions.js @@ -0,0 +1,135 @@ +/* + * Copyright 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function(exports) { + 'use strict'; + + var Eid = require('./eid'); + var commonExConstructor = function(eid, message) { + if (!(eid instanceof Eid)) { + eid = new Eid(eid.toString()); + } + this.message = message !== undefined ? (eid + " " + message) : eid; + this.eid = eid; + } + + /** + * This class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * This exception class is baseline of all Eid runtime exception classes. It is designed to ease of use and provide strict ID for + * given Exception usage. This approach speed up development of large application and helps support teams to by giving the both + * static and random ID for each possible unpredicted bug. + *

+ * This is best to use with tools and plugins like + * EidGenerator for Netbeans IDE + *

+ * For convenience use {@link eid.Preconditions} + * + * @constructor + * @param {string} eid - an exception Id, should be generated + * @param {string} message - an message for the exception + * @author Krzysztof Suszyński + */ + function EidRuntimeException(eid, message) { + this.name = 'EidRuntimeException'; + commonExConstructor.apply(this, [eid, message]); + } + EidRuntimeException.prototype = new Error(); + + /** + * This class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * This id Eid version of {@link NullPointerException} + * + * @constructor + * @param {string} eid - an exception Id, should be generated + * @param {string} message - an message for the exception + * @see NullPointerException + * @see EidRuntimeException + * @author Krzysztof Suszyński + */ + function EidNullPointerException(eid, message) { + this.name = 'EidNullPointerException'; + commonExConstructor.apply(this, [eid, message]); + } + EidNullPointerException.prototype = EidRuntimeException.prototype; + + /** + * This class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * This is Eid version of {@link IllegalArgumentException} + * + * @constructor + * @param {string} eid - an exception Id, should be generated + * @param {string} message - an message for the exception + * @see IllegalArgumentException + * @see EidRuntimeException + * @author Krzysztof Suszyński + */ + function EidIllegalArgumentException(eid, message) { + this.name = 'EidIllegalArgumentException'; + commonExConstructor.apply(this, [eid, message]); + } + EidIllegalArgumentException.prototype = EidRuntimeException.prototype; + + /** + * This class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * This id Eid version of {@link IllegalStateException} + * + * @constructor + * @param {string} eid - an exception Id, should be generated + * @param {string} message - an message for the exception + * @see IllegalStateException + * @see EidRuntimeException + * @author Krzysztof Suszyński + */ + function EidIllegalStateException(eid, message) { + this.name = 'EidIllegalStateException'; + commonExConstructor.apply(this, [eid, message]); + } + EidIllegalStateException.prototype = EidRuntimeException.prototype; + + /** + * This class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * This id Eid version of {@link IndexOutOfBoundsException} + * + * @constructor + * @param {string} eid - an exception Id, should be generated + * @param {string} message - an message for the exception + * @see IndexOutOfBoundsException + * @see EidRuntimeException + * @author Krzysztof Suszyński + */ + function EidIndexOutOfBoundsException(eid, message) { + this.name = 'EidIndexOutOfBoundsException'; + commonExConstructor.apply(this, [eid, message]); + } + EidIndexOutOfBoundsException.prototype = EidRuntimeException.prototype; + + exports.EidRuntimeException = EidRuntimeException; + exports.EidNullPointerException = EidNullPointerException; + exports.EidIllegalArgumentException = EidIllegalArgumentException; + exports.EidIllegalStateException = EidIllegalStateException; + exports.EidIndexOutOfBoundsException = EidIndexOutOfBoundsException; + +})(exports); diff --git a/lib/eid/preconditions.js b/lib/eid/preconditions.js new file mode 100644 index 0000000..5762f94 --- /dev/null +++ b/lib/eid/preconditions.js @@ -0,0 +1,279 @@ +/* + * Copyright 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function(module) { +'use strict'; + +var Eid = require('./eid'); +var EidRuntimeException = require('./exceptions').EidRuntimeException; +var EidNullPointerException = require('./exceptions').EidNullPointerException; +var EidIllegalArgumentException = require('./exceptions').EidIllegalArgumentException; +var EidIllegalStateException = require('./exceptions').EidIllegalStateException; +var EidIndexOutOfBoundsException = require('./exceptions').EidIndexOutOfBoundsException; + +/** + * This class shouldn't be used in any public API or library. It is designed to be used for in-house development + * of end user applications which will report Bugs in standardized error pages or post them to issue tracker. + *

+ * Static convenience methods that help a method or constructor check whether it was invoked correctly (whether its + * preconditions + * have been met). These methods generally accept a {@code boolean} expression which is expected to be {@code true} (or in the + * case of {@code + * checkNotNull}, an object reference which is expected to be non-null). When {@code false} (or {@code null}) is passed instead, + * the {@code EidPreconditions} method throws an unchecked exception, which helps the calling method communicate to its + * caller that + * that caller has made a mistake. + *

+ * Each method accepts a EID String or {@link Eid} object, which is designed to ease of use and provide strict ID for given + * Exception usage. This approach speed up development of large application and helps support teams to by giving the both static + * and random ID for each possible unpredicted bug. + *

+ * This is best to use with tools and plugins like + * EidGenerator for Netbeans IDE + *

+ * Example: + *

   {@code
+ *
+ *   /**
+ *    * Returns the positive square root of the given value.
+ *    *
+ *    * @throws EidIllegalArgumentException if the value is negative
+ *    *}{@code /
+ *   public static double sqrt(double value) {
+ *     EidPreconditions.checkArgument(value >= 0.0, "20150718:012333");
+ *     // calculate the square root
+ *   }
+ *
+ *   void exampleBadCaller() {
+ *     double d = sqrt(-1.0);
+ *   }
+ * }
+ *

+ * In this example, {@code checkArgument} throws an {@code EidIllegalArgumentException} to indicate that {@code exampleBadCaller} + * made an error in its call to {@code sqrt}. Exception, when it will be printed will contain user given Eid and also + * Randomly generated ID. Those fields can be displayed to user on error page on posted directly to issue tracker. + *

+ * Example: + *

+ *

+ *
+ * {@code
+ *   // Main application class for ex.: http servlet
+ *    try {
+ *        performRequest(request, response);
+ *    } catch (EidRuntimeException ex) {
+ *        issuesTracker.put(ex);
+ *        throw ex;
+ *    }
+ * }
+ *

+ *

+ *

Functional try to execute blocks

+ *

+ *

+ * Using functional blocks to handle operations, that are intended to operate properly, simplify the code and makes it more + * readable. It's also good way to deal with untested, uncovered {@code catch} blocks. It's easy and gives developers nice way of + * dealing with countless operations that suppose to work as intended. + *

+ *

+ * Example: + *


+ *
+ *     InputStream is = EidPreconditions.tryToExecute({@code new UnsafeSupplier}() {
+ *        {@literal @}Override
+ *         public InputStream get() throws IOException {
+ *             return this.getClass().getClassLoader()
+ *                 .getResourceAsStream("project.properties");
+ *         }
+ *     }, "20150718:121521");
+ * 
+ * + * @constructor + * @author Krzysztof Suszyński + * @since 0.1.0 (idea imported from Guava Library and COI code) + */ +function EidPreconditions() {} + +function isNullike(reference) { + return reference === null || reference === undefined; +} + +function checkNotNull(reference) { + if (isNullike(reference)) { + throw new TypeError("Pass not-null Eid to EidPreconditions first!"); + } + return reference; +} + +function ensureEid(candidate) { + candidate = checkNotNull(candidate); + var eid; + if (!(candidate instanceof Eid)) { + eid = new Eid(candidate + ''); + } else { + eid = candidate; + } + return eid; +} + +/** + * Ensures that an object reference passed as a parameter to the calling method is not null-like. + * + * @param {Object} reference - an object reference + * @param {string|Eid} eid - the exception ID to use if the check fails + * @param {string} message - message for produced exception + * @return {Object} the non-null reference that was validated + * @throws {EidNullPointerException} if {@code reference} is null-like + */ +EidPreconditions.checkNotNullable = function(reference, eid, message) { + var checkedEid = ensureEid(eid); + if (isNullike(reference)) { + throw new EidNullPointerException(checkedEid, message); + } + return reference; +}; + +/** + * Ensures that an object reference passed as a parameter to the calling method is not null. + * + * @param {Object} reference - an object reference + * @param {string|Eid} eid - the exception ID to use if the check fails + * @param {string} message - message for produced exception + * @return {Object} the non-null reference that was validated + * @throws {EidNullPointerException} if {@code reference} is null-like + */ +EidPreconditions.checkNotNull = function(reference, eid, message) { + var checkedEid = ensureEid(eid); + if (reference === null) { + throw new EidNullPointerException(checkedEid, message); + } + return reference; +}; + +/** + * Ensures that an object reference passed as a parameter to the calling method is not undefined. + * + * @param {Object} reference - an object reference + * @param {string|Eid} eid - the exception ID to use if the check fails + * @param {string} message - message for produced exception + * @return {Object} the non-null reference that was validated + * @throws {EidNullPointerException} if {@code reference} is null-like + */ +EidPreconditions.checkNotUndefined = function(reference, eid, message) { + var checkedEid = ensureEid(eid); + if (reference === undefined) { + throw new EidNullPointerException(checkedEid, message); + } + return reference; +}; + +/** + * Ensures the truth of an expression involving one or more parameters to the calling method. + * + * @param {boolean} expression - a boolean expression + * @param {string|Eid} eid - the exception ID to use if the check fails + * @param {string} message - optional message for generated exception + * @throws {EidIllegalArgumentException} if {@code expression} is false + * @throws {EidNullPointerException} if {@code expression} is null + */ +EidPreconditions.checkArgument = function(expression, eid, message) { + var checkedEid = ensureEid(eid); + if (!EidPreconditions.checkNotNullable(expression, checkedEid)) { + throw new EidIllegalArgumentException(checkedEid, message) + } +}; + +/** + * Ensures the truth of an expression involving the state of the calling instance, but not involving any parameters to the + * calling method. + * + * @param {boolean} expression - a boolean expression + * @param {string|Eid} eid - the exception ID to use if the check fails + * @param {string} message - optional message for generated exception + * @throws {EidIllegalStateException} if {@code expression} is false + * @throws {EidNullPointerException} if {@code expression} is null + */ +EidPreconditions.checkState = function(expression, eid, message) { + var checkedEid = ensureEid(eid); + if (!EidPreconditions.checkNotNullable(expression, checkedEid)) { + throw new EidIllegalStateException(checkedEid, message); + } +}; + +function isIndexAndSizeIllegal(index, size) { + return index < 0 || index > size; +} + +function isSizeIllegal(size) { + return size < 0; +} + +/** + * Ensures that {@code index} specifies a valid element in an array, list or string of size {@code size}. An element + * index may range from zero, inclusive, to {@code size}, exclusive. + * + * @param {number} index - a user-supplied index identifying an element of an array, list or string + * @param {numer} size - the size of that array, list or string + * @param {string|Eid} eid - the text to use to describe this index in an error message + * @param {string} message - optional message for generated exception + * @return {number} the value of {@code index} + * @throws {EidIndexOutOfBoundsException} if {@code index} is negative or is not less than {@code size} + * @throws {EidIllegalArgumentException} if {@code size} is negative + */ +EidPreconditions.checkElementIndex = function(index, size, eid, message) { + var checkedEid = ensureEid(eid); + if (isSizeIllegal(size)) { + throw new EidIllegalArgumentException(checkedEid, message); + } + if (isIndexAndSizeIllegal(index, size)) { + throw new EidIndexOutOfBoundsException(checkedEid, message); + } + return index; +}; + +/** + * Tries to execute code in given unsafe supplier code block, and if exception is thrown, it will gets rethrown as a + * {@link EidRuntimeException} with eid given as a argument. This is because this exception is threaded as a software bug! + *

+ * Example: + *


+ *
+ * Document doc = EidPreconditions.tryToExecute({@code new UnsafeSupplier}() {
+ *    {@literal @}Override
+ *     public Document get() throws IOException {
+ *          DocumentBuilder docBuilder = ...
+ *          return docBuilder.parse(new InputSource(reader));
+ *     }
+ * }, new Eid("20150718:121521"));
+ * 
+ * + * @param return type + * @param supplier unsafe supplier code to be executed within a try-catch block + * @param eid unique developer identifier from date for ex.: "20150716:123200" + * @return A block of code return type, if exception is not thrown + * @throws EidRuntimeException if code block thrown any exception, which in that case is wrapped in EidRuntimeException + */ +EidPreconditions.tryToExecute = function(supplier, eid) { + var checkedEid = ensureEid(eid); + try { + return EidPreconditions.checkNotNullable(supplier, checkedEid).apply(); + } catch (throwable) { + throw new EidRuntimeException(checkedEid, throwable); + } +}; + +module.exports = EidPreconditions; +})(module); diff --git a/package.json b/package.json new file mode 100644 index 0000000..7f69697 --- /dev/null +++ b/package.json @@ -0,0 +1,50 @@ +{ + "name": "eid.js", + "version": "1.0.0", + "description": "EID Runtime Exceptions and Utilities for JS", + "main": "lib/eid.js", + "directories": { + "lib": "./lib" + }, + "dependencies": {}, + "devDependencies": { + "browserify": "^13.0.0", + "expect.js": "^0.3.1", + "globby": "^4.0.0", + "gulp": "^3.9.0", + "gulp-coverage": "^0.3.38", + "gulp-coveralls": "^0.1.4", + "gulp-eslint": "^1.1.1", + "gulp-mocha": "^2.2.0", + "gulp-serve": "^1.2.0", + "gulp-sourcemaps": "^1.6.0", + "gulp-uglify": "^1.5.1", + "gulp-util": "^3.0.7", + "through2": "^2.0.0", + "vinyl-buffer": "^1.0.0", + "vinyl-source-stream": "^1.1.0" + }, + "scripts": { + "clean": "gulp clean", + "test": "gulp test", + "build": "gulp build", + "serve": "gulp serve" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/wavesoftware/javascript-eid-exceptions.git" + }, + "keywords": [ + "debug", + "expection", + "preconditions", + "quality", + "qa" + ], + "author": "Krzysztof Suszynski ", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/wavesoftware/javascript-eid-exceptions/issues" + }, + "homepage": "https://github.com/wavesoftware/javascript-eid-exceptions#readme" +} diff --git a/test/eid.js b/test/eid.js new file mode 100644 index 0000000..8385079 --- /dev/null +++ b/test/eid.js @@ -0,0 +1,170 @@ +/* + * Copyright 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var Eid = require('../lib/eid'); +var expect = require('expect.js'); + +describe('Eid', function() { + describe('.setFormat()', function () { + afterEach(function() { + Eid.setFormat(Eid.DEFAULT_FORMAT); + }); + it('should set a valid new format and return last', function() { + var fmt = "{%s-%s}"; + var prev = Eid.setFormat(fmt); + expect(prev).to.eql(Eid.DEFAULT_FORMAT); + + prev = Eid.setFormat(fmt); + expect(prev).to.eql(fmt); + }); + it('should throw error on null', function() { + var fn = function() { + Eid.setFormat(null); + }; + expect(fn).to.throwError(TypeError, 'Format can\'t be null, but just received one'); + }); + it('should throw error on invalid format', function() { + var fn = function() { + Eid.setFormat("%s -->"); + }; + expect(fn).to.throwError(TypeError); + expect(fn).to.throwError(/Given format contains to little format specifiers, expected 2 but given "\%s \-\-\>"/); + }); + }); + + describe('.setRefFormat()', function() { + afterEach(function() { + Eid.setRefFormat(Eid.DEFAULT_REF_FORMAT); + }); + it('should set a valid new ref format and return last', function() { + var fmt = "%s:%s --> %s"; + var prev = Eid.setRefFormat(fmt); + expect(prev).to.eql(Eid.DEFAULT_REF_FORMAT); + }); + }); + + describe('.setMessageFormat()', function() { + afterEach(function() { + Eid.setMessageFormat(Eid.DEFAULT_MESSAGE_FORMAT); + }); + it('should set a valid new message format and return last', function() { + var fmt = "%s --> %s"; + var prev = Eid.setMessageFormat(fmt); + expect(prev).to.eql(Eid.DEFAULT_MESSAGE_FORMAT); + }); + }); + + describe('.getMessageFormat()', function() { + it('should return original actually set message format', function() { + var fmt = Eid.getMessageFormat(); + expect(fmt).to.eql(Eid.DEFAULT_MESSAGE_FORMAT); + }) + }); + + describe('.setUniqIdGenerator()', function() { + afterEach(function() { + Eid.setUniqIdGenerator(Eid.DEFAULT_UNIQ_ID_GENERATOR); + }); + it('should throw error if given null', function() { + var fn = function() { + Eid.setUniqIdGenerator(null); + } + expect(fn).to.throwException(TypeError); + expect(fn).to.throwException(/^Unique ID generator can't be null, but given one$/); + }); + it('should set properlly if given correct implementation', function() { + var gen = { + generateUniqId: function() { + return 5; // just like SONY here :-) + } + }; + var prev = Eid.setUniqIdGenerator(gen); + expect(prev).to.be(Eid.DEFAULT_UNIQ_ID_GENERATOR); + var eid = new Eid('20160110:221413'); + expect(eid.toString()).to.eql('[20160110:221413]<5>'); + }); + }); + + describe('.DEFAULT_MESSAGE_FORMAT', function() { + it('should be equal "%s => %s"', function() { + expect(Eid.DEFAULT_MESSAGE_FORMAT).to.eql("%s => %s"); + }); + }); + + describe('.DEFAULT_FORMAT', function() { + it('should be equal "[%s]<%s>"', function() { + expect(Eid.DEFAULT_FORMAT).to.eql("[%s]<%s>"); + }); + }); + + describe('.DEFAULT_REF_FORMAT', function() { + it('should be equal "[%s|%s]<%s>"', function() { + expect(Eid.DEFAULT_REF_FORMAT).to.eql("[%s|%s]<%s>"); + }); + }); + + describe('.DEFAULT_UNIQ_ID_GENERATOR', function() { + it('should be instance of UniqIdGenerator', function() { + expect(Eid.DEFAULT_UNIQ_ID_GENERATOR.generateUniqId()).to.match(/^[a-z0-9]{5,6}$/); + }); + }); + + describe('#toString()', function() { + describe('without ref number', function() { + var subject = new Eid('20160110:214452'); + it('should print object with eid and uniq id', function() { + expect(subject.toString()).to.match(/^\[20160110:214452]\<[a-z0-9]{5,6}\>$/); + }); + }); + describe('with ref number', function() { + var subject = new Eid('20160110:214944', 'ORA-1029'); + it('should print object with eid, ref and uniq id', function() { + expect(subject.toString()).to.match(/^\[20160110:214944\|ORA-1029\]\<[a-z0-9]{5,6}\>$/); + }); + }); + }); + + describe('#makeLogMessage()', function() { + var eid = new Eid('20160110:215138'); + var messageFormat = "My test object is: %s"; + var testObject = { 'a': 67 }; + testObject.toString = function() { + return JSON.stringify(this); + }; + it('should print log message as: [20160110:215138] => My test object is: {"a":67}', function() { + expect(eid.makeLogMessage(messageFormat, testObject)).to.match(/^\[20160110:215138\]\<[a-z0-9]{5,6}\> => My test object is: {"a":67}$/); + }); + }); + + describe('given a eid == new Eid("20160110:220223", "EX-556")', function() { + var eid = new Eid('20160110:220223', 'EX-556'); + describe('#getId()', function() { + it('should return 20160110:220223 as id', function() { + expect(eid.getId()).to.be('20160110:220223'); + }); + }); + describe('#getRef()', function() { + it('should return EX-556 as ref', function() { + expect(eid.getRef()).to.be('EX-556'); + }); + }); + describe('#getUniq()', function() { + it('should return xxxxxx as uniq id', function() { + expect(eid.getUniq()).to.match(/^[a-z0-9]{5,6}$/); + }); + }); + }); +}); diff --git a/test/eid/exceptions.js b/test/eid/exceptions.js new file mode 100644 index 0000000..bce72c6 --- /dev/null +++ b/test/eid/exceptions.js @@ -0,0 +1,91 @@ +/* + * Copyright 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var expect = require('expect.js'); +var EidRuntimeException = require('../../lib/eid/exceptions').EidRuntimeException; +var EidNullPointerException = require('../../lib/eid/exceptions').EidNullPointerException; +var EidIllegalArgumentException = require('../../lib/eid/exceptions').EidIllegalArgumentException; +var EidIllegalStateException = require('../../lib/eid/exceptions').EidIllegalStateException; +var EidIndexOutOfBoundsException = require('../../lib/eid/exceptions').EidIndexOutOfBoundsException; + +describe('EidRuntimeException', function() { + var ex = new EidRuntimeException('20160110:230223', 'A null pointer occured!'); + it('should contain proper message', function() { + expect(ex.toString()).to.match(/EidRuntimeException: \[20160110:230223\]\<[a-z0-9]+\> A null pointer occured!/); + }); + it('should contain a stack trace', function() { + expect(ex.stack).to.not.empty(); + }); + it('should inherits Error', function() { + expect(ex instanceof Error).to.be.ok(); + }); +}); + +describe('EidNullPointerException', function() { + var ex = new EidNullPointerException('20160110:223238', 'A null pointer occured!'); + it('should contain proper message', function() { + expect(ex.toString()).to.match(/EidNullPointerException: \[20160110:223238\]\<[a-z0-9]+\> A null pointer occured!/); + }); + it('should contain a stack trace', function() { + expect(ex.stack).to.not.empty(); + }); + it('should inherits Error and EidRuntimeException', function() { + expect(ex instanceof Error).to.be.ok(); + expect(ex instanceof EidRuntimeException).to.be.ok(); + }); +}); + +describe('EidIllegalArgumentException', function() { + var ex = new EidIllegalArgumentException('20160110:230031', 'A null pointer occured!'); + it('should contain proper message', function() { + expect(ex.toString()).to.match(/EidIllegalArgumentException: \[20160110:230031\]\<[a-z0-9]+\> A null pointer occured!/); + }); + it('should contain a stack trace', function() { + expect(ex.stack).to.not.empty(); + }); + it('should inherits Error and EidRuntimeException', function() { + expect(ex instanceof Error).to.be.ok(); + expect(ex instanceof EidRuntimeException).to.be.ok(); + }); +}); + +describe('EidIllegalStateException', function() { + var ex = new EidIllegalStateException('20160110:230112', 'A null pointer occured!'); + it('should contain proper message', function() { + expect(ex.toString()).to.match(/EidIllegalStateException: \[20160110:230112\]\<[a-z0-9]+\> A null pointer occured!/); + }); + it('should contain a stack trace', function() { + expect(ex.stack).to.not.empty(); + }); + it('should inherits Error and EidRuntimeException', function() { + expect(ex instanceof Error).to.be.ok(); + expect(ex instanceof EidRuntimeException).to.be.ok(); + }); +}); + +describe('EidIndexOutOfBoundsException', function() { + var ex = new EidIndexOutOfBoundsException('20160110:230140', 'A null pointer occured!'); + it('should contain proper message', function() { + expect(ex.toString()).to.match(/EidIndexOutOfBoundsException: \[20160110:230140\]\<[a-z0-9]+\> A null pointer occured!/); + }); + it('should contain a stack trace', function() { + expect(ex.stack).to.not.empty(); + }); + it('should inherits Error and EidRuntimeException', function() { + expect(ex instanceof Error).to.be.ok(); + expect(ex instanceof EidRuntimeException).to.be.ok(); + }); +}); diff --git a/test/eid/preconditions.js b/test/eid/preconditions.js new file mode 100644 index 0000000..08f5819 --- /dev/null +++ b/test/eid/preconditions.js @@ -0,0 +1,223 @@ +/* + * Copyright 2016 Wave Software + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var EidPreconditions = require('../../lib/eid/preconditions'); +var EidNullPointerException = require('../../lib/eid/exceptions').EidNullPointerException; +var EidIllegalArgumentException = require('../../lib/eid/exceptions').EidIllegalArgumentException; +var EidIllegalStateException = require('../../lib/eid/exceptions').EidIllegalStateException; +var EidIndexOutOfBoundsException = require('../../lib/eid/exceptions').EidIndexOutOfBoundsException; +var EidRuntimeException = require('../../lib/eid/exceptions').EidRuntimeException; +var Eid = require('../../lib/eid'); +var expect = require('expect.js'); + +describe('EidPreconditions', function() { + var eid = '20160111:004403'; + var eidRegex = /20160111:004403/; + + describe('.checkNotNullable()', function() { + describe('giving a null value', function() { + it('should throw EidNullPointerException', function() { + var fn = function() { + EidPreconditions.checkNotNullable(null, eid); + }; + expect(fn).to.throwException(function(e) { + expect(e.toString()).to.match(eidRegex); + expect(e.message).to.match(eidRegex); + expect(e).to.be.a(EidNullPointerException); + expect(e).not.to.be.a(TypeError); + }); + }); + }); + describe('giving a undefined value', function() { + it('should throw EidNullPointerException', function() { + var fn = function() { + EidPreconditions.checkNotNullable(undefined, eid); + }; + expect(fn).to.throwException(function(e) { + expect(e.toString()).to.match(eidRegex); + expect(e.message).to.match(eidRegex); + expect(e).to.be.a(EidNullPointerException); + expect(e).not.to.be.a(TypeError); + }); + }); + }); + describe('giving a string value', function() { + it('should return original value', function() { + var given = 'YjdlYjExZGQ0MzY3YjIxO'; + var result = EidPreconditions.checkNotNullable(given, eid); + expect(result).to.be(given); + }); + }); + }); + + + describe('.checkNotNull()', function() { + describe('giving a null value', function() { + it('should throw EidNullPointerException', function() { + var fn = function() { + EidPreconditions.checkNotNull(null, eid); + }; + expect(fn).to.throwException(function(e) { + expect(e.toString()).to.match(eidRegex); + expect(e.message).to.match(eidRegex); + expect(e).to.be.a(EidNullPointerException); + expect(e).not.to.be.a(TypeError); + }); + }); + }); + describe('giving a string value', function() { + it('should return original value', function() { + var given = 'YjdlYjExZGQ0MzY3YjIxO'; + var result = EidPreconditions.checkNotNull(given, eid); + expect(result).to.be(given); + }); + }); + }); + + + describe('.checkNotUndefined()', function() { + describe('giving a undefined value', function() { + it('should throw EidNullPointerException', function() { + var fn = function() { + EidPreconditions.checkNotUndefined(undefined, eid); + }; + expect(fn).to.throwException(function(e) { + expect(e.toString()).to.match(eidRegex); + expect(e.message).to.match(eidRegex); + expect(e).to.be.a(EidNullPointerException); + expect(e).not.to.be.a(TypeError); + }); + }); + }); + describe('giving a string value', function() { + it('should return original value', function() { + var given = 'YjdlYjExZGQ0MzY3YjIxO'; + var result = EidPreconditions.checkNotUndefined(given, eid); + expect(result).to.be(given); + }); + }); + }); + + + describe('.checkArgument()', function() { + describe('giving an Eid object', function() { + var eidObject = new Eid(eid); + it('should run without errors', function() { + var fn = function() { + EidPreconditions.checkArgument(true, eidObject); + }; + expect(fn).not.to.throwException(); + }); + }); + describe('giving a nullable value', function() { + it('should throw TypeError', function() { + var fn = function() { + EidPreconditions.checkArgument(true, undefined); + }; + expect(fn).to.throwException(function(e) { + expect(e.toString()).to.match(/Pass not-null Eid to EidPreconditions first!/); + expect(e).to.be.a(TypeError); + }); + }); + }); + describe('giving a falsy value', function() { + it('should throw EidIllegalArgumentException', function() { + var fn = function() { + EidPreconditions.checkArgument(false, eid); + }; + expect(fn).to.throwException(function(e) { + expect(e.toString()).to.match(eidRegex); + expect(e).to.be.a(EidIllegalArgumentException); + }); + }); + }); + }); + + + describe('.checkState()', function() { + describe('giving a falsy value', function() { + it('should throw EidIllegalStateException', function() { + var fn = function() { + EidPreconditions.checkState(false, eid); + }; + expect(fn).to.throwException(function(e) { + expect(e.toString()).to.match(eidRegex); + expect(e).to.be.a(EidIllegalStateException); + }); + }); + }); + }); + + + describe('.checkElementIndex()', function() { + describe('giving a invalid size of -6', function() { + it('should throw EidIllegalArgumentException', function() { + var fn = function() { + EidPreconditions.checkElementIndex(0, -6, eid); + }; + expect(fn).to.throwException(function(e) { + expect(e.toString()).to.match(eidRegex); + expect(e).to.be.a(EidIllegalArgumentException); + }); + }); + }); + describe('giving a invalid index value of 6, and size of 2', function() { + it('should throw EidIndexOutOfBoundsException', function() { + var fn = function() { + EidPreconditions.checkElementIndex(6, 2, eid); + }; + expect(fn).to.throwException(function(e) { + expect(e.toString()).to.match(eidRegex); + expect(e).to.be.a(EidIndexOutOfBoundsException); + }); + }); + }); + describe('giving a valid index of 2 and size of 5', function() { + it('should return index of 2', function() { + var result = EidPreconditions.checkElementIndex(2, 5, eid); + expect(result).to.be(2); + }); + }); + }); + + + describe('.tryToExecute()', function() { + describe('giving a valid supplier function', function() { + it('should return supplier value', function() { + var fn = function() { + return 6; + }; + var result = EidPreconditions.tryToExecute(fn, eid); + expect(result).to.be(6); + }); + }); + describe('giving a supplier that throws TypeError function', function() { + it('should throw EidRuntimeException', function() { + var fn = function() { + throw new TypeError('invalid type!'); + }; + var testClousure = function() { + EidPreconditions.tryToExecute(fn, eid); + }; + expect(testClousure).to.throwException(function(e) { + expect(e.toString()).to.match(eidRegex); + expect(e.toString()).to.match(/invalid type!/); + expect(e).to.be.a(EidRuntimeException); + }); + }); + }); + }); +}); diff --git a/test/index.html b/test/index.html new file mode 100644 index 0000000..052ae7a --- /dev/null +++ b/test/index.html @@ -0,0 +1,107 @@ + + + + + ExceptionID.js - manual test page + + + + + + + +

ExceptionID.js - showcase

+ +

Code:

+

+    try {
+      // Example entity objects
+      var users = [];
+      for (var i = 0; i < 5; i++) {
+        var user = { id: 67112 - i };
+        user.toString = function() { return '[User id=' + this.id + ']'; };
+        users.push(user);
+      }
+
+      // logging support
+      for (var i = 0; i < users.length; i++) {
+        var user = users[i];
+        var eid = new Eid('20160111:223928', 'WJS-17');
+        log.debug(eid.makeLogMessage('An entity: %s', user));
+        log.debug(eid.makeLogMessage('%s has even ID: %s', user, user.id % 2 === 0));
+      }
+
+      // preconditions!
+      var EidPreconditions = Eid.preconditions;
+      EidPreconditions.checkArgument(true, '20160111:223749');
+      EidPreconditions.checkState(false, '20160111:224215', 'A extra message');
+    } catch(e) {
+      // Top level of your application
+      log.error(e.toString() + ' - ' + e.stack);
+      // or better save your exceptions!
+      logGateway.put(e, {eid: e.eid});
+    }
+    
+

Console:

+

+    
+  
+