diff --git a/dist/autolayout.kiwi.js b/dist/autolayout.kiwi.js
new file mode 100644
index 0000000..074b79c
--- /dev/null
+++ b/dist/autolayout.kiwi.js
@@ -0,0 +1,6534 @@
+/**
+* AutoLayout.js is licensed under the MIT license. If a copy of the
+* MIT-license was not distributed with this file, You can obtain one at:
+* http://opensource.org/licenses/mit-license.html.
+*
+* @author: Hein Rutjes (IjzerenHein)
+* @license MIT
+* @copyright Gloey Apps, 2015
+*
+* @library autolayout.js
+* @version 0.4.0
+* @generated 27-07-2015
+*/
+/*-----------------------------------------------------------------------------
+| Kiwi (TypeScript version)
+|
+| Copyright (c) 2015, Nucleic Development Team.
+|
+| Distributed under the terms of the Modified BSD License.
+|
+| The full license is in the file COPYING.txt, distributed with this software.
+|----------------------------------------------------------------------------*/
+
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.AutoLayout = f()}})(function(){var define,module,exports;return (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;o
+///
+var tsu;
+(function (tsu) {
+ /**
+ * Perform a lower bound search on a sorted array.
+ *
+ * @param array The array of sorted items to search.
+ * @param value The value to located in the array.
+ * @param compare The value comparison function.
+ * @returns The index of the first element in the array which
+ * compares greater than or equal to the given value.
+ */
+ function lowerBound(array, value, compare) {
+ var begin = 0;
+ var n = array.length;
+ var half;
+ var middle;
+ while (n > 0) {
+ half = n >> 1;
+ middle = begin + half;
+ if (compare(array[middle], value) < 0) {
+ begin = middle + 1;
+ n -= half + 1;
+ } else {
+ n = half;
+ }
+ }
+ return begin;
+ }
+ tsu.lowerBound = lowerBound;
+
+ /**
+ * Perform a binary search on a sorted array.
+ *
+ * @param array The array of sorted items to search.
+ * @param value The value to located in the array.
+ * @param compare The value comparison function.
+ * @returns The index of the found item, or -1.
+ */
+ function binarySearch(array, value, compare) {
+ var index = lowerBound(array, value, compare);
+ if (index === array.length) {
+ return -1;
+ }
+ var item = array[index];
+ if (compare(item, value) !== 0) {
+ return -1;
+ }
+ return index;
+ }
+ tsu.binarySearch = binarySearch;
+
+ /**
+ * Perform a binary find on a sorted array.
+ *
+ * @param array The array of sorted items to search.
+ * @param value The value to located in the array.
+ * @param compare The value comparison function.
+ * @returns The found item in the array, or undefined.
+ */
+ function binaryFind(array, value, compare) {
+ var index = lowerBound(array, value, compare);
+ if (index === array.length) {
+ return undefined;
+ }
+ var item = array[index];
+ if (compare(item, value) !== 0) {
+ return undefined;
+ }
+ return item;
+ }
+ tsu.binaryFind = binaryFind;
+
+})(tsu || (tsu = {}));
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014, Nucleic Development Team.
+|
+| Distributed under the terms of the Modified BSD License.
+|
+| The full license is in the file COPYING.txt, distributed with this software.
+|----------------------------------------------------------------------------*/
+///
+var tsu;
+(function (tsu) {
+ /**
+ * A base class for implementing array-based data structures.
+ *
+ * @class
+ */
+ var ArrayBase = (function () {
+ function ArrayBase() {
+ /*
+ * The internal data array.
+ *
+ * @protected
+ */
+ this._array = [];
+ }
+ /**
+ * Returns the number of items in the array.
+ */
+ ArrayBase.prototype.size = function () {
+ return this._array.length;
+ };
+
+ /**
+ * Returns true if the array is empty.
+ */
+ ArrayBase.prototype.empty = function () {
+ return this._array.length === 0;
+ };
+
+ /**
+ * Returns the item at the given array index.
+ *
+ * @param index The integer index of the desired item.
+ */
+ ArrayBase.prototype.itemAt = function (index) {
+ return this._array[index];
+ };
+
+ /**
+ * Removes and returns the item at the given index.
+ *
+ * @param index The integer index of the desired item.
+ */
+ ArrayBase.prototype.takeAt = function (index) {
+ return this._array.splice(index, 1)[0];
+ };
+
+ /**
+ * Clear the internal contents of array.
+ */
+ ArrayBase.prototype.clear = function () {
+ this._array = [];
+ };
+
+ /**
+ * Swap this array's contents with another array.
+ *
+ * @param other The array base to use for the swap.
+ */
+ ArrayBase.prototype.swap = function (other) {
+ var array = this._array;
+ this._array = other._array;
+ other._array = array;
+ };
+
+ /**
+ * Returns an iterator over the array of items.
+ */
+ ArrayBase.prototype.__iter__ = function () {
+ return tsu.iter(this._array);
+ };
+
+ /**
+ * Returns a reverse iterator over the array of items.
+ */
+ ArrayBase.prototype.__reversed__ = function () {
+ return tsu.reversed(this._array);
+ };
+ return ArrayBase;
+ })();
+ tsu.ArrayBase = ArrayBase;
+})(tsu || (tsu = {}));
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014, Nucleic Development Team.
+|
+| Distributed under the terms of the Modified BSD License.
+|
+| The full license is in the file COPYING.txt, distributed with this software.
+|----------------------------------------------------------------------------*/
+var __extends = this.__extends || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ __.prototype = b.prototype;
+ d.prototype = new __();
+};
+///
+///
+///
+///
+var tsu;
+(function (tsu) {
+ /**
+ * A mapping container build on a sorted array.
+ *
+ * @class
+ */
+ var AssociativeArray = (function (_super) {
+ __extends(AssociativeArray, _super);
+ /**
+ * Construct a new AssociativeArray.
+ *
+ * @param compare The key comparison function.
+ */
+ function AssociativeArray(compare) {
+ _super.call(this);
+ this._compare = compare;
+ this._wrapped = wrapCompare(compare);
+ }
+ /**
+ * Returns the key comparison function used by this array.
+ */
+ AssociativeArray.prototype.comparitor = function () {
+ return this._compare;
+ };
+
+ /**
+ * Return the array index of the given key, or -1.
+ *
+ * @param key The key to locate in the array.
+ */
+ AssociativeArray.prototype.indexOf = function (key) {
+ return tsu.binarySearch(this._array, key, this._wrapped);
+ };
+
+ /**
+ * Returns true if the key is in the array, false otherwise.
+ *
+ * @param key The key to locate in the array.
+ */
+ AssociativeArray.prototype.contains = function (key) {
+ return tsu.binarySearch(this._array, key, this._wrapped) >= 0;
+ };
+
+ /**
+ * Returns the pair associated with the given key, or undefined.
+ *
+ * @param key The key to locate in the array.
+ */
+ AssociativeArray.prototype.find = function (key) {
+ return tsu.binaryFind(this._array, key, this._wrapped);
+ };
+
+ /**
+ * Returns the pair associated with the key if it exists.
+ *
+ * If the key does not exist, a new pair will be created and
+ * inserted using the value created by the given factory.
+ *
+ * @param key The key to locate in the array.
+ * @param factory The function which creates the default value.
+ */
+ AssociativeArray.prototype.setDefault = function (key, factory) {
+ var array = this._array;
+ var index = tsu.lowerBound(array, key, this._wrapped);
+ if (index === array.length) {
+ var pair = new tsu.Pair(key, factory());
+ array.push(pair);
+ return pair;
+ }
+ var currPair = array[index];
+ if (this._compare(currPair.first, key) !== 0) {
+ var pair = new tsu.Pair(key, factory());
+ array.splice(index, 0, pair);
+ return pair;
+ }
+ return currPair;
+ };
+
+ /**
+ * Insert the pair into the array and return the pair.
+ *
+ * This will overwrite any existing entry in the array.
+ *
+ * @param key The key portion of the pair.
+ * @param value The value portion of the pair.
+ */
+ AssociativeArray.prototype.insert = function (key, value) {
+ var array = this._array;
+ var index = tsu.lowerBound(array, key, this._wrapped);
+ if (index === array.length) {
+ var pair = new tsu.Pair(key, value);
+ array.push(pair);
+ return pair;
+ }
+ var currPair = array[index];
+ if (this._compare(currPair.first, key) !== 0) {
+ var pair = new tsu.Pair(key, value);
+ array.splice(index, 0, pair);
+ return pair;
+ }
+ currPair.second = value;
+ return currPair;
+ };
+
+ AssociativeArray.prototype.update = function (object) {
+ var _this = this;
+ if (object instanceof AssociativeArray) {
+ var obj = object;
+ this._array = merge(this._array, obj._array, this._compare);
+ } else {
+ tsu.forEach(object, function (pair) {
+ _this.insert(pair.first, pair.second);
+ });
+ }
+ };
+
+ /**
+ * Removes and returns the pair for the given key, or undefined.
+ *
+ * @param key The key to remove from the map.
+ */
+ AssociativeArray.prototype.erase = function (key) {
+ var array = this._array;
+ var index = tsu.binarySearch(array, key, this._wrapped);
+ if (index < 0) {
+ return undefined;
+ }
+ return array.splice(index, 1)[0];
+ };
+
+ /**
+ * Create a copy of this associative array.
+ */
+ AssociativeArray.prototype.copy = function () {
+ var theCopy = new AssociativeArray(this._compare);
+ var copyArray = theCopy._array;
+ var thisArray = this._array;
+ for (var i = 0, n = thisArray.length; i < n; ++i) {
+ copyArray.push(thisArray[i].copy());
+ }
+ return theCopy;
+ };
+ return AssociativeArray;
+ })(tsu.ArrayBase);
+ tsu.AssociativeArray = AssociativeArray;
+
+ /**
+ * An internal which wraps a comparison key function.
+ */
+ function wrapCompare(cmp) {
+ return function (pair, value) {
+ return cmp(pair.first, value);
+ };
+ }
+
+ /**
+ * An internal function which merges two ordered pair arrays.
+ */
+ function merge(first, second, compare) {
+ var i = 0, j = 0;
+ var len1 = first.length;
+ var len2 = second.length;
+ var merged = [];
+ while (i < len1 && j < len2) {
+ var a = first[i];
+ var b = second[j];
+ var v = compare(a.first, b.first);
+ if (v < 0) {
+ merged.push(a.copy());
+ ++i;
+ } else if (v > 0) {
+ merged.push(b.copy());
+ ++j;
+ } else {
+ merged.push(b.copy());
+ ++i;
+ ++j;
+ }
+ }
+ while (i < len1) {
+ merged.push(first[i].copy());
+ ++i;
+ }
+ while (j < len2) {
+ merged.push(second[j].copy());
+ ++j;
+ }
+ return merged;
+ }
+})(tsu || (tsu = {}));
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014, Nucleic Development Team.
+|
+| Distributed under the terms of the Modified BSD License.
+|
+| The full license is in the file COPYING.txt, distributed with this software.
+|----------------------------------------------------------------------------*/
+///
+///
+///
+///
+///
+///
+
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014, Nucleic Development Team.
+|
+| Distributed under the terms of the Modified BSD License.
+|
+| The full license is in the file COPYING.txt, distributed with this software.
+|----------------------------------------------------------------------------*/
+//
+//
+/**
+ * Kiwi is an efficient implementation of the Cassowary constraint solving
+ * algorithm, based on the seminal Cassowary paper.
+ * It is *not* a refactoring or port of the original C++ solver, but
+ * has been designed from the ground up to be lightweight and fast.
+ *
+ * **Example**
+ * ```javascript
+ * var kiwi = require('kiwi');
+ *
+ * // Create a solver
+ * var solver = new kiwi.Solver();
+ *
+ * // Create and add some editable variables
+ * var left = new kiwi.Variable();
+ * var width = new kiwi.Variable();
+ * solver.addEditVariable(left, kiwi.Strength.strong);
+ * solver.addEditVariable(width, kiwi.Strength.strong);
+ *
+ * // Create a variable calculated through a constraint
+ * var centerX = new kiwi.Variable();
+ * var expr = new kiwi.Expression([-1, centerX], left, [0.5, width]);
+ * solver.addConstraint(new kiwi.Constraint(expr, kiwi.Operator.Eq, kiwi.Strength.required));
+ *
+ * // Suggest some values to the solver
+ * solver.suggestValue(left, 0);
+ * solver.suggestValue(width, 500);
+ *
+ * // Lets solve the problem!
+ * solver.updateVariables();
+ * assert(centerX.value(), 250);
+ * ```
+ *
+ * ##API Documentation
+ * @module kiwi
+ */
+var kiwi;
+(function (kiwi) {
+ /**
+ * An enum defining the linear constraint operators.
+ *
+ * |Value|Operator|Description|
+ * |----|-----|-----|
+ * |`Le`|<=|Less than equal|
+ * |`Ge`|>=|Greater than equal|
+ * |`Eq`|==|Equal|
+ *
+ * @enum {Number}
+ */
+ (function (Operator) {
+ Operator[Operator["Le"] = 0] = "Le";
+ Operator[Operator["Ge"] = 1] = "Ge";
+ Operator[Operator["Eq"] = 2] = "Eq"; // ==
+ })(kiwi.Operator || (kiwi.Operator = {}));
+ var Operator = kiwi.Operator;
+ /**
+ * A linear constraint equation.
+ *
+ * A constraint equation is composed of an expression, an operator,
+ * and a strength. The RHS of the equation is implicitly zero.
+ *
+ * @class
+ * @param {Expression} expression The constraint expression (LHS).
+ * @param {Operator} operator The equation operator.
+ * @param {Expression} [rhs] Right hand side of the expression.
+ * @param {Number} [strength=Strength.required] The strength of the constraint.
+ */
+ var Constraint = (function () {
+ function Constraint(expression, operator, rhs, strength) {
+ if (strength === void 0) { strength = kiwi.Strength.required; }
+ this._id = CnId++;
+ this._operator = operator;
+ this._strength = kiwi.Strength.clip(strength);
+ if ((rhs === undefined) && (expression instanceof kiwi.Expression)) {
+ this._expression = expression;
+ }
+ else {
+ this._expression = expression.minus(rhs);
+ }
+ }
+ /**
+ * A static constraint comparison function.
+ * @private
+ */
+ Constraint.Compare = function (a, b) {
+ return a.id() - b.id();
+ };
+ /**
+ * Returns the unique id number of the constraint.
+ * @private
+ */
+ Constraint.prototype.id = function () {
+ return this._id;
+ };
+ /**
+ * Returns the expression of the constraint.
+ *
+ * @return {Expression} expression
+ */
+ Constraint.prototype.expression = function () {
+ return this._expression;
+ };
+ /**
+ * Returns the relational operator of the constraint.
+ *
+ * @return {Operator} linear constraint operator
+ */
+ Constraint.prototype.op = function () {
+ return this._operator;
+ };
+ /**
+ * Returns the strength of the constraint.
+ *
+ * @return {Number} strength
+ */
+ Constraint.prototype.strength = function () {
+ return this._strength;
+ };
+ return Constraint;
+ })();
+ kiwi.Constraint = Constraint;
+ /**
+ * The internal constraint id counter.
+ * @private
+ */
+ var CnId = 0;
+})(kiwi || (kiwi = {}));
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014, Nucleic Development Team.
+|
+| Distributed under the terms of the Modified BSD License.
+|
+| The full license is in the file COPYING.txt, distributed with this software.
+|----------------------------------------------------------------------------*/
+///
+var kiwi;
+(function (kiwi) {
+ function createMap(compare) {
+ return new tsu.AssociativeArray(compare);
+ }
+ kiwi.createMap = createMap;
+})(kiwi || (kiwi = {}));
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014, Nucleic Development Team.
+|
+| Distributed under the terms of the Modified BSD License.
+|
+| The full license is in the file COPYING.txt, distributed with this software.
+|----------------------------------------------------------------------------*/
+var kiwi;
+(function (kiwi) {
+ /**
+ * The primary user constraint variable.
+ *
+ * @class
+ * @param {String} [name=""] The name to associated with the variable.
+ */
+ var Variable = (function () {
+ function Variable(name) {
+ if (name === void 0) { name = ""; }
+ this._value = 0.0;
+ this._context = null;
+ this._id = VarId++;
+ this._name = name;
+ }
+ /**
+ * A static variable comparison function.
+ * @private
+ */
+ Variable.Compare = function (a, b) {
+ return a.id() - b.id();
+ };
+ /**
+ * Returns the unique id number of the variable.
+ * @private
+ */
+ Variable.prototype.id = function () {
+ return this._id;
+ };
+ /**
+ * Returns the name of the variable.
+ *
+ * @return {String} name of the variable
+ */
+ Variable.prototype.name = function () {
+ return this._name;
+ };
+ /**
+ * Set the name of the variable.
+ *
+ * @param {String} name Name of the variable
+ */
+ Variable.prototype.setName = function (name) {
+ this._name = name;
+ };
+ /**
+ * Returns the user context object of the variable.
+ * @private
+ */
+ Variable.prototype.context = function () {
+ return this._context;
+ };
+ /**
+ * Set the user context object of the variable.
+ * @private
+ */
+ Variable.prototype.setContext = function (context) {
+ this._context = context;
+ };
+ /**
+ * Returns the value of the variable.
+ *
+ * @return {Number} Calculated value
+ */
+ Variable.prototype.value = function () {
+ return this._value;
+ };
+ /**
+ * Set the value of the variable.
+ * @private
+ */
+ Variable.prototype.setValue = function (value) {
+ this._value = value;
+ };
+ /**
+ * Creates a new Expression by adding a number, variable or expression
+ * to the variable.
+ *
+ * @param {Number|Variable|Expression} value Value to add.
+ * @return {Expression} expression
+ */
+ Variable.prototype.plus = function (value) {
+ return new kiwi.Expression(this, value);
+ };
+ /**
+ * Creates a new Expression by substracting a number, variable or expression
+ * from the variable.
+ *
+ * @param {Number|Variable|Expression} value Value to substract.
+ * @return {Expression} expression
+ */
+ Variable.prototype.minus = function (value) {
+ return new kiwi.Expression(this, typeof value === 'number' ? -value : [-1, value]);
+ };
+ /**
+ * Creates a new Expression by multiplying with a fixed number.
+ *
+ * @param {Number} coefficient Coefficient to multiply with.
+ * @return {Expression} expression
+ */
+ Variable.prototype.multiply = function (coefficient) {
+ return new kiwi.Expression([coefficient, this]);
+ };
+ /**
+ * Creates a new Expression by dividing with a fixed number.
+ *
+ * @param {Number} coefficient Coefficient to divide by.
+ * @return {Expression} expression
+ */
+ Variable.prototype.divide = function (coefficient) {
+ return new kiwi.Expression([1 / coefficient, this]);
+ };
+ /**
+ * Returns the JSON representation of the variable.
+ * @private
+ */
+ Variable.prototype.toJSON = function () {
+ return {
+ name: this._name,
+ value: this._value
+ };
+ };
+ return Variable;
+ })();
+ kiwi.Variable = Variable;
+ /**
+ * The internal variable id counter.
+ * @private
+ */
+ var VarId = 0;
+})(kiwi || (kiwi = {}));
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014, Nucleic Development Team.
+|
+| Distributed under the terms of the Modified BSD License.
+|
+| The full license is in the file COPYING.txt, distributed with this software.
+|----------------------------------------------------------------------------*/
+///
+///
+///
+var kiwi;
+(function (kiwi) {
+ /**
+ * An expression of variable terms and a constant.
+ *
+ * The constructor accepts an arbitrary number of parameters,
+ * each of which must be one of the following types:
+ * - number
+ * - Variable
+ * - Expression
+ * - 2-tuple of [number, Variable|Expression]
+ *
+ * The parameters are summed. The tuples are multiplied.
+ *
+ * @class
+ * @param {...(number|Variable|Expression|Array)} args
+ */
+ var Expression = (function () {
+ function Expression() {
+ var parsed = parseArgs(arguments);
+ this._terms = parsed.terms;
+ this._constant = parsed.constant;
+ }
+ /**
+ * Returns the mapping of terms in the expression.
+ *
+ * This *must* be treated as const.
+ * @private
+ */
+ Expression.prototype.terms = function () {
+ return this._terms;
+ };
+ /**
+ * Returns the constant of the expression.
+ * @private
+ */
+ Expression.prototype.constant = function () {
+ return this._constant;
+ };
+ /**
+ * Returns the computed value of the expression.
+ *
+ * @private
+ * @return {Number} computed value of the expression
+ */
+ Expression.prototype.value = function () {
+ var result = this._constant;
+ for (var i = 0, n = this._terms.size(); i < n; i++) {
+ var pair = this._terms.itemAt(i);
+ result += pair.first.value() * pair.second;
+ }
+ return result;
+ };
+ /**
+ * Creates a new Expression by adding a number, variable or expression
+ * to the expression.
+ *
+ * @param {Number|Variable|Expression} value Value to add.
+ * @return {Expression} expression
+ */
+ Expression.prototype.plus = function (value) {
+ return new Expression(this, value);
+ };
+ /**
+ * Creates a new Expression by substracting a number, variable or expression
+ * from the expression.
+ *
+ * @param {Number|Variable|Expression} value Value to substract.
+ * @return {Expression} expression
+ */
+ Expression.prototype.minus = function (value) {
+ return new Expression(this, typeof value === 'number' ? -value : [-1, value]);
+ };
+ /**
+ * Creates a new Expression by multiplying with a fixed number.
+ *
+ * @param {Number} coefficient Coefficient to multiply with.
+ * @return {Expression} expression
+ */
+ Expression.prototype.multiply = function (coefficient) {
+ return new Expression([coefficient, this]);
+ };
+ /**
+ * Creates a new Expression by dividing with a fixed number.
+ *
+ * @param {Number} coefficient Coefficient to divide by.
+ * @return {Expression} expression
+ */
+ Expression.prototype.divide = function (coefficient) {
+ return new Expression([1 / coefficient, this]);
+ };
+ return Expression;
+ })();
+ kiwi.Expression = Expression;
+ /**
+ * An internal argument parsing function.
+ * @private
+ */
+ function parseArgs(args) {
+ var constant = 0.0;
+ var factory = function () { return 0.0; };
+ var terms = kiwi.createMap(kiwi.Variable.Compare);
+ for (var i = 0, n = args.length; i < n; ++i) {
+ var item = args[i];
+ if (typeof item === "number") {
+ constant += item;
+ }
+ else if (item instanceof kiwi.Variable) {
+ terms.setDefault(item, factory).second += 1.0;
+ }
+ else if (item instanceof Expression) {
+ constant += item.constant();
+ var terms2 = item.terms();
+ for (var j = 0, k = terms2.size(); j < k; j++) {
+ var termPair = terms2.itemAt(j);
+ terms.setDefault(termPair.first, factory).second += termPair.second;
+ }
+ }
+ else if (item instanceof Array) {
+ if (item.length !== 2) {
+ throw new Error("array must have length 2");
+ }
+ var value = item[0];
+ var value2 = item[1];
+ if (typeof value !== "number") {
+ throw new Error("array item 0 must be a number");
+ }
+ if (value2 instanceof kiwi.Variable) {
+ terms.setDefault(value2, factory).second += value;
+ }
+ else if (value2 instanceof Expression) {
+ constant += (value2.constant() * value);
+ var terms2 = value2.terms();
+ for (var j = 0, k = terms2.size(); j < k; j++) {
+ var termPair = terms2.itemAt(j);
+ terms.setDefault(termPair.first, factory).second += (termPair.second * value);
+ }
+ }
+ else {
+ throw new Error("array item 1 must be a variable or expression");
+ }
+ }
+ else {
+ throw new Error("invalid Expression argument: " + item);
+ }
+ }
+ return { terms: terms, constant: constant };
+ }
+})(kiwi || (kiwi = {}));
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014, Nucleic Development Team.
+|
+| Distributed under the terms of the Modified BSD License.
+|
+| The full license is in the file COPYING.txt, distributed with this software.
+|----------------------------------------------------------------------------*/
+var kiwi;
+(function (kiwi) {
+ /**
+ * @class Strength
+ */
+ var Strength;
+ (function (Strength) {
+ /**
+ * Create a new symbolic strength.
+ *
+ * @param {Number} a strong
+ * @param {Number} b medium
+ * @param {Number} c weak
+ * @param {Number} [w] weight
+ * @return {Number} strength
+ */
+ function create(a, b, c, w) {
+ if (w === void 0) { w = 1.0; }
+ var result = 0.0;
+ result += Math.max(0.0, Math.min(1000.0, a * w)) * 1000000.0;
+ result += Math.max(0.0, Math.min(1000.0, b * w)) * 1000.0;
+ result += Math.max(0.0, Math.min(1000.0, c * w));
+ return result;
+ }
+ Strength.create = create;
+ /**
+ * The 'required' symbolic strength.
+ */
+ Strength.required = create(1000.0, 1000.0, 1000.0);
+ /**
+ * The 'strong' symbolic strength.
+ */
+ Strength.strong = create(1.0, 0.0, 0.0);
+ /**
+ * The 'medium' symbolic strength.
+ */
+ Strength.medium = create(0.0, 1.0, 0.0);
+ /**
+ * The 'weak' symbolic strength.
+ */
+ Strength.weak = create(0.0, 0.0, 1.0);
+ /**
+ * Clip a symbolic strength to the allowed min and max.
+ * @private
+ */
+ function clip(value) {
+ return Math.max(0.0, Math.min(Strength.required, value));
+ }
+ Strength.clip = clip;
+ })(Strength = kiwi.Strength || (kiwi.Strength = {}));
+})(kiwi || (kiwi = {}));
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014, Nucleic Development Team.
+|
+| Distributed under the terms of the Modified BSD License.
+|
+| The full license is in the file COPYING.txt, distributed with this software.
+|----------------------------------------------------------------------------*/
+///
+///
+///
+///
+///
+///
+var kiwi;
+(function (kiwi) {
+ /**
+ * The constraint solver class.
+ *
+ * @class
+ */
+ var Solver = (function () {
+ /**
+ * Construct a new Solver.
+ */
+ function Solver() {
+ this._cnMap = createCnMap();
+ this._rowMap = createRowMap();
+ this._varMap = createVarMap();
+ this._editMap = createEditMap();
+ this._infeasibleRows = [];
+ this._objective = new Row();
+ this._artificial = null;
+ this._idTick = 0;
+ }
+ /**
+ * Creates and add a constraint to the solver.
+ *
+ * @param {Expression|Variable} lhs Left hand side of the expression
+ * @param {Operator} operator Operator
+ * @param {Expression|Variable|Number} rhs Right hand side of the expression
+ * @param {Number} [strength=Strength.required] Strength
+ */
+ Solver.prototype.createConstraint = function (lhs, operator, rhs, strength) {
+ if (strength === void 0) { strength = kiwi.Strength.required; }
+ var cn = new kiwi.Constraint(lhs, operator, rhs, strength);
+ this.addConstraint(cn);
+ return cn;
+ };
+ /**
+ * Add a constraint to the solver.
+ *
+ * @param {Constraint} constraint Constraint to add to the solver
+ */
+ Solver.prototype.addConstraint = function (constraint) {
+ var cnPair = this._cnMap.find(constraint);
+ if (cnPair !== undefined) {
+ throw new Error("duplicate constraint");
+ }
+ // Creating a row causes symbols to be reserved for the variables
+ // in the constraint. If this method exits with an exception,
+ // then its possible those variables will linger in the var map.
+ // Since its likely that those variables will be used in other
+ // constraints and since exceptional conditions are uncommon,
+ // i'm not too worried about aggressive cleanup of the var map.
+ var data = this._createRow(constraint);
+ var row = data.row;
+ var tag = data.tag;
+ var subject = this._chooseSubject(row, tag);
+ // If chooseSubject couldnt find a valid entering symbol, one
+ // last option is available if the entire row is composed of
+ // dummy variables. If the constant of the row is zero, then
+ // this represents redundant constraints and the new dummy
+ // marker can enter the basis. If the constant is non-zero,
+ // then it represents an unsatisfiable constraint.
+ if (subject.type() === 0 /* Invalid */ && row.allDummies()) {
+ if (!nearZero(row.constant())) {
+ throw new Error("unsatisfiable constraint");
+ }
+ else {
+ subject = tag.marker;
+ }
+ }
+ // If an entering symbol still isn't found, then the row must
+ // be added using an artificial variable. If that fails, then
+ // the row represents an unsatisfiable constraint.
+ if (subject.type() === 0 /* Invalid */) {
+ if (!this._addWithArtificialVariable(row)) {
+ throw new Error("unsatisfiable constraint");
+ }
+ }
+ else {
+ row.solveFor(subject);
+ this._substitute(subject, row);
+ this._rowMap.insert(subject, row);
+ }
+ this._cnMap.insert(constraint, tag);
+ // Optimizing after each constraint is added performs less
+ // aggregate work due to a smaller average system size. It
+ // also ensures the solver remains in a consistent state.
+ this._optimize(this._objective);
+ };
+ /**
+ * Remove a constraint from the solver.
+ *
+ * @param {Constraint} constraint Constraint to remove from the solver
+ */
+ Solver.prototype.removeConstraint = function (constraint) {
+ var cnPair = this._cnMap.erase(constraint);
+ if (cnPair === undefined) {
+ throw new Error("unknown constraint");
+ }
+ // Remove the error effects from the objective function
+ // *before* pivoting, or substitutions into the objective
+ // will lead to incorrect solver results.
+ this._removeConstraintEffects(constraint, cnPair.second);
+ // If the marker is basic, simply drop the row. Otherwise,
+ // pivot the marker into the basis and then drop the row.
+ var marker = cnPair.second.marker;
+ var rowPair = this._rowMap.erase(marker);
+ if (rowPair === undefined) {
+ var leaving = this._getMarkerLeavingSymbol(marker);
+ if (leaving.type() === 0 /* Invalid */) {
+ throw new Error("failed to find leaving row");
+ }
+ rowPair = this._rowMap.erase(leaving);
+ rowPair.second.solveForEx(leaving, marker);
+ this._substitute(marker, rowPair.second);
+ }
+ // Optimizing after each constraint is removed ensures that the
+ // solver remains consistent. It makes the solver api easier to
+ // use at a small tradeoff for speed.
+ this._optimize(this._objective);
+ };
+ /**
+ * Test whether the solver contains the constraint.
+ *
+ * @param {Constraint} constraint Constraint to test for
+ * @return {Bool} true or false
+ */
+ Solver.prototype.hasConstraint = function (constraint) {
+ return this._cnMap.contains(constraint);
+ };
+ /**
+ * Add an edit variable to the solver.
+ *
+ * @param {Variable} variable Edit variable to add to the solver
+ * @param {Number} strength Strength, should be less than `Strength.required`
+ */
+ Solver.prototype.addEditVariable = function (variable, strength) {
+ var editPair = this._editMap.find(variable);
+ if (editPair !== undefined) {
+ throw new Error("duplicate edit variable");
+ }
+ strength = kiwi.Strength.clip(strength);
+ if (strength === kiwi.Strength.required) {
+ throw new Error("bad required strength");
+ }
+ var expr = new kiwi.Expression(variable);
+ var cn = new kiwi.Constraint(expr, 2 /* Eq */, undefined, strength);
+ this.addConstraint(cn);
+ var tag = this._cnMap.find(cn).second;
+ var info = { tag: tag, constraint: cn, constant: 0.0 };
+ this._editMap.insert(variable, info);
+ };
+ /**
+ * Remove an edit variable from the solver.
+ *
+ * @param {Variable} variable Edit variable to remove from the solver
+ */
+ Solver.prototype.removeEditVariable = function (variable) {
+ var editPair = this._editMap.erase(variable);
+ if (editPair === undefined) {
+ throw new Error("unknown edit variable");
+ }
+ this.removeConstraint(editPair.second.constraint);
+ };
+ /**
+ * Test whether the solver contains the edit variable.
+ *
+ * @param {Variable} variable Edit variable to test for
+ * @return {Bool} true or false
+ */
+ Solver.prototype.hasEditVariable = function (variable) {
+ return this._editMap.contains(variable);
+ };
+ /**
+ * Suggest the value of an edit variable.
+ *
+ * @param {Variable} variable Edit variable to suggest a value for
+ * @param {Number} value Suggested value
+ */
+ Solver.prototype.suggestValue = function (variable, value) {
+ var editPair = this._editMap.find(variable);
+ if (editPair === undefined) {
+ throw new Error("unknown edit variable");
+ }
+ var rows = this._rowMap;
+ var info = editPair.second;
+ var delta = value - info.constant;
+ info.constant = value;
+ // Check first if the positive error variable is basic.
+ var marker = info.tag.marker;
+ var rowPair = rows.find(marker);
+ if (rowPair !== undefined) {
+ if (rowPair.second.add(-delta) < 0.0) {
+ this._infeasibleRows.push(marker);
+ }
+ this._dualOptimize();
+ return;
+ }
+ // Check next if the negative error variable is basic.
+ var other = info.tag.other;
+ var rowPair = rows.find(other);
+ if (rowPair !== undefined) {
+ if (rowPair.second.add(delta) < 0.0) {
+ this._infeasibleRows.push(other);
+ }
+ this._dualOptimize();
+ return;
+ }
+ for (var i = 0, n = rows.size(); i < n; ++i) {
+ var rowPair = rows.itemAt(i);
+ var row = rowPair.second;
+ var coeff = row.coefficientFor(marker);
+ if (coeff !== 0.0 && row.add(delta * coeff) < 0.0 && rowPair.first.type() !== 1 /* External */) {
+ this._infeasibleRows.push(rowPair.first);
+ }
+ }
+ this._dualOptimize();
+ };
+ /**
+ * Update the values of the variables.
+ */
+ Solver.prototype.updateVariables = function () {
+ var vars = this._varMap;
+ var rows = this._rowMap;
+ for (var i = 0, n = vars.size(); i < n; ++i) {
+ var pair = vars.itemAt(i);
+ var rowPair = rows.find(pair.second);
+ if (rowPair !== undefined) {
+ pair.first.setValue(rowPair.second.constant());
+ }
+ else {
+ pair.first.setValue(0.0);
+ }
+ }
+ };
+ /**
+ * Get the symbol for the given variable.
+ *
+ * If a symbol does not exist for the variable, one will be created.
+ * @private
+ */
+ Solver.prototype._getVarSymbol = function (variable) {
+ var _this = this;
+ var factory = function () { return _this._makeSymbol(1 /* External */); };
+ return this._varMap.setDefault(variable, factory).second;
+ };
+ /**
+ * Create a new Row object for the given constraint.
+ *
+ * The terms in the constraint will be converted to cells in the row.
+ * Any term in the constraint with a coefficient of zero is ignored.
+ * This method uses the `_getVarSymbol` method to get the symbol for
+ * the variables added to the row. If the symbol for a given cell
+ * variable is basic, the cell variable will be substituted with the
+ * basic row.
+ *
+ * The necessary slack and error variables will be added to the row.
+ * If the constant for the row is negative, the sign for the row
+ * will be inverted so the constant becomes positive.
+ *
+ * Returns the created Row and the tag for tracking the constraint.
+ * @private
+ */
+ Solver.prototype._createRow = function (constraint) {
+ var expr = constraint.expression();
+ var row = new Row(expr.constant());
+ // Substitute the current basic variables into the row.
+ var terms = expr.terms();
+ for (var i = 0, n = terms.size(); i < n; ++i) {
+ var termPair = terms.itemAt(i);
+ if (!nearZero(termPair.second)) {
+ var symbol = this._getVarSymbol(termPair.first);
+ var basicPair = this._rowMap.find(symbol);
+ if (basicPair !== undefined) {
+ row.insertRow(basicPair.second, termPair.second);
+ }
+ else {
+ row.insertSymbol(symbol, termPair.second);
+ }
+ }
+ }
+ // Add the necessary slack, error, and dummy variables.
+ var objective = this._objective;
+ var strength = constraint.strength();
+ var tag = { marker: INVALID_SYMBOL, other: INVALID_SYMBOL };
+ switch (constraint.op()) {
+ case 0 /* Le */:
+ case 1 /* Ge */:
+ {
+ var coeff = constraint.op() === 0 /* Le */ ? 1.0 : -1.0;
+ var slack = this._makeSymbol(2 /* Slack */);
+ tag.marker = slack;
+ row.insertSymbol(slack, coeff);
+ if (strength < kiwi.Strength.required) {
+ var error = this._makeSymbol(3 /* Error */);
+ tag.other = error;
+ row.insertSymbol(error, -coeff);
+ objective.insertSymbol(error, strength);
+ }
+ break;
+ }
+ case 2 /* Eq */:
+ {
+ if (strength < kiwi.Strength.required) {
+ var errplus = this._makeSymbol(3 /* Error */);
+ var errminus = this._makeSymbol(3 /* Error */);
+ tag.marker = errplus;
+ tag.other = errminus;
+ row.insertSymbol(errplus, -1.0); // v = eplus - eminus
+ row.insertSymbol(errminus, 1.0); // v - eplus + eminus = 0
+ objective.insertSymbol(errplus, strength);
+ objective.insertSymbol(errminus, strength);
+ }
+ else {
+ var dummy = this._makeSymbol(4 /* Dummy */);
+ tag.marker = dummy;
+ row.insertSymbol(dummy);
+ }
+ break;
+ }
+ }
+ // Ensure the row has a positive constant.
+ if (row.constant() < 0.0) {
+ row.reverseSign();
+ }
+ return { row: row, tag: tag };
+ };
+ /**
+ * Choose the subject for solving for the row.
+ *
+ * This method will choose the best subject for using as the solve
+ * target for the row. An invalid symbol will be returned if there
+ * is no valid target.
+ *
+ * The symbols are chosen according to the following precedence:
+ *
+ * 1) The first symbol representing an external variable.
+ * 2) A negative slack or error tag variable.
+ *
+ * If a subject cannot be found, an invalid symbol will be returned.
+ *
+ * @private
+ */
+ Solver.prototype._chooseSubject = function (row, tag) {
+ var cells = row.cells();
+ for (var i = 0, n = cells.size(); i < n; ++i) {
+ var pair = cells.itemAt(i);
+ if (pair.first.type() === 1 /* External */) {
+ return pair.first;
+ }
+ }
+ var type = tag.marker.type();
+ if (type === 2 /* Slack */ || type === 3 /* Error */) {
+ if (row.coefficientFor(tag.marker) < 0.0) {
+ return tag.marker;
+ }
+ }
+ type = tag.other.type();
+ if (type === 2 /* Slack */ || type === 3 /* Error */) {
+ if (row.coefficientFor(tag.other) < 0.0) {
+ return tag.other;
+ }
+ }
+ return INVALID_SYMBOL;
+ };
+ /**
+ * Add the row to the tableau using an artificial variable.
+ *
+ * This will return false if the constraint cannot be satisfied.
+ *
+ * @private
+ */
+ Solver.prototype._addWithArtificialVariable = function (row) {
+ // Create and add the artificial variable to the tableau.
+ var art = this._makeSymbol(2 /* Slack */);
+ this._rowMap.insert(art, row.copy());
+ this._artificial = row.copy();
+ // Optimize the artificial objective. This is successful
+ // only if the artificial objective is optimized to zero.
+ this._optimize(this._artificial);
+ var success = nearZero(this._artificial.constant());
+ this._artificial = null;
+ // If the artificial variable is basic, pivot the row so that
+ // it becomes non-basic. If the row is constant, exit early.
+ var pair = this._rowMap.erase(art);
+ if (pair !== undefined) {
+ var basicRow = pair.second;
+ if (basicRow.isConstant()) {
+ return success;
+ }
+ var entering = this._anyPivotableSymbol(basicRow);
+ if (entering.type() === 0 /* Invalid */) {
+ return false; // unsatisfiable (will this ever happen?)
+ }
+ basicRow.solveForEx(art, entering);
+ this._substitute(entering, basicRow);
+ this._rowMap.insert(entering, basicRow);
+ }
+ // Remove the artificial variable from the tableau.
+ var rows = this._rowMap;
+ for (var i = 0, n = rows.size(); i < n; ++i) {
+ rows.itemAt(i).second.removeSymbol(art);
+ }
+ this._objective.removeSymbol(art);
+ return success;
+ };
+ /**
+ * Substitute the parametric symbol with the given row.
+ *
+ * This method will substitute all instances of the parametric symbol
+ * in the tableau and the objective function with the given row.
+ *
+ * @private
+ */
+ Solver.prototype._substitute = function (symbol, row) {
+ var rows = this._rowMap;
+ for (var i = 0, n = rows.size(); i < n; ++i) {
+ var pair = rows.itemAt(i);
+ pair.second.substitute(symbol, row);
+ if (pair.second.constant() < 0.0 && pair.first.type() !== 1 /* External */) {
+ this._infeasibleRows.push(pair.first);
+ }
+ }
+ this._objective.substitute(symbol, row);
+ if (this._artificial) {
+ this._artificial.substitute(symbol, row);
+ }
+ };
+ /**
+ * Optimize the system for the given objective function.
+ *
+ * This method performs iterations of Phase 2 of the simplex method
+ * until the objective function reaches a minimum.
+ *
+ * @private
+ */
+ Solver.prototype._optimize = function (objective) {
+ while (true) {
+ var entering = this._getEnteringSymbol(objective);
+ if (entering.type() === 0 /* Invalid */) {
+ return;
+ }
+ var leaving = this._getLeavingSymbol(entering);
+ if (leaving.type() === 0 /* Invalid */) {
+ throw new Error("the objective is unbounded");
+ }
+ // pivot the entering symbol into the basis
+ var row = this._rowMap.erase(leaving).second;
+ row.solveForEx(leaving, entering);
+ this._substitute(entering, row);
+ this._rowMap.insert(entering, row);
+ }
+ };
+ /**
+ * Optimize the system using the dual of the simplex method.
+ *
+ * The current state of the system should be such that the objective
+ * function is optimal, but not feasible. This method will perform
+ * an iteration of the dual simplex method to make the solution both
+ * optimal and feasible.
+ *
+ * @private
+ */
+ Solver.prototype._dualOptimize = function () {
+ var rows = this._rowMap;
+ var infeasible = this._infeasibleRows;
+ while (infeasible.length !== 0) {
+ var leaving = infeasible.pop();
+ var pair = rows.find(leaving);
+ if (pair !== undefined && pair.second.constant() < 0.0) {
+ var entering = this._getDualEnteringSymbol(pair.second);
+ if (entering.type() === 0 /* Invalid */) {
+ throw new Error("dual optimize failed");
+ }
+ // pivot the entering symbol into the basis
+ var row = pair.second;
+ rows.erase(leaving);
+ row.solveForEx(leaving, entering);
+ this._substitute(entering, row);
+ rows.insert(entering, row);
+ }
+ }
+ };
+ /**
+ * Compute the entering variable for a pivot operation.
+ *
+ * This method will return first symbol in the objective function which
+ * is non-dummy and has a coefficient less than zero. If no symbol meets
+ * the criteria, it means the objective function is at a minimum, and an
+ * invalid symbol is returned.
+ *
+ * @private
+ */
+ Solver.prototype._getEnteringSymbol = function (objective) {
+ var cells = objective.cells();
+ for (var i = 0, n = cells.size(); i < n; ++i) {
+ var pair = cells.itemAt(i);
+ var symbol = pair.first;
+ if (pair.second < 0.0 && symbol.type() !== 4 /* Dummy */) {
+ return symbol;
+ }
+ }
+ return INVALID_SYMBOL;
+ };
+ /**
+ * Compute the entering symbol for the dual optimize operation.
+ *
+ * This method will return the symbol in the row which has a positive
+ * coefficient and yields the minimum ratio for its respective symbol
+ * in the objective function. The provided row *must* be infeasible.
+ * If no symbol is found which meats the criteria, an invalid symbol
+ * is returned.
+ *
+ * @private
+ */
+ Solver.prototype._getDualEnteringSymbol = function (row) {
+ var ratio = Number.MAX_VALUE;
+ var entering = INVALID_SYMBOL;
+ var cells = row.cells();
+ for (var i = 0, n = cells.size(); i < n; ++i) {
+ var pair = cells.itemAt(i);
+ var symbol = pair.first;
+ var c = pair.second;
+ if (c > 0.0 && symbol.type() !== 4 /* Dummy */) {
+ var coeff = this._objective.coefficientFor(symbol);
+ var r = coeff / c;
+ if (r < ratio) {
+ ratio = r;
+ entering = symbol;
+ }
+ }
+ }
+ return entering;
+ };
+ /**
+ * Compute the symbol for pivot exit row.
+ *
+ * This method will return the symbol for the exit row in the row
+ * map. If no appropriate exit symbol is found, an invalid symbol
+ * will be returned. This indicates that the objective function is
+ * unbounded.
+ *
+ * @private
+ */
+ Solver.prototype._getLeavingSymbol = function (entering) {
+ var ratio = Number.MAX_VALUE;
+ var found = INVALID_SYMBOL;
+ var rows = this._rowMap;
+ for (var i = 0, n = rows.size(); i < n; ++i) {
+ var pair = rows.itemAt(i);
+ var symbol = pair.first;
+ if (symbol.type() !== 1 /* External */) {
+ var row = pair.second;
+ var temp = row.coefficientFor(entering);
+ if (temp < 0.0) {
+ var temp_ratio = -row.constant() / temp;
+ if (temp_ratio < ratio) {
+ ratio = temp_ratio;
+ found = symbol;
+ }
+ }
+ }
+ }
+ return found;
+ };
+ /**
+ * Compute the leaving symbol for a marker variable.
+ *
+ * This method will return a symbol corresponding to a basic row
+ * which holds the given marker variable. The row will be chosen
+ * according to the following precedence:
+ *
+ * 1) The row with a restricted basic varible and a negative coefficient
+ * for the marker with the smallest ratio of -constant / coefficient.
+ *
+ * 2) The row with a restricted basic variable and the smallest ratio
+ * of constant / coefficient.
+ *
+ * 3) The last unrestricted row which contains the marker.
+ *
+ * If the marker does not exist in any row, an invalid symbol will be
+ * returned. This indicates an internal solver error since the marker
+ * *should* exist somewhere in the tableau.
+ *
+ * @private
+ */
+ Solver.prototype._getMarkerLeavingSymbol = function (marker) {
+ var dmax = Number.MAX_VALUE;
+ var r1 = dmax;
+ var r2 = dmax;
+ var invalid = INVALID_SYMBOL;
+ var first = invalid;
+ var second = invalid;
+ var third = invalid;
+ var rows = this._rowMap;
+ for (var i = 0, n = rows.size(); i < n; ++i) {
+ var pair = rows.itemAt(i);
+ var row = pair.second;
+ var c = row.coefficientFor(marker);
+ if (c === 0.0) {
+ continue;
+ }
+ var symbol = pair.first;
+ if (symbol.type() === 1 /* External */) {
+ third = symbol;
+ }
+ else if (c < 0.0) {
+ var r = -row.constant() / c;
+ if (r < r1) {
+ r1 = r;
+ first = symbol;
+ }
+ }
+ else {
+ var r = row.constant() / c;
+ if (r < r2) {
+ r2 = r;
+ second = symbol;
+ }
+ }
+ }
+ if (first !== invalid) {
+ return first;
+ }
+ if (second !== invalid) {
+ return second;
+ }
+ return third;
+ };
+ /**
+ * Remove the effects of a constraint on the objective function.
+ *
+ * @private
+ */
+ Solver.prototype._removeConstraintEffects = function (cn, tag) {
+ if (tag.marker.type() === 3 /* Error */) {
+ this._removeMarkerEffects(tag.marker, cn.strength());
+ }
+ if (tag.other.type() === 3 /* Error */) {
+ this._removeMarkerEffects(tag.other, cn.strength());
+ }
+ };
+ /**
+ * Remove the effects of an error marker on the objective function.
+ *
+ * @private
+ */
+ Solver.prototype._removeMarkerEffects = function (marker, strength) {
+ var pair = this._rowMap.find(marker);
+ if (pair !== undefined) {
+ this._objective.insertRow(pair.second, -strength);
+ }
+ else {
+ this._objective.insertSymbol(marker, -strength);
+ }
+ };
+ /**
+ * Get the first Slack or Error symbol in the row.
+ *
+ * If no such symbol is present, an invalid symbol will be returned.
+ *
+ * @private
+ */
+ Solver.prototype._anyPivotableSymbol = function (row) {
+ var cells = row.cells();
+ for (var i = 0, n = cells.size(); i < n; ++i) {
+ var pair = cells.itemAt(i);
+ var type = pair.first.type();
+ if (type === 2 /* Slack */ || type === 3 /* Error */) {
+ return pair.first;
+ }
+ }
+ return INVALID_SYMBOL;
+ };
+ /**
+ * Returns a new Symbol of the given type.
+ *
+ * @private
+ */
+ Solver.prototype._makeSymbol = function (type) {
+ return new Symbol(type, this._idTick++);
+ };
+ return Solver;
+ })();
+ kiwi.Solver = Solver;
+ /**
+ * Test whether a value is approximately zero.
+ * @private
+ */
+ function nearZero(value) {
+ var eps = 1.0e-8;
+ return value < 0.0 ? -value < eps : value < eps;
+ }
+ /**
+ * An internal function for creating a constraint map.
+ * @private
+ */
+ function createCnMap() {
+ return kiwi.createMap(kiwi.Constraint.Compare);
+ }
+ /**
+ * An internal function for creating a row map.
+ * @private
+ */
+ function createRowMap() {
+ return kiwi.createMap(Symbol.Compare);
+ }
+ /**
+ * An internal function for creating a variable map.
+ * @private
+ */
+ function createVarMap() {
+ return kiwi.createMap(kiwi.Variable.Compare);
+ }
+ /**
+ * An internal function for creating an edit map.
+ * @private
+ */
+ function createEditMap() {
+ return kiwi.createMap(kiwi.Variable.Compare);
+ }
+ /**
+ * An enum defining the available symbol types.
+ * @private
+ */
+ var SymbolType;
+ (function (SymbolType) {
+ SymbolType[SymbolType["Invalid"] = 0] = "Invalid";
+ SymbolType[SymbolType["External"] = 1] = "External";
+ SymbolType[SymbolType["Slack"] = 2] = "Slack";
+ SymbolType[SymbolType["Error"] = 3] = "Error";
+ SymbolType[SymbolType["Dummy"] = 4] = "Dummy";
+ })(SymbolType || (SymbolType = {}));
+ /**
+ * An internal class representing a symbol in the solver.
+ * @private
+ */
+ var Symbol = (function () {
+ /**
+ * Construct a new Symbol
+ *
+ * @param [type] The type of the symbol.
+ * @param [id] The unique id number of the symbol.
+ */
+ function Symbol(type, id) {
+ this._id = id;
+ this._type = type;
+ }
+ /**
+ * The static Symbol comparison function.
+ */
+ Symbol.Compare = function (a, b) {
+ return a.id() - b.id();
+ };
+ /**
+ * Returns the unique id number of the symbol.
+ */
+ Symbol.prototype.id = function () {
+ return this._id;
+ };
+ /**
+ * Returns the type of the symbol.
+ */
+ Symbol.prototype.type = function () {
+ return this._type;
+ };
+ return Symbol;
+ })();
+ /**
+ * A static invalid symbol
+ * @private
+ */
+ var INVALID_SYMBOL = new Symbol(0 /* Invalid */, -1);
+ /**
+ * An internal row class used by the solver.
+ * @private
+ */
+ var Row = (function () {
+ /**
+ * Construct a new Row.
+ */
+ function Row(constant) {
+ if (constant === void 0) { constant = 0.0; }
+ this._cellMap = kiwi.createMap(Symbol.Compare);
+ this._constant = constant;
+ }
+ /**
+ * Returns the mapping of symbols to coefficients.
+ */
+ Row.prototype.cells = function () {
+ return this._cellMap;
+ };
+ /**
+ * Returns the constant for the row.
+ */
+ Row.prototype.constant = function () {
+ return this._constant;
+ };
+ /**
+ * Returns true if the row is a constant value.
+ */
+ Row.prototype.isConstant = function () {
+ return this._cellMap.empty();
+ };
+ /**
+ * Returns true if the Row has all dummy symbols.
+ */
+ Row.prototype.allDummies = function () {
+ var cells = this._cellMap;
+ for (var i = 0, n = cells.size(); i < n; ++i) {
+ var pair = cells.itemAt(i);
+ if (pair.first.type() !== 4 /* Dummy */) {
+ return false;
+ }
+ }
+ return true;
+ };
+ /**
+ * Create a copy of the row.
+ */
+ Row.prototype.copy = function () {
+ var theCopy = new Row(this._constant);
+ theCopy._cellMap = this._cellMap.copy();
+ return theCopy;
+ };
+ /**
+ * Add a constant value to the row constant.
+ *
+ * Returns the new value of the constant.
+ */
+ Row.prototype.add = function (value) {
+ return this._constant += value;
+ };
+ /**
+ * Insert the symbol into the row with the given coefficient.
+ *
+ * If the symbol already exists in the row, the coefficient
+ * will be added to the existing coefficient. If the resulting
+ * coefficient is zero, the symbol will be removed from the row.
+ */
+ Row.prototype.insertSymbol = function (symbol, coefficient) {
+ if (coefficient === void 0) { coefficient = 1.0; }
+ var pair = this._cellMap.setDefault(symbol, function () { return 0.0; });
+ if (nearZero(pair.second += coefficient)) {
+ this._cellMap.erase(symbol);
+ }
+ };
+ /**
+ * Insert a row into this row with a given coefficient.
+ *
+ * The constant and the cells of the other row will be
+ * multiplied by the coefficient and added to this row. Any
+ * cell with a resulting coefficient of zero will be removed
+ * from the row.
+ */
+ Row.prototype.insertRow = function (other, coefficient) {
+ if (coefficient === void 0) { coefficient = 1.0; }
+ this._constant += other._constant * coefficient;
+ var cells = other._cellMap;
+ for (var i = 0, n = cells.size(); i < n; ++i) {
+ var pair = cells.itemAt(i);
+ this.insertSymbol(pair.first, pair.second * coefficient);
+ }
+ };
+ /**
+ * Remove a symbol from the row.
+ */
+ Row.prototype.removeSymbol = function (symbol) {
+ this._cellMap.erase(symbol);
+ };
+ /**
+ * Reverse the sign of the constant and cells in the row.
+ */
+ Row.prototype.reverseSign = function () {
+ this._constant = -this._constant;
+ var cells = this._cellMap;
+ for (var i = 0, n = cells.size(); i < n; ++i) {
+ var pair = cells.itemAt(i);
+ pair.second = -pair.second;
+ }
+ };
+ /**
+ * Solve the row for the given symbol.
+ *
+ * This method assumes the row is of the form
+ * a * x + b * y + c = 0 and (assuming solve for x) will modify
+ * the row to represent the right hand side of
+ * x = -b/a * y - c / a. The target symbol will be removed from
+ * the row, and the constant and other cells will be multiplied
+ * by the negative inverse of the target coefficient.
+ *
+ * The given symbol *must* exist in the row.
+ */
+ Row.prototype.solveFor = function (symbol) {
+ var cells = this._cellMap;
+ var pair = cells.erase(symbol);
+ var coeff = -1.0 / pair.second;
+ this._constant *= coeff;
+ for (var i = 0, n = cells.size(); i < n; ++i) {
+ cells.itemAt(i).second *= coeff;
+ }
+ };
+ /**
+ * Solve the row for the given symbols.
+ *
+ * This method assumes the row is of the form
+ * x = b * y + c and will solve the row such that
+ * y = x / b - c / b. The rhs symbol will be removed from the
+ * row, the lhs added, and the result divided by the negative
+ * inverse of the rhs coefficient.
+ *
+ * The lhs symbol *must not* exist in the row, and the rhs
+ * symbol must* exist in the row.
+ */
+ Row.prototype.solveForEx = function (lhs, rhs) {
+ this.insertSymbol(lhs, -1.0);
+ this.solveFor(rhs);
+ };
+ /**
+ * Returns the coefficient for the given symbol.
+ */
+ Row.prototype.coefficientFor = function (symbol) {
+ var pair = this._cellMap.find(symbol);
+ return pair !== undefined ? pair.second : 0.0;
+ };
+ /**
+ * Substitute a symbol with the data from another row.
+ *
+ * Given a row of the form a * x + b and a substitution of the
+ * form x = 3 * y + c the row will be updated to reflect the
+ * expression 3 * a * y + a * c + b.
+ *
+ * If the symbol does not exist in the row, this is a no-op.
+ */
+ Row.prototype.substitute = function (symbol, row) {
+ var pair = this._cellMap.erase(symbol);
+ if (pair !== undefined) {
+ this.insertRow(row, pair.second);
+ }
+ };
+ return Row;
+ })();
+})(kiwi || (kiwi = {}));
+/*-----------------------------------------------------------------------------
+| Copyright (c) 2014, Nucleic Development Team.
+|
+| Distributed under the terms of the Modified BSD License.
+|
+| The full license is in the file COPYING.txt, distributed with this software.
+|----------------------------------------------------------------------------*/
+///
+///
+///
+///
+///
+///
+
+return kiwi;
+
+}));
+
+},{}],2:[function(require,module,exports){
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+var kiwi = require('kiwi/ts/bin/kiwi');
+
+'use strict';
+
+/**
+ * Layout attributes.
+ * @enum {String}
+ */
+var Attribute = {
+ CONST: 'const',
+ NOTANATTRIBUTE: 'const',
+ VARIABLE: 'var',
+ LEFT: 'left',
+ RIGHT: 'right',
+ TOP: 'top',
+ BOTTOM: 'bottom',
+ WIDTH: 'width',
+ HEIGHT: 'height',
+ CENTERX: 'centerX',
+ CENTERY: 'centerY',
+ /*LEADING: 'leading',
+ TRAILING: 'trailing'*/
+ /** Used by the extended VFL syntax. */
+ ZINDEX: 'zIndex'
+};
+
+/**
+ * Relation types.
+ * @enum {String}
+ */
+var Relation = {
+ /** Less than or equal */
+ LEQ: 'leq',
+ /** Equal */
+ EQU: 'equ',
+ /** Greater than or equal */
+ GEQ: 'geq'
+};
+
+/**
+ * Layout priorities.
+ * @enum {String}
+ */
+var Priority = {
+ REQUIRED: 1000,
+ DEFAULTHIGH: 750,
+ DEFAULTLOW: 250
+ //FITTINGSIZELEVEL: 50,
+};
+
+var parser = (function () {
+ /*
+ * Generated by PEG.js 0.8.0.
+ *
+ * http://pegjs.majda.cz/
+ */
+
+ function peg$subclass(child, parent) {
+ function ctor() {
+ this.constructor = child;
+ }
+ ctor.prototype = parent.prototype;
+ child.prototype = new ctor();
+ }
+
+ function SyntaxError(message, expected, found, offset, line, column) {
+ this.message = message;
+ this.expected = expected;
+ this.found = found;
+ this.offset = offset;
+ this.line = line;
+ this.column = column;
+
+ this.name = 'SyntaxError';
+ }
+
+ peg$subclass(SyntaxError, Error);
+
+ function parse(input) {
+ var options = arguments.length > 1 ? arguments[1] : {},
+ peg$FAILED = {},
+ peg$startRuleFunctions = { visualFormatString: peg$parsevisualFormatString },
+ peg$startRuleFunction = peg$parsevisualFormatString,
+ peg$c0 = peg$FAILED,
+ peg$c1 = null,
+ peg$c2 = ':',
+ peg$c3 = { type: 'literal', value: ':', description: '":"' },
+ peg$c4 = [],
+ peg$c5 = function peg$c5(o, superto, view, views, tosuper) {
+ return {
+ orientation: o ? o[0] : 'horizontal',
+ cascade: (superto || []).concat([view], [].concat.apply([], views), tosuper || [])
+ };
+ },
+ peg$c6 = 'H',
+ peg$c7 = { type: 'literal', value: 'H', description: '"H"' },
+ peg$c8 = 'V',
+ peg$c9 = { type: 'literal', value: 'V', description: '"V"' },
+ peg$c10 = function peg$c10(orient) {
+ return orient == 'H' ? 'horizontal' : 'vertical';
+ },
+ peg$c11 = '|',
+ peg$c12 = { type: 'literal', value: '|', description: '"|"' },
+ peg$c13 = function peg$c13() {
+ return { view: null };
+ },
+ peg$c14 = '[',
+ peg$c15 = { type: 'literal', value: '[', description: '"["' },
+ peg$c16 = ']',
+ peg$c17 = { type: 'literal', value: ']', description: '"]"' },
+ peg$c18 = function peg$c18(view, predicates) {
+ return extend(view, predicates ? { constraints: predicates } : {});
+ },
+ peg$c19 = '-',
+ peg$c20 = { type: 'literal', value: '-', description: '"-"' },
+ peg$c21 = function peg$c21(predicateList) {
+ return predicateList;
+ },
+ peg$c22 = function peg$c22() {
+ return [{ relation: 'equ', constant: 'default', $parserOffset: offset() }];
+ },
+ peg$c23 = '',
+ peg$c24 = function peg$c24() {
+ return [{ relation: 'equ', constant: 0, $parserOffset: offset() }];
+ },
+ peg$c25 = function peg$c25(n) {
+ return [{ relation: 'equ', constant: n, $parserOffset: offset() }];
+ },
+ peg$c26 = '(',
+ peg$c27 = { type: 'literal', value: '(', description: '"("' },
+ peg$c28 = ',',
+ peg$c29 = { type: 'literal', value: ',', description: '","' },
+ peg$c30 = ')',
+ peg$c31 = { type: 'literal', value: ')', description: '")"' },
+ peg$c32 = function peg$c32(p, ps) {
+ return [p].concat(ps.map(function (p) {
+ return p[1];
+ }));
+ },
+ peg$c33 = '@',
+ peg$c34 = { type: 'literal', value: '@', description: '"@"' },
+ peg$c35 = function peg$c35(r, o, p) {
+ return extend({ relation: 'equ' }, r || {}, o, p ? p[1] : {});
+ },
+ peg$c36 = '==',
+ peg$c37 = { type: 'literal', value: '==', description: '"=="' },
+ peg$c38 = function peg$c38() {
+ return { relation: 'equ', $parserOffset: offset() };
+ },
+ peg$c39 = '<=',
+ peg$c40 = { type: 'literal', value: '<=', description: '"<="' },
+ peg$c41 = function peg$c41() {
+ return { relation: 'leq', $parserOffset: offset() };
+ },
+ peg$c42 = '>=',
+ peg$c43 = { type: 'literal', value: '>=', description: '">="' },
+ peg$c44 = function peg$c44() {
+ return { relation: 'geq', $parserOffset: offset() };
+ },
+ peg$c45 = /^[0-9]/,
+ peg$c46 = { type: 'class', value: '[0-9]', description: '[0-9]' },
+ peg$c47 = function peg$c47(digits) {
+ return { priority: parseInt(digits.join(''), 10) };
+ },
+ peg$c48 = function peg$c48(n) {
+ return { constant: n };
+ },
+ peg$c49 = /^[a-zA-Z_]/,
+ peg$c50 = { type: 'class', value: '[a-zA-Z_]', description: '[a-zA-Z_]' },
+ peg$c51 = /^[a-zA-Z0-9_]/,
+ peg$c52 = { type: 'class', value: '[a-zA-Z0-9_]', description: '[a-zA-Z0-9_]' },
+ peg$c53 = function peg$c53(f, v) {
+ return { view: f + v };
+ },
+ peg$c54 = '.',
+ peg$c55 = { type: 'literal', value: '.', description: '"."' },
+ peg$c56 = function peg$c56(digits, decimals) {
+ return parseFloat(digits.concat('.').concat(decimals).join(''), 10);
+ },
+ peg$c57 = function peg$c57(digits) {
+ return parseInt(digits.join(''), 10);
+ },
+ peg$currPos = 0,
+ peg$reportedPos = 0,
+ peg$cachedPos = 0,
+ peg$cachedPosDetails = { line: 1, column: 1, seenCR: false },
+ peg$maxFailPos = 0,
+ peg$maxFailExpected = [],
+ peg$silentFails = 0,
+ peg$result;
+
+ if ('startRule' in options) {
+ if (!(options.startRule in peg$startRuleFunctions)) {
+ throw new Error('Can\'t start parsing from rule "' + options.startRule + '".');
+ }
+
+ peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
+ }
+
+ function text() {
+ return input.substring(peg$reportedPos, peg$currPos);
+ }
+
+ function offset() {
+ return peg$reportedPos;
+ }
+
+ function line() {
+ return peg$computePosDetails(peg$reportedPos).line;
+ }
+
+ function column() {
+ return peg$computePosDetails(peg$reportedPos).column;
+ }
+
+ function expected(description) {
+ throw peg$buildException(null, [{ type: 'other', description: description }], peg$reportedPos);
+ }
+
+ function error(message) {
+ throw peg$buildException(message, null, peg$reportedPos);
+ }
+
+ function peg$computePosDetails(pos) {
+ function advance(details, startPos, endPos) {
+ var p, ch;
+
+ for (p = startPos; p < endPos; p++) {
+ ch = input.charAt(p);
+ if (ch === '\n') {
+ if (!details.seenCR) {
+ details.line++;
+ }
+ details.column = 1;
+ details.seenCR = false;
+ } else if (ch === '\r' || ch === '\u2028' || ch === '\u2029') {
+ details.line++;
+ details.column = 1;
+ details.seenCR = true;
+ } else {
+ details.column++;
+ details.seenCR = false;
+ }
+ }
+ }
+
+ if (peg$cachedPos !== pos) {
+ if (peg$cachedPos > pos) {
+ peg$cachedPos = 0;
+ peg$cachedPosDetails = { line: 1, column: 1, seenCR: false };
+ }
+ advance(peg$cachedPosDetails, peg$cachedPos, pos);
+ peg$cachedPos = pos;
+ }
+
+ return peg$cachedPosDetails;
+ }
+
+ function peg$fail(expected) {
+ if (peg$currPos < peg$maxFailPos) {
+ return;
+ }
+
+ if (peg$currPos > peg$maxFailPos) {
+ peg$maxFailPos = peg$currPos;
+ peg$maxFailExpected = [];
+ }
+
+ peg$maxFailExpected.push(expected);
+ }
+
+ function peg$buildException(message, expected, pos) {
+ function cleanupExpected(expected) {
+ var i = 1;
+
+ expected.sort(function (a, b) {
+ if (a.description < b.description) {
+ return -1;
+ } else if (a.description > b.description) {
+ return 1;
+ } else {
+ return 0;
+ }
+ });
+
+ while (i < expected.length) {
+ if (expected[i - 1] === expected[i]) {
+ expected.splice(i, 1);
+ } else {
+ i++;
+ }
+ }
+ }
+
+ function buildMessage(expected, found) {
+ function stringEscape(s) {
+ function hex(ch) {
+ return ch.charCodeAt(0).toString(16).toUpperCase();
+ }
+
+ return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\x08/g, '\\b').replace(/\t/g, '\\t').replace(/\n/g, '\\n').replace(/\f/g, '\\f').replace(/\r/g, '\\r').replace(/[\x00-\x07\x0B\x0E\x0F]/g, function (ch) {
+ return '\\x0' + hex(ch);
+ }).replace(/[\x10-\x1F\x80-\xFF]/g, function (ch) {
+ return '\\x' + hex(ch);
+ }).replace(/[\u0180-\u0FFF]/g, function (ch) {
+ return '\\u0' + hex(ch);
+ }).replace(/[\u1080-\uFFFF]/g, function (ch) {
+ return '\\u' + hex(ch);
+ });
+ }
+
+ var expectedDescs = new Array(expected.length),
+ expectedDesc,
+ foundDesc,
+ i;
+
+ for (i = 0; i < expected.length; i++) {
+ expectedDescs[i] = expected[i].description;
+ }
+
+ expectedDesc = expected.length > 1 ? expectedDescs.slice(0, -1).join(', ') + ' or ' + expectedDescs[expected.length - 1] : expectedDescs[0];
+
+ foundDesc = found ? '"' + stringEscape(found) + '"' : 'end of input';
+
+ return 'Expected ' + expectedDesc + ' but ' + foundDesc + ' found.';
+ }
+
+ var posDetails = peg$computePosDetails(pos),
+ found = pos < input.length ? input.charAt(pos) : null;
+
+ if (expected !== null) {
+ cleanupExpected(expected);
+ }
+
+ return new SyntaxError(message !== null ? message : buildMessage(expected, found), expected, found, pos, posDetails.line, posDetails.column);
+ }
+
+ function peg$parsevisualFormatString() {
+ var s0, s1, s2, s3, s4, s5, s6, s7;
+
+ s0 = peg$currPos;
+ s1 = peg$currPos;
+ s2 = peg$parseorientation();
+ if (s2 !== peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 58) {
+ s3 = peg$c2;
+ peg$currPos++;
+ } else {
+ s3 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c3);
+ }
+ }
+ if (s3 !== peg$FAILED) {
+ s2 = [s2, s3];
+ s1 = s2;
+ } else {
+ peg$currPos = s1;
+ s1 = peg$c0;
+ }
+ } else {
+ peg$currPos = s1;
+ s1 = peg$c0;
+ }
+ if (s1 === peg$FAILED) {
+ s1 = peg$c1;
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$currPos;
+ s3 = peg$parsesuperview();
+ if (s3 !== peg$FAILED) {
+ s4 = peg$parseconnection();
+ if (s4 !== peg$FAILED) {
+ s3 = [s3, s4];
+ s2 = s3;
+ } else {
+ peg$currPos = s2;
+ s2 = peg$c0;
+ }
+ } else {
+ peg$currPos = s2;
+ s2 = peg$c0;
+ }
+ if (s2 === peg$FAILED) {
+ s2 = peg$c1;
+ }
+ if (s2 !== peg$FAILED) {
+ s3 = peg$parseview();
+ if (s3 !== peg$FAILED) {
+ s4 = [];
+ s5 = peg$currPos;
+ s6 = peg$parseconnection();
+ if (s6 !== peg$FAILED) {
+ s7 = peg$parseview();
+ if (s7 !== peg$FAILED) {
+ s6 = [s6, s7];
+ s5 = s6;
+ } else {
+ peg$currPos = s5;
+ s5 = peg$c0;
+ }
+ } else {
+ peg$currPos = s5;
+ s5 = peg$c0;
+ }
+ while (s5 !== peg$FAILED) {
+ s4.push(s5);
+ s5 = peg$currPos;
+ s6 = peg$parseconnection();
+ if (s6 !== peg$FAILED) {
+ s7 = peg$parseview();
+ if (s7 !== peg$FAILED) {
+ s6 = [s6, s7];
+ s5 = s6;
+ } else {
+ peg$currPos = s5;
+ s5 = peg$c0;
+ }
+ } else {
+ peg$currPos = s5;
+ s5 = peg$c0;
+ }
+ }
+ if (s4 !== peg$FAILED) {
+ s5 = peg$currPos;
+ s6 = peg$parseconnection();
+ if (s6 !== peg$FAILED) {
+ s7 = peg$parsesuperview();
+ if (s7 !== peg$FAILED) {
+ s6 = [s6, s7];
+ s5 = s6;
+ } else {
+ peg$currPos = s5;
+ s5 = peg$c0;
+ }
+ } else {
+ peg$currPos = s5;
+ s5 = peg$c0;
+ }
+ if (s5 === peg$FAILED) {
+ s5 = peg$c1;
+ }
+ if (s5 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c5(s1, s2, s3, s4, s5);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parseorientation() {
+ var s0, s1;
+
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 72) {
+ s1 = peg$c6;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c7);
+ }
+ }
+ if (s1 === peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 86) {
+ s1 = peg$c8;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c9);
+ }
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c10(s1);
+ }
+ s0 = s1;
+
+ return s0;
+ }
+
+ function peg$parsesuperview() {
+ var s0, s1;
+
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 124) {
+ s1 = peg$c11;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c12);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c13();
+ }
+ s0 = s1;
+
+ return s0;
+ }
+
+ function peg$parseview() {
+ var s0, s1, s2, s3, s4;
+
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 91) {
+ s1 = peg$c14;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c15);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parseviewName();
+ if (s2 !== peg$FAILED) {
+ s3 = peg$parsepredicateListWithParens();
+ if (s3 === peg$FAILED) {
+ s3 = peg$c1;
+ }
+ if (s3 !== peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 93) {
+ s4 = peg$c16;
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c17);
+ }
+ }
+ if (s4 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c18(s2, s3);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parseconnection() {
+ var s0, s1, s2, s3;
+
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 45) {
+ s1 = peg$c19;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c20);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parsepredicateList();
+ if (s2 !== peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 45) {
+ s3 = peg$c19;
+ peg$currPos++;
+ } else {
+ s3 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c20);
+ }
+ }
+ if (s3 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c21(s2);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 45) {
+ s1 = peg$c19;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c20);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c22();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ s1 = peg$c23;
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c24();
+ }
+ s0 = s1;
+ }
+ }
+
+ return s0;
+ }
+
+ function peg$parsepredicateList() {
+ var s0;
+
+ s0 = peg$parsesimplePredicate();
+ if (s0 === peg$FAILED) {
+ s0 = peg$parsepredicateListWithParens();
+ }
+
+ return s0;
+ }
+
+ function peg$parsesimplePredicate() {
+ var s0, s1;
+
+ s0 = peg$currPos;
+ s1 = peg$parsenumber();
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c25(s1);
+ }
+ s0 = s1;
+
+ return s0;
+ }
+
+ function peg$parsepredicateListWithParens() {
+ var s0, s1, s2, s3, s4, s5, s6;
+
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 40) {
+ s1 = peg$c26;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c27);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parsepredicate();
+ if (s2 !== peg$FAILED) {
+ s3 = [];
+ s4 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 44) {
+ s5 = peg$c28;
+ peg$currPos++;
+ } else {
+ s5 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c29);
+ }
+ }
+ if (s5 !== peg$FAILED) {
+ s6 = peg$parsepredicate();
+ if (s6 !== peg$FAILED) {
+ s5 = [s5, s6];
+ s4 = s5;
+ } else {
+ peg$currPos = s4;
+ s4 = peg$c0;
+ }
+ } else {
+ peg$currPos = s4;
+ s4 = peg$c0;
+ }
+ while (s4 !== peg$FAILED) {
+ s3.push(s4);
+ s4 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 44) {
+ s5 = peg$c28;
+ peg$currPos++;
+ } else {
+ s5 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c29);
+ }
+ }
+ if (s5 !== peg$FAILED) {
+ s6 = peg$parsepredicate();
+ if (s6 !== peg$FAILED) {
+ s5 = [s5, s6];
+ s4 = s5;
+ } else {
+ peg$currPos = s4;
+ s4 = peg$c0;
+ }
+ } else {
+ peg$currPos = s4;
+ s4 = peg$c0;
+ }
+ }
+ if (s3 !== peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 41) {
+ s4 = peg$c30;
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c31);
+ }
+ }
+ if (s4 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c32(s2, s3);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parsepredicate() {
+ var s0, s1, s2, s3, s4, s5;
+
+ s0 = peg$currPos;
+ s1 = peg$parserelation();
+ if (s1 === peg$FAILED) {
+ s1 = peg$c1;
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parseobjectOfPredicate();
+ if (s2 !== peg$FAILED) {
+ s3 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 64) {
+ s4 = peg$c33;
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c34);
+ }
+ }
+ if (s4 !== peg$FAILED) {
+ s5 = peg$parsepriority();
+ if (s5 !== peg$FAILED) {
+ s4 = [s4, s5];
+ s3 = s4;
+ } else {
+ peg$currPos = s3;
+ s3 = peg$c0;
+ }
+ } else {
+ peg$currPos = s3;
+ s3 = peg$c0;
+ }
+ if (s3 === peg$FAILED) {
+ s3 = peg$c1;
+ }
+ if (s3 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c35(s1, s2, s3);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parserelation() {
+ var s0, s1;
+
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 2) === peg$c36) {
+ s1 = peg$c36;
+ peg$currPos += 2;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c37);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c38();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 2) === peg$c39) {
+ s1 = peg$c39;
+ peg$currPos += 2;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c40);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c41();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 2) === peg$c42) {
+ s1 = peg$c42;
+ peg$currPos += 2;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c43);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c44();
+ }
+ s0 = s1;
+ }
+ }
+
+ return s0;
+ }
+
+ function peg$parseobjectOfPredicate() {
+ var s0;
+
+ s0 = peg$parseconstant();
+ if (s0 === peg$FAILED) {
+ s0 = peg$parseviewName();
+ }
+
+ return s0;
+ }
+
+ function peg$parsepriority() {
+ var s0, s1, s2;
+
+ s0 = peg$currPos;
+ s1 = [];
+ if (peg$c45.test(input.charAt(peg$currPos))) {
+ s2 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c46);
+ }
+ }
+ if (s2 !== peg$FAILED) {
+ while (s2 !== peg$FAILED) {
+ s1.push(s2);
+ if (peg$c45.test(input.charAt(peg$currPos))) {
+ s2 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c46);
+ }
+ }
+ }
+ } else {
+ s1 = peg$c0;
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c47(s1);
+ }
+ s0 = s1;
+
+ return s0;
+ }
+
+ function peg$parseconstant() {
+ var s0, s1;
+
+ s0 = peg$currPos;
+ s1 = peg$parsenumber();
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c48(s1);
+ }
+ s0 = s1;
+
+ return s0;
+ }
+
+ function peg$parseviewName() {
+ var s0, s1, s2, s3, s4;
+
+ s0 = peg$currPos;
+ s1 = peg$currPos;
+ s2 = [];
+ if (peg$c49.test(input.charAt(peg$currPos))) {
+ s3 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s3 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c50);
+ }
+ }
+ if (s3 !== peg$FAILED) {
+ while (s3 !== peg$FAILED) {
+ s2.push(s3);
+ if (peg$c49.test(input.charAt(peg$currPos))) {
+ s3 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s3 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c50);
+ }
+ }
+ }
+ } else {
+ s2 = peg$c0;
+ }
+ if (s2 !== peg$FAILED) {
+ s2 = input.substring(s1, peg$currPos);
+ }
+ s1 = s2;
+ if (s1 !== peg$FAILED) {
+ s2 = peg$currPos;
+ s3 = [];
+ if (peg$c51.test(input.charAt(peg$currPos))) {
+ s4 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c52);
+ }
+ }
+ while (s4 !== peg$FAILED) {
+ s3.push(s4);
+ if (peg$c51.test(input.charAt(peg$currPos))) {
+ s4 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c52);
+ }
+ }
+ }
+ if (s3 !== peg$FAILED) {
+ s3 = input.substring(s2, peg$currPos);
+ }
+ s2 = s3;
+ if (s2 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c53(s1, s2);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parsenumber() {
+ var s0, s1, s2, s3, s4;
+
+ s0 = peg$currPos;
+ s1 = [];
+ if (peg$c45.test(input.charAt(peg$currPos))) {
+ s2 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c46);
+ }
+ }
+ if (s2 !== peg$FAILED) {
+ while (s2 !== peg$FAILED) {
+ s1.push(s2);
+ if (peg$c45.test(input.charAt(peg$currPos))) {
+ s2 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c46);
+ }
+ }
+ }
+ } else {
+ s1 = peg$c0;
+ }
+ if (s1 !== peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 46) {
+ s2 = peg$c54;
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c55);
+ }
+ }
+ if (s2 !== peg$FAILED) {
+ s3 = [];
+ if (peg$c45.test(input.charAt(peg$currPos))) {
+ s4 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c46);
+ }
+ }
+ if (s4 !== peg$FAILED) {
+ while (s4 !== peg$FAILED) {
+ s3.push(s4);
+ if (peg$c45.test(input.charAt(peg$currPos))) {
+ s4 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c46);
+ }
+ }
+ }
+ } else {
+ s3 = peg$c0;
+ }
+ if (s3 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c56(s1, s3);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ s1 = [];
+ if (peg$c45.test(input.charAt(peg$currPos))) {
+ s2 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c46);
+ }
+ }
+ if (s2 !== peg$FAILED) {
+ while (s2 !== peg$FAILED) {
+ s1.push(s2);
+ if (peg$c45.test(input.charAt(peg$currPos))) {
+ s2 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c46);
+ }
+ }
+ }
+ } else {
+ s1 = peg$c0;
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c57(s1);
+ }
+ s0 = s1;
+ }
+
+ return s0;
+ }
+
+ function extend(dst) {
+ for (var i = 1; i < arguments.length; i++) {
+ for (var k in arguments[i]) {
+ dst[k] = arguments[i][k];
+ }
+ }
+ return dst;
+ }
+
+ peg$result = peg$startRuleFunction();
+
+ if (peg$result !== peg$FAILED && peg$currPos === input.length) {
+ return peg$result;
+ } else {
+ if (peg$result !== peg$FAILED && peg$currPos < input.length) {
+ peg$fail({ type: 'end', description: 'end of input' });
+ }
+
+ throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos);
+ }
+ }
+
+ return {
+ SyntaxError: SyntaxError,
+ parse: parse
+ };
+})();
+
+var parserExt = (function () {
+ /*
+ * Generated by PEG.js 0.8.0.
+ *
+ * http://pegjs.majda.cz/
+ */
+
+ function peg$subclass(child, parent) {
+ function ctor() {
+ this.constructor = child;
+ }
+ ctor.prototype = parent.prototype;
+ child.prototype = new ctor();
+ }
+
+ function SyntaxError(message, expected, found, offset, line, column) {
+ this.message = message;
+ this.expected = expected;
+ this.found = found;
+ this.offset = offset;
+ this.line = line;
+ this.column = column;
+
+ this.name = 'SyntaxError';
+ }
+
+ peg$subclass(SyntaxError, Error);
+
+ function parse(input) {
+ var options = arguments.length > 1 ? arguments[1] : {},
+ peg$FAILED = {},
+ peg$startRuleFunctions = { visualFormatString: peg$parsevisualFormatString },
+ peg$startRuleFunction = peg$parsevisualFormatString,
+ peg$c0 = peg$FAILED,
+ peg$c1 = null,
+ peg$c2 = ':',
+ peg$c3 = { type: 'literal', value: ':', description: '":"' },
+ peg$c4 = [],
+ peg$c5 = function peg$c5(o, superto, view, views, tosuper, comments) {
+ return {
+ orientation: o ? o[0] : 'horizontal',
+ cascade: (superto || []).concat([view], [].concat.apply([], views), tosuper || [])
+ };
+ },
+ peg$c6 = 'H',
+ peg$c7 = { type: 'literal', value: 'H', description: '"H"' },
+ peg$c8 = 'V',
+ peg$c9 = { type: 'literal', value: 'V', description: '"V"' },
+ peg$c10 = 'Z',
+ peg$c11 = { type: 'literal', value: 'Z', description: '"Z"' },
+ peg$c12 = function peg$c12(orient) {
+ return orient == 'H' ? 'horizontal' : orient == 'V' ? 'vertical' : 'zIndex';
+ },
+ peg$c13 = ' ',
+ peg$c14 = { type: 'literal', value: ' ', description: '" "' },
+ peg$c15 = '//',
+ peg$c16 = { type: 'literal', value: '//', description: '"//"' },
+ peg$c17 = { type: 'any', description: 'any character' },
+ peg$c18 = '|',
+ peg$c19 = { type: 'literal', value: '|', description: '"|"' },
+ peg$c20 = function peg$c20() {
+ return { view: null };
+ },
+ peg$c21 = '[',
+ peg$c22 = { type: 'literal', value: '[', description: '"["' },
+ peg$c23 = ']',
+ peg$c24 = { type: 'literal', value: ']', description: '"]"' },
+ peg$c25 = function peg$c25(view, predicates, cascadedViews) {
+ return extend(extend(view, predicates ? { constraints: predicates } : {}), cascadedViews ? {
+ cascade: cascadedViews
+ } : {});
+ },
+ peg$c26 = function peg$c26(views, connection) {
+ return [].concat([].concat.apply([], views), [connection]);
+ },
+ peg$c27 = '->',
+ peg$c28 = { type: 'literal', value: '->', description: '"->"' },
+ peg$c29 = function peg$c29() {
+ return [{ relation: 'none', $parserOffset: offset() }];
+ },
+ peg$c30 = '-',
+ peg$c31 = { type: 'literal', value: '-', description: '"-"' },
+ peg$c32 = function peg$c32(predicateList) {
+ return predicateList;
+ },
+ peg$c33 = function peg$c33() {
+ return [{ relation: 'equ', constant: 'default', $parserOffset: offset() }];
+ },
+ peg$c34 = '~',
+ peg$c35 = { type: 'literal', value: '~', description: '"~"' },
+ peg$c36 = function peg$c36() {
+ return [{ relation: 'equ', equalSpacing: true, $parserOffset: offset() }];
+ },
+ peg$c37 = '',
+ peg$c38 = function peg$c38() {
+ return [{ relation: 'equ', constant: 0, $parserOffset: offset() }];
+ },
+ peg$c39 = function peg$c39(p) {
+ return [{ relation: 'equ', multiplier: p.multiplier, $parserOffset: offset() }];
+ },
+ peg$c40 = function peg$c40(n) {
+ return [{ relation: 'equ', constant: n, $parserOffset: offset() }];
+ },
+ peg$c41 = '(',
+ peg$c42 = { type: 'literal', value: '(', description: '"("' },
+ peg$c43 = ',',
+ peg$c44 = { type: 'literal', value: ',', description: '","' },
+ peg$c45 = ')',
+ peg$c46 = { type: 'literal', value: ')', description: '")"' },
+ peg$c47 = function peg$c47(p, ps) {
+ return [p].concat(ps.map(function (p) {
+ return p[1];
+ }));
+ },
+ peg$c48 = '@',
+ peg$c49 = { type: 'literal', value: '@', description: '"@"' },
+ peg$c50 = function peg$c50(r, o, p) {
+ return extend({ relation: 'equ' }, r || {}, o, p ? p[1] : {});
+ },
+ peg$c51 = function peg$c51(r, o, p) {
+ return extend({ relation: 'equ', equalSpacing: true }, r || {}, o, p ? p[1] : {});
+ },
+ peg$c52 = '==',
+ peg$c53 = { type: 'literal', value: '==', description: '"=="' },
+ peg$c54 = function peg$c54() {
+ return { relation: 'equ', $parserOffset: offset() };
+ },
+ peg$c55 = '<=',
+ peg$c56 = { type: 'literal', value: '<=', description: '"<="' },
+ peg$c57 = function peg$c57() {
+ return { relation: 'leq', $parserOffset: offset() };
+ },
+ peg$c58 = '>=',
+ peg$c59 = { type: 'literal', value: '>=', description: '">="' },
+ peg$c60 = function peg$c60() {
+ return { relation: 'geq', $parserOffset: offset() };
+ },
+ peg$c61 = /^[0-9]/,
+ peg$c62 = { type: 'class', value: '[0-9]', description: '[0-9]' },
+ peg$c63 = function peg$c63(digits) {
+ return { priority: parseInt(digits.join(''), 10) };
+ },
+ peg$c64 = function peg$c64(n) {
+ return { constant: n };
+ },
+ peg$c65 = '%',
+ peg$c66 = { type: 'literal', value: '%', description: '"%"' },
+ peg$c67 = function peg$c67(n) {
+ return { view: null, multiplier: n / 100 };
+ },
+ peg$c68 = function peg$c68(vn, a, m, c) {
+ return { view: vn.view, attribute: a ? a : undefined, multiplier: m ? m : 1, constant: c ? c : undefined };
+ },
+ peg$c69 = '.left',
+ peg$c70 = { type: 'literal', value: '.left', description: '".left"' },
+ peg$c71 = function peg$c71() {
+ return 'left';
+ },
+ peg$c72 = '.right',
+ peg$c73 = { type: 'literal', value: '.right', description: '".right"' },
+ peg$c74 = function peg$c74() {
+ return 'right';
+ },
+ peg$c75 = '.top',
+ peg$c76 = { type: 'literal', value: '.top', description: '".top"' },
+ peg$c77 = function peg$c77() {
+ return 'top';
+ },
+ peg$c78 = '.bottom',
+ peg$c79 = { type: 'literal', value: '.bottom', description: '".bottom"' },
+ peg$c80 = function peg$c80() {
+ return 'bottom';
+ },
+ peg$c81 = '.width',
+ peg$c82 = { type: 'literal', value: '.width', description: '".width"' },
+ peg$c83 = function peg$c83() {
+ return 'width';
+ },
+ peg$c84 = '.height',
+ peg$c85 = { type: 'literal', value: '.height', description: '".height"' },
+ peg$c86 = function peg$c86() {
+ return 'height';
+ },
+ peg$c87 = '.centerX',
+ peg$c88 = { type: 'literal', value: '.centerX', description: '".centerX"' },
+ peg$c89 = function peg$c89() {
+ return 'centerX';
+ },
+ peg$c90 = '.centerY',
+ peg$c91 = { type: 'literal', value: '.centerY', description: '".centerY"' },
+ peg$c92 = function peg$c92() {
+ return 'centerY';
+ },
+ peg$c93 = '/',
+ peg$c94 = { type: 'literal', value: '/', description: '"/"' },
+ peg$c95 = function peg$c95(n) {
+ return 1 / n;
+ },
+ peg$c96 = '*',
+ peg$c97 = { type: 'literal', value: '*', description: '"*"' },
+ peg$c98 = function peg$c98(n) {
+ return n;
+ },
+ peg$c99 = function peg$c99(n) {
+ return -n;
+ },
+ peg$c100 = '+',
+ peg$c101 = { type: 'literal', value: '+', description: '"+"' },
+ peg$c102 = /^[a-zA-Z_]/,
+ peg$c103 = { type: 'class', value: '[a-zA-Z_]', description: '[a-zA-Z_]' },
+ peg$c104 = /^[a-zA-Z0-9_]/,
+ peg$c105 = { type: 'class', value: '[a-zA-Z0-9_]', description: '[a-zA-Z0-9_]' },
+ peg$c106 = function peg$c106(f, v) {
+ return { view: f + v };
+ },
+ peg$c107 = '.',
+ peg$c108 = { type: 'literal', value: '.', description: '"."' },
+ peg$c109 = function peg$c109(digits, decimals) {
+ return parseFloat(digits.concat('.').concat(decimals).join(''), 10);
+ },
+ peg$c110 = function peg$c110(digits) {
+ return parseInt(digits.join(''), 10);
+ },
+ peg$currPos = 0,
+ peg$reportedPos = 0,
+ peg$cachedPos = 0,
+ peg$cachedPosDetails = { line: 1, column: 1, seenCR: false },
+ peg$maxFailPos = 0,
+ peg$maxFailExpected = [],
+ peg$silentFails = 0,
+ peg$result;
+
+ if ('startRule' in options) {
+ if (!(options.startRule in peg$startRuleFunctions)) {
+ throw new Error('Can\'t start parsing from rule "' + options.startRule + '".');
+ }
+
+ peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
+ }
+
+ function text() {
+ return input.substring(peg$reportedPos, peg$currPos);
+ }
+
+ function offset() {
+ return peg$reportedPos;
+ }
+
+ function line() {
+ return peg$computePosDetails(peg$reportedPos).line;
+ }
+
+ function column() {
+ return peg$computePosDetails(peg$reportedPos).column;
+ }
+
+ function expected(description) {
+ throw peg$buildException(null, [{ type: 'other', description: description }], peg$reportedPos);
+ }
+
+ function error(message) {
+ throw peg$buildException(message, null, peg$reportedPos);
+ }
+
+ function peg$computePosDetails(pos) {
+ function advance(details, startPos, endPos) {
+ var p, ch;
+
+ for (p = startPos; p < endPos; p++) {
+ ch = input.charAt(p);
+ if (ch === '\n') {
+ if (!details.seenCR) {
+ details.line++;
+ }
+ details.column = 1;
+ details.seenCR = false;
+ } else if (ch === '\r' || ch === '\u2028' || ch === '\u2029') {
+ details.line++;
+ details.column = 1;
+ details.seenCR = true;
+ } else {
+ details.column++;
+ details.seenCR = false;
+ }
+ }
+ }
+
+ if (peg$cachedPos !== pos) {
+ if (peg$cachedPos > pos) {
+ peg$cachedPos = 0;
+ peg$cachedPosDetails = { line: 1, column: 1, seenCR: false };
+ }
+ advance(peg$cachedPosDetails, peg$cachedPos, pos);
+ peg$cachedPos = pos;
+ }
+
+ return peg$cachedPosDetails;
+ }
+
+ function peg$fail(expected) {
+ if (peg$currPos < peg$maxFailPos) {
+ return;
+ }
+
+ if (peg$currPos > peg$maxFailPos) {
+ peg$maxFailPos = peg$currPos;
+ peg$maxFailExpected = [];
+ }
+
+ peg$maxFailExpected.push(expected);
+ }
+
+ function peg$buildException(message, expected, pos) {
+ function cleanupExpected(expected) {
+ var i = 1;
+
+ expected.sort(function (a, b) {
+ if (a.description < b.description) {
+ return -1;
+ } else if (a.description > b.description) {
+ return 1;
+ } else {
+ return 0;
+ }
+ });
+
+ while (i < expected.length) {
+ if (expected[i - 1] === expected[i]) {
+ expected.splice(i, 1);
+ } else {
+ i++;
+ }
+ }
+ }
+
+ function buildMessage(expected, found) {
+ function stringEscape(s) {
+ function hex(ch) {
+ return ch.charCodeAt(0).toString(16).toUpperCase();
+ }
+
+ return s.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\x08/g, '\\b').replace(/\t/g, '\\t').replace(/\n/g, '\\n').replace(/\f/g, '\\f').replace(/\r/g, '\\r').replace(/[\x00-\x07\x0B\x0E\x0F]/g, function (ch) {
+ return '\\x0' + hex(ch);
+ }).replace(/[\x10-\x1F\x80-\xFF]/g, function (ch) {
+ return '\\x' + hex(ch);
+ }).replace(/[\u0180-\u0FFF]/g, function (ch) {
+ return '\\u0' + hex(ch);
+ }).replace(/[\u1080-\uFFFF]/g, function (ch) {
+ return '\\u' + hex(ch);
+ });
+ }
+
+ var expectedDescs = new Array(expected.length),
+ expectedDesc,
+ foundDesc,
+ i;
+
+ for (i = 0; i < expected.length; i++) {
+ expectedDescs[i] = expected[i].description;
+ }
+
+ expectedDesc = expected.length > 1 ? expectedDescs.slice(0, -1).join(', ') + ' or ' + expectedDescs[expected.length - 1] : expectedDescs[0];
+
+ foundDesc = found ? '"' + stringEscape(found) + '"' : 'end of input';
+
+ return 'Expected ' + expectedDesc + ' but ' + foundDesc + ' found.';
+ }
+
+ var posDetails = peg$computePosDetails(pos),
+ found = pos < input.length ? input.charAt(pos) : null;
+
+ if (expected !== null) {
+ cleanupExpected(expected);
+ }
+
+ return new SyntaxError(message !== null ? message : buildMessage(expected, found), expected, found, pos, posDetails.line, posDetails.column);
+ }
+
+ function peg$parsevisualFormatString() {
+ var s0, s1, s2, s3, s4, s5, s6, s7;
+
+ s0 = peg$currPos;
+ s1 = peg$currPos;
+ s2 = peg$parseorientation();
+ if (s2 !== peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 58) {
+ s3 = peg$c2;
+ peg$currPos++;
+ } else {
+ s3 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c3);
+ }
+ }
+ if (s3 !== peg$FAILED) {
+ s2 = [s2, s3];
+ s1 = s2;
+ } else {
+ peg$currPos = s1;
+ s1 = peg$c0;
+ }
+ } else {
+ peg$currPos = s1;
+ s1 = peg$c0;
+ }
+ if (s1 === peg$FAILED) {
+ s1 = peg$c1;
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$currPos;
+ s3 = peg$parsesuperview();
+ if (s3 !== peg$FAILED) {
+ s4 = peg$parseconnection();
+ if (s4 !== peg$FAILED) {
+ s3 = [s3, s4];
+ s2 = s3;
+ } else {
+ peg$currPos = s2;
+ s2 = peg$c0;
+ }
+ } else {
+ peg$currPos = s2;
+ s2 = peg$c0;
+ }
+ if (s2 === peg$FAILED) {
+ s2 = peg$c1;
+ }
+ if (s2 !== peg$FAILED) {
+ s3 = peg$parseview();
+ if (s3 !== peg$FAILED) {
+ s4 = [];
+ s5 = peg$currPos;
+ s6 = peg$parseconnection();
+ if (s6 !== peg$FAILED) {
+ s7 = peg$parseview();
+ if (s7 !== peg$FAILED) {
+ s6 = [s6, s7];
+ s5 = s6;
+ } else {
+ peg$currPos = s5;
+ s5 = peg$c0;
+ }
+ } else {
+ peg$currPos = s5;
+ s5 = peg$c0;
+ }
+ while (s5 !== peg$FAILED) {
+ s4.push(s5);
+ s5 = peg$currPos;
+ s6 = peg$parseconnection();
+ if (s6 !== peg$FAILED) {
+ s7 = peg$parseview();
+ if (s7 !== peg$FAILED) {
+ s6 = [s6, s7];
+ s5 = s6;
+ } else {
+ peg$currPos = s5;
+ s5 = peg$c0;
+ }
+ } else {
+ peg$currPos = s5;
+ s5 = peg$c0;
+ }
+ }
+ if (s4 !== peg$FAILED) {
+ s5 = peg$currPos;
+ s6 = peg$parseconnection();
+ if (s6 !== peg$FAILED) {
+ s7 = peg$parsesuperview();
+ if (s7 !== peg$FAILED) {
+ s6 = [s6, s7];
+ s5 = s6;
+ } else {
+ peg$currPos = s5;
+ s5 = peg$c0;
+ }
+ } else {
+ peg$currPos = s5;
+ s5 = peg$c0;
+ }
+ if (s5 === peg$FAILED) {
+ s5 = peg$c1;
+ }
+ if (s5 !== peg$FAILED) {
+ s6 = peg$parsecomments();
+ if (s6 === peg$FAILED) {
+ s6 = peg$c1;
+ }
+ if (s6 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c5(s1, s2, s3, s4, s5, s6);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parseorientation() {
+ var s0, s1;
+
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 72) {
+ s1 = peg$c6;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c7);
+ }
+ }
+ if (s1 === peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 86) {
+ s1 = peg$c8;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c9);
+ }
+ }
+ if (s1 === peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 90) {
+ s1 = peg$c10;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c11);
+ }
+ }
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c12(s1);
+ }
+ s0 = s1;
+
+ return s0;
+ }
+
+ function peg$parsecomments() {
+ var s0, s1, s2, s3, s4;
+
+ s0 = peg$currPos;
+ s1 = [];
+ if (input.charCodeAt(peg$currPos) === 32) {
+ s2 = peg$c13;
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c14);
+ }
+ }
+ while (s2 !== peg$FAILED) {
+ s1.push(s2);
+ if (input.charCodeAt(peg$currPos) === 32) {
+ s2 = peg$c13;
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c14);
+ }
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ if (input.substr(peg$currPos, 2) === peg$c15) {
+ s2 = peg$c15;
+ peg$currPos += 2;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c16);
+ }
+ }
+ if (s2 !== peg$FAILED) {
+ s3 = [];
+ if (input.length > peg$currPos) {
+ s4 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c17);
+ }
+ }
+ while (s4 !== peg$FAILED) {
+ s3.push(s4);
+ if (input.length > peg$currPos) {
+ s4 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c17);
+ }
+ }
+ }
+ if (s3 !== peg$FAILED) {
+ s1 = [s1, s2, s3];
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parsesuperview() {
+ var s0, s1;
+
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 124) {
+ s1 = peg$c18;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c19);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c20();
+ }
+ s0 = s1;
+
+ return s0;
+ }
+
+ function peg$parseview() {
+ var s0, s1, s2, s3, s4, s5;
+
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 91) {
+ s1 = peg$c21;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c22);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parseviewName();
+ if (s2 !== peg$FAILED) {
+ s3 = peg$parsepredicateListWithParens();
+ if (s3 === peg$FAILED) {
+ s3 = peg$c1;
+ }
+ if (s3 !== peg$FAILED) {
+ s4 = peg$parsecascadedViews();
+ if (s4 === peg$FAILED) {
+ s4 = peg$c1;
+ }
+ if (s4 !== peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 93) {
+ s5 = peg$c23;
+ peg$currPos++;
+ } else {
+ s5 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c24);
+ }
+ }
+ if (s5 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c25(s2, s3, s4);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parsecascadedViews() {
+ var s0, s1, s2, s3, s4, s5;
+
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 58) {
+ s1 = peg$c2;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c3);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = [];
+ s3 = peg$currPos;
+ s4 = peg$parseconnection();
+ if (s4 !== peg$FAILED) {
+ s5 = peg$parseview();
+ if (s5 !== peg$FAILED) {
+ s4 = [s4, s5];
+ s3 = s4;
+ } else {
+ peg$currPos = s3;
+ s3 = peg$c0;
+ }
+ } else {
+ peg$currPos = s3;
+ s3 = peg$c0;
+ }
+ if (s3 !== peg$FAILED) {
+ while (s3 !== peg$FAILED) {
+ s2.push(s3);
+ s3 = peg$currPos;
+ s4 = peg$parseconnection();
+ if (s4 !== peg$FAILED) {
+ s5 = peg$parseview();
+ if (s5 !== peg$FAILED) {
+ s4 = [s4, s5];
+ s3 = s4;
+ } else {
+ peg$currPos = s3;
+ s3 = peg$c0;
+ }
+ } else {
+ peg$currPos = s3;
+ s3 = peg$c0;
+ }
+ }
+ } else {
+ s2 = peg$c0;
+ }
+ if (s2 !== peg$FAILED) {
+ s3 = peg$parseconnection();
+ if (s3 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c26(s2, s3);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parseconnection() {
+ var s0, s1, s2, s3;
+
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 2) === peg$c27) {
+ s1 = peg$c27;
+ peg$currPos += 2;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c28);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c29();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 45) {
+ s1 = peg$c30;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c31);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parsepredicateList();
+ if (s2 !== peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 45) {
+ s3 = peg$c30;
+ peg$currPos++;
+ } else {
+ s3 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c31);
+ }
+ }
+ if (s3 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c32(s2);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 45) {
+ s1 = peg$c30;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c31);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c33();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 126) {
+ s1 = peg$c34;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c35);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parseequalSpacingPredicateList();
+ if (s2 !== peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 126) {
+ s3 = peg$c34;
+ peg$currPos++;
+ } else {
+ s3 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c35);
+ }
+ }
+ if (s3 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c32(s2);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 126) {
+ s1 = peg$c34;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c35);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c36();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ s1 = peg$c37;
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c38();
+ }
+ s0 = s1;
+ }
+ }
+ }
+ }
+ }
+
+ return s0;
+ }
+
+ function peg$parsepredicateList() {
+ var s0;
+
+ s0 = peg$parsesimplePredicate();
+ if (s0 === peg$FAILED) {
+ s0 = peg$parsepredicateListWithParens();
+ }
+
+ return s0;
+ }
+
+ function peg$parsesimplePredicate() {
+ var s0, s1;
+
+ s0 = peg$currPos;
+ s1 = peg$parsepercentage();
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c39(s1);
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ s1 = peg$parsenumber();
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c40(s1);
+ }
+ s0 = s1;
+ }
+
+ return s0;
+ }
+
+ function peg$parsepredicateListWithParens() {
+ var s0, s1, s2, s3, s4, s5, s6;
+
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 40) {
+ s1 = peg$c41;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c42);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parsepredicate();
+ if (s2 !== peg$FAILED) {
+ s3 = [];
+ s4 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 44) {
+ s5 = peg$c43;
+ peg$currPos++;
+ } else {
+ s5 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c44);
+ }
+ }
+ if (s5 !== peg$FAILED) {
+ s6 = peg$parsepredicate();
+ if (s6 !== peg$FAILED) {
+ s5 = [s5, s6];
+ s4 = s5;
+ } else {
+ peg$currPos = s4;
+ s4 = peg$c0;
+ }
+ } else {
+ peg$currPos = s4;
+ s4 = peg$c0;
+ }
+ while (s4 !== peg$FAILED) {
+ s3.push(s4);
+ s4 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 44) {
+ s5 = peg$c43;
+ peg$currPos++;
+ } else {
+ s5 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c44);
+ }
+ }
+ if (s5 !== peg$FAILED) {
+ s6 = peg$parsepredicate();
+ if (s6 !== peg$FAILED) {
+ s5 = [s5, s6];
+ s4 = s5;
+ } else {
+ peg$currPos = s4;
+ s4 = peg$c0;
+ }
+ } else {
+ peg$currPos = s4;
+ s4 = peg$c0;
+ }
+ }
+ if (s3 !== peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 41) {
+ s4 = peg$c45;
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c46);
+ }
+ }
+ if (s4 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c47(s2, s3);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parsepredicate() {
+ var s0, s1, s2, s3, s4, s5;
+
+ s0 = peg$currPos;
+ s1 = peg$parserelation();
+ if (s1 === peg$FAILED) {
+ s1 = peg$c1;
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parseobjectOfPredicate();
+ if (s2 !== peg$FAILED) {
+ s3 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 64) {
+ s4 = peg$c48;
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c49);
+ }
+ }
+ if (s4 !== peg$FAILED) {
+ s5 = peg$parsepriority();
+ if (s5 !== peg$FAILED) {
+ s4 = [s4, s5];
+ s3 = s4;
+ } else {
+ peg$currPos = s3;
+ s3 = peg$c0;
+ }
+ } else {
+ peg$currPos = s3;
+ s3 = peg$c0;
+ }
+ if (s3 === peg$FAILED) {
+ s3 = peg$c1;
+ }
+ if (s3 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c50(s1, s2, s3);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parseequalSpacingPredicateList() {
+ var s0, s1, s2, s3, s4, s5, s6;
+
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 40) {
+ s1 = peg$c41;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c42);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parseequalSpacingPredicate();
+ if (s2 !== peg$FAILED) {
+ s3 = [];
+ s4 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 44) {
+ s5 = peg$c43;
+ peg$currPos++;
+ } else {
+ s5 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c44);
+ }
+ }
+ if (s5 !== peg$FAILED) {
+ s6 = peg$parseequalSpacingPredicate();
+ if (s6 !== peg$FAILED) {
+ s5 = [s5, s6];
+ s4 = s5;
+ } else {
+ peg$currPos = s4;
+ s4 = peg$c0;
+ }
+ } else {
+ peg$currPos = s4;
+ s4 = peg$c0;
+ }
+ while (s4 !== peg$FAILED) {
+ s3.push(s4);
+ s4 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 44) {
+ s5 = peg$c43;
+ peg$currPos++;
+ } else {
+ s5 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c44);
+ }
+ }
+ if (s5 !== peg$FAILED) {
+ s6 = peg$parseequalSpacingPredicate();
+ if (s6 !== peg$FAILED) {
+ s5 = [s5, s6];
+ s4 = s5;
+ } else {
+ peg$currPos = s4;
+ s4 = peg$c0;
+ }
+ } else {
+ peg$currPos = s4;
+ s4 = peg$c0;
+ }
+ }
+ if (s3 !== peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 41) {
+ s4 = peg$c45;
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c46);
+ }
+ }
+ if (s4 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c47(s2, s3);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parseequalSpacingPredicate() {
+ var s0, s1, s2, s3, s4, s5;
+
+ s0 = peg$currPos;
+ s1 = peg$parserelation();
+ if (s1 === peg$FAILED) {
+ s1 = peg$c1;
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parseobjectOfPredicate();
+ if (s2 !== peg$FAILED) {
+ s3 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 64) {
+ s4 = peg$c48;
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c49);
+ }
+ }
+ if (s4 !== peg$FAILED) {
+ s5 = peg$parsepriority();
+ if (s5 !== peg$FAILED) {
+ s4 = [s4, s5];
+ s3 = s4;
+ } else {
+ peg$currPos = s3;
+ s3 = peg$c0;
+ }
+ } else {
+ peg$currPos = s3;
+ s3 = peg$c0;
+ }
+ if (s3 === peg$FAILED) {
+ s3 = peg$c1;
+ }
+ if (s3 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c51(s1, s2, s3);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parserelation() {
+ var s0, s1;
+
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 2) === peg$c52) {
+ s1 = peg$c52;
+ peg$currPos += 2;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c53);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c54();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 2) === peg$c55) {
+ s1 = peg$c55;
+ peg$currPos += 2;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c56);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c57();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 2) === peg$c58) {
+ s1 = peg$c58;
+ peg$currPos += 2;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c59);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c60();
+ }
+ s0 = s1;
+ }
+ }
+
+ return s0;
+ }
+
+ function peg$parseobjectOfPredicate() {
+ var s0;
+
+ s0 = peg$parsepercentage();
+ if (s0 === peg$FAILED) {
+ s0 = peg$parseconstant();
+ if (s0 === peg$FAILED) {
+ s0 = peg$parseviewPredicate();
+ }
+ }
+
+ return s0;
+ }
+
+ function peg$parsepriority() {
+ var s0, s1, s2;
+
+ s0 = peg$currPos;
+ s1 = [];
+ if (peg$c61.test(input.charAt(peg$currPos))) {
+ s2 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c62);
+ }
+ }
+ if (s2 !== peg$FAILED) {
+ while (s2 !== peg$FAILED) {
+ s1.push(s2);
+ if (peg$c61.test(input.charAt(peg$currPos))) {
+ s2 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c62);
+ }
+ }
+ }
+ } else {
+ s1 = peg$c0;
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c63(s1);
+ }
+ s0 = s1;
+
+ return s0;
+ }
+
+ function peg$parseconstant() {
+ var s0, s1;
+
+ s0 = peg$currPos;
+ s1 = peg$parsenumber();
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c64(s1);
+ }
+ s0 = s1;
+
+ return s0;
+ }
+
+ function peg$parsepercentage() {
+ var s0, s1, s2;
+
+ s0 = peg$currPos;
+ s1 = peg$parsenumber();
+ if (s1 !== peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 37) {
+ s2 = peg$c65;
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c66);
+ }
+ }
+ if (s2 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c67(s1);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parseviewPredicate() {
+ var s0, s1, s2, s3, s4;
+
+ s0 = peg$currPos;
+ s1 = peg$parseviewName();
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parseattribute();
+ if (s2 === peg$FAILED) {
+ s2 = peg$c1;
+ }
+ if (s2 !== peg$FAILED) {
+ s3 = peg$parsemultiplier();
+ if (s3 === peg$FAILED) {
+ s3 = peg$c1;
+ }
+ if (s3 !== peg$FAILED) {
+ s4 = peg$parseconstantExpr();
+ if (s4 === peg$FAILED) {
+ s4 = peg$c1;
+ }
+ if (s4 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c68(s1, s2, s3, s4);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parseattribute() {
+ var s0, s1;
+
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 5) === peg$c69) {
+ s1 = peg$c69;
+ peg$currPos += 5;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c70);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c71();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 6) === peg$c72) {
+ s1 = peg$c72;
+ peg$currPos += 6;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c73);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c74();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 4) === peg$c75) {
+ s1 = peg$c75;
+ peg$currPos += 4;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c76);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c77();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 7) === peg$c78) {
+ s1 = peg$c78;
+ peg$currPos += 7;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c79);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c80();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 6) === peg$c81) {
+ s1 = peg$c81;
+ peg$currPos += 6;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c82);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c83();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 7) === peg$c84) {
+ s1 = peg$c84;
+ peg$currPos += 7;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c85);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c86();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 8) === peg$c87) {
+ s1 = peg$c87;
+ peg$currPos += 8;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c88);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c89();
+ }
+ s0 = s1;
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.substr(peg$currPos, 8) === peg$c90) {
+ s1 = peg$c90;
+ peg$currPos += 8;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c91);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c92();
+ }
+ s0 = s1;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return s0;
+ }
+
+ function peg$parsemultiplier() {
+ var s0, s1, s2;
+
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 47) {
+ s1 = peg$c93;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c94);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parsenumber();
+ if (s2 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c95(s2);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 42) {
+ s1 = peg$c96;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c97);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parsenumber();
+ if (s2 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c98(s2);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ }
+
+ return s0;
+ }
+
+ function peg$parseconstantExpr() {
+ var s0, s1, s2;
+
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 45) {
+ s1 = peg$c30;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c31);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parsenumber();
+ if (s2 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c99(s2);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ if (input.charCodeAt(peg$currPos) === 43) {
+ s1 = peg$c100;
+ peg$currPos++;
+ } else {
+ s1 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c101);
+ }
+ }
+ if (s1 !== peg$FAILED) {
+ s2 = peg$parsenumber();
+ if (s2 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c98(s2);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ }
+
+ return s0;
+ }
+
+ function peg$parseviewName() {
+ var s0, s1, s2, s3, s4;
+
+ s0 = peg$currPos;
+ s1 = peg$currPos;
+ s2 = [];
+ if (peg$c102.test(input.charAt(peg$currPos))) {
+ s3 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s3 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c103);
+ }
+ }
+ if (s3 !== peg$FAILED) {
+ while (s3 !== peg$FAILED) {
+ s2.push(s3);
+ if (peg$c102.test(input.charAt(peg$currPos))) {
+ s3 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s3 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c103);
+ }
+ }
+ }
+ } else {
+ s2 = peg$c0;
+ }
+ if (s2 !== peg$FAILED) {
+ s2 = input.substring(s1, peg$currPos);
+ }
+ s1 = s2;
+ if (s1 !== peg$FAILED) {
+ s2 = peg$currPos;
+ s3 = [];
+ if (peg$c104.test(input.charAt(peg$currPos))) {
+ s4 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c105);
+ }
+ }
+ while (s4 !== peg$FAILED) {
+ s3.push(s4);
+ if (peg$c104.test(input.charAt(peg$currPos))) {
+ s4 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c105);
+ }
+ }
+ }
+ if (s3 !== peg$FAILED) {
+ s3 = input.substring(s2, peg$currPos);
+ }
+ s2 = s3;
+ if (s2 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c106(s1, s2);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+
+ return s0;
+ }
+
+ function peg$parsenumber() {
+ var s0, s1, s2, s3, s4;
+
+ s0 = peg$currPos;
+ s1 = [];
+ if (peg$c61.test(input.charAt(peg$currPos))) {
+ s2 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c62);
+ }
+ }
+ if (s2 !== peg$FAILED) {
+ while (s2 !== peg$FAILED) {
+ s1.push(s2);
+ if (peg$c61.test(input.charAt(peg$currPos))) {
+ s2 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c62);
+ }
+ }
+ }
+ } else {
+ s1 = peg$c0;
+ }
+ if (s1 !== peg$FAILED) {
+ if (input.charCodeAt(peg$currPos) === 46) {
+ s2 = peg$c107;
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c108);
+ }
+ }
+ if (s2 !== peg$FAILED) {
+ s3 = [];
+ if (peg$c61.test(input.charAt(peg$currPos))) {
+ s4 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c62);
+ }
+ }
+ if (s4 !== peg$FAILED) {
+ while (s4 !== peg$FAILED) {
+ s3.push(s4);
+ if (peg$c61.test(input.charAt(peg$currPos))) {
+ s4 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s4 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c62);
+ }
+ }
+ }
+ } else {
+ s3 = peg$c0;
+ }
+ if (s3 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c109(s1, s3);
+ s0 = s1;
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ } else {
+ peg$currPos = s0;
+ s0 = peg$c0;
+ }
+ if (s0 === peg$FAILED) {
+ s0 = peg$currPos;
+ s1 = [];
+ if (peg$c61.test(input.charAt(peg$currPos))) {
+ s2 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c62);
+ }
+ }
+ if (s2 !== peg$FAILED) {
+ while (s2 !== peg$FAILED) {
+ s1.push(s2);
+ if (peg$c61.test(input.charAt(peg$currPos))) {
+ s2 = input.charAt(peg$currPos);
+ peg$currPos++;
+ } else {
+ s2 = peg$FAILED;
+ if (peg$silentFails === 0) {
+ peg$fail(peg$c62);
+ }
+ }
+ }
+ } else {
+ s1 = peg$c0;
+ }
+ if (s1 !== peg$FAILED) {
+ peg$reportedPos = s0;
+ s1 = peg$c110(s1);
+ }
+ s0 = s1;
+ }
+
+ return s0;
+ }
+
+ function extend(dst) {
+ for (var i = 1; i < arguments.length; i++) {
+ for (var k in arguments[i]) {
+ dst[k] = arguments[i][k];
+ }
+ }
+ return dst;
+ }
+
+ peg$result = peg$startRuleFunction();
+
+ if (peg$result !== peg$FAILED && peg$currPos === input.length) {
+ return peg$result;
+ } else {
+ if (peg$result !== peg$FAILED && peg$currPos < input.length) {
+ peg$fail({ type: 'end', description: 'end of input' });
+ }
+
+ throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos);
+ }
+ }
+
+ return {
+ SyntaxError: SyntaxError,
+ parse: parse
+ };
+})();
+
+var Orientation = {
+ HORIZONTAL: 1,
+ VERTICAL: 2,
+ ZINDEX: 4
+};
+
+/**
+ * Helper function that inserts equal spacers (~).
+ * @private
+ */
+function _processEqualSpacer(context, stackView) {
+
+ // Determine unique name for the spacer
+ context.equalSpacerIndex = context.equalSpacerIndex || 1;
+ var name = '_~' + context.lineIndex + ':' + context.equalSpacerIndex + '~';
+ if (context.equalSpacerIndex > 1) {
+
+ // Ensure that all spacers have the same width/height
+ context.constraints.push({
+ view1: '_~' + context.lineIndex + ':1~',
+ attr1: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
+ relation: context.relation.relation || Relation.EQU,
+ view2: name,
+ attr2: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
+ priority: context.relation.priority
+ });
+ }
+ context.equalSpacerIndex++;
+
+ // Enforce proportional width/height
+ if (context.relation.multiplier && context.relation.multiplier !== 1) {
+ context.constraints.push({
+ view1: name,
+ attr1: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
+ relation: context.relation.relation || Relation.EQU,
+ view2: null,
+ attr2: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
+ priority: context.relation.priority,
+ multiplier: context.relation.multiplier
+ });
+ context.relation.multiplier = undefined;
+ } else if (context.relation.constant) {
+ context.constraints.push({
+ view1: name,
+ attr1: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
+ relation: Relation.EQU,
+ view2: null,
+ attr2: Attribute.CONST,
+ priority: context.relation.priority,
+ constant: context.relation.constant
+ });
+ context.relation.constant = undefined;
+ }
+
+ // Add constraint
+ switch (context.orientation) {
+ case Orientation.HORIZONTAL:
+ context.attr1 = context.view1 !== stackView ? Attribute.RIGHT : Attribute.LEFT;
+ context.attr2 = Attribute.LEFT;
+ break;
+ case Orientation.VERTICAL:
+ context.attr1 = context.view1 !== stackView ? Attribute.BOTTOM : Attribute.TOP;
+ context.attr2 = Attribute.TOP;
+ break;
+ case Orientation.ZINDEX:
+ context.attr1 = Attribute.ZINDEX;
+ context.attr2 = Attribute.ZINDEX;
+ context.relation.constant = context.view1 !== stackView ? 'default' : 0;
+ break;
+ }
+ context.constraints.push({
+ view1: context.view1,
+ attr1: context.attr1,
+ relation: context.relation.relation,
+ view2: name,
+ attr2: context.attr2,
+ priority: context.relation.priority
+ });
+ context.view1 = name;
+}
+
+/**
+ * Helper function that inserts proportional spacers (-12%-).
+ * @private
+ */
+function _processProportionalSpacer(context, stackView) {
+ context.proportionalSpacerIndex = context.proportionalSpacerIndex || 1;
+ var name = '_-' + context.lineIndex + ':' + context.proportionalSpacerIndex + '-';
+ context.proportionalSpacerIndex++;
+ context.constraints.push({
+ view1: name,
+ attr1: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
+ relation: context.relation.relation || Relation.EQU,
+ view2: null, // or relative to the stackView... food for thought
+ attr2: context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT,
+ priority: context.relation.priority,
+ multiplier: context.relation.multiplier
+ });
+ context.relation.multiplier = undefined;
+
+ // Add constraint
+ switch (context.orientation) {
+ case Orientation.HORIZONTAL:
+ context.attr1 = context.view1 !== stackView ? Attribute.RIGHT : Attribute.LEFT;
+ context.attr2 = Attribute.LEFT;
+ break;
+ case Orientation.VERTICAL:
+ context.attr1 = context.view1 !== stackView ? Attribute.BOTTOM : Attribute.TOP;
+ context.attr2 = Attribute.TOP;
+ break;
+ case Orientation.ZINDEX:
+ context.attr1 = Attribute.ZINDEX;
+ context.attr2 = Attribute.ZINDEX;
+ context.relation.constant = context.view1 !== stackView ? 'default' : 0;
+ break;
+ }
+ context.constraints.push({
+ view1: context.view1,
+ attr1: context.attr1,
+ relation: context.relation.relation,
+ view2: name,
+ attr2: context.attr2,
+ priority: context.relation.priority
+ });
+ context.view1 = name;
+}
+
+/**
+ * In case of a stack-view, set constraints for opposite orientations
+ * @private
+ */
+function _processStackView(context, name, subView) {
+ var viewName = undefined;
+ for (var orientation = 1; orientation <= 4; orientation *= 2) {
+ if (subView.orientations & orientation && subView.stack.orientation !== orientation && !(subView.stack.processedOrientations & orientation)) {
+ subView.stack.processedOrientations = subView.stack.processedOrientations | orientation;
+ viewName = viewName || {
+ name: name,
+ type: 'stack'
+ };
+ for (var i = 0, j = subView.stack.subViews.length; i < j; i++) {
+ if (orientation === Orientation.ZINDEX) {
+ context.constraints.push({
+ view1: viewName,
+ attr1: Attribute.ZINDEX,
+ relation: Relation.EQU,
+ view2: subView.stack.subViews[i],
+ attr2: Attribute.ZINDEX
+ });
+ } else {
+ context.constraints.push({
+ view1: viewName,
+ attr1: orientation === Orientation.VERTICAL ? Attribute.HEIGHT : Attribute.WIDTH,
+ relation: Relation.EQU,
+ view2: subView.stack.subViews[i],
+ attr2: orientation === Orientation.VERTICAL ? Attribute.HEIGHT : Attribute.WIDTH
+ });
+ context.constraints.push({
+ view1: viewName,
+ attr1: orientation === Orientation.VERTICAL ? Attribute.TOP : Attribute.LEFT,
+ relation: Relation.EQU,
+ view2: subView.stack.subViews[i],
+ attr2: orientation === Orientation.VERTICAL ? Attribute.TOP : Attribute.LEFT
+ });
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Recursive helper function that processes the cascaded data.
+ * @private
+ */
+function _processCascade(context, cascade, stackView) {
+ var subViews = [];
+ var subView = undefined;
+ if (stackView) {
+ cascade.push({ view: stackView });
+ }
+ for (var i = 0; i < cascade.length; i++) {
+ context.item = cascade[i];
+ if (!Array.isArray(context.item) && context.item.hasOwnProperty('view')) {
+ context.view1 = context.view2;
+ context.view2 = context.item.view;
+ if (context.view1 !== undefined && context.view2 !== undefined && context.relation) {
+ if (context.item.view !== stackView) {
+ subViews.push(context.item.view);
+ subView = context.subViews[context.item.view];
+ if (!subView) {
+ subView = { orientations: 0 };
+ context.subViews[context.item.view] = subView;
+ }
+ subView.orientations = subView.orientations | context.orientation;
+ if (subView.stack) {
+ _processStackView(context, context.item.view, subView);
+ }
+ }
+ if (context.relation.equalSpacing) {
+ _processEqualSpacer(context, stackView);
+ }
+ if (context.relation.multiplier) {
+ _processProportionalSpacer(context, stackView);
+ }
+ if (context.relation.relation !== 'none') {
+ switch (context.orientation) {
+ case Orientation.HORIZONTAL:
+ context.attr1 = context.view1 !== stackView ? Attribute.RIGHT : Attribute.LEFT;
+ context.attr2 = context.view2 !== stackView ? Attribute.LEFT : Attribute.RIGHT;
+ break;
+ case Orientation.VERTICAL:
+ context.attr1 = context.view1 !== stackView ? Attribute.BOTTOM : Attribute.TOP;
+ context.attr2 = context.view2 !== stackView ? Attribute.TOP : Attribute.BOTTOM;
+ break;
+ case Orientation.ZINDEX:
+ context.attr1 = Attribute.ZINDEX;
+ context.attr2 = Attribute.ZINDEX;
+ context.relation.constant = context.view1 !== stackView ? 'default' : 0;
+ break;
+ }
+ context.constraints.push({
+ view1: context.view1,
+ attr1: context.attr1,
+ relation: context.relation.relation,
+ view2: context.view2,
+ attr2: context.attr2,
+ multiplier: context.relation.multiplier,
+ constant: context.relation.constant === 'default' || !context.relation.constant ? context.relation.constant : -context.relation.constant,
+ priority: context.relation.priority
+ //,variable: context.relation.variable
+ });
+ }
+ }
+ context.relation = undefined;
+
+ // process view size constraints
+ if (context.item.constraints) {
+ for (var n = 0; n < context.item.constraints.length; n++) {
+ context.attr1 = context.horizontal ? Attribute.WIDTH : Attribute.HEIGHT;
+ context.attr2 = context.item.constraints[n].view || context.item.constraints[n].multiplier ? context.item.constraints[n].attribute || context.attr1 : context.item.constraints[n].variable ? Attribute.VARIABLE : Attribute.CONST;
+ context.constraints.push({
+ view1: context.item.view,
+ attr1: context.attr1,
+ relation: context.item.constraints[n].relation,
+ view2: context.item.constraints[n].view,
+ attr2: context.attr2,
+ multiplier: context.item.constraints[n].multiplier,
+ constant: context.item.constraints[n].constant,
+ priority: context.item.constraints[n].priority
+ //,variable: context.item.constraints[n].variable
+ });
+ }
+ }
+
+ // Process cascaded data (child stack-views)
+ if (context.item.cascade) {
+ _processCascade(context, context.item.cascade, context.item.view);
+ }
+ } else {
+ context.relation = context.item[0];
+ }
+ }
+
+ if (stackView) {
+ subView = context.subViews[stackView];
+ if (subView.stack) {
+ throw new Error('A stack with name "' + stackView + '"" already exists');
+ }
+ subView.stack = {
+ orientation: context.orientation,
+ processedOrientations: context.orientation,
+ subViews: subViews
+ };
+ _processStackView(context, stackView, subView);
+ }
+}
+
+var metaInfoCategories = ['viewport', 'spacing', 'colors', 'shapes', 'widths', 'heights'];
+
+/**
+ * VisualFormat
+ *
+ * @namespace VisualFormat
+ */
+
+var VisualFormat = (function () {
+ function VisualFormat() {
+ _classCallCheck(this, VisualFormat);
+ }
+
+ _createClass(VisualFormat, null, [{
+ key: 'parseLine',
+
+ /**
+ * Parses a single line of vfl into an array of constraint definitions.
+ *
+ * When the visual-format could not be succesfully parsed an exception is thrown containing
+ * additional info about the parse error and column position.
+ *
+ * @param {String} visualFormat Visual format string (cannot contain line-endings!).
+ * @param {Object} [options] Configuration options.
+ * @param {Boolean} [options.extended] When set to true uses the extended syntax (default: false).
+ * @param {String} [options.outFormat] Output format (`constraints` or `raw`) (default: `constraints`).
+ * @param {Number} [options.lineIndex] Line-index used when auto generating equal-spacing constraints.
+ * @return {Array} Array of constraint definitions.
+ */
+ value: function parseLine(visualFormat, options) {
+ if (visualFormat.length === 0 || options && options.extended && visualFormat.indexOf('//') === 0) {
+ return [];
+ }
+ var res = options && options.extended ? parserExt.parse(visualFormat) : parser.parse(visualFormat);
+ if (options && options.outFormat === 'raw') {
+ return [res];
+ }
+ var context = {
+ constraints: [],
+ lineIndex: (options ? options.lineIndex : undefined) || 1,
+ subViews: (options ? options.subViews : undefined) || {}
+ };
+ switch (res.orientation) {
+ case 'horizontal':
+ context.orientation = Orientation.HORIZONTAL;
+ context.horizontal = true;
+ break;
+ case 'vertical':
+ context.orientation = Orientation.VERTICAL;
+ break;
+ case 'zIndex':
+ context.orientation = Orientation.ZINDEX;
+ break;
+ }
+ _processCascade(context, res.cascade, null);
+ return context.constraints;
+ }
+ }, {
+ key: 'parse',
+
+ /**
+ * Parses one or more visual format strings into an array of constraint definitions.
+ *
+ * When the visual-format could not be succesfully parsed an exception is thrown containing
+ * additional info about the parse error and column position.
+ *
+ * @param {String|Array} visualFormat One or more visual format strings.
+ * @param {Object} [options] Configuration options.
+ * @param {Boolean} [options.extended] When set to true uses the extended syntax (default: false).
+ * @param {Boolean} [options.strict] When set to false trims any leading/trailing spaces and ignores empty lines (default: true).
+ * @param {String} [options.lineSeperator] String that defines the end of a line (default `\n`).
+ * @param {String} [options.outFormat] Output format (`constraints` or `raw`) (default: `constraints`).
+ * @return {Array} Array of constraint definitions.
+ */
+ value: function parse(visualFormat, options) {
+ var lineSeperator = options && options.lineSeperator ? options.lineSeperator : '\n';
+ if (!Array.isArray(visualFormat) && visualFormat.indexOf(lineSeperator) < 0) {
+ try {
+ return this.parseLine(visualFormat, options);
+ } catch (err) {
+ err.source = visualFormat;
+ throw err;
+ }
+ }
+
+ // Decompose visual-format into an array of strings, and within those strings
+ // search for line-endings, and treat each line as a seperate visual-format.
+ visualFormat = Array.isArray(visualFormat) ? visualFormat : [visualFormat];
+ var lines = undefined;
+ var constraints = [];
+ var lineIndex = 0;
+ var line = undefined;
+ var parseOptions = {
+ lineIndex: lineIndex,
+ extended: options && options.extended,
+ strict: options && options.strict !== undefined ? options.strict : true,
+ outFormat: options ? options.outFormat : undefined,
+ subViews: {}
+ };
+ try {
+ for (var i = 0; i < visualFormat.length; i++) {
+ lines = visualFormat[i].split(lineSeperator);
+ for (var j = 0; j < lines.length; j++) {
+ line = lines[j];
+ lineIndex++;
+ parseOptions.lineIndex = lineIndex;
+ if (!parseOptions.strict) {
+ line = line.trim();
+ }
+ if (parseOptions.strict || line.length) {
+ constraints = constraints.concat(this.parseLine(line, parseOptions));
+ }
+ }
+ }
+ } catch (err) {
+ err.source = line;
+ err.line = lineIndex;
+ throw err;
+ }
+ return constraints;
+ }
+ }, {
+ key: 'parseMetaInfo',
+
+ /**
+ * Parses meta information from the comments in the VFL.
+ *
+ * Additional meta information can be specified in the comments
+ * for previewing and rendering purposes. For instance, the view-port
+ * aspect-ratio, sub-view widths and colors, can be specified. The
+ * following example renders three colored circles in the visual-format editor:
+ *
+ * ```vfl
+ * //viewport aspect-ratio:3/1 max-height:300
+ * //colors red:#FF0000 green:#00FF00 blue:#0000FF
+ * //shapes red:circle green:circle blue:circle
+ * H:|-[row:[red(green,blue)]-[green]-[blue]]-|
+ * V:|[row]|
+ * ```
+ *
+ * Supported categories and properties:
+ *
+ * |Category|Property|Example|
+ * |--------|--------|-------|
+ * |`viewport`|`aspect-ratio:{width}/{height}`|`//viewport aspect-ratio:16/9`|
+ * ||`width:[{number}/intrinsic]`|`//viewport width:10`|
+ * ||`height:[{number}/intrinsic]`|`//viewport height:intrinsic`|
+ * ||`min-width:{number}`|
+ * ||`max-width:{number}`|
+ * ||`min-height:{number}`|
+ * ||`max-height:{number}`|
+ * |`spacing`|`[{number}/array]`|`//spacing:8` or `//spacing:[10, 20, 5]`|
+ * |`widths`|`{view-name}:[{number}/intrinsic]`|`//widths subview1:100`|
+ * |`heights`|`{view-name}:[{number}/intrinsic]`|`//heights subview1:intrinsic`|
+ * |`colors`|`{view-name}:{color}`|`//colors redview:#FF0000 blueview:#00FF00`|
+ * |`shapes`|`{view-name}:[circle/square]`|`//shapes avatar:circle`|
+ *
+ * @param {String|Array} visualFormat One or more visual format strings.
+ * @param {Object} [options] Configuration options.
+ * @param {String} [options.lineSeperator] String that defines the end of a line (default `\n`).
+ * @return {Object} meta-info
+ */
+ value: function parseMetaInfo(visualFormat, options) {
+ var lineSeperator = options && options.lineSeperator ? options.lineSeperator : '\n';
+ visualFormat = Array.isArray(visualFormat) ? visualFormat : [visualFormat];
+ var metaInfo = {};
+ var key;
+ for (var k = 0; k < visualFormat.length; k++) {
+ var lines = visualFormat[k].split(lineSeperator);
+ for (var i = 0; i < lines.length; i++) {
+ var line = lines[i];
+ for (var c = 0; c < metaInfoCategories.length; c++) {
+ var category = metaInfoCategories[c];
+ if (line.indexOf('//' + category + ' ') === 0) {
+ var items = line.substring(3 + category.length).split(' ');
+ for (var j = 0; j < items.length; j++) {
+ var item = items[j].split(':');
+ metaInfo[category] = metaInfo[category] || {};
+ metaInfo[category][item[0]] = item.length > 1 ? item[1] : '';
+ }
+ } else if (line.indexOf('//' + category + ':') === 0) {
+ metaInfo[category] = line.substring(3 + category.length);
+ }
+ }
+ }
+ }
+ if (metaInfo.viewport) {
+ var viewport = metaInfo.viewport;
+ var aspectRatio = viewport['aspect-ratio'];
+ if (aspectRatio) {
+ aspectRatio = aspectRatio.split('/');
+ viewport['aspect-ratio'] = parseInt(aspectRatio[0]) / parseInt(aspectRatio[1]);
+ }
+ if (viewport.height !== undefined) {
+ viewport.height = viewport.height === 'intrinsic' ? true : parseInt(viewport.height);
+ }
+ if (viewport.width !== undefined) {
+ viewport.width = viewport.width === 'intrinsic' ? true : parseInt(viewport.width);
+ }
+ if (viewport['max-height'] !== undefined) {
+ viewport['max-height'] = parseInt(viewport['max-height']);
+ }
+ if (viewport['max-width'] !== undefined) {
+ viewport['max-width'] = parseInt(viewport['max-width']);
+ }
+ if (viewport['min-height'] !== undefined) {
+ viewport['min-height'] = parseInt(viewport['min-height']);
+ }
+ if (viewport['min-width'] !== undefined) {
+ viewport['min-width'] = parseInt(viewport['min-width']);
+ }
+ }
+ if (metaInfo.widths) {
+ for (key in metaInfo.widths) {
+ var width = metaInfo.widths[key] === 'intrinsic' ? true : parseInt(metaInfo.widths[key]);
+ metaInfo.widths[key] = width;
+ if (width === undefined || isNaN(width)) {
+ delete metaInfo.widths[key];
+ }
+ }
+ }
+ if (metaInfo.heights) {
+ for (key in metaInfo.heights) {
+ var height = metaInfo.heights[key] === 'intrinsic' ? true : parseInt(metaInfo.heights[key]);
+ metaInfo.heights[key] = height;
+ if (height === undefined || isNaN(height)) {
+ delete metaInfo.heights[key];
+ }
+ }
+ }
+ if (metaInfo.spacing) {
+ var value = JSON.parse(metaInfo.spacing);
+ metaInfo.spacing = value;
+ if (value === undefined || isNaN(value)) {
+ delete metaInfo.spacing;
+ }
+ }
+ return metaInfo;
+ }
+ }]);
+
+ return VisualFormat;
+})();
+
+var SubView = (function () {
+ function SubView(options) {
+ _classCallCheck(this, SubView);
+
+ this._name = options.name;
+ this._type = options.type;
+ this._solver = options.solver;
+ this._attr = {};
+ if (!options.name) {
+ if (false) {
+ this._attr[Attribute.LEFT] = new c.Variable();
+ this._solver.addConstraint(new c.StayConstraint(this._attr[Attribute.LEFT], c.Strength.required));
+ this._attr[Attribute.TOP] = new c.Variable();
+ this._solver.addConstraint(new c.StayConstraint(this._attr[Attribute.TOP], c.Strength.required));
+ this._attr[Attribute.ZINDEX] = new c.Variable();
+ this._solver.addConstraint(new c.StayConstraint(this._attr[Attribute.ZINDEX], c.Strength.required));
+ } else {
+ this._attr[Attribute.LEFT] = new kiwi.Variable();
+ this._solver.addConstraint(new kiwi.Constraint(this._attr[Attribute.LEFT], kiwi.Operator.Eq, 0));
+ this._attr[Attribute.TOP] = new kiwi.Variable();
+ this._solver.addConstraint(new kiwi.Constraint(this._attr[Attribute.TOP], kiwi.Operator.Eq, 0));
+ this._attr[Attribute.ZINDEX] = new kiwi.Variable();
+ this._solver.addConstraint(new kiwi.Constraint(this._attr[Attribute.ZINDEX], kiwi.Operator.Eq, 0));
+ }
+ }
+ }
+
+ _createClass(SubView, [{
+ key: 'toJSON',
+ value: function toJSON() {
+ return {
+ name: this.name,
+ left: this.left,
+ top: this.top,
+ width: this.width,
+ height: this.height
+ };
+ }
+ }, {
+ key: 'toString',
+ value: function toString() {
+ JSON.stringify(this.toJSON(), undefined, 2);
+ }
+ }, {
+ key: 'name',
+
+ /**
+ * Name of the sub-view.
+ * @readonly
+ * @type {String}
+ */
+ get: function () {
+ return this._name;
+ }
+ }, {
+ key: 'left',
+
+ /**
+ * Left value (`Attribute.LEFT`).
+ * @readonly
+ * @type {Number}
+ */
+ get: function () {
+ return this._getAttrValue(Attribute.LEFT);
+ }
+ }, {
+ key: 'right',
+
+ /**
+ * Right value (`Attribute.RIGHT`).
+ * @readonly
+ * @type {Number}
+ */
+ get: function () {
+ return this._getAttrValue(Attribute.RIGHT);
+ }
+ }, {
+ key: 'width',
+
+ /**
+ * Width value (`Attribute.WIDTH`).
+ * @type {Number}
+ */
+ get: function () {
+ return this._getAttrValue(Attribute.WIDTH);
+ }
+ }, {
+ key: 'height',
+
+ /**
+ * Height value (`Attribute.HEIGHT`).
+ * @readonly
+ * @type {Number}
+ */
+ get: function () {
+ return this._getAttrValue(Attribute.HEIGHT);
+ }
+ }, {
+ key: 'intrinsicWidth',
+
+ /**
+ * Intrinsic width of the sub-view.
+ *
+ * Use this property to explicitely set the width of the sub-view, e.g.:
+ * ```javascript
+ * var view = new AutoLayout.View(AutoLayout.VisualFormat.parse('|[child1][child2]|'), {
+ * width: 500
+ * });
+ * view.subViews.child1.intrinsicWidth = 100;
+ * console.log('child2 width: ' + view.subViews.child2.width); // 400
+ * ```
+ *
+ * @type {Number}
+ */
+ get: function () {
+ return this._intrinsicWidth;
+ },
+ set: function (value) {
+ if (value !== undefined && value !== this._intrinsicWidth) {
+ var attr = this._getAttr(Attribute.WIDTH);
+ if (this._intrinsicWidth === undefined) {
+ if (false) {
+ this._solver.addEditVar(attr, new c.Strength('required', this._name ? 998 : 999, 1000, 1000));
+ } else {
+ this._solver.addEditVariable(attr, kiwi.Strength.create(this._name ? 998 : 999, 1000, 1000));
+ }
+ }
+ this._intrinsicWidth = value;
+ this._solver.suggestValue(attr, value);
+ if (false) {
+ this._solver.resolve();
+ } else {
+ this._solver.updateVariables();
+ }
+ }
+ }
+ }, {
+ key: 'intrinsicHeight',
+
+ /**
+ * Intrinsic height of the sub-view.
+ *
+ * See `intrinsicWidth`.
+ *
+ * @type {Number}
+ */
+ get: function () {
+ return this._intrinsicHeight;
+ },
+ set: function (value) {
+ if (value !== undefined && value !== this._intrinsicHeight) {
+ var attr = this._getAttr(Attribute.HEIGHT);
+ if (this._intrinsicHeight === undefined) {
+ if (false) {
+ this._solver.addEditVar(attr, new c.Strength('required', this._name ? 998 : 999, 1000, 1000));
+ } else {
+ this._solver.addEditVariable(attr, kiwi.Strength.create(this._name ? 998 : 999, 1000, 1000));
+ }
+ }
+ this._intrinsicHeight = value;
+ this._solver.suggestValue(attr, value);
+ if (false) {
+ this._solver.resolve();
+ } else {
+ this._solver.updateVariables();
+ }
+ }
+ }
+ }, {
+ key: 'top',
+
+ /**
+ * Top value (`Attribute.TOP`).
+ * @readonly
+ * @type {Number}
+ */
+ get: function () {
+ return this._getAttrValue(Attribute.TOP);
+ }
+ }, {
+ key: 'bottom',
+
+ /**
+ * Bottom value (`Attribute.BOTTOM`).
+ * @readonly
+ * @type {Number}
+ */
+ get: function () {
+ return this._getAttrValue(Attribute.BOTTOM);
+ }
+ }, {
+ key: 'centerX',
+
+ /**
+ * Horizontal center (`Attribute.CENTERX`).
+ * @readonly
+ * @type {Number}
+ */
+ get: function () {
+ return this._getAttrValue(Attribute.CENTERX);
+ }
+ }, {
+ key: 'centerY',
+
+ /**
+ * Vertical center (`Attribute.CENTERY`).
+ * @readonly
+ * @type {Number}
+ */
+ get: function () {
+ return this._getAttrValue(Attribute.CENTERY);
+ }
+ }, {
+ key: 'zIndex',
+
+ /**
+ * Z-index (`Attribute.ZINDEX`).
+ * @readonly
+ * @type {Number}
+ */
+ get: function () {
+ return this._getAttrValue(Attribute.ZINDEX);
+ }
+ }, {
+ key: 'type',
+
+ /**
+ * Returns the type of the sub-view.
+ * @readonly
+ * @type {String}
+ */
+ get: function () {
+ return this._type;
+ }
+ }, {
+ key: 'getValue',
+
+ /**
+ * Gets the value of one of the attributes.
+ *
+ * @param {String|Attribute} attr Attribute name (e.g. 'right', 'centerY', Attribute.TOP).
+ * @return {Number} value or `undefined`
+ */
+ value: function getValue(attr) {
+ return this._attr[attr] ? this._attr[attr].value() : undefined;
+ }
+ }, {
+ key: '_getAttr',
+
+ /**
+ * @private
+ */
+ value: function _getAttr(attr) {
+ if (this._attr[attr]) {
+ return this._attr[attr];
+ }
+ this._attr[attr] = false ? new c.Variable() : new kiwi.Variable();
+ switch (attr) {
+ case Attribute.RIGHT:
+ this._getAttr(Attribute.LEFT);
+ this._getAttr(Attribute.WIDTH);
+ if (false) {
+ this._solver.addConstraint(new c.Equation(this._attr[attr], c.plus(this._attr[Attribute.LEFT], this._attr[Attribute.WIDTH])));
+ } else {
+ this._solver.addConstraint(new kiwi.Constraint(this._attr[attr], kiwi.Operator.Eq, this._attr[Attribute.LEFT].plus(this._attr[Attribute.WIDTH])));
+ }
+ break;
+ case Attribute.BOTTOM:
+ this._getAttr(Attribute.TOP);
+ this._getAttr(Attribute.HEIGHT);
+ if (false) {
+ this._solver.addConstraint(new c.Equation(this._attr[attr], c.plus(this._attr[Attribute.TOP], this._attr[Attribute.HEIGHT])));
+ } else {
+ this._solver.addConstraint(new kiwi.Constraint(this._attr[attr], kiwi.Operator.Eq, this._attr[Attribute.TOP].plus(this._attr[Attribute.HEIGHT])));
+ }
+ break;
+ case Attribute.CENTERX:
+ this._getAttr(Attribute.LEFT);
+ this._getAttr(Attribute.WIDTH);
+ if (false) {
+ this._solver.addConstraint(new c.Equation(this._attr[attr], c.plus(this._attr[Attribute.LEFT], c.divide(this._attr[Attribute.WIDTH], 2))));
+ } else {
+ this._solver.addConstraint(new kiwi.Constraint(this._attr[attr], kiwi.Operator.Eq, this._attr[Attribute.LEFT].plus(this._attr[Attribute.WIDTH].divide(2))));
+ }
+ break;
+ case Attribute.CENTERY:
+ this._getAttr(Attribute.TOP);
+ this._getAttr(Attribute.HEIGHT);
+ if (false) {
+ this._solver.addConstraint(new c.Equation(this._attr[attr], c.plus(this._attr[Attribute.TOP], c.divide(this._attr[Attribute.HEIGHT], 2))));
+ } else {
+ this._solver.addConstraint(new kiwi.Constraint(this._attr[attr], kiwi.Operator.Eq, this._attr[Attribute.TOP].plus(this._attr[Attribute.HEIGHT].divide(2))));
+ }
+ break;
+ }
+ if (!false) {
+ this._solver.updateVariables();
+ }
+ return this._attr[attr];
+ }
+ }, {
+ key: '_getAttrValue',
+
+ /**
+ * @private
+ */
+ value: function _getAttrValue(attr) {
+ if (false) {
+ return this._getAttr(attr).value;
+ } else {
+ return this._getAttr(attr).value();
+ }
+ }
+ }]);
+
+ return SubView;
+})();
+
+var defaultPriorityStrength = false ? new c.Strength('defaultPriority', 0, 1000, 1000) : kiwi.Strength.create(0, 1000, 1000);
+
+function _getConst(name, value) {
+ if (false) {
+ var vr = new c.Variable({ value: value });
+ this._solver.addConstraint(new c.StayConstraint(vr, c.Strength.required, 0));
+ return vr;
+ } else {
+ var vr = new kiwi.Variable();
+ this._solver.addConstraint(new kiwi.Constraint(vr, kiwi.Operator.Eq, value));
+ return vr;
+ }
+}
+
+function _getSubView(viewName) {
+ if (!viewName) {
+ return this._parentSubView;
+ } else if (viewName.name) {
+ this._subViews[viewName.name] = this._subViews[viewName.name] || new SubView({
+ name: viewName.name,
+ solver: this._solver
+ });
+ this._subViews[viewName.name]._type = this._subViews[viewName.name]._type || viewName.type;
+ return this._subViews[viewName.name];
+ } else {
+ this._subViews[viewName] = this._subViews[viewName] || new SubView({
+ name: viewName,
+ solver: this._solver
+ });
+ return this._subViews[viewName];
+ }
+}
+
+function _getSpacing(constraint) {
+ var index = 4;
+ if (!constraint.view1 && constraint.attr1 === 'left') {
+ index = 3;
+ } else if (!constraint.view1 && constraint.attr1 === 'top') {
+ index = 0;
+ } else if (!constraint.view2 && constraint.attr2 === 'right') {
+ index = 1;
+ } else if (!constraint.view2 && constraint.attr2 === 'bottom') {
+ index = 2;
+ } else {
+ switch (constraint.attr1) {
+ case 'left':
+ case 'right':
+ case 'centerX':
+ case 'leading':
+ case 'trailing':
+ index = 4;
+ break;
+ case 'zIndex':
+ index = 6;
+ break;
+ default:
+ index = 5;
+ }
+ }
+ this._spacingVars = this._spacingVars || new Array(7);
+ this._spacingExpr = this._spacingExpr || new Array(7);
+ if (!this._spacingVars[index]) {
+ if (false) {
+ this._spacingVars[index] = new c.Variable();
+ this._solver.addEditVar(this._spacingVars[index]);
+ this._spacingExpr[index] = c.minus(0, this._spacingVars[index]);
+ } else {
+ this._spacingVars[index] = new kiwi.Variable();
+ this._solver.addEditVariable(this._spacingVars[index], kiwi.Strength.create(999, 1000, 1000));
+ this._spacingExpr[index] = this._spacingVars[index].multiply(-1);
+ }
+ this._solver.suggestValue(this._spacingVars[index], this._spacing[index]);
+ }
+ return this._spacingExpr[index];
+}
+
+function _addConstraint(constraint) {
+ //this.constraints.push(constraint);
+ var relation = undefined;
+ var multiplier = constraint.multiplier !== undefined ? constraint.multiplier : 1;
+ var constant = constraint.constant !== undefined ? constraint.constant : 0;
+ if (constant === 'default') {
+ constant = _getSpacing.call(this, constraint);
+ }
+ var attr1 = _getSubView.call(this, constraint.view1)._getAttr(constraint.attr1);
+ var attr2 = undefined;
+ if (false) {
+ if (constraint.attr2 === Attribute.CONST) {
+ attr2 = _getConst.call(this, undefined, constraint.constant);
+ } else {
+ attr2 = _getSubView.call(this, constraint.view2)._getAttr(constraint.attr2);
+ if (multiplier !== 1 && constant) {
+ attr2 = c.plus(c.times(attr2, multiplier), constant);
+ } else if (constant) {
+ attr2 = c.plus(attr2, constant);
+ } else if (multiplier !== 1) {
+ attr2 = c.times(attr2, multiplier);
+ }
+ }
+ var strength = constraint.priority !== undefined && constraint.priority < 1000 ? new c.Strength('priority', 0, constraint.priority, 1000) : defaultPriorityStrength;
+ switch (constraint.relation) {
+ case Relation.EQU:
+ relation = new c.Equation(attr1, attr2, strength);
+ break;
+ case Relation.GEQ:
+ relation = new c.Inequality(attr1, c.GEQ, attr2, strength);
+ break;
+ case Relation.LEQ:
+ relation = new c.Inequality(attr1, c.LEQ, attr2, strength);
+ break;
+ default:
+ throw 'Invalid relation specified: ' + constraint.relation;
+ }
+ } else {
+ if (constraint.attr2 === Attribute.CONST) {
+ attr2 = _getConst.call(this, undefined, constraint.constant);
+ } else {
+ attr2 = _getSubView.call(this, constraint.view2)._getAttr(constraint.attr2);
+ if (multiplier !== 1 && constant) {
+ attr2 = attr2.multiply(multiplier).plus(constant);
+ } else if (constant) {
+ attr2 = attr2.plus(constant);
+ } else if (multiplier !== 1) {
+ attr2 = attr2.multiply(multiplier);
+ }
+ }
+ var strength = constraint.priority !== undefined && constraint.priority < 1000 ? kiwi.Strength.create(0, constraint.priority, 1000) : defaultPriorityStrength;
+ switch (constraint.relation) {
+ case Relation.EQU:
+ relation = new kiwi.Constraint(attr1, kiwi.Operator.Eq, attr2, strength);
+ break;
+ case Relation.GEQ:
+ relation = new kiwi.Constraint(attr1, kiwi.Operator.Ge, attr2, strength);
+ break;
+ case Relation.LEQ:
+ relation = new kiwi.Constraint(attr1, kiwi.Operator.Le, attr2, strength);
+ break;
+ default:
+ throw 'Invalid relation specified: ' + constraint.relation;
+ }
+ }
+ this._solver.addConstraint(relation);
+}
+
+function _compareSpacing(old, newz) {
+ if (old === newz) {
+ return true;
+ }
+ if (!old || !newz) {
+ return false;
+ }
+ for (var i = 0; i < 7; i++) {
+ if (old[i] !== newz[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/**
+ * AutoLayoutJS API reference.
+ *
+ * ### Index
+ *
+ * |Entity|Type|Description|
+ * |---|---|---|
+ * |[AutoLayout](#autolayout)|`namespace`|Top level AutoLayout object.|
+ * |[VisualFormat](#autolayoutvisualformat--object)|`namespace`|Parses VFL into constraints.|
+ * |[View](#autolayoutview)|`class`|Main entity for adding & evaluating constraints.|
+ * |[SubView](#autolayoutsubview--object)|`class`|SubView's are automatically created when constraints are added to views. They give access to the evaluated results.|
+ * |[Attribute](#autolayoutattribute--enum)|`enum`|Attribute types that are supported when adding constraints.|
+ * |[Relation](#autolayoutrelation--enum)|`enum`|Relationship types that are supported when adding constraints.|
+ * |[Priority](#autolayoutpriority--enum)|`enum`|Default priority values for when adding constraints.|
+ *
+ * ### AutoLayout
+ *
+ * @module AutoLayout
+ */
+
+var View = (function () {
+
+ /**
+ * @class View
+ * @param {Object} [options] Configuration options.
+ * @param {Number} [options.width] Initial width of the view.
+ * @param {Number} [options.height] Initial height of the view.
+ * @param {Number|Object} [options.spacing] Spacing for the view (default: 8) (see `setSpacing`).
+ * @param {Array} [options.constraints] One or more constraint definitions (see `addConstraints`).
+ */
+
+ function View(options) {
+ _classCallCheck(this, View);
+
+ this._solver = false ? new c.SimplexSolver() : new kiwi.Solver();
+ this._subViews = {};
+ //this._spacing = undefined;
+ this._parentSubView = new SubView({
+ solver: this._solver
+ });
+ this.setSpacing(options && options.spacing !== undefined ? options.spacing : 8);
+ //this.constraints = [];
+ if (options) {
+ if (options.width !== undefined || options.height !== undefined) {
+ this.setSize(options.width, options.height);
+ }
+ if (options.constraints) {
+ this.addConstraints(options.constraints);
+ }
+ }
+ }
+
+ _createClass(View, [{
+ key: 'setSize',
+
+ /**
+ * Sets the width and height of the view.
+ *
+ * @param {Number} width Width of the view.
+ * @param {Number} height Height of the view.
+ * @return {View} this
+ */
+ value: function setSize(width, height /*, depth*/) {
+ this._parentSubView.intrinsicWidth = width;
+ this._parentSubView.intrinsicHeight = height;
+ return this;
+ }
+ }, {
+ key: 'width',
+
+ /**
+ * Width that was set using `setSize`.
+ * @readonly
+ * @type {Number}
+ */
+ get: function () {
+ return this._parentSubView.intrinsicWidth;
+ }
+ }, {
+ key: 'height',
+
+ /**
+ * Height that was set using `setSize`.
+ * @readonly
+ * @type {Number}
+ */
+ get: function () {
+ return this._parentSubView.intrinsicHeight;
+ }
+ }, {
+ key: 'fittingWidth',
+
+ /**
+ * Width that is calculated from the constraints and the `.intrinsicWidth` of
+ * the sub-views.
+ *
+ * When the width has been explicitely set using `setSize`, the fittingWidth
+ * will **always** be the same as the explicitely set width. To calculate the size
+ * based on the content, use:
+ * ```javascript
+ * var view = new AutoLayout.View({
+ * constraints: VisualFormat.parse('|-[view1]-[view2]-'),
+ * spacing: 20
+ * });
+ * view.subViews.view1.intrinsicWidth = 100;
+ * view.subViews.view2.intrinsicWidth = 100;
+ * console.log('fittingWidth: ' + view.fittingWidth); // 260
+ * ```
+ *
+ * @readonly
+ * @type {Number}
+ */
+ get: function () {
+ return this._parentSubView.width;
+ }
+ }, {
+ key: 'fittingHeight',
+
+ /**
+ * Height that is calculated from the constraints and the `.intrinsicHeight` of
+ * the sub-views.
+ *
+ * See `.fittingWidth`.
+ *
+ * @readonly
+ * @type {Number}
+ */
+ get: function () {
+ return this._parentSubView.height;
+ }
+ }, {
+ key: 'setSpacing',
+
+ /**
+ * Sets the spacing for the view.
+ *
+ * The spacing can be set for 7 different variables:
+ * `top`, `right`, `bottom`, `left`, `width`, `height` and `zIndex`. The `left`-spacing is
+ * used when a spacer is used between the parent-view and a sub-view (e.g. `|-[subView]`).
+ * The same is true for the `right`, `top` and `bottom` spacers. The `width` and `height` are
+ * used for spacers in between sub-views (e.g. `[view1]-[view2]`).
+ *
+ * Instead of using the full spacing syntax, it is also possible to use shorthand notations:
+ *
+ * |Syntax|Type|Description|
+ * |---|---|---|
+ * |`[top, right, bottom, left, width, height, zIndex]`|Array(7)|Full syntax including z-index **(clockwise order)**.|
+ * |`[top, right, bottom, left, width, height]`|Array(6)|Full horizontal & vertical spacing syntax (no z-index) **(clockwise order)**.|
+ * |`[horizontal, vertical, zIndex]`|Array(3)|Horizontal = left, right, width, vertical = top, bottom, height.|
+ * |`[horizontal, vertical]`|Array(2)|Horizontal = left, right, width, vertical = top, bottom, height, z-index = 1.|
+ * |`spacing`|Number|Horizontal & vertical spacing are all the same, z-index = 1.|
+ *
+ * Examples:
+ * ```javascript
+ * view.setSpacing(10); // horizontal & vertical spacing 10
+ * view.setSpacing([10, 15, 2]); // horizontal spacing 10, vertical spacing 15, z-axis spacing 2
+ * view.setSpacing([10, 20, 10, 20, 5, 5]); // top, right, bottom, left, horizontal, vertical
+ * view.setSpacing([10, 20, 10, 20, 5, 5, 1]); // top, right, bottom, left, horizontal, vertical, z
+ * ```
+ *
+ * @param {Number|Array} spacing
+ * @return {View} this
+ */
+ value: function setSpacing(spacing) {
+ // convert spacing into array: [top, right, bottom, left, horz, vert, z-index]
+ switch (Array.isArray(spacing) ? spacing.length : -1) {
+ case -1:
+ spacing = [spacing, spacing, spacing, spacing, spacing, spacing, 1];break;
+ case 1:
+ spacing = [spacing[0], spacing[0], spacing[0], spacing[0], spacing[0], spacing[0], 1];break;
+ case 2:
+ spacing = [spacing[1], spacing[0], spacing[1], spacing[0], spacing[0], spacing[1], 1];break;
+ case 3:
+ spacing = [spacing[1], spacing[0], spacing[1], spacing[0], spacing[0], spacing[1], spacing[2]];break;
+ case 6:
+ spacing = [spacing[0], spacing[1], spacing[2], spacing[3], spacing[4], spacing[5], 1];break;
+ case 7:
+ break;
+ default:
+ throw 'Invalid spacing syntax';
+ }
+ if (!_compareSpacing(this._spacing, spacing)) {
+ this._spacing = spacing;
+ // update spacing variables
+ if (this._spacingVars) {
+ for (var i = 0; i < this._spacingVars.length; i++) {
+ if (this._spacingVars[i]) {
+ this._solver.suggestValue(this._spacingVars[i], this._spacing[i]);
+ }
+ }
+ if (false) {
+ this._solver.resolve();
+ } else {
+ this._solver.updateVariables();
+ }
+ }
+ }
+ return this;
+ }
+ }, {
+ key: 'addConstraint',
+
+ /**
+ * Adds a constraint definition.
+ *
+ * A constraint definition has the following format:
+ *
+ * ```javascript
+ * constraint: {
+ * view1: {String},
+ * attr1: {AutoLayout.Attribute},
+ * relation: {AutoLayout.Relation},
+ * view2: {String},
+ * attr2: {AutoLayout.Attribute},
+ * multiplier: {Number},
+ * constant: {Number},
+ * priority: {Number}(0..1000)
+ * }
+ * ```
+ * @param {Object} constraint Constraint definition.
+ * @return {View} this
+ */
+ value: function addConstraint(constraint) {
+ _addConstraint.call(this, constraint);
+ if (!false) {
+ this._solver.updateVariables();
+ }
+ return this;
+ }
+ }, {
+ key: 'addConstraints',
+
+ /**
+ * Adds one or more constraint definitions.
+ *
+ * A constraint definition has the following format:
+ *
+ * ```javascript
+ * constraint: {
+ * view1: {String},
+ * attr1: {AutoLayout.Attribute},
+ * relation: {AutoLayout.Relation},
+ * view2: {String},
+ * attr2: {AutoLayout.Attribute},
+ * multiplier: {Number},
+ * constant: {Number},
+ * priority: {Number}(0..1000)
+ * }
+ * ```
+ * @param {Array} constraints One or more constraint definitions.
+ * @return {View} this
+ */
+ value: function addConstraints(constraints) {
+ for (var j = 0; j < constraints.length; j++) {
+ _addConstraint.call(this, constraints[j]);
+ }
+ if (!false) {
+ this._solver.updateVariables();
+ }
+ return this;
+ }
+ }, {
+ key: 'subViews',
+
+ /**
+ * Dictionary of `SubView` objects that have been created when adding constraints.
+ * @readonly
+ * @type {Object.SubView}
+ */
+ get: function () {
+ return this._subViews;
+ }
+
+ /**
+ * Checks whether the constraints incompletely specify the location
+ * of the subViews.
+ * @private
+ */
+ //get hasAmbiguousLayout() {
+ // Todo
+ //}
+
+ }]);
+
+ return View;
+})();
+
+var AutoLayout = {
+ Attribute: Attribute,
+ Relation: Relation,
+ Priority: Priority,
+ VisualFormat: VisualFormat,
+ View: View,
+ SubView: SubView
+ //DOM: DOM
+};
+
+module.exports = AutoLayout;
+
+},{"kiwi/ts/bin/kiwi":1}]},{},[2])(2)
+});
\ No newline at end of file