├── .gitignore ├── README.md ├── app.js ├── bower_components └── gss │ ├── .bower.json │ ├── CHANGES.md │ ├── LICENSE │ ├── README.md │ ├── bower.json │ ├── dist │ ├── gss.js │ ├── gss.min.js │ ├── gss │ │ └── vendor │ │ │ ├── MutationObserver.js │ │ │ ├── observe.js │ │ │ └── sidetable.js │ ├── slightlyoff-cassowary.js │ │ └── bin │ │ │ └── c.js │ ├── worker.js │ └── worker.min.js │ └── vendor │ ├── MutationObserver.js │ ├── gl-matrix-min.js │ ├── gl-matrix.js │ ├── observe.js │ └── sidetable.js ├── index.html ├── index.js ├── package.json └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *~ 3 | bundle.js -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-gss 2 | ![unmaintained](http://img.shields.io/badge/status-unmaintained-red.png) 3 | constraint layout system for components using grid stylesheets 4 | 5 | ```js 6 | var VerticalCenter = React.createClass({ 7 | render: function() { 8 | return this.transferPropsTo( 9 | 10 | {this.props.children} 11 | 12 | ); 13 | } 14 | }); 15 | 16 | var App = React.createClass({ 17 | render: function() { 18 | // You can prefix the props on Box with >= or <= for more control 19 | return ( 20 | 21 | 27 |

Heading

28 |
29 | 34 |
Left nav
35 |
36 | 42 |
Content
43 |
44 |
45 | ); 46 | } 47 | }); 48 | ``` 49 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | /** @jsx React.DOM */ 2 | 3 | var React = require('react'); 4 | var mq = require('react-responsive'); 5 | var {AutoLayout, Box} = require('./index'); 6 | 7 | var App = React.createClass({ 8 | render: function() { 9 | return ( 10 | 11 |

This is the header

12 | 13 |
This is the left nav
14 |
15 | 16 | 17 | Content here 18 | 19 | 20 |
21 | ); 22 | } 23 | }); 24 | 25 | GSS.once('afterLoaded', function() { 26 | React.renderComponent(, document.body); 27 | }); 28 | -------------------------------------------------------------------------------- /bower_components/gss/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gss", 3 | "homepage": "http://gridstylesheets.org/", 4 | "authors": [ 5 | "Dan Tocchini " 6 | ], 7 | "description": "Grid Style Sheets Runtime", 8 | "main": [ 9 | "dist/gss.js", 10 | "dist/gss.min.js", 11 | "dist/worker.js", 12 | "dist/worker.min.js" 13 | ], 14 | "keywords": [ 15 | "gss" 16 | ], 17 | "license": "MIT", 18 | "ignore": [ 19 | "/components", 20 | "/node_modules", 21 | "/bower_components", 22 | ".gitignore", 23 | "/src", 24 | "/lib", 25 | "/spec", 26 | "/demo", 27 | "/docs", 28 | "_layouts", 29 | "_includes", 30 | "_config.yml", 31 | "CNAME", 32 | "component.json", 33 | "package.json", 34 | "Gruntfile.coffee", 35 | "index.html", 36 | ".travis.yml" 37 | ], 38 | "version": "1.0.4-beta", 39 | "_release": "1.0.4-beta", 40 | "_resolution": { 41 | "type": "version", 42 | "tag": "1.0.4-beta", 43 | "commit": "4e1d9f5d824dd57800e1d2c1f87097c8417acf51" 44 | }, 45 | "_source": "git://github.com/the-gss/engine.git", 46 | "_target": "~1.0.4-beta", 47 | "_originalSource": "gss", 48 | "_direct": true 49 | } -------------------------------------------------------------------------------- /bower_components/gss/CHANGES.md: -------------------------------------------------------------------------------- 1 | GSS Engine ChangeLog 2 | ==================== 3 | 4 | ## 1.0.3-beta (May 24th 2014) 5 | 6 | - Selectors other than id, class & tag can now be used in CCSS when surrounded by parans: 7 | 8 | ```css 9 | (.section > article:not(.featured))[font-size] == 100; 10 | ``` 11 | 12 | - Support for plural selectors on either side of a constraint operator: 13 | 14 | ```css 15 | .article[font-size] == .header[font-size]; 16 | 17 | @h |[.a][.b]| in(.cont) chain-width; 18 | 19 | .container { 20 | @h |[.itemA][.itemB]| in(::) chain-width; 21 | } 22 | ``` 23 | 24 | - 2D sugar props: `size`, `position`, `center`, `intrinsic-size`, `top-left`, `top-right`, `bottom-left`, `bottom-right` 25 | 26 | 27 | ## 1.0.2-beta (April 14th 2014) 28 | 29 | - VGL: `@grid-template` empty zones can be defined with `.` 30 | - VGL: added `in()` to `@grid-template` 31 | - VGL: added `h/v/top/right/bottom/left-gap()` to `@grid-template` 32 | 33 | VGL is still undocumented & under heavy dev. 34 | 35 | ## 1.0.1-beta (April 7th 2014) 36 | 37 | - VFL: **Point** support 38 | - VFL: shorthands `@h` & `@v` for `@horizontal` & `@vertical` 39 | - VFL: `outer-gap()` 40 | - VFL: Default containing element selector to `::this` 41 | 42 | ### New VFL Sugar 43 | 44 | With the new VFL API sugar, the following: 45 | 46 | ```css 47 | #container { 48 | @h |-[#a]-[#b]-| gap(10) outer-gap(20); 49 | } 50 | ``` 51 | 52 | is equivalent too: 53 | 54 | ```css 55 | @horizontal |-20-[#a]-10-[#b]-20-| in(#container); 56 | ``` 57 | 58 | ### VFL Points 59 | 60 | Elements can be aligned relative to arbitrary positioned points using `< Number | Constraint Variable | Element Property >` 61 | 62 | To horizontally align two buttons, each 8px from the center of the window: 63 | 64 | ```css 65 | /* VFL */ 66 | @h [#btn1]-<::window[center-x]>-[#btn2] gap(8); 67 | 68 | /* Equivalent CCSS */ 69 | #btn1[right] + 8 == ::window[center-x]; 70 | ::window[center-x] + 8 == #btn2[left]; 71 | ``` 72 | 73 | Alignments can be positioned within points: 74 | 75 | ```css 76 | /* VFL */ 77 | @h <#wall[center-x]>-[#poster]-[#clock]-<::window[right])> gap(7); 78 | 79 | /* Equivalent CCSS */ 80 | #wall[center-x] + 7 == #poster[left]; 81 | #poster[right] + 7 == #clock[left]; 82 | ::window[right] - 7 == #clock[right]; 83 | ``` 84 | 85 | Numbers, variables and arithmetic can be used: 86 | 87 | ```css 88 | /* VFL */ 89 | @v <100>[#box]<[row2]>; 90 | 91 | /* Equivalent CCSS */ 92 | 100 == #box[top]; 93 | #box[bottom] == [row2]; 94 | ```css 95 | 96 | -------------------------------------------------------------------------------- /bower_components/gss/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2014 The Grid 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /bower_components/gss/README.md: -------------------------------------------------------------------------------- 1 | GSS engine [![Build Status](https://travis-ci.org/the-gss/engine.png?branch=master)](https://travis-ci.org/the-gss/engine) 2 | ========== 3 | 4 | [![Cross-browser testing status](https://saucelabs.com/browser-matrix/gss-engine.svg)](https://saucelabs.com/u/gss-engine) 5 | 6 | Compiles and runs Grid Style Sheet (GSS) rules. GSS is an implementation of Badros & Borning's [Constraint Cascading Style Sheets](http://www.cs.washington.edu/research/constraints/web/ccss-uwtr.pdf), enabling far better layout control through building relational rules between different elements. 7 | 8 | GSS supports the following syntaxes for defining layout rules: 9 | 10 | * [CCSS](https://github.com/the-gss/ccss-compiler#readme) - direct constraints related to position and size of DOM elements 11 | * [VFL](https://github.com/the-gss/vfl-compiler#readme) - horizontal and vertical spacing constraints based on [Apple's Visual Format Language](https://developer.apple.com/library/ios/documentation/userexperience/conceptual/AutolayoutPG/VisualFormatLanguage/VisualFormatLanguage.html) 12 | 13 | Additionally, support for [GTL](https://github.com/the-gss/gtl-compiler#readme), based on the [W3C Grid Template Language](http://dev.w3.org/csswg/css-template/) is planned. 14 | 15 | The main GSS repository provides a [Component](http://component.io/) library handling both the compilation and application of the layout constraints. 16 | 17 | Please refer to for documentation and usage instructions. 18 | -------------------------------------------------------------------------------- /bower_components/gss/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gss", 3 | "homepage": "http://gridstylesheets.org/", 4 | "authors": [ 5 | "Dan Tocchini " 6 | ], 7 | "description": "Grid Style Sheets Runtime", 8 | "main": ["dist/gss.js","dist/gss.min.js","dist/worker.js","dist/worker.min.js"], 9 | "keywords": [ 10 | "gss" 11 | ], 12 | "license": "MIT", 13 | "ignore": [ 14 | "/components", 15 | "/node_modules", 16 | "/bower_components", 17 | ".gitignore", 18 | "/src", 19 | "/lib", 20 | "/spec", 21 | "/demo", 22 | "/docs", 23 | "_layouts", 24 | "_includes", 25 | "_config.yml", 26 | "CNAME", 27 | "component.json", 28 | "package.json", 29 | "Gruntfile.coffee", 30 | "index.html", 31 | ".travis.yml" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /bower_components/gss/dist/gss/vendor/MutationObserver.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 The Polymer Authors. All rights reserved. 3 | * Use of this source code is goverened by a BSD-style 4 | * license that can be found in the LICENSE file. 5 | */ 6 | 7 | (function(scope) { 8 | 'use strict'; 9 | 10 | var setEndOfMicrotask = scope.setEndOfMicrotask 11 | var wrapIfNeeded = scope.wrapIfNeeded 12 | var wrappers = scope.wrappers; 13 | 14 | var registrationsTable = new WeakMap(); 15 | var globalMutationObservers = []; 16 | var isScheduled = false; 17 | 18 | function scheduleCallback(observer) { 19 | if (isScheduled) 20 | return; 21 | setEndOfMicrotask(notifyObservers); 22 | isScheduled = true; 23 | } 24 | 25 | // http://dom.spec.whatwg.org/#mutation-observers 26 | function notifyObservers() { 27 | isScheduled = false; 28 | 29 | do { 30 | var notifyList = globalMutationObservers.slice(); 31 | var anyNonEmpty = false; 32 | for (var i = 0; i < notifyList.length; i++) { 33 | var mo = notifyList[i]; 34 | var queue = mo.takeRecords(); 35 | removeTransientObserversFor(mo); 36 | if (queue.length) { 37 | mo.callback_(queue, mo); 38 | anyNonEmpty = true; 39 | } 40 | } 41 | } while (anyNonEmpty); 42 | } 43 | 44 | /** 45 | * @param {string} type 46 | * @param {Node} target 47 | * @constructor 48 | */ 49 | function MutationRecord(type, target) { 50 | this.type = type; 51 | this.target = target; 52 | this.addedNodes = new wrappers.NodeList(); 53 | this.removedNodes = new wrappers.NodeList(); 54 | this.previousSibling = null; 55 | this.nextSibling = null; 56 | this.attributeName = null; 57 | this.attributeNamespace = null; 58 | this.oldValue = null; 59 | } 60 | 61 | /** 62 | * Registers transient observers to ancestor and its ancesors for the node 63 | * which was removed. 64 | * @param {!Node} ancestor 65 | * @param {!Node} node 66 | */ 67 | function registerTransientObservers(ancestor, node) { 68 | for (; ancestor; ancestor = ancestor.parentNode) { 69 | var registrations = registrationsTable.get(ancestor); 70 | if (!registrations) 71 | continue; 72 | for (var i = 0; i < registrations.length; i++) { 73 | var registration = registrations[i]; 74 | if (registration.options.subtree) 75 | registration.addTransientObserver(node); 76 | } 77 | } 78 | } 79 | 80 | function removeTransientObserversFor(observer) { 81 | for (var i = 0; i < observer.nodes_.length; i++) { 82 | var node = observer.nodes_[i]; 83 | var registrations = registrationsTable.get(node); 84 | if (!registrations) 85 | return; 86 | for (var j = 0; j < registrations.length; j++) { 87 | var registration = registrations[j]; 88 | if (registration.observer === observer) 89 | registration.removeTransientObservers(); 90 | } 91 | } 92 | } 93 | 94 | // http://dom.spec.whatwg.org/#queue-a-mutation-record 95 | function enqueueMutation(target, type, data) { 96 | // 1. 97 | var interestedObservers = Object.create(null); 98 | var associatedStrings = Object.create(null); 99 | 100 | // 2. 101 | for (var node = target; node; node = node.parentNode) { 102 | // 3. 103 | var registrations = registrationsTable.get(node); 104 | if (!registrations) 105 | continue; 106 | for (var j = 0; j < registrations.length; j++) { 107 | var registration = registrations[j]; 108 | var options = registration.options; 109 | // 1. 110 | if (node !== target && !options.subtree) 111 | continue; 112 | 113 | // 2. 114 | if (type === 'attributes' && !options.attributes) 115 | continue; 116 | 117 | // 3. If type is "attributes", options's attributeFilter is present, and 118 | // either options's attributeFilter does not contain name or namespace 119 | // is non-null, continue. 120 | if (type === 'attributes' && options.attributeFilter && 121 | (data.namespace !== null || 122 | options.attributeFilter.indexOf(data.name) === -1)) { 123 | continue; 124 | } 125 | 126 | // 4. 127 | if (type === 'characterData' && !options.characterData) 128 | continue; 129 | 130 | // 5. 131 | if (type === 'childList' && !options.childList) 132 | continue; 133 | 134 | // 6. 135 | var observer = registration.observer; 136 | interestedObservers[observer.uid_] = observer; 137 | 138 | // 7. If either type is "attributes" and options's attributeOldValue is 139 | // true, or type is "characterData" and options's characterDataOldValue 140 | // is true, set the paired string of registered observer's observer in 141 | // interested observers to oldValue. 142 | if (type === 'attributes' && options.attributeOldValue || 143 | type === 'characterData' && options.characterDataOldValue) { 144 | associatedStrings[observer.uid_] = data.oldValue; 145 | } 146 | } 147 | } 148 | 149 | var anyRecordsEnqueued = false; 150 | 151 | // 4. 152 | for (var uid in interestedObservers) { 153 | var observer = interestedObservers[uid]; 154 | var record = new MutationRecord(type, target); 155 | 156 | // 2. 157 | if ('name' in data && 'namespace' in data) { 158 | record.attributeName = data.name; 159 | record.attributeNamespace = data.namespace; 160 | } 161 | 162 | // 3. 163 | if (data.addedNodes) 164 | record.addedNodes = data.addedNodes; 165 | 166 | // 4. 167 | if (data.removedNodes) 168 | record.removedNodes = data.removedNodes; 169 | 170 | // 5. 171 | if (data.previousSibling) 172 | record.previousSibling = data.previousSibling; 173 | 174 | // 6. 175 | if (data.nextSibling) 176 | record.nextSibling = data.nextSibling; 177 | 178 | // 7. 179 | if (associatedStrings[uid] !== undefined) 180 | record.oldValue = associatedStrings[uid]; 181 | 182 | // 8. 183 | observer.records_.push(record); 184 | 185 | anyRecordsEnqueued = true; 186 | } 187 | 188 | if (anyRecordsEnqueued) 189 | scheduleCallback(); 190 | } 191 | 192 | var slice = Array.prototype.slice; 193 | 194 | /** 195 | * @param {!Object} options 196 | * @constructor 197 | */ 198 | function MutationObserverOptions(options) { 199 | this.childList = !!options.childList; 200 | this.subtree = !!options.subtree; 201 | 202 | // 1. If either options' attributeOldValue or attributeFilter is present 203 | // and options' attributes is omitted, set options' attributes to true. 204 | if (!('attributes' in options) && 205 | ('attributeOldValue' in options || 'attributeFilter' in options)) { 206 | this.attributes = true; 207 | } else { 208 | this.attributes = !!options.attributes; 209 | } 210 | 211 | // 2. If options' characterDataOldValue is present and options' 212 | // characterData is omitted, set options' characterData to true. 213 | if ('characterDataOldValue' in options && !('characterData' in options)) 214 | this.characterData = true; 215 | else 216 | this.characterData = !!options.characterData; 217 | 218 | // 3. & 4. 219 | if (!this.attributes && 220 | (options.attributeOldValue || 'attributeFilter' in options) || 221 | // 5. 222 | !this.characterData && options.characterDataOldValue) { 223 | throw new TypeError(); 224 | } 225 | 226 | this.characterData = !!options.characterData; 227 | this.attributeOldValue = !!options.attributeOldValue; 228 | this.characterDataOldValue = !!options.characterDataOldValue; 229 | if ('attributeFilter' in options) { 230 | if (options.attributeFilter == null || 231 | typeof options.attributeFilter !== 'object') { 232 | throw new TypeError(); 233 | } 234 | this.attributeFilter = slice.call(options.attributeFilter); 235 | } else { 236 | this.attributeFilter = null; 237 | } 238 | } 239 | 240 | var uidCounter = 0; 241 | 242 | /** 243 | * The class that maps to the DOM MutationObserver interface. 244 | * @param {Function} callback. 245 | * @constructor 246 | */ 247 | function MutationObserver(callback) { 248 | this.callback_ = callback; 249 | this.nodes_ = []; 250 | this.records_ = []; 251 | this.uid_ = ++uidCounter; 252 | 253 | // This will leak. There is no way to implement this without WeakRefs :'( 254 | globalMutationObservers.push(this); 255 | } 256 | 257 | MutationObserver.prototype = { 258 | // http://dom.spec.whatwg.org/#dom-mutationobserver-observe 259 | observe: function(target, options) { 260 | target = wrapIfNeeded(target); 261 | 262 | var newOptions = new MutationObserverOptions(options); 263 | 264 | // 6. 265 | var registration; 266 | var registrations = registrationsTable.get(target); 267 | if (!registrations) 268 | registrationsTable.set(target, registrations = []); 269 | 270 | for (var i = 0; i < registrations.length; i++) { 271 | if (registrations[i].observer === this) { 272 | registration = registrations[i]; 273 | // 6.1. 274 | registration.removeTransientObservers(); 275 | // 6.2. 276 | registration.options = newOptions; 277 | } 278 | } 279 | 280 | // 7. 281 | if (!registration) { 282 | registration = new Registration(this, target, newOptions); 283 | registrations.push(registration); 284 | this.nodes_.push(target); 285 | } 286 | }, 287 | 288 | // http://dom.spec.whatwg.org/#dom-mutationobserver-disconnect 289 | disconnect: function() { 290 | this.nodes_.forEach(function(node) { 291 | var registrations = registrationsTable.get(node); 292 | for (var i = 0; i < registrations.length; i++) { 293 | var registration = registrations[i]; 294 | if (registration.observer === this) { 295 | registrations.splice(i, 1); 296 | // Each node can only have one registered observer associated with 297 | // this observer. 298 | break; 299 | } 300 | } 301 | }, this); 302 | this.records_ = []; 303 | }, 304 | 305 | takeRecords: function() { 306 | var copyOfRecords = this.records_; 307 | this.records_ = []; 308 | return copyOfRecords; 309 | } 310 | }; 311 | 312 | /** 313 | * Class used to represent a registered observer. 314 | * @param {MutationObserver} observer 315 | * @param {Node} target 316 | * @param {MutationObserverOptions} options 317 | * @constructor 318 | */ 319 | function Registration(observer, target, options) { 320 | this.observer = observer; 321 | this.target = target; 322 | this.options = options; 323 | this.transientObservedNodes = []; 324 | } 325 | 326 | Registration.prototype = { 327 | /** 328 | * Adds a transient observer on node. The transient observer gets removed 329 | * next time we deliver the change records. 330 | * @param {Node} node 331 | */ 332 | addTransientObserver: function(node) { 333 | // Don't add transient observers on the target itself. We already have all 334 | // the required listeners set up on the target. 335 | if (node === this.target) 336 | return; 337 | 338 | this.transientObservedNodes.push(node); 339 | var registrations = registrationsTable.get(node); 340 | if (!registrations) 341 | registrationsTable.set(node, registrations = []); 342 | 343 | // We know that registrations does not contain this because we already 344 | // checked if node === this.target. 345 | registrations.push(this); 346 | }, 347 | 348 | removeTransientObservers: function() { 349 | var transientObservedNodes = this.transientObservedNodes; 350 | this.transientObservedNodes = []; 351 | 352 | for (var i = 0; i < transientObservedNodes.length; i++) { 353 | var node = transientObservedNodes[i]; 354 | var registrations = registrationsTable.get(node); 355 | for (var j = 0; j < registrations.length; j++) { 356 | if (registrations[j] === this) { 357 | registrations.splice(j, 1); 358 | // Each node can only have one registered observer associated with 359 | // this observer. 360 | break; 361 | } 362 | } 363 | } 364 | } 365 | }; 366 | 367 | scope.enqueueMutation = enqueueMutation; 368 | scope.registerTransientObservers = registerTransientObservers; 369 | scope.wrappers.MutationObserver = MutationObserver; 370 | scope.wrappers.MutationRecord = MutationRecord; 371 | 372 | })(window.ShadowDOMPolyfill); -------------------------------------------------------------------------------- /bower_components/gss/dist/gss/vendor/observe.js: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | (function(global) { 16 | 'use strict'; 17 | 18 | function detectObjectObserve() { 19 | if (typeof Object.observe !== 'function' || 20 | typeof Array.observe !== 'function') { 21 | return false; 22 | } 23 | 24 | var gotSplice = false; 25 | function callback(records) { 26 | if (records[0].type === 'splice' && records[1].type === 'splice') 27 | gotSplice = true; 28 | } 29 | 30 | var test = [0]; 31 | Array.observe(test, callback); 32 | test[1] = 1; 33 | test.length = 0; 34 | Object.deliverChangeRecords(callback); 35 | return gotSplice; 36 | } 37 | 38 | var hasObserve = detectObjectObserve(); 39 | 40 | function detectEval() { 41 | // don't test for eval if document has CSP securityPolicy object and we can see that 42 | // eval is not supported. This avoids an error message in console even when the exception 43 | // is caught 44 | if (global.document && 45 | 'securityPolicy' in global.document && 46 | !global.document.securityPolicy.allowsEval) { 47 | return false; 48 | } 49 | 50 | try { 51 | var f = new Function('', 'return true;'); 52 | return f(); 53 | } catch (ex) { 54 | return false; 55 | } 56 | } 57 | 58 | var hasEval = detectEval(); 59 | 60 | function isIndex(s) { 61 | return +s === s >>> 0; 62 | } 63 | 64 | function toNumber(s) { 65 | return +s; 66 | } 67 | 68 | function isObject(obj) { 69 | return obj === Object(obj); 70 | } 71 | 72 | var numberIsNaN = global.Number.isNaN || function isNaN(value) { 73 | return typeof value === 'number' && global.isNaN(value); 74 | } 75 | 76 | function areSameValue(left, right) { 77 | if (left === right) 78 | return left !== 0 || 1 / left === 1 / right; 79 | if (numberIsNaN(left) && numberIsNaN(right)) 80 | return true; 81 | 82 | return left !== left && right !== right; 83 | } 84 | 85 | var createObject = ('__proto__' in {}) ? 86 | function(obj) { return obj; } : 87 | function(obj) { 88 | var proto = obj.__proto__; 89 | if (!proto) 90 | return obj; 91 | var newObject = Object.create(proto); 92 | Object.getOwnPropertyNames(obj).forEach(function(name) { 93 | Object.defineProperty(newObject, name, 94 | Object.getOwnPropertyDescriptor(obj, name)); 95 | }); 96 | return newObject; 97 | }; 98 | 99 | var identStart = '[\$_a-zA-Z]'; 100 | var identPart = '[\$_a-zA-Z0-9]'; 101 | var ident = identStart + '+' + identPart + '*'; 102 | var elementIndex = '(?:[0-9]|[1-9]+[0-9]+)'; 103 | var identOrElementIndex = '(?:' + ident + '|' + elementIndex + ')'; 104 | var path = '(?:' + identOrElementIndex + ')(?:\\s*\\.\\s*' + identOrElementIndex + ')*'; 105 | var pathRegExp = new RegExp('^' + path + '$'); 106 | 107 | function isPathValid(s) { 108 | if (typeof s != 'string') 109 | return false; 110 | s = s.trim(); 111 | 112 | if (s == '') 113 | return true; 114 | 115 | if (s[0] == '.') 116 | return false; 117 | 118 | return pathRegExp.test(s); 119 | } 120 | 121 | var constructorIsPrivate = {}; 122 | 123 | function Path(s, privateToken) { 124 | if (privateToken !== constructorIsPrivate) 125 | throw Error('Use Path.get to retrieve path objects'); 126 | 127 | if (s.trim() == '') 128 | return this; 129 | 130 | if (isIndex(s)) { 131 | this.push(s); 132 | return this; 133 | } 134 | 135 | s.split(/\s*\.\s*/).filter(function(part) { 136 | return part; 137 | }).forEach(function(part) { 138 | this.push(part); 139 | }, this); 140 | 141 | if (hasEval && !hasObserve && this.length) { 142 | this.getValueFrom = this.compiledGetValueFromFn(); 143 | } 144 | } 145 | 146 | // TODO(rafaelw): Make simple LRU cache 147 | var pathCache = {}; 148 | 149 | function getPath(pathString) { 150 | if (pathString instanceof Path) 151 | return pathString; 152 | 153 | if (pathString == null) 154 | pathString = ''; 155 | 156 | if (typeof pathString !== 'string') 157 | pathString = String(pathString); 158 | 159 | var path = pathCache[pathString]; 160 | if (path) 161 | return path; 162 | if (!isPathValid(pathString)) 163 | return invalidPath; 164 | var path = new Path(pathString, constructorIsPrivate); 165 | pathCache[pathString] = path; 166 | return path; 167 | } 168 | 169 | Path.get = getPath; 170 | 171 | Path.prototype = createObject({ 172 | __proto__: [], 173 | valid: true, 174 | 175 | toString: function() { 176 | return this.join('.'); 177 | }, 178 | 179 | getValueFrom: function(obj, observedSet) { 180 | for (var i = 0; i < this.length; i++) { 181 | if (obj == null) 182 | return; 183 | if (observedSet) 184 | observedSet.observe(obj); 185 | obj = obj[this[i]]; 186 | } 187 | return obj; 188 | }, 189 | 190 | compiledGetValueFromFn: function() { 191 | var accessors = this.map(function(ident) { 192 | return isIndex(ident) ? '["' + ident + '"]' : '.' + ident; 193 | }); 194 | 195 | var str = ''; 196 | var pathString = 'obj'; 197 | str += 'if (obj != null'; 198 | var i = 0; 199 | for (; i < (this.length - 1); i++) { 200 | var ident = this[i]; 201 | pathString += accessors[i]; 202 | str += ' &&\n ' + pathString + ' != null'; 203 | } 204 | str += ')\n'; 205 | 206 | pathString += accessors[i]; 207 | 208 | str += ' return ' + pathString + ';\nelse\n return undefined;'; 209 | return new Function('obj', str); 210 | }, 211 | 212 | setValueFrom: function(obj, value) { 213 | if (!this.length) 214 | return false; 215 | 216 | for (var i = 0; i < this.length - 1; i++) { 217 | if (!isObject(obj)) 218 | return false; 219 | obj = obj[this[i]]; 220 | } 221 | 222 | if (!isObject(obj)) 223 | return false; 224 | 225 | obj[this[i]] = value; 226 | return true; 227 | } 228 | }); 229 | 230 | var invalidPath = new Path('', constructorIsPrivate); 231 | invalidPath.valid = false; 232 | invalidPath.getValueFrom = invalidPath.setValueFrom = function() {}; 233 | 234 | var MAX_DIRTY_CHECK_CYCLES = 1000; 235 | 236 | function dirtyCheck(observer) { 237 | var cycles = 0; 238 | while (cycles < MAX_DIRTY_CHECK_CYCLES && observer.check()) { 239 | observer.report(); 240 | cycles++; 241 | } 242 | if (global.testingExposeCycleCount) 243 | global.dirtyCheckCycleCount = cycles; 244 | } 245 | 246 | function objectIsEmpty(object) { 247 | for (var prop in object) 248 | return false; 249 | return true; 250 | } 251 | 252 | function diffIsEmpty(diff) { 253 | return objectIsEmpty(diff.added) && 254 | objectIsEmpty(diff.removed) && 255 | objectIsEmpty(diff.changed); 256 | } 257 | 258 | function diffObjectFromOldObject(object, oldObject) { 259 | var added = {}; 260 | var removed = {}; 261 | var changed = {}; 262 | var oldObjectHas = {}; 263 | 264 | for (var prop in oldObject) { 265 | var newValue = object[prop]; 266 | 267 | if (newValue !== undefined && newValue === oldObject[prop]) 268 | continue; 269 | 270 | if (!(prop in object)) { 271 | removed[prop] = undefined; 272 | continue; 273 | } 274 | 275 | if (newValue !== oldObject[prop]) 276 | changed[prop] = newValue; 277 | } 278 | 279 | for (var prop in object) { 280 | if (prop in oldObject) 281 | continue; 282 | 283 | added[prop] = object[prop]; 284 | } 285 | 286 | if (Array.isArray(object) && object.length !== oldObject.length) 287 | changed.length = object.length; 288 | 289 | return { 290 | added: added, 291 | removed: removed, 292 | changed: changed 293 | }; 294 | } 295 | 296 | function copyObject(object, opt_copy) { 297 | var copy = opt_copy || (Array.isArray(object) ? [] : {}); 298 | for (var prop in object) { 299 | copy[prop] = object[prop]; 300 | }; 301 | if (Array.isArray(object)) 302 | copy.length = object.length; 303 | return copy; 304 | } 305 | 306 | function Observer(object, callback, target, token) { 307 | this.closed = false; 308 | this.object = object; 309 | this.callback = callback; 310 | // TODO(rafaelw): Hold this.target weakly when WeakRef is available. 311 | this.target = target; 312 | this.token = token; 313 | this.reporting = true; 314 | if (hasObserve) { 315 | var self = this; 316 | this.boundInternalCallback = function(records) { 317 | self.internalCallback(records); 318 | }; 319 | } 320 | 321 | addToAll(this); 322 | } 323 | 324 | Observer.prototype = { 325 | internalCallback: function(records) { 326 | if (this.closed) 327 | return; 328 | if (this.reporting && this.check(records)) { 329 | this.report(); 330 | if (this.testingResults) 331 | this.testingResults.anyChanged = true; 332 | } 333 | }, 334 | 335 | close: function() { 336 | if (this.closed) 337 | return; 338 | if (this.object && typeof this.object.close === 'function') 339 | this.object.close(); 340 | 341 | this.disconnect(); 342 | this.object = undefined; 343 | this.closed = true; 344 | }, 345 | 346 | deliver: function(testingResults) { 347 | if (this.closed) 348 | return; 349 | if (hasObserve) { 350 | this.testingResults = testingResults; 351 | Object.deliverChangeRecords(this.boundInternalCallback); 352 | this.testingResults = undefined; 353 | } else { 354 | dirtyCheck(this); 355 | } 356 | }, 357 | 358 | report: function() { 359 | if (!this.reporting) 360 | return; 361 | 362 | this.sync(false); 363 | if (this.callback) { 364 | this.reportArgs.push(this.token); 365 | this.invokeCallback(this.reportArgs); 366 | } 367 | this.reportArgs = undefined; 368 | }, 369 | 370 | invokeCallback: function(args) { 371 | try { 372 | this.callback.apply(this.target, args); 373 | } catch (ex) { 374 | Observer._errorThrownDuringCallback = true; 375 | console.error('Exception caught during observer callback: ' + (ex.stack || ex)); 376 | } 377 | }, 378 | 379 | reset: function() { 380 | if (this.closed) 381 | return; 382 | 383 | if (hasObserve) { 384 | this.reporting = false; 385 | Object.deliverChangeRecords(this.boundInternalCallback); 386 | this.reporting = true; 387 | } 388 | 389 | this.sync(true); 390 | } 391 | } 392 | 393 | var collectObservers = !hasObserve || global.forceCollectObservers; 394 | var allObservers; 395 | Observer._allObserversCount = 0; 396 | 397 | if (collectObservers) { 398 | allObservers = []; 399 | } 400 | 401 | function addToAll(observer) { 402 | if (!collectObservers) 403 | return; 404 | 405 | allObservers.push(observer); 406 | Observer._allObserversCount++; 407 | } 408 | 409 | var runningMicrotaskCheckpoint = false; 410 | 411 | var hasDebugForceFullDelivery = typeof Object.deliverAllChangeRecords == 'function'; 412 | 413 | global.Platform = global.Platform || {}; 414 | 415 | global.Platform.performMicrotaskCheckpoint = function() { 416 | if (runningMicrotaskCheckpoint) 417 | return; 418 | 419 | if (hasDebugForceFullDelivery) { 420 | Object.deliverAllChangeRecords(); 421 | return; 422 | } 423 | 424 | if (!collectObservers) 425 | return; 426 | 427 | runningMicrotaskCheckpoint = true; 428 | 429 | var cycles = 0; 430 | var results = {}; 431 | 432 | do { 433 | cycles++; 434 | var toCheck = allObservers; 435 | allObservers = []; 436 | results.anyChanged = false; 437 | 438 | for (var i = 0; i < toCheck.length; i++) { 439 | var observer = toCheck[i]; 440 | if (observer.closed) 441 | continue; 442 | 443 | if (hasObserve) { 444 | observer.deliver(results); 445 | } else if (observer.check()) { 446 | results.anyChanged = true; 447 | observer.report(); 448 | } 449 | 450 | allObservers.push(observer); 451 | } 452 | } while (cycles < MAX_DIRTY_CHECK_CYCLES && results.anyChanged); 453 | 454 | if (global.testingExposeCycleCount) 455 | global.dirtyCheckCycleCount = cycles; 456 | 457 | Observer._allObserversCount = allObservers.length; 458 | runningMicrotaskCheckpoint = false; 459 | }; 460 | 461 | if (collectObservers) { 462 | global.Platform.clearObservers = function() { 463 | allObservers = []; 464 | }; 465 | } 466 | 467 | function ObjectObserver(object, callback, target, token) { 468 | Observer.call(this, object, callback, target, token); 469 | this.connect(); 470 | this.sync(true); 471 | } 472 | 473 | ObjectObserver.prototype = createObject({ 474 | __proto__: Observer.prototype, 475 | 476 | connect: function() { 477 | if (hasObserve) 478 | Object.observe(this.object, this.boundInternalCallback); 479 | }, 480 | 481 | sync: function(hard) { 482 | if (!hasObserve) 483 | this.oldObject = copyObject(this.object); 484 | }, 485 | 486 | check: function(changeRecords) { 487 | var diff; 488 | var oldValues; 489 | if (hasObserve) { 490 | if (!changeRecords) 491 | return false; 492 | 493 | oldValues = {}; 494 | diff = diffObjectFromChangeRecords(this.object, changeRecords, 495 | oldValues); 496 | } else { 497 | oldValues = this.oldObject; 498 | diff = diffObjectFromOldObject(this.object, this.oldObject); 499 | } 500 | 501 | if (diffIsEmpty(diff)) 502 | return false; 503 | 504 | this.reportArgs = 505 | [diff.added || {}, diff.removed || {}, diff.changed || {}]; 506 | this.reportArgs.push(function(property) { 507 | return oldValues[property]; 508 | }); 509 | 510 | return true; 511 | }, 512 | 513 | disconnect: function() { 514 | if (!hasObserve) 515 | this.oldObject = undefined; 516 | else if (this.object) 517 | Object.unobserve(this.object, this.boundInternalCallback); 518 | } 519 | }); 520 | 521 | function ArrayObserver(array, callback, target, token) { 522 | if (!Array.isArray(array)) 523 | throw Error('Provided object is not an Array'); 524 | ObjectObserver.call(this, array, callback, target, token); 525 | } 526 | 527 | ArrayObserver.prototype = createObject({ 528 | __proto__: ObjectObserver.prototype, 529 | 530 | connect: function() { 531 | if (hasObserve) 532 | Array.observe(this.object, this.boundInternalCallback); 533 | }, 534 | 535 | sync: function() { 536 | if (!hasObserve) 537 | this.oldObject = this.object.slice(); 538 | }, 539 | 540 | check: function(changeRecords) { 541 | var splices; 542 | if (hasObserve) { 543 | if (!changeRecords) 544 | return false; 545 | splices = projectArraySplices(this.object, changeRecords); 546 | } else { 547 | splices = calcSplices(this.object, 0, this.object.length, 548 | this.oldObject, 0, this.oldObject.length); 549 | } 550 | 551 | if (!splices || !splices.length) 552 | return false; 553 | 554 | this.reportArgs = [splices]; 555 | return true; 556 | } 557 | }); 558 | 559 | ArrayObserver.applySplices = function(previous, current, splices) { 560 | splices.forEach(function(splice) { 561 | var spliceArgs = [splice.index, splice.removed.length]; 562 | var addIndex = splice.index; 563 | while (addIndex < splice.index + splice.addedCount) { 564 | spliceArgs.push(current[addIndex]); 565 | addIndex++; 566 | } 567 | 568 | Array.prototype.splice.apply(previous, spliceArgs); 569 | }); 570 | }; 571 | 572 | function ObservedSet(callback) { 573 | this.arr = []; 574 | this.callback = callback; 575 | this.isObserved = true; 576 | } 577 | 578 | var objProto = Object.getPrototypeOf({}); 579 | var arrayProto = Object.getPrototypeOf([]); 580 | ObservedSet.prototype = { 581 | reset: function() { 582 | this.isObserved = !this.isObserved; 583 | }, 584 | 585 | observe: function(obj) { 586 | if (!isObject(obj) || obj === objProto || obj === arrayProto) 587 | return; 588 | var i = this.arr.indexOf(obj); 589 | if (i >= 0 && this.arr[i+1] === this.isObserved) 590 | return; 591 | 592 | if (i < 0) { 593 | i = this.arr.length; 594 | this.arr[i] = obj; 595 | Object.observe(obj, this.callback); 596 | } 597 | 598 | this.arr[i+1] = this.isObserved; 599 | this.observe(Object.getPrototypeOf(obj)); 600 | }, 601 | 602 | cleanup: function() { 603 | var i = 0, j = 0; 604 | var isObserved = this.isObserved; 605 | while(j < this.arr.length) { 606 | var obj = this.arr[j]; 607 | if (this.arr[j + 1] == isObserved) { 608 | if (i < j) { 609 | this.arr[i] = obj; 610 | this.arr[i + 1] = isObserved; 611 | } 612 | i += 2; 613 | } else { 614 | Object.unobserve(obj, this.callback); 615 | } 616 | j += 2; 617 | } 618 | 619 | this.arr.length = i; 620 | } 621 | }; 622 | 623 | function PathObserver(object, path, callback, target, token, valueFn, 624 | setValueFn) { 625 | var path = path instanceof Path ? path : getPath(path); 626 | if (!path || !path.length || !isObject(object)) { 627 | this.value_ = path ? path.getValueFrom(object) : undefined; 628 | this.value = valueFn ? valueFn(this.value_) : this.value_; 629 | this.closed = true; 630 | return; 631 | } 632 | 633 | Observer.call(this, object, callback, target, token); 634 | this.valueFn = valueFn; 635 | this.setValueFn = setValueFn; 636 | this.path = path; 637 | 638 | this.connect(); 639 | this.sync(true); 640 | } 641 | 642 | PathObserver.prototype = createObject({ 643 | __proto__: Observer.prototype, 644 | 645 | connect: function() { 646 | if (hasObserve) 647 | this.observedSet = new ObservedSet(this.boundInternalCallback); 648 | }, 649 | 650 | disconnect: function() { 651 | this.value = undefined; 652 | this.value_ = undefined; 653 | if (this.observedSet) { 654 | this.observedSet.reset(); 655 | this.observedSet.cleanup(); 656 | this.observedSet = undefined; 657 | } 658 | }, 659 | 660 | check: function() { 661 | // Note: Extracting this to a member function for use here and below 662 | // regresses dirty-checking path perf by about 25% =-(. 663 | if (this.observedSet) 664 | this.observedSet.reset(); 665 | 666 | this.value_ = this.path.getValueFrom(this.object, this.observedSet); 667 | 668 | if (this.observedSet) 669 | this.observedSet.cleanup(); 670 | 671 | if (areSameValue(this.value_, this.oldValue_)) 672 | return false; 673 | 674 | this.value = this.valueFn ? this.valueFn(this.value_) : this.value_; 675 | this.reportArgs = [this.value, this.oldValue]; 676 | return true; 677 | }, 678 | 679 | sync: function(hard) { 680 | if (hard) { 681 | if (this.observedSet) 682 | this.observedSet.reset(); 683 | 684 | this.value_ = this.path.getValueFrom(this.object, this.observedSet); 685 | this.value = this.valueFn ? this.valueFn(this.value_) : this.value_; 686 | 687 | if (this.observedSet) 688 | this.observedSet.cleanup(); 689 | } 690 | 691 | this.oldValue_ = this.value_; 692 | this.oldValue = this.value; 693 | }, 694 | 695 | setValue: function(newValue) { 696 | if (!this.path) 697 | return; 698 | if (typeof this.setValueFn === 'function') 699 | newValue = this.setValueFn(newValue); 700 | this.path.setValueFrom(this.object, newValue); 701 | } 702 | }); 703 | 704 | function CompoundPathObserver(callback, target, token, valueFn) { 705 | Observer.call(this, undefined, callback, target, token); 706 | this.valueFn = valueFn; 707 | 708 | this.observed = []; 709 | this.values = []; 710 | this.value = undefined; 711 | this.oldValue = undefined; 712 | this.oldValues = undefined; 713 | this.changeFlags = undefined; 714 | this.started = false; 715 | } 716 | 717 | CompoundPathObserver.prototype = createObject({ 718 | __proto__: PathObserver.prototype, 719 | 720 | addPath: function(object, path) { 721 | if (this.started) 722 | throw Error('Cannot add more paths once started.'); 723 | 724 | var path = path instanceof Path ? path : getPath(path); 725 | var value = path ? path.getValueFrom(object) : undefined; 726 | 727 | this.observed.push(object, path); 728 | this.values.push(value); 729 | }, 730 | 731 | start: function() { 732 | this.connect(); 733 | this.sync(true); 734 | }, 735 | 736 | getValues: function() { 737 | if (this.observedSet) 738 | this.observedSet.reset(); 739 | 740 | var anyChanged = false; 741 | for (var i = 0; i < this.observed.length; i = i+2) { 742 | var path = this.observed[i+1]; 743 | if (!path) 744 | continue; 745 | var object = this.observed[i]; 746 | var value = path.getValueFrom(object, this.observedSet); 747 | var oldValue = this.values[i/2]; 748 | if (!areSameValue(value, oldValue)) { 749 | if (!anyChanged && !this.valueFn) { 750 | this.oldValues = this.oldValues || []; 751 | this.changeFlags = this.changeFlags || []; 752 | for (var j = 0; j < this.values.length; j++) { 753 | this.oldValues[j] = this.values[j]; 754 | this.changeFlags[j] = false; 755 | } 756 | } 757 | 758 | if (!this.valueFn) 759 | this.changeFlags[i/2] = true; 760 | 761 | this.values[i/2] = value; 762 | anyChanged = true; 763 | } 764 | } 765 | 766 | if (this.observedSet) 767 | this.observedSet.cleanup(); 768 | 769 | return anyChanged; 770 | }, 771 | 772 | check: function() { 773 | if (!this.getValues()) 774 | return; 775 | 776 | if (this.valueFn) { 777 | this.value = this.valueFn(this.values); 778 | 779 | if (areSameValue(this.value, this.oldValue)) 780 | return false; 781 | 782 | this.reportArgs = [this.value, this.oldValue]; 783 | } else { 784 | this.reportArgs = [this.values, this.oldValues, this.changeFlags]; 785 | } 786 | 787 | return true; 788 | }, 789 | 790 | sync: function(hard) { 791 | if (hard) { 792 | this.getValues(); 793 | if (this.valueFn) 794 | this.value = this.valueFn(this.values); 795 | } 796 | 797 | if (this.valueFn) 798 | this.oldValue = this.value; 799 | }, 800 | 801 | close: function() { 802 | if (this.observed) { 803 | for (var i = 0; i < this.observed.length; i = i + 2) { 804 | var object = this.observed[i]; 805 | if (object && typeof object.close === 'function') 806 | object.close(); 807 | } 808 | this.observed = undefined; 809 | this.values = undefined; 810 | } 811 | 812 | Observer.prototype.close.call(this); 813 | } 814 | }); 815 | 816 | var knownRecordTypes = { 817 | 'new': true, 818 | 'updated': true, 819 | 'deleted': true 820 | }; 821 | 822 | function notifyFunction(object, name) { 823 | if (typeof Object.observe !== 'function') 824 | return; 825 | 826 | var notifier = Object.getNotifier(object); 827 | return function(type, oldValue) { 828 | var changeRecord = { 829 | object: object, 830 | type: type, 831 | name: name 832 | }; 833 | if (arguments.length === 2) 834 | changeRecord.oldValue = oldValue; 835 | notifier.notify(changeRecord); 836 | } 837 | } 838 | 839 | // TODO(rafaelw): It should be possible for the Object.observe case to have 840 | // every PathObserver used by defineProperty share a single Object.observe 841 | // callback, and thus get() can simply call observer.deliver() and any changes 842 | // to any dependent value will be observed. 843 | PathObserver.defineProperty = function(object, name, descriptor) { 844 | // TODO(rafaelw): Validate errors 845 | var obj = descriptor.object; 846 | var path = getPath(descriptor.path); 847 | var notify = notifyFunction(object, name); 848 | 849 | var observer = new PathObserver(obj, descriptor.path, 850 | function(newValue, oldValue) { 851 | if (notify) 852 | notify('updated', oldValue); 853 | } 854 | ); 855 | 856 | Object.defineProperty(object, name, { 857 | get: function() { 858 | return path.getValueFrom(obj); 859 | }, 860 | set: function(newValue) { 861 | path.setValueFrom(obj, newValue); 862 | }, 863 | configurable: true 864 | }); 865 | 866 | return { 867 | close: function() { 868 | var oldValue = path.getValueFrom(obj); 869 | if (notify) 870 | observer.deliver(); 871 | observer.close(); 872 | Object.defineProperty(object, name, { 873 | value: oldValue, 874 | writable: true, 875 | configurable: true 876 | }); 877 | } 878 | }; 879 | } 880 | 881 | function diffObjectFromChangeRecords(object, changeRecords, oldValues) { 882 | var added = {}; 883 | var removed = {}; 884 | 885 | for (var i = 0; i < changeRecords.length; i++) { 886 | var record = changeRecords[i]; 887 | if (!knownRecordTypes[record.type]) { 888 | console.error('Unknown changeRecord type: ' + record.type); 889 | console.error(record); 890 | continue; 891 | } 892 | 893 | if (!(record.name in oldValues)) 894 | oldValues[record.name] = record.oldValue; 895 | 896 | if (record.type == 'updated') 897 | continue; 898 | 899 | if (record.type == 'new') { 900 | if (record.name in removed) 901 | delete removed[record.name]; 902 | else 903 | added[record.name] = true; 904 | 905 | continue; 906 | } 907 | 908 | // type = 'deleted' 909 | if (record.name in added) { 910 | delete added[record.name]; 911 | delete oldValues[record.name]; 912 | } else { 913 | removed[record.name] = true; 914 | } 915 | } 916 | 917 | for (var prop in added) 918 | added[prop] = object[prop]; 919 | 920 | for (var prop in removed) 921 | removed[prop] = undefined; 922 | 923 | var changed = {}; 924 | for (var prop in oldValues) { 925 | if (prop in added || prop in removed) 926 | continue; 927 | 928 | var newValue = object[prop]; 929 | if (oldValues[prop] !== newValue) 930 | changed[prop] = newValue; 931 | } 932 | 933 | return { 934 | added: added, 935 | removed: removed, 936 | changed: changed 937 | }; 938 | } 939 | 940 | function newSplice(index, removed, addedCount) { 941 | return { 942 | index: index, 943 | removed: removed, 944 | addedCount: addedCount 945 | }; 946 | } 947 | 948 | var EDIT_LEAVE = 0; 949 | var EDIT_UPDATE = 1; 950 | var EDIT_ADD = 2; 951 | var EDIT_DELETE = 3; 952 | 953 | function ArraySplice() {} 954 | 955 | ArraySplice.prototype = { 956 | 957 | // Note: This function is *based* on the computation of the Levenshtein 958 | // "edit" distance. The one change is that "updates" are treated as two 959 | // edits - not one. With Array splices, an update is really a delete 960 | // followed by an add. By retaining this, we optimize for "keeping" the 961 | // maximum array items in the original array. For example: 962 | // 963 | // 'xxxx123' -> '123yyyy' 964 | // 965 | // With 1-edit updates, the shortest path would be just to update all seven 966 | // characters. With 2-edit updates, we delete 4, leave 3, and add 4. This 967 | // leaves the substring '123' intact. 968 | calcEditDistances: function(current, currentStart, currentEnd, 969 | old, oldStart, oldEnd) { 970 | // "Deletion" columns 971 | var rowCount = oldEnd - oldStart + 1; 972 | var columnCount = currentEnd - currentStart + 1; 973 | var distances = new Array(rowCount); 974 | 975 | // "Addition" rows. Initialize null column. 976 | for (var i = 0; i < rowCount; i++) { 977 | distances[i] = new Array(columnCount); 978 | distances[i][0] = i; 979 | } 980 | 981 | // Initialize null row 982 | for (var j = 0; j < columnCount; j++) 983 | distances[0][j] = j; 984 | 985 | for (var i = 1; i < rowCount; i++) { 986 | for (var j = 1; j < columnCount; j++) { 987 | if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1])) 988 | distances[i][j] = distances[i - 1][j - 1]; 989 | else { 990 | var north = distances[i - 1][j] + 1; 991 | var west = distances[i][j - 1] + 1; 992 | distances[i][j] = north < west ? north : west; 993 | } 994 | } 995 | } 996 | 997 | return distances; 998 | }, 999 | 1000 | // This starts at the final weight, and walks "backward" by finding 1001 | // the minimum previous weight recursively until the origin of the weight 1002 | // matrix. 1003 | spliceOperationsFromEditDistances: function(distances) { 1004 | var i = distances.length - 1; 1005 | var j = distances[0].length - 1; 1006 | var current = distances[i][j]; 1007 | var edits = []; 1008 | while (i > 0 || j > 0) { 1009 | if (i == 0) { 1010 | edits.push(EDIT_ADD); 1011 | j--; 1012 | continue; 1013 | } 1014 | if (j == 0) { 1015 | edits.push(EDIT_DELETE); 1016 | i--; 1017 | continue; 1018 | } 1019 | var northWest = distances[i - 1][j - 1]; 1020 | var west = distances[i - 1][j]; 1021 | var north = distances[i][j - 1]; 1022 | 1023 | var min; 1024 | if (west < north) 1025 | min = west < northWest ? west : northWest; 1026 | else 1027 | min = north < northWest ? north : northWest; 1028 | 1029 | if (min == northWest) { 1030 | if (northWest == current) { 1031 | edits.push(EDIT_LEAVE); 1032 | } else { 1033 | edits.push(EDIT_UPDATE); 1034 | current = northWest; 1035 | } 1036 | i--; 1037 | j--; 1038 | } else if (min == west) { 1039 | edits.push(EDIT_DELETE); 1040 | i--; 1041 | current = west; 1042 | } else { 1043 | edits.push(EDIT_ADD); 1044 | j--; 1045 | current = north; 1046 | } 1047 | } 1048 | 1049 | edits.reverse(); 1050 | return edits; 1051 | }, 1052 | 1053 | /** 1054 | * Splice Projection functions: 1055 | * 1056 | * A splice map is a representation of how a previous array of items 1057 | * was transformed into a new array of items. Conceptually it is a list of 1058 | * tuples of 1059 | * 1060 | * 1061 | * 1062 | * which are kept in ascending index order of. The tuple represents that at 1063 | * the |index|, |removed| sequence of items were removed, and counting forward 1064 | * from |index|, |addedCount| items were added. 1065 | */ 1066 | 1067 | /** 1068 | * Lacking individual splice mutation information, the minimal set of 1069 | * splices can be synthesized given the previous state and final state of an 1070 | * array. The basic approach is to calculate the edit distance matrix and 1071 | * choose the shortest path through it. 1072 | * 1073 | * Complexity: O(l * p) 1074 | * l: The length of the current array 1075 | * p: The length of the old array 1076 | */ 1077 | calcSplices: function(current, currentStart, currentEnd, 1078 | old, oldStart, oldEnd) { 1079 | var prefixCount = 0; 1080 | var suffixCount = 0; 1081 | 1082 | var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart); 1083 | if (currentStart == 0 && oldStart == 0) 1084 | prefixCount = this.sharedPrefix(current, old, minLength); 1085 | 1086 | if (currentEnd == current.length && oldEnd == old.length) 1087 | suffixCount = this.sharedSuffix(current, old, minLength - prefixCount); 1088 | 1089 | currentStart += prefixCount; 1090 | oldStart += prefixCount; 1091 | currentEnd -= suffixCount; 1092 | oldEnd -= suffixCount; 1093 | 1094 | if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) 1095 | return []; 1096 | 1097 | if (currentStart == currentEnd) { 1098 | var splice = newSplice(currentStart, [], 0); 1099 | while (oldStart < oldEnd) 1100 | splice.removed.push(old[oldStart++]); 1101 | 1102 | return [ splice ]; 1103 | } else if (oldStart == oldEnd) 1104 | return [ newSplice(currentStart, [], currentEnd - currentStart) ]; 1105 | 1106 | var ops = this.spliceOperationsFromEditDistances( 1107 | this.calcEditDistances(current, currentStart, currentEnd, 1108 | old, oldStart, oldEnd)); 1109 | 1110 | var splice = undefined; 1111 | var splices = []; 1112 | var index = currentStart; 1113 | var oldIndex = oldStart; 1114 | for (var i = 0; i < ops.length; i++) { 1115 | switch(ops[i]) { 1116 | case EDIT_LEAVE: 1117 | if (splice) { 1118 | splices.push(splice); 1119 | splice = undefined; 1120 | } 1121 | 1122 | index++; 1123 | oldIndex++; 1124 | break; 1125 | case EDIT_UPDATE: 1126 | if (!splice) 1127 | splice = newSplice(index, [], 0); 1128 | 1129 | splice.addedCount++; 1130 | index++; 1131 | 1132 | splice.removed.push(old[oldIndex]); 1133 | oldIndex++; 1134 | break; 1135 | case EDIT_ADD: 1136 | if (!splice) 1137 | splice = newSplice(index, [], 0); 1138 | 1139 | splice.addedCount++; 1140 | index++; 1141 | break; 1142 | case EDIT_DELETE: 1143 | if (!splice) 1144 | splice = newSplice(index, [], 0); 1145 | 1146 | splice.removed.push(old[oldIndex]); 1147 | oldIndex++; 1148 | break; 1149 | } 1150 | } 1151 | 1152 | if (splice) { 1153 | splices.push(splice); 1154 | } 1155 | return splices; 1156 | }, 1157 | 1158 | sharedPrefix: function(current, old, searchLength) { 1159 | for (var i = 0; i < searchLength; i++) 1160 | if (!this.equals(current[i], old[i])) 1161 | return i; 1162 | return searchLength; 1163 | }, 1164 | 1165 | sharedSuffix: function(current, old, searchLength) { 1166 | var index1 = current.length; 1167 | var index2 = old.length; 1168 | var count = 0; 1169 | while (count < searchLength && this.equals(current[--index1], old[--index2])) 1170 | count++; 1171 | 1172 | return count; 1173 | }, 1174 | 1175 | calculateSplices: function(current, previous) { 1176 | return this.calcSplices(current, 0, current.length, previous, 0, 1177 | previous.length); 1178 | }, 1179 | 1180 | equals: function(currentValue, previousValue) { 1181 | return currentValue === previousValue; 1182 | } 1183 | }; 1184 | 1185 | var arraySplice = new ArraySplice(); 1186 | 1187 | function calcSplices(current, currentStart, currentEnd, 1188 | old, oldStart, oldEnd) { 1189 | return arraySplice.calcSplices(current, currentStart, currentEnd, 1190 | old, oldStart, oldEnd); 1191 | } 1192 | 1193 | function intersect(start1, end1, start2, end2) { 1194 | // Disjoint 1195 | if (end1 < start2 || end2 < start1) 1196 | return -1; 1197 | 1198 | // Adjacent 1199 | if (end1 == start2 || end2 == start1) 1200 | return 0; 1201 | 1202 | // Non-zero intersect, span1 first 1203 | if (start1 < start2) { 1204 | if (end1 < end2) 1205 | return end1 - start2; // Overlap 1206 | else 1207 | return end2 - start2; // Contained 1208 | } else { 1209 | // Non-zero intersect, span2 first 1210 | if (end2 < end1) 1211 | return end2 - start1; // Overlap 1212 | else 1213 | return end1 - start1; // Contained 1214 | } 1215 | } 1216 | 1217 | function mergeSplice(splices, index, removed, addedCount) { 1218 | 1219 | var splice = newSplice(index, removed, addedCount); 1220 | 1221 | var inserted = false; 1222 | var insertionOffset = 0; 1223 | 1224 | for (var i = 0; i < splices.length; i++) { 1225 | var current = splices[i]; 1226 | current.index += insertionOffset; 1227 | 1228 | if (inserted) 1229 | continue; 1230 | 1231 | var intersectCount = intersect(splice.index, 1232 | splice.index + splice.removed.length, 1233 | current.index, 1234 | current.index + current.addedCount); 1235 | 1236 | if (intersectCount >= 0) { 1237 | // Merge the two splices 1238 | 1239 | splices.splice(i, 1); 1240 | i--; 1241 | 1242 | insertionOffset -= current.addedCount - current.removed.length; 1243 | 1244 | splice.addedCount += current.addedCount - intersectCount; 1245 | var deleteCount = splice.removed.length + 1246 | current.removed.length - intersectCount; 1247 | 1248 | if (!splice.addedCount && !deleteCount) { 1249 | // merged splice is a noop. discard. 1250 | inserted = true; 1251 | } else { 1252 | var removed = current.removed; 1253 | 1254 | if (splice.index < current.index) { 1255 | // some prefix of splice.removed is prepended to current.removed. 1256 | var prepend = splice.removed.slice(0, current.index - splice.index); 1257 | Array.prototype.push.apply(prepend, removed); 1258 | removed = prepend; 1259 | } 1260 | 1261 | if (splice.index + splice.removed.length > current.index + current.addedCount) { 1262 | // some suffix of splice.removed is appended to current.removed. 1263 | var append = splice.removed.slice(current.index + current.addedCount - splice.index); 1264 | Array.prototype.push.apply(removed, append); 1265 | } 1266 | 1267 | splice.removed = removed; 1268 | if (current.index < splice.index) { 1269 | splice.index = current.index; 1270 | } 1271 | } 1272 | } else if (splice.index < current.index) { 1273 | // Insert splice here. 1274 | 1275 | inserted = true; 1276 | 1277 | splices.splice(i, 0, splice); 1278 | i++; 1279 | 1280 | var offset = splice.addedCount - splice.removed.length 1281 | current.index += offset; 1282 | insertionOffset += offset; 1283 | } 1284 | } 1285 | 1286 | if (!inserted) 1287 | splices.push(splice); 1288 | } 1289 | 1290 | function createInitialSplices(array, changeRecords) { 1291 | var splices = []; 1292 | 1293 | for (var i = 0; i < changeRecords.length; i++) { 1294 | var record = changeRecords[i]; 1295 | switch(record.type) { 1296 | case 'splice': 1297 | mergeSplice(splices, record.index, record.removed.slice(), record.addedCount); 1298 | break; 1299 | case 'new': 1300 | case 'updated': 1301 | case 'deleted': 1302 | if (!isIndex(record.name)) 1303 | continue; 1304 | var index = toNumber(record.name); 1305 | if (index < 0) 1306 | continue; 1307 | mergeSplice(splices, index, [record.oldValue], 1); 1308 | break; 1309 | default: 1310 | console.error('Unexpected record type: ' + JSON.stringify(record)); 1311 | break; 1312 | } 1313 | } 1314 | 1315 | return splices; 1316 | } 1317 | 1318 | function projectArraySplices(array, changeRecords) { 1319 | var splices = []; 1320 | 1321 | createInitialSplices(array, changeRecords).forEach(function(splice) { 1322 | if (splice.addedCount == 1 && splice.removed.length == 1) { 1323 | if (splice.removed[0] !== array[splice.index]) 1324 | splices.push(splice); 1325 | 1326 | return 1327 | }; 1328 | 1329 | splices = splices.concat(calcSplices(array, splice.index, splice.index + splice.addedCount, 1330 | splice.removed, 0, splice.removed.length)); 1331 | }); 1332 | 1333 | return splices; 1334 | } 1335 | 1336 | global.Observer = Observer; 1337 | global.Observer.hasObjectObserve = hasObserve; 1338 | global.ArrayObserver = ArrayObserver; 1339 | global.ArrayObserver.calculateSplices = function(current, previous) { 1340 | return arraySplice.calculateSplices(current, previous); 1341 | }; 1342 | 1343 | global.ArraySplice = ArraySplice; 1344 | global.ObjectObserver = ObjectObserver; 1345 | global.PathObserver = PathObserver; 1346 | global.CompoundPathObserver = CompoundPathObserver; 1347 | global.Path = Path; 1348 | })(typeof global !== 'undefined' && global ? global : this); -------------------------------------------------------------------------------- /bower_components/gss/dist/gss/vendor/sidetable.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The Polymer Authors. All rights reserved. 3 | * Use of this source code is goverened by a BSD-style 4 | * license that can be found in the LICENSE file. 5 | */ 6 | 7 | // SideTable is a weak map where possible. If WeakMap is not available the 8 | // association is stored as an expando property. 9 | var SideTable; 10 | // TODO(arv): WeakMap does not allow for Node etc to be keys in Firefox 11 | if (typeof WeakMap !== 'undefined' && navigator.userAgent.indexOf('Firefox/') < 0) { 12 | SideTable = WeakMap; 13 | } else { 14 | (function() { 15 | var defineProperty = Object.defineProperty; 16 | var hasOwnProperty = Object.hasOwnProperty; 17 | var counter = new Date().getTime() % 1e9; 18 | 19 | SideTable = function() { 20 | this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__'); 21 | }; 22 | 23 | SideTable.prototype = { 24 | set: function(key, value) { 25 | defineProperty(key, this.name, {value: value, writable: true}); 26 | }, 27 | get: function(key) { 28 | return hasOwnProperty.call(key, this.name) ? key[this.name] : undefined; 29 | }, 30 | delete: function(key) { 31 | this.set(key, undefined); 32 | } 33 | } 34 | })(); 35 | } -------------------------------------------------------------------------------- /bower_components/gss/dist/slightlyoff-cassowary.js/bin/c.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Parts Copyright (C) 2011-2012, Alex Russell (slightlyoff@chromium.org) 3 | * Parts Copyright (C) Copyright (C) 1998-2000 Greg J. Badros 4 | * 5 | * Use of this source code is governed by http://www.apache.org/licenses/LICENSE-2.0 6 | * 7 | * This is a compiled version of Cassowary/JS. For source versions or to 8 | * contribute, see the github project: 9 | * 10 | * https://github.com/slightlyoff/cassowary-js-refactor 11 | * 12 | */ 13 | 14 | (function() { 15 | !function(a){"use strict";try{!function(){}.bind(a)}catch(b){Object.defineProperty(Function.prototype,"bind",{value:function(a){var b=this;return function(){return b.apply(a,arguments)}},enumerable:!1,configurable:!0,writable:!0})}var c="undefined"!=typeof a.HTMLElement,d=function(a){for(var b=null;a&&a!=Object.prototype;){if(a.tagName){b=a.tagName;break}a=a.prototype}return b||"div"},e=1e-8,f={},g=function(a,b){if(a&&b){if("function"==typeof a[b])return a[b];var c=a.prototype;if(c&&"function"==typeof c[b])return c[b];if(c!==Object.prototype&&c!==Function.prototype)return"function"==typeof a.__super__?g(a.__super__,b):void 0}},h=a.c=function(){return h._api?h._api.apply(this,arguments):void 0};h.debug=!1,h.trace=!1,h.verbose=!1,h.traceAdded=!1,h.GC=!1,h.GEQ=1,h.LEQ=2,h.inherit=function(b){var e=null,g=null;b["extends"]&&(g=b["extends"],delete b["extends"]),b.initialize&&(e=b.initialize,delete b.initialize);var i=e||function(){};Object.defineProperty(i,"__super__",{value:g?g:Object,enumerable:!1,configurable:!0,writable:!1}),b._t&&(f[b._t]=i);var j=i.prototype=Object.create(g?g.prototype:Object.prototype);if(h.extend(j,b),c&&g&&g.prototype instanceof a.HTMLElement){var k=i,l=d(j),m=function(a){return a.__proto__=j,k.apply(a,arguments),j.created&&a.created(),j.decorate&&a.decorate(),a};this.extend(j,{upgrade:m}),i=function(){return m(a.document.createElement(l))},i.prototype=j,this.extend(i,{ctor:k})}return i},h.own=function(b,c,d){return Object.getOwnPropertyNames(b).forEach(c,d||a),b},h.extend=function(a,b){return h.own(b,function(c){var d=Object.getOwnPropertyDescriptor(b,c);try{"function"==typeof d.get||"function"==typeof d.set?Object.defineProperty(a,c,d):"function"==typeof d.value||"_"===c.charAt(0)?(d.writable=!0,d.configurable=!0,d.enumerable=!1,Object.defineProperty(a,c,d)):a[c]=b[c]}catch(e){}}),a},h.traceprint=function(a){h.verbose&&console.log(a)},h.fnenterprint=function(a){console.log("* "+a)},h.fnexitprint=function(a){console.log("- "+a)},h.assert=function(a,b){if(!a)throw new h.InternalError("Assertion failed: "+b)};var i=function(a){return"number"==typeof a?h.Expression.fromConstant(a):a instanceof h.Variable?h.Expression.fromVariable(a):a};h.plus=function(a,b){return a=i(a),b=i(b),a.plus(b)},h.minus=function(a,b){return a=i(a),b=i(b),a.minus(b)},h.times=function(a,b){return a=i(a),b=i(b),a.times(b)},h.divide=function(a,b){return a=i(a),b=i(b),a.divide(b)},h.approx=function(a,b){return a===b?!0:(a=+a,b=+b,0==a?Math.abs(b)30||this._deleted>this._compactThreshold&&(this._compact(),this._deleted=0)},"delete":function(a){a=a.hashCode,this._store.hasOwnProperty(a)&&(this._deleted++,delete this._store[a],this.size>0&&this.size--)},each:function(a,b){if(this.size){this._perhapsCompact();var c=this._store,d=this._keyStrMap;for(var e in this._store)this._store.hasOwnProperty(e)&&a.call(b||null,d[e],c[e])}},escapingEach:function(a,b){if(this.size){this._perhapsCompact();for(var c=this,e=this._store,f=this._keyStrMap,g=d,h=Object.keys(e),i=0;i "+c+"\n"}),b}})}(this.c||module.parent.exports||{}),function(a){"use strict";a.HashSet=a.inherit({_t:"c.HashSet",initialize:function(){this.storage=[],this.size=0,this.hashCode=a._inc()},add:function(a){var b=this.storage;b.indexOf(a),-1==b.indexOf(a)&&(b[b.length]=a),this.size=this.storage.length},values:function(){return this.storage},has:function(a){var b=this.storage;return-1!=b.indexOf(a)},"delete":function(a){var b=this.storage.indexOf(a);return-1==b?null:(this.storage.splice(b,1)[0],this.size=this.storage.length,void 0)},clear:function(){this.storage.length=0},each:function(a,b){this.size&&this.storage.forEach(a,b)},escapingEach:function(a,b){this.size&&this.storage.forEach(a,b)},toString:function(){var a=this.size+" {",b=!0;return this.each(function(c){b?b=!1:a+=", ",a+=c}),a+="}\n"},toJSON:function(){var a=[];return this.each(function(b){a[a.length]=b.toJSON()}),{_t:"c.HashSet",data:a}},fromJSON:function(b){var c=new a.HashSet;return b.data&&(c.size=b.data.length,c.storage=b.data),c}})}(this.c||module.parent.exports||{}),function(a){"use strict";a.Error=a.inherit({initialize:function(a){a&&(this._description=a)},_name:"c.Error",_description:"An error has occured in Cassowary",set description(a){this._description=a},get description(){return"("+this._name+") "+this._description},get message(){return this.description},toString:function(){return this.description}});var b=function(b,c){return a.inherit({"extends":a.Error,initialize:function(){a.Error.apply(this,arguments)},_name:b||"",_description:c||""})};a.ConstraintNotFound=b("c.ConstraintNotFound","Tried to remove a constraint never added to the tableu"),a.InternalError=b("c.InternalError"),a.NonExpression=b("c.NonExpression","The resulting expression would be non"),a.NotEnoughStays=b("c.NotEnoughStays","There are not enough stays to give specific values to every variable"),a.RequiredFailure=b("c.RequiredFailure","A required constraint cannot be satisfied"),a.TooDifficult=b("c.TooDifficult","The constraints are too difficult to solve")}(this.c||module.parent.exports||{}),function(a){"use strict";var b=1e3;a.SymbolicWeight=a.inherit({_t:"c.SymbolicWeight",initialize:function(){this.value=0;for(var a=1,c=arguments.length-1;c>=0;--c)this.value+=arguments[c]*a,a*=b},toJSON:function(){return{_t:this._t,value:this.value}}})}(this.c||module.parent.exports||{}),function(a){a.Strength=a.inherit({initialize:function(b,c,d,e){this.name=b,this.symbolicWeight=c instanceof a.SymbolicWeight?c:new a.SymbolicWeight(c,d,e)},get required(){return this===a.Strength.required},toString:function(){return this.name+(this.isRequired?"":":"+this.symbolicWeight)}}),a.Strength.required=new a.Strength("",1e3,1e3,1e3),a.Strength.strong=new a.Strength("strong",1,0,0),a.Strength.medium=new a.Strength("medium",0,1,0),a.Strength.weak=new a.Strength("weak",0,0,1)}(this.c||("undefined"!=typeof module?module.parent.exports.c:{})),function(a){"use strict";a.AbstractVariable=a.inherit({isDummy:!1,isExternal:!1,isPivotable:!1,isRestricted:!1,_init:function(b,c){this.hashCode=a._inc(),this.name=(c||"")+this.hashCode,b&&("undefined"!=typeof b.name&&(this.name=b.name),"undefined"!=typeof b.value&&(this.value=b.value),"undefined"!=typeof b.prefix&&(this._prefix=b.prefix))},_prefix:"",name:"",value:0,valueOf:function(){return this.value},toJSON:function(){var a={};return this._t&&(a._t=this._t),this.name&&(a.name=this.name),"undefined"!=typeof this.value&&(a.value=this.value),this._prefix&&(a._prefix=this._prefix),this._t&&(a._t=this._t),a},fromJSON:function(b,c){var d=new c;return a.extend(d,b),d},toString:function(){return this._prefix+"["+this.name+":"+this.value+"]"}}),a.Variable=a.inherit({_t:"c.Variable","extends":a.AbstractVariable,initialize:function(b){this._init(b,"v");var c=a.Variable._map;c&&(c[this.name]=this)},isExternal:!0}),a.DummyVariable=a.inherit({_t:"c.DummyVariable","extends":a.AbstractVariable,initialize:function(a){this._init(a,"d")},isDummy:!0,isRestricted:!0,value:"dummy"}),a.ObjectiveVariable=a.inherit({_t:"c.ObjectiveVariable","extends":a.AbstractVariable,initialize:function(a){this._init(a,"o")},value:"obj"}),a.SlackVariable=a.inherit({_t:"c.SlackVariable","extends":a.AbstractVariable,initialize:function(a){this._init(a,"s")},isPivotable:!0,isRestricted:!0,value:"slack"})}(this.c||module.parent.exports||{}),function(a){"use strict";a.Point=a.inherit({initialize:function(b,c,d){if(b instanceof a.Variable)this._x=b;else{var e={value:b};d&&(e.name="x"+d),this._x=new a.Variable(e)}if(c instanceof a.Variable)this._y=c;else{var f={value:c};d&&(f.name="y"+d),this._y=new a.Variable(f)}},get x(){return this._x},set x(b){b instanceof a.Variable?this._x=b:this._x.value=b},get y(){return this._y},set y(b){b instanceof a.Variable?this._y=b:this._y.value=b},toString:function(){return"("+this.x+", "+this.y+")"}})}(this.c||module.parent.exports||{}),function(a){"use strict";var b=function(a,b){return"number"==typeof a?a:b};a.Expression=a.inherit({initialize:function(c,d,e){this.constant=b(e,0),this.terms=new a.HashTable,c instanceof a.AbstractVariable?(d=b(d,1),this.setVariable(c,d)):"number"==typeof c&&(isNaN(c)?console.trace():this.constant=c)},initializeFromHash:function(b,c){return a.verbose&&(console.log("*******************************"),console.log("clone c.initializeFromHash"),console.log("*******************************")),a.GC&&console.log("clone c.Expression"),this.constant=b,this.terms=c.clone(),this},multiplyMe:function(a){this.constant*=a;var b=this.terms;return b.each(function(c,d){b.set(c,d*a)}),this},clone:function(){a.verbose&&(console.log("*******************************"),console.log("clone c.Expression"),console.log("*******************************"));var b=a.Expression.empty();return b.initializeFromHash(this.constant,this.terms),b},times:function(b){if("number"==typeof b)return this.clone().multiplyMe(b);if(this.isConstant)return b.times(this.constant);if(b.isConstant)return this.times(b.constant);throw new a.NonExpression},plus:function(b){return b instanceof a.Expression?this.clone().addExpression(b,1):b instanceof a.Variable?this.clone().addVariable(b,1):void 0},minus:function(b){return b instanceof a.Expression?this.clone().addExpression(b,-1):b instanceof a.Variable?this.clone().addVariable(b,-1):void 0},divide:function(b){if("number"==typeof b){if(a.approx(b,0))throw new a.NonExpression;return this.times(1/b)}if(b instanceof a.Expression){if(!b.isConstant)throw new a.NonExpression;return this.times(1/b.constant)}},addExpression:function(c,d,e,f){return c instanceof a.AbstractVariable&&(c=a.Expression.fromVariable(c)),d=b(d,1),this.constant+=d*c.constant,c.terms.each(function(a,b){this.addVariable(a,b*d,e,f)},this),this},addVariable:function(b,c,d,e){null==c&&(c=1),a.trace&&console.log("c.Expression::addVariable():",b,c);var f=this.terms.get(b);if(f){var g=f+c;0==g||a.approx(g,0)?(e&&e.noteRemovedVariable(b,d),this.terms.delete(b)):this.setVariable(b,g)}else a.approx(c,0)||(this.setVariable(b,c),e&&e.noteAddedVariable(b,d));return this},setVariable:function(a,b){return this.terms.set(a,b),this},anyPivotableVariable:function(){if(this.isConstant)throw new a.InternalError("anyPivotableVariable called on a constant");var b=this.terms.escapingEach(function(a){return a.isPivotable?{retval:a}:void 0});return b&&void 0!==b.retval?b.retval:null},substituteOut:function(b,c,d,e){a.trace&&(a.fnenterprint("CLE:substituteOut: "+b+", "+c+", "+d+", ..."),a.traceprint("this = "+this)),this.setVariable.bind(this);var g=this.terms,h=g.get(b);g.delete(b),this.constant+=h*c.constant,c.terms.each(function(b,c){var f=g.get(b);if(f){var i=f+h*c;a.approx(i,0)?(e.noteRemovedVariable(b,d),g.delete(b)):g.set(b,i)}else g.set(b,h*c),e&&e.noteAddedVariable(b,d)}),a.trace&&a.traceprint("Now this is "+this)},changeSubject:function(a,b){this.setVariable(a,this.newSubject(b))},newSubject:function(b){a.trace&&a.fnenterprint("newSubject:"+b);var c=1/this.terms.get(b);return this.terms.delete(b),this.multiplyMe(-c),c},coefficientFor:function(a){return this.terms.get(a)||0},get isConstant(){return 0==this.terms.size},toString:function(){var b="",c=!1;if(!a.approx(this.constant,0)||this.isConstant){if(b+=this.constant,this.isConstant)return b;c=!0}return this.terms.each(function(a,d){c&&(b+=" + "),b+=d+"*"+a,c=!0}),b},equals:function(b){return b===this?!0:b instanceof a.Expression&&b.constant===this.constant&&b.terms.equals(this.terms)},Plus:function(a,b){return a.plus(b)},Minus:function(a,b){return a.minus(b)},Times:function(a,b){return a.times(b)},Divide:function(a,b){return a.divide(b)}}),a.Expression.empty=function(){return new a.Expression(void 0,1,0)},a.Expression.fromConstant=function(b){return new a.Expression(b)},a.Expression.fromValue=function(b){return b=+b,new a.Expression(void 0,b,0)},a.Expression.fromVariable=function(b){return new a.Expression(b,1,0)}}(this.c||module.parent.exports||{}),function(a){"use strict";a.AbstractConstraint=a.inherit({initialize:function(b,c){this.hashCode=a._inc(),this.strength=b||a.Strength.required,this.weight=c||1},isEditConstraint:!1,isInequality:!1,isStayConstraint:!1,get required(){return this.strength===a.Strength.required},toString:function(){return this.strength+" {"+this.weight+"} ("+this.expression+")"}});var b=a.AbstractConstraint.prototype.toString,c=function(b,c,d){a.AbstractConstraint.call(this,c||a.Strength.strong,d),this.variable=b,this.expression=new a.Expression(b,-1,b.value)};a.EditConstraint=a.inherit({"extends":a.AbstractConstraint,initialize:function(){c.apply(this,arguments)},isEditConstraint:!0,toString:function(){return"edit:"+b.call(this)}}),a.StayConstraint=a.inherit({"extends":a.AbstractConstraint,initialize:function(){c.apply(this,arguments)},isStayConstraint:!0,toString:function(){return"stay:"+b.call(this)}});var d=a.Constraint=a.inherit({"extends":a.AbstractConstraint,initialize:function(b,c,d){a.AbstractConstraint.call(this,c,d),this.expression=b}});a.Inequality=a.inherit({"extends":a.Constraint,_cloneOrNewCle:function(b){return b.clone?b.clone():new a.Expression(b)},initialize:function(b,c,e,f,g){var h=b instanceof a.Expression,i=e instanceof a.Expression,j=b instanceof a.AbstractVariable,k=e instanceof a.AbstractVariable,l="number"==typeof b,m="number"==typeof e;if((h||l)&&k){var n=b,o=c,p=e,q=f,r=g;if(d.call(this,this._cloneOrNewCle(n),q,r),o==a.LEQ)this.expression.multiplyMe(-1),this.expression.addVariable(p);else{if(o!=a.GEQ)throw new a.InternalError("Invalid operator in c.Inequality constructor");this.expression.addVariable(p,-1)}}else if(j&&(i||m)){var n=e,o=c,p=b,q=f,r=g;if(d.call(this,this._cloneOrNewCle(n),q,r),o==a.GEQ)this.expression.multiplyMe(-1),this.expression.addVariable(p);else{if(o!=a.LEQ)throw new a.InternalError("Invalid operator in c.Inequality constructor");this.expression.addVariable(p,-1)}}else{if(h&&m){var s=b,o=c,t=e,q=f,r=g;if(d.call(this,this._cloneOrNewCle(s),q,r),o==a.LEQ)this.expression.multiplyMe(-1),this.expression.addExpression(this._cloneOrNewCle(t));else{if(o!=a.GEQ)throw new a.InternalError("Invalid operator in c.Inequality constructor");this.expression.addExpression(this._cloneOrNewCle(t),-1)}return this}if(l&&i){var s=e,o=c,t=b,q=f,r=g;if(d.call(this,this._cloneOrNewCle(s),q,r),o==a.GEQ)this.expression.multiplyMe(-1),this.expression.addExpression(this._cloneOrNewCle(t));else{if(o!=a.LEQ)throw new a.InternalError("Invalid operator in c.Inequality constructor");this.expression.addExpression(this._cloneOrNewCle(t),-1)}return this}if(h&&i){var s=b,o=c,t=e,q=f,r=g;if(d.call(this,this._cloneOrNewCle(t),q,r),o==a.GEQ)this.expression.multiplyMe(-1),this.expression.addExpression(this._cloneOrNewCle(s));else{if(o!=a.LEQ)throw new a.InternalError("Invalid operator in c.Inequality constructor");this.expression.addExpression(this._cloneOrNewCle(s),-1)}}else{if(h)return d.call(this,b,c,e);if(c==a.GEQ)d.call(this,new a.Expression(e),f,g),this.expression.multiplyMe(-1),this.expression.addVariable(b);else{if(c!=a.LEQ)throw new a.InternalError("Invalid operator in c.Inequality constructor");d.call(this,new a.Expression(e),f,g),this.expression.addVariable(b,-1)}}}},isInequality:!0,toString:function(){return d.prototype.toString.call(this)+" >= 0) id: "+this.hashCode}}),a.Equation=a.inherit({"extends":a.Constraint,initialize:function(b,c,e,f){if(b instanceof a.Expression&&!c||c instanceof a.Strength)d.call(this,b,c,e);else if(b instanceof a.AbstractVariable&&c instanceof a.Expression){var g=b,h=c,i=e,j=f;d.call(this,h.clone(),i,j),this.expression.addVariable(g,-1)}else if(b instanceof a.AbstractVariable&&"number"==typeof c){var g=b,k=c,i=e,j=f;d.call(this,new a.Expression(k),i,j),this.expression.addVariable(g,-1)}else if(b instanceof a.Expression&&c instanceof a.AbstractVariable){var h=b,g=c,i=e,j=f;d.call(this,h.clone(),i,j),this.expression.addVariable(g,-1)}else{if(!(b instanceof a.Expression||b instanceof a.AbstractVariable||"number"==typeof b)||!(c instanceof a.Expression||c instanceof a.AbstractVariable||"number"==typeof c))throw"Bad initializer to c.Equation";b=b instanceof a.Expression?b.clone():new a.Expression(b),c=c instanceof a.Expression?c.clone():new a.Expression(c),d.call(this,b,e,f),this.expression.addExpression(c,-1)}a.assert(this.strength instanceof a.Strength,"_strength not set")},toString:function(){return d.prototype.toString.call(this)+" = 0)"}})}(this.c||module.parent.exports||{}),function(a){"use strict";a.EditInfo=a.inherit({initialize:function(a,b,c,d,e){this.constraint=a,this.editPlus=b,this.editMinus=c,this.prevEditConstant=d,this.index=e},toString:function(){return""}})}(this.c||module.parent.exports||{}),function(a){"use strict";a.Tableau=a.inherit({initialize:function(){this.columns=new a.HashTable,this.rows=new a.HashTable,this._infeasibleRows=new a.HashSet,this._externalRows=new a.HashSet,this._externalParametricVars=new a.HashSet},noteRemovedVariable:function(b,c){a.trace&&console.log("c.Tableau::noteRemovedVariable: ",b,c);var d=this.columns.get(b);c&&d&&d.delete(c)},noteAddedVariable:function(a,b){b&&this.insertColVar(a,b)},getInternalInfo:function(){var a="Tableau Information:\n";return a+="Rows: "+this.rows.size,a+=" (= "+(this.rows.size-1)+" constraints)",a+="\nColumns: "+this.columns.size,a+="\nInfeasible Rows: "+this._infeasibleRows.size,a+="\nExternal basic variables: "+this._externalRows.size,a+="\nExternal parametric variables: ",a+=this._externalParametricVars.size,a+="\n"},toString:function(){var a="Tableau:\n";return this.rows.each(function(b,c){a+=b,a+=" <==> ",a+=c,a+="\n"}),a+="\nColumns:\n",a+=this.columns,a+="\nInfeasible rows: ",a+=this._infeasibleRows,a+="External basic variables: ",a+=this._externalRows,a+="External parametric variables: ",a+=this._externalParametricVars},insertColVar:function(b,c){var d=this.columns.get(b);d||(d=new a.HashSet,this.columns.set(b,d)),d.add(c)},addRow:function(b,c){a.trace&&a.fnenterprint("addRow: "+b+", "+c),this.rows.set(b,c),c.terms.each(function(a){this.insertColVar(a,b),a.isExternal&&this._externalParametricVars.add(a)},this),b.isExternal&&this._externalRows.add(b),a.trace&&a.traceprint(this.toString())},removeColumn:function(b){a.trace&&a.fnenterprint("removeColumn:"+b);var c=this.columns.get(b);c?(this.columns.delete(b),c.each(function(a){var c=this.rows.get(a);c.terms.delete(b)},this)):a.trace&&console.log("Could not find var",b,"in columns"),b.isExternal&&(this._externalRows.delete(b),this._externalParametricVars.delete(b))},removeRow:function(b){a.trace&&a.fnenterprint("removeRow:"+b);var c=this.rows.get(b);return a.assert(null!=c),c.terms.each(function(c){var e=this.columns.get(c);null!=e&&(a.trace&&console.log("removing from varset:",b),e.delete(b))},this),this._infeasibleRows.delete(b),b.isExternal&&this._externalRows.delete(b),this.rows.delete(b),a.trace&&a.fnexitprint("returning "+c),c},substituteOut:function(b,c){a.trace&&a.fnenterprint("substituteOut:"+b+", "+c),a.trace&&a.traceprint(this.toString());var d=this.columns.get(b);d.each(function(a){var d=this.rows.get(a);d.substituteOut(b,c,a,this),a.isRestricted&&d.constant<0&&this._infeasibleRows.add(a)},this),b.isExternal&&(this._externalRows.add(b),this._externalParametricVars.delete(b)),this.columns.delete(b)},columnsHasKey:function(a){return!!this.columns.get(a)}})}(this.c||module.parent.exports||{}),function(a){var b=a.Tableau,c=b.prototype,d=1e-8,e=a.Strength.weak;a.SimplexSolver=a.inherit({"extends":a.Tableau,initialize:function(){a.Tableau.call(this),this._stayMinusErrorVars=[],this._stayPlusErrorVars=[],this._errorVars=new a.HashTable,this._markerVars=new a.HashTable,this._objective=new a.ObjectiveVariable({name:"Z"}),this._editVarMap=new a.HashTable,this._editVarList=[],this._slackCounter=0,this._artificialCounter=0,this._dummyCounter=0,this.autoSolve=!0,this._needsSolving=!1,this._optimizeCount=0,this.rows.set(this._objective,a.Expression.empty()),this._editVariableStack=[0],a.trace&&a.traceprint("objective expr == "+this.rows.get(this._objective))},add:function(){for(var a=0;a0,"_editVarMap.size > 0"),this._infeasibleRows.clear(),this._resetStayConstants(),this._editVariableStack[this._editVariableStack.length]=this._editVarMap.size,this},endEdit:function(){return a.assert(this._editVarMap.size>0,"_editVarMap.size > 0"),this.resolve(),this._editVariableStack.pop(),this.removeEditVarsTo(this._editVariableStack[this._editVariableStack.length-1]),this},removeAllEditVars:function(){return this.removeEditVarsTo(0)},removeEditVarsTo:function(b){try{for(var c=this._editVarList.length,d=b;c>d;d++)this._editVarList[d]&&this.removeConstraint(this._editVarMap.get(this._editVarList[d].v).constraint);return this._editVarList.length=b,a.assert(this._editVarMap.size==b,"_editVarMap.size == n"),this}catch(e){throw new a.InternalError("Constraint not found in removeEditVarsTo")}},addPointStays:function(b){return a.trace&&console.log("addPointStays",b),b.forEach(function(a,b){this.addStay(a.x,e,Math.pow(2,b)),this.addStay(a.y,e,Math.pow(2,b))},this),this},addStay:function(b,c,d){var f=new a.StayConstraint(b,c||e,d||1);return this.addConstraint(f)},removeConstraint:function(b){a.trace&&a.fnenterprint("removeConstraintInternal: "+b),a.trace&&a.traceprint(this.toString()),this._needsSolving=!0,this._resetStayConstants();var c=this.rows.get(this._objective),d=this._errorVars.get(b);a.trace&&a.traceprint("eVars == "+d),null!=d&&d.each(function(e){var f=this.rows.get(e);null==f?c.addVariable(e,-b.weight*b.strength.symbolicWeight.value,this._objective,this):c.addExpression(f,-b.weight*b.strength.symbolicWeight.value,this._objective,this),a.trace&&a.traceprint("now eVars == "+d)},this);var e=this._markerVars.get(b);if(this._markerVars.delete(b),null==e)throw new a.InternalError("Constraint not found in removeConstraintInternal");if(a.trace&&a.traceprint("Looking to remove var "+e),null==this.rows.get(e)){var f=this.columns.get(e);a.trace&&a.traceprint("Must pivot -- columns are "+f);var g=null,h=0;f.each(function(b){if(b.isRestricted){var c=this.rows.get(b),d=c.coefficientFor(e);if(a.trace&&a.traceprint("Marker "+e+"'s coefficient in "+c+" is "+d),0>d){var f=-c.constant/d;(null==g||h>f||a.approx(f,h)&&b.hashCoded)&&(h=d,g=a)}},this)),null==g&&(0==f.size?this.removeColumn(e):f.escapingEach(function(a){return a!=this._objective?(g=a,{brk:!0}):void 0},this)),null!=g&&this.pivot(e,g)}if(null!=this.rows.get(e)&&this.removeRow(e),null!=d&&d.each(function(a){a!=e&&this.removeColumn(a)},this),b.isStayConstraint){if(null!=d)for(var j=0;je&&this.suggestValue(a,b[e])},this),this.resolve()},resolvePair:function(a,b){this.suggestValue(this._editVarList[0].v,a),this.suggestValue(this._editVarList[1].v,b),this.resolve()},resolve:function(){a.trace&&a.fnenterprint("resolve()"),this.dualOptimize(),this._setExternalVariables(),this._infeasibleRows.clear(),this._resetStayConstants()},suggestValue:function(b,c){a.trace&&console.log("suggestValue("+b+", "+c+")");var d=this._editVarMap.get(b);if(!d)throw new a.Error("suggestValue for variable "+b+", but var is not an edit variable");var e=c-d.prevEditConstant;return d.prevEditConstant=c,this.deltaEditConstant(e,d.editPlus,d.editMinus),this},solve:function(){return this._needsSolving&&(this.optimize(this._objective),this._setExternalVariables()),this},setEditedValue:function(b,c){if(!this.columnsHasKey(b)&&null==this.rows.get(b))return b.value=c,this;if(!a.approx(c,b.value)){this.addEditVar(b),this.beginEdit();try{this.suggestValue(b,c)}catch(d){throw new a.InternalError("Error in setEditedValue")}this.endEdit()}return this},addVar:function(b){if(!this.columnsHasKey(b)&&null==this.rows.get(b)){try{this.addStay(b)}catch(c){throw new a.InternalError("Error in addVar -- required failure is impossible")}a.trace&&a.traceprint("added initial stay on "+b)}return this},getInternalInfo:function(){var a=c.getInternalInfo.call(this);return a+="\nSolver info:\n",a+="Stay Error Variables: ",a+=this._stayPlusErrorVars.length+this._stayMinusErrorVars.length,a+=" ("+this._stayPlusErrorVars.length+" +, ",a+=this._stayMinusErrorVars.length+" -)\n",a+="Edit Variables: "+this._editVarMap.size,a+="\n"},getDebugInfo:function(){return this.toString()+this.getInternalInfo()+"\n"},toString:function(){var a=c.getInternalInfo.call(this);return a+="\n_stayPlusErrorVars: ",a+="["+this._stayPlusErrorVars+"]",a+="\n_stayMinusErrorVars: ",a+="["+this._stayMinusErrorVars+"]",a+="\n",a+="_editVarMap:\n"+this._editVarMap,a+="\n"},addWithArtificialVariable:function(b){a.trace&&a.fnenterprint("addWithArtificialVariable: "+b);var c=new a.SlackVariable({value:++this._artificialCounter,prefix:"a"}),d=new a.ObjectiveVariable({name:"az"}),e=b.clone();a.trace&&a.traceprint("before addRows:\n"+this),this.addRow(d,e),this.addRow(c,b),a.trace&&a.traceprint("after addRows:\n"+this),this.optimize(d);var f=this.rows.get(d);if(a.trace&&a.traceprint("azTableauRow.constant == "+f.constant),!a.approx(f.constant,0))throw this.removeRow(d),this.removeColumn(c),new a.RequiredFailure;var g=this.rows.get(c);if(null!=g){if(g.isConstant)return this.removeRow(c),this.removeRow(d),void 0;var h=g.anyPivotableVariable();this.pivot(h,c)}a.assert(null==this.rows.get(c),"rowExpression(av) == null"),this.removeColumn(c),this.removeRow(d)},tryAddingDirectly:function(b){a.trace&&a.fnenterprint("tryAddingDirectly: "+b);var c=this.chooseSubject(b);return null==c?(a.trace&&a.fnexitprint("returning false"),!1):(b.newSubject(c),this.columnsHasKey(c)&&this.substituteOut(c,b),this.addRow(c,b),a.trace&&a.fnexitprint("returning true"),!0)},chooseSubject:function(b){a.trace&&a.fnenterprint("chooseSubject: "+b);var c=null,d=!1,e=!1,f=b.terms,g=f.escapingEach(function(a,b){if(d){if(!a.isRestricted&&!this.columnsHasKey(a))return{retval:a}}else if(a.isRestricted){if(!e&&!a.isDummy&&0>b){var f=this.columns.get(a);(null==f||1==f.size&&this.columnsHasKey(this._objective))&&(c=a,e=!0)}}else c=a,d=!0},this);if(g&&void 0!==g.retval)return g.retval;if(null!=c)return c;var h=0,g=f.escapingEach(function(a,b){return a.isDummy?(this.columnsHasKey(a)||(c=a,h=b),void 0):{retval:null}},this);if(g&&void 0!==g.retval)return g.retval;if(!a.approx(b.constant,0))throw new a.RequiredFailure;return h>0&&b.multiplyMe(-1),c},deltaEditConstant:function(b,c,d){a.trace&&a.fnenterprint("deltaEditConstant :"+b+", "+c+", "+d);var e=this.rows.get(c);if(null!=e)return e.constant+=b,e.constant<0&&this._infeasibleRows.add(c),void 0;var f=this.rows.get(d);if(null!=f)return f.constant+=-b,f.constant<0&&this._infeasibleRows.add(d),void 0;var g=this.columns.get(d);g||console.log("columnVars is null -- tableau is:\n"+this),g.each(function(a){var c=this.rows.get(a),e=c.coefficientFor(d);c.constant+=e*b,a.isRestricted&&c.constant<0&&this._infeasibleRows.add(a)},this)},dualOptimize:function(){a.trace&&a.fnenterprint("dualOptimize:");for(var b=this.rows.get(this._objective);this._infeasibleRows.size;){var c=this._infeasibleRows.values()[0];this._infeasibleRows.delete(c);var d=null,e=this.rows.get(c);if(e&&e.constant<0){var g,f=Number.MAX_VALUE,h=e.terms;if(h.each(function(c,e){if(e>0&&c.isPivotable){var h=b.coefficientFor(c);g=h/e,(f>g||a.approx(g,f)&&c.hashCodeb?(g=b,e=a,{brk:1}):void 0},this),g>=-d)return;a.trace&&console.log("entryVar:",e,"objectiveCoeff:",g);var i=Number.MAX_VALUE,j=this.columns.get(e),k=0;if(j.each(function(b){if(a.trace&&a.traceprint("Checking "+b),b.isPivotable){var c=this.rows.get(b),d=c.coefficientFor(e);a.trace&&a.traceprint("pivotable, coeff = "+d),0>d&&(k=-c.constant/d,(i>k||a.approx(k,i)&&b.hashCoded;d++){var e=this.rows.get(b[d]);null===e&&(e=this.rows.get(this._stayMinusErrorVars[d])),null!=e&&(e.constant=0)}},_setExternalVariables:function(){a.trace&&a.fnenterprint("_setExternalVariables:"),a.trace&&a.traceprint(this.toString());var b={};this._externalParametricVars.each(function(c){null!=this.rows.get(c)?a.trace&&console.log("Error: variable"+c+" in _externalParametricVars is basic"):(c.value=0,b[c.name]=0)},this),this._externalRows.each(function(a){var c=this.rows.get(a);a.value!=c.constant&&(a.value=c.constant,b[a.name]=c.constant)},this),this._changed=b,this._needsSolving=!1,this._informCallbacks(),this.onsolved()},onsolved:function(){},_informCallbacks:function(){if(this._callbacks){var a=this._changed;this._callbacks.forEach(function(b){b(a)})}},_addCallback:function(a){var b=this._callbacks||(this._callbacks=[]);b[b.length]=a},insertErrorVar:function(b,c){a.trace&&a.fnenterprint("insertErrorVar:"+b+", "+c);var d=this._errorVars.get(c);d||(d=new a.HashSet,this._errorVars.set(b,d)),d.add(c)}})}(this.c||module.parent.exports||{}),function(a){"use strict";a.Timer=a.inherit({initialize:function(){this.isRunning=!1,this._elapsedMs=0},start:function(){return this.isRunning=!0,this._startReading=new Date,this},stop:function(){return this.isRunning=!1,this._elapsedMs+=new Date-this._startReading,this},reset:function(){return this.isRunning=!1,this._elapsedMs=0,this},elapsedTime:function(){return this.isRunning?(this._elapsedMs+(new Date-this._startReading))/1e3:this._elapsedMs/1e3}})}(this.c||module.parent.exports||{}),this.c.parser=function(){function a(a){return'"'+a.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-\x1F\x80-\uFFFF]/g,escape)+'"'}var b={parse:function(b,c){function k(a){g>e||(e>g&&(g=e,h=[]),h.push(a))}function l(){var a,b,c,d,f;if(d=e,f=e,a=z(),null!==a){for(b=[],c=m();null!==c;)b.push(c),c=m();null!==b?(c=z(),null!==c?a=[a,b,c]:(a=null,e=f)):(a=null,e=f)}else a=null,e=f;return null!==a&&(a=function(a,b){return b}(d,a[1])),null===a&&(e=d),a}function m(){var a,b,c,d;return c=e,d=e,a=P(),null!==a?(b=s(),null!==b?a=[a,b]:(a=null,e=d)):(a=null,e=d),null!==a&&(a=function(a,b){return b}(c,a[0])),null===a&&(e=c),a}function n(){var a;return b.length>e?(a=b.charAt(e),e++):(a=null,0===f&&k("any character")),a}function o(){var a;return/^[a-zA-Z]/.test(b.charAt(e))?(a=b.charAt(e),e++):(a=null,0===f&&k("[a-zA-Z]")),null===a&&(36===b.charCodeAt(e)?(a="$",e++):(a=null,0===f&&k('"$"')),null===a&&(95===b.charCodeAt(e)?(a="_",e++):(a=null,0===f&&k('"_"')))),a}function p(){var a;return f++,/^[\t\x0B\f \xA0\uFEFF]/.test(b.charAt(e))?(a=b.charAt(e),e++):(a=null,0===f&&k("[\\t\\x0B\\f \\xA0\\uFEFF]")),f--,0===f&&null===a&&k("whitespace"),a}function q(){var a;return/^[\n\r\u2028\u2029]/.test(b.charAt(e))?(a=b.charAt(e),e++):(a=null,0===f&&k("[\\n\\r\\u2028\\u2029]")),a}function r(){var a;return f++,10===b.charCodeAt(e)?(a="\n",e++):(a=null,0===f&&k('"\\n"')),null===a&&("\r\n"===b.substr(e,2)?(a="\r\n",e+=2):(a=null,0===f&&k('"\\r\\n"')),null===a&&(13===b.charCodeAt(e)?(a="\r",e++):(a=null,0===f&&k('"\\r"')),null===a&&(8232===b.charCodeAt(e)?(a="\u2028",e++):(a=null,0===f&&k('"\\u2028"')),null===a&&(8233===b.charCodeAt(e)?(a="\u2029",e++):(a=null,0===f&&k('"\\u2029"')))))),f--,0===f&&null===a&&k("end of line"),a}function s(){var a,c,d;return d=e,a=z(),null!==a?(59===b.charCodeAt(e)?(c=";",e++):(c=null,0===f&&k('";"')),null!==c?a=[a,c]:(a=null,e=d)):(a=null,e=d),null===a&&(d=e,a=y(),null!==a?(c=r(),null!==c?a=[a,c]:(a=null,e=d)):(a=null,e=d),null===a&&(d=e,a=z(),null!==a?(c=t(),null!==c?a=[a,c]:(a=null,e=d)):(a=null,e=d))),a}function t(){var a,c;return c=e,f++,b.length>e?(a=b.charAt(e),e++):(a=null,0===f&&k("any character")),f--,null===a?a="":(a=null,e=c),a}function u(){var a;return f++,a=v(),null===a&&(a=x()),f--,0===f&&null===a&&k("comment"),a}function v(){var a,c,d,g,h,i,j;if(h=e,"/*"===b.substr(e,2)?(a="/*",e+=2):(a=null,0===f&&k('"/*"')),null!==a){for(c=[],i=e,j=e,f++,"*/"===b.substr(e,2)?(d="*/",e+=2):(d=null,0===f&&k('"*/"')),f--,null===d?d="":(d=null,e=j),null!==d?(g=n(),null!==g?d=[d,g]:(d=null,e=i)):(d=null,e=i);null!==d;)c.push(d),i=e,j=e,f++,"*/"===b.substr(e,2)?(d="*/",e+=2):(d=null,0===f&&k('"*/"')),f--,null===d?d="":(d=null,e=j),null!==d?(g=n(),null!==g?d=[d,g]:(d=null,e=i)):(d=null,e=i);null!==c?("*/"===b.substr(e,2)?(d="*/",e+=2):(d=null,0===f&&k('"*/"')),null!==d?a=[a,c,d]:(a=null,e=h)):(a=null,e=h)}else a=null,e=h;return a}function w(){var a,c,d,g,h,i,j;if(h=e,"/*"===b.substr(e,2)?(a="/*",e+=2):(a=null,0===f&&k('"/*"')),null!==a){for(c=[],i=e,j=e,f++,"*/"===b.substr(e,2)?(d="*/",e+=2):(d=null,0===f&&k('"*/"')),null===d&&(d=q()),f--,null===d?d="":(d=null,e=j),null!==d?(g=n(),null!==g?d=[d,g]:(d=null,e=i)):(d=null,e=i);null!==d;)c.push(d),i=e,j=e,f++,"*/"===b.substr(e,2)?(d="*/",e+=2):(d=null,0===f&&k('"*/"')),null===d&&(d=q()),f--,null===d?d="":(d=null,e=j),null!==d?(g=n(),null!==g?d=[d,g]:(d=null,e=i)):(d=null,e=i);null!==c?("*/"===b.substr(e,2)?(d="*/",e+=2):(d=null,0===f&&k('"*/"')),null!==d?a=[a,c,d]:(a=null,e=h)):(a=null,e=h)}else a=null,e=h;return a}function x(){var a,c,d,g,h,i,j;if(h=e,"//"===b.substr(e,2)?(a="//",e+=2):(a=null,0===f&&k('"//"')),null!==a){for(c=[],i=e,j=e,f++,d=q(),f--,null===d?d="":(d=null,e=j),null!==d?(g=n(),null!==g?d=[d,g]:(d=null,e=i)):(d=null,e=i);null!==d;)c.push(d),i=e,j=e,f++,d=q(),f--,null===d?d="":(d=null,e=j),null!==d?(g=n(),null!==g?d=[d,g]:(d=null,e=i)):(d=null,e=i);null!==c?(d=q(),null===d&&(d=t()),null!==d?a=[a,c,d]:(a=null,e=h)):(a=null,e=h)}else a=null,e=h;return a}function y(){var a,b;for(a=[],b=p(),null===b&&(b=w(),null===b&&(b=x()));null!==b;)a.push(b),b=p(),null===b&&(b=w(),null===b&&(b=x()));return a}function z(){var a,b;for(a=[],b=p(),null===b&&(b=r(),null===b&&(b=u()));null!==b;)a.push(b),b=p(),null===b&&(b=r(),null===b&&(b=u()));return a}function A(){var a,b;return b=e,a=C(),null===a&&(a=B()),null!==a&&(a=function(a,b){return{type:"NumericLiteral",value:b}}(b,a)),null===a&&(e=b),a}function B(){var a,c,d;if(d=e,/^[0-9]/.test(b.charAt(e))?(c=b.charAt(e),e++):(c=null,0===f&&k("[0-9]")),null!==c)for(a=[];null!==c;)a.push(c),/^[0-9]/.test(b.charAt(e))?(c=b.charAt(e),e++):(c=null,0===f&&k("[0-9]"));else a=null;return null!==a&&(a=function(a,b){return parseInt(b.join(""))}(d,a)),null===a&&(e=d),a}function C(){var a,c,d,g,h;return g=e,h=e,a=B(),null!==a?(46===b.charCodeAt(e)?(c=".",e++):(c=null,0===f&&k('"."')),null!==c?(d=B(),null!==d?a=[a,c,d]:(a=null,e=h)):(a=null,e=h)):(a=null,e=h),null!==a&&(a=function(a,b){return parseFloat(b.join(""))}(g,a)),null===a&&(e=g),a}function D(){var a,c,d,g;if(g=e,/^[\-+]/.test(b.charAt(e))?(a=b.charAt(e),e++):(a=null,0===f&&k("[\\-+]")),a=null!==a?a:"",null!==a){if(/^[0-9]/.test(b.charAt(e))?(d=b.charAt(e),e++):(d=null,0===f&&k("[0-9]")),null!==d)for(c=[];null!==d;)c.push(d),/^[0-9]/.test(b.charAt(e))?(d=b.charAt(e),e++):(d=null,0===f&&k("[0-9]"));else c=null;null!==c?a=[a,c]:(a=null,e=g)}else a=null,e=g;return a}function E(){var a,b;return f++,b=e,a=F(),null!==a&&(a=function(a,b){return b}(b,a)),null===a&&(e=b),f--,0===f&&null===a&&k("identifier"),a}function F(){var a,b,c,d,g;if(f++,d=e,g=e,a=o(),null!==a){for(b=[],c=o();null!==c;)b.push(c),c=o();null!==b?a=[a,b]:(a=null,e=g)}else a=null,e=g;return null!==a&&(a=function(a,b,c){return b+c.join("")}(d,a[0],a[1])),null===a&&(e=d),f--,0===f&&null===a&&k("identifier"),a}function G(){var a,c,d,g,h,i,j;return i=e,a=E(),null!==a&&(a=function(a,b){return{type:"Variable",name:b}}(i,a)),null===a&&(e=i),null===a&&(a=A(),null===a&&(i=e,j=e,40===b.charCodeAt(e)?(a="(",e++):(a=null,0===f&&k('"("')),null!==a?(c=z(),null!==c?(d=P(),null!==d?(g=z(),null!==g?(41===b.charCodeAt(e)?(h=")",e++):(h=null,0===f&&k('")"')),null!==h?a=[a,c,d,g,h]:(a=null,e=j)):(a=null,e=j)):(a=null,e=j)):(a=null,e=j)):(a=null,e=j),null!==a&&(a=function(a,b){return b}(i,a[2])),null===a&&(e=i))),a}function H(){var a,b,c,d,f;return a=G(),null===a&&(d=e,f=e,a=I(),null!==a?(b=z(),null!==b?(c=H(),null!==c?a=[a,b,c]:(a=null,e=f)):(a=null,e=f)):(a=null,e=f),null!==a&&(a=function(a,b,c){return{type:"UnaryExpression",operator:b,expression:c}}(d,a[0],a[2])),null===a&&(e=d)),a}function I(){var a;return 43===b.charCodeAt(e)?(a="+",e++):(a=null,0===f&&k('"+"')),null===a&&(45===b.charCodeAt(e)?(a="-",e++):(a=null,0===f&&k('"-"')),null===a&&(33===b.charCodeAt(e)?(a="!",e++):(a=null,0===f&&k('"!"')))),a}function J(){var a,b,c,d,f,g,h,i,j;if(h=e,i=e,a=H(),null!==a){for(b=[],j=e,c=z(),null!==c?(d=K(),null!==d?(f=z(),null!==f?(g=H(),null!==g?c=[c,d,f,g]:(c=null,e=j)):(c=null,e=j)):(c=null,e=j)):(c=null,e=j);null!==c;)b.push(c),j=e,c=z(),null!==c?(d=K(),null!==d?(f=z(),null!==f?(g=H(),null!==g?c=[c,d,f,g]:(c=null,e=j)):(c=null,e=j)):(c=null,e=j)):(c=null,e=j);null!==b?a=[a,b]:(a=null,e=i)}else a=null,e=i;return null!==a&&(a=function(a,b,c){for(var d=b,e=0;e="===b.substr(e,2)?(a=">=",e+=2):(a=null,0===f&&k('">="')),null===a&&(60===b.charCodeAt(e)?(a="<",e++):(a=null,0===f&&k('"<"')),null===a&&(62===b.charCodeAt(e)?(a=">",e++):(a=null,0===f&&k('">"'))))),a}function P(){var a,c,d,g,h,i,j,l,m;if(j=e,l=e,a=N(),null!==a){for(c=[],m=e,d=z(),null!==d?("=="===b.substr(e,2)?(g="==",e+=2):(g=null,0===f&&k('"=="')),null!==g?(h=z(),null!==h?(i=N(),null!==i?d=[d,g,h,i]:(d=null,e=m)):(d=null,e=m)):(d=null,e=m)):(d=null,e=m);null!==d;)c.push(d),m=e,d=z(),null!==d?("=="===b.substr(e,2)?(g="==",e+=2):(g=null,0===f&&k('"=="')),null!==g?(h=z(),null!==h?(i=N(),null!==i?d=[d,g,h,i]:(d=null,e=m)):(d=null,e=m)):(d=null,e=m)):(d=null,e=m);null!==c?a=[a,c]:(a=null,e=l)}else a=null,e=l;return null!==a&&(a=function(a,b,c){for(var d=b,e=0;e0&&(i=1/Math.sqrt(i),e[0]=t[0]*i,e[1]=t[1]*i),e},o.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]},o.cross=function(e,t,n){var r=t[0]*n[1]-t[1]*n[0];return e[0]=e[1]=0,e[2]=r,e},o.lerp=function(e,t,n,r){var i=t[0],s=t[1];return e[0]=i+r*(n[0]-i),e[1]=s+r*(n[1]-s),e},o.random=function(e,t){t=t||1;var n=r()*2*Math.PI;return e[0]=Math.cos(n)*t,e[1]=Math.sin(n)*t,e},o.transformMat2=function(e,t,n){var r=t[0],i=t[1];return e[0]=n[0]*r+n[2]*i,e[1]=n[1]*r+n[3]*i,e},o.transformMat2d=function(e,t,n){var r=t[0],i=t[1];return e[0]=n[0]*r+n[2]*i+n[4],e[1]=n[1]*r+n[3]*i+n[5],e},o.transformMat3=function(e,t,n){var r=t[0],i=t[1];return e[0]=n[0]*r+n[3]*i+n[6],e[1]=n[1]*r+n[4]*i+n[7],e},o.transformMat4=function(e,t,n){var r=t[0],i=t[1];return e[0]=n[0]*r+n[4]*i+n[12],e[1]=n[1]*r+n[5]*i+n[13],e},o.forEach=function(){var e=o.create();return function(t,n,r,i,s,o){var u,a;n||(n=2),r||(r=0),i?a=Math.min(i*n+r,t.length):a=t.length;for(u=r;u0&&(s=1/Math.sqrt(s),e[0]=t[0]*s,e[1]=t[1]*s,e[2]=t[2]*s),e},u.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]},u.cross=function(e,t,n){var r=t[0],i=t[1],s=t[2],o=n[0],u=n[1],a=n[2];return e[0]=i*a-s*u,e[1]=s*o-r*a,e[2]=r*u-i*o,e},u.lerp=function(e,t,n,r){var i=t[0],s=t[1],o=t[2];return e[0]=i+r*(n[0]-i),e[1]=s+r*(n[1]-s),e[2]=o+r*(n[2]-o),e},u.random=function(e,t){t=t||1;var n=r()*2*Math.PI,i=r()*2-1,s=Math.sqrt(1-i*i)*t;return e[0]=Math.cos(n)*s,e[1]=Math.sin(n)*s,e[2]=i*t,e},u.transformMat4=function(e,t,n){var r=t[0],i=t[1],s=t[2];return e[0]=n[0]*r+n[4]*i+n[8]*s+n[12],e[1]=n[1]*r+n[5]*i+n[9]*s+n[13],e[2]=n[2]*r+n[6]*i+n[10]*s+n[14],e},u.transformMat3=function(e,t,n){var r=t[0],i=t[1],s=t[2];return e[0]=r*n[0]+i*n[3]+s*n[6],e[1]=r*n[1]+i*n[4]+s*n[7],e[2]=r*n[2]+i*n[5]+s*n[8],e},u.transformQuat=function(e,t,n){var r=t[0],i=t[1],s=t[2],o=n[0],u=n[1],a=n[2],f=n[3],l=f*r+u*s-a*i,c=f*i+a*r-o*s,h=f*s+o*i-u*r,p=-o*r-u*i-a*s;return e[0]=l*f+p*-o+c*-a-h*-u,e[1]=c*f+p*-u+h*-o-l*-a,e[2]=h*f+p*-a+l*-u-c*-o,e},u.forEach=function(){var e=u.create();return function(t,n,r,i,s,o){var u,a;n||(n=3),r||(r=0),i?a=Math.min(i*n+r,t.length):a=t.length;for(u=r;u0&&(o=1/Math.sqrt(o),e[0]=t[0]*o,e[1]=t[1]*o,e[2]=t[2]*o,e[3]=t[3]*o),e},a.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3]},a.lerp=function(e,t,n,r){var i=t[0],s=t[1],o=t[2],u=t[3];return e[0]=i+r*(n[0]-i),e[1]=s+r*(n[1]-s),e[2]=o+r*(n[2]-o),e[3]=u+r*(n[3]-u),e},a.random=function(e,t){return t=t||1,e[0]=r(),e[1]=r(),e[2]=r(),e[3]=r(),a.normalize(e,e),a.scale(e,e,t),e},a.transformMat4=function(e,t,n){var r=t[0],i=t[1],s=t[2],o=t[3];return e[0]=n[0]*r+n[4]*i+n[8]*s+n[12]*o,e[1]=n[1]*r+n[5]*i+n[9]*s+n[13]*o,e[2]=n[2]*r+n[6]*i+n[10]*s+n[14]*o,e[3]=n[3]*r+n[7]*i+n[11]*s+n[15]*o,e},a.transformQuat=function(e,t,n){var r=t[0],i=t[1],s=t[2],o=n[0],u=n[1],a=n[2],f=n[3],l=f*r+u*s-a*i,c=f*i+a*r-o*s,h=f*s+o*i-u*r,p=-o*r-u*i-a*s;return e[0]=l*f+p*-o+c*-a-h*-u,e[1]=c*f+p*-u+h*-o-l*-a,e[2]=h*f+p*-a+l*-u-c*-o,e},a.forEach=function(){var e=a.create();return function(t,n,r,i,s,o){var u,a;n||(n=4),r||(r=0),i?a=Math.min(i*n+r,t.length):a=t.length;for(u=r;u.999999?(r[0]=0,r[1]=0,r[2]=0,r[3]=1,r):(u.cross(e,i,s),r[0]=e[0],r[1]=e[1],r[2]=e[2],r[3]=1+o,p.normalize(r,r))}}(),p.setAxes=function(){var e=c.create();return function(t,n,r,i){return e[0]=r[0],e[3]=r[1],e[6]=r[2],e[1]=i[0],e[4]=i[1],e[7]=i[2],e[2]=-n[0],e[5]=-n[1],e[8]=-n[2],p.normalize(t,p.fromMat3(t,e))}}(),p.clone=a.clone,p.fromValues=a.fromValues,p.copy=a.copy,p.set=a.set,p.identity=function(e){return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e},p.setAxisAngle=function(e,t,n){n*=.5;var r=Math.sin(n);return e[0]=r*t[0],e[1]=r*t[1],e[2]=r*t[2],e[3]=Math.cos(n),e},p.add=a.add,p.multiply=function(e,t,n){var r=t[0],i=t[1],s=t[2],o=t[3],u=n[0],a=n[1],f=n[2],l=n[3];return e[0]=r*l+o*u+i*f-s*a,e[1]=i*l+o*a+s*u-r*f,e[2]=s*l+o*f+r*a-i*u,e[3]=o*l-r*u-i*a-s*f,e},p.mul=p.multiply,p.scale=a.scale,p.rotateX=function(e,t,n){n*=.5;var r=t[0],i=t[1],s=t[2],o=t[3],u=Math.sin(n),a=Math.cos(n);return e[0]=r*a+o*u,e[1]=i*a+s*u,e[2]=s*a-i*u,e[3]=o*a-r*u,e},p.rotateY=function(e,t,n){n*=.5;var r=t[0],i=t[1],s=t[2],o=t[3],u=Math.sin(n),a=Math.cos(n);return e[0]=r*a-s*u,e[1]=i*a+o*u,e[2]=s*a+r*u,e[3]=o*a-i*u,e},p.rotateZ=function(e,t,n){n*=.5;var r=t[0],i=t[1],s=t[2],o=t[3],u=Math.sin(n),a=Math.cos(n);return e[0]=r*a+i*u,e[1]=i*a-r*u,e[2]=s*a+o*u,e[3]=o*a-s*u,e},p.calculateW=function(e,t){var n=t[0],r=t[1],i=t[2];return e[0]=n,e[1]=r,e[2]=i,e[3]=-Math.sqrt(Math.abs(1-n*n-r*r-i*i)),e},p.dot=a.dot,p.lerp=a.lerp,p.slerp=function(e,t,n,r){var i=t[0],s=t[1],o=t[2],u=t[3],a=n[0],f=n[1],l=n[2],c=n[3],h,p,d,v,m;return p=i*a+s*f+o*l+u*c,p<0&&(p=-p,a=-a,f=-f,l=-l,c=-c),1-p>1e-6?(h=Math.acos(p),d=Math.sin(h),v=Math.sin((1-r)*h)/d,m=Math.sin(r*h)/d):(v=1-r,m=r),e[0]=v*i+m*a,e[1]=v*s+m*f,e[2]=v*o+m*l,e[3]=v*u+m*c,e},p.invert=function(e,t){var n=t[0],r=t[1],i=t[2],s=t[3],o=n*n+r*r+i*i+s*s,u=o?1/o:0;return e[0]=-n*u,e[1]=-r*u,e[2]=-i*u,e[3]=s*u,e},p.conjugate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=t[3],e},p.length=a.length,p.len=p.length,p.squaredLength=a.squaredLength,p.sqrLen=p.squaredLength,p.normalize=a.normalize,p.fromMat3=function(e,t){var n=t[0]+t[4]+t[8],r;if(n>0)r=Math.sqrt(n+1),e[3]=.5*r,r=.5/r,e[0]=(t[7]-t[5])*r,e[1]=(t[2]-t[6])*r,e[2]=(t[3]-t[1])*r;else{var i=0;t[4]>t[0]&&(i=1),t[8]>t[i*3+i]&&(i=2);var s=(i+1)%3,o=(i+2)%3;r=Math.sqrt(t[i*3+i]-t[s*3+s]-t[o*3+o]+1),e[i]=.5*r,r=.5/r,e[3]=(t[o*3+s]-t[s*3+o])*r,e[s]=(t[s*3+i]+t[i*3+s])*r,e[o]=(t[o*3+i]+t[i*3+o])*r}return e},p.str=function(e){return"quat("+e[0]+", "+e[1]+", "+e[2]+", "+e[3]+")"},typeof e!="undefined"&&(e.quat=p)}(t.exports)})(this); 29 | -------------------------------------------------------------------------------- /bower_components/gss/vendor/observe.js: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | (function(global) { 16 | 'use strict'; 17 | 18 | function detectObjectObserve() { 19 | if (typeof Object.observe !== 'function' || 20 | typeof Array.observe !== 'function') { 21 | return false; 22 | } 23 | 24 | var gotSplice = false; 25 | function callback(records) { 26 | if (records[0].type === 'splice' && records[1].type === 'splice') 27 | gotSplice = true; 28 | } 29 | 30 | var test = [0]; 31 | Array.observe(test, callback); 32 | test[1] = 1; 33 | test.length = 0; 34 | Object.deliverChangeRecords(callback); 35 | return gotSplice; 36 | } 37 | 38 | var hasObserve = detectObjectObserve(); 39 | 40 | function detectEval() { 41 | // don't test for eval if document has CSP securityPolicy object and we can see that 42 | // eval is not supported. This avoids an error message in console even when the exception 43 | // is caught 44 | if (global.document && 45 | 'securityPolicy' in global.document && 46 | !global.document.securityPolicy.allowsEval) { 47 | return false; 48 | } 49 | 50 | try { 51 | var f = new Function('', 'return true;'); 52 | return f(); 53 | } catch (ex) { 54 | return false; 55 | } 56 | } 57 | 58 | var hasEval = detectEval(); 59 | 60 | function isIndex(s) { 61 | return +s === s >>> 0; 62 | } 63 | 64 | function toNumber(s) { 65 | return +s; 66 | } 67 | 68 | function isObject(obj) { 69 | return obj === Object(obj); 70 | } 71 | 72 | var numberIsNaN = global.Number.isNaN || function isNaN(value) { 73 | return typeof value === 'number' && global.isNaN(value); 74 | } 75 | 76 | function areSameValue(left, right) { 77 | if (left === right) 78 | return left !== 0 || 1 / left === 1 / right; 79 | if (numberIsNaN(left) && numberIsNaN(right)) 80 | return true; 81 | 82 | return left !== left && right !== right; 83 | } 84 | 85 | var createObject = ('__proto__' in {}) ? 86 | function(obj) { return obj; } : 87 | function(obj) { 88 | var proto = obj.__proto__; 89 | if (!proto) 90 | return obj; 91 | var newObject = Object.create(proto); 92 | Object.getOwnPropertyNames(obj).forEach(function(name) { 93 | Object.defineProperty(newObject, name, 94 | Object.getOwnPropertyDescriptor(obj, name)); 95 | }); 96 | return newObject; 97 | }; 98 | 99 | var identStart = '[\$_a-zA-Z]'; 100 | var identPart = '[\$_a-zA-Z0-9]'; 101 | var ident = identStart + '+' + identPart + '*'; 102 | var elementIndex = '(?:[0-9]|[1-9]+[0-9]+)'; 103 | var identOrElementIndex = '(?:' + ident + '|' + elementIndex + ')'; 104 | var path = '(?:' + identOrElementIndex + ')(?:\\s*\\.\\s*' + identOrElementIndex + ')*'; 105 | var pathRegExp = new RegExp('^' + path + '$'); 106 | 107 | function isPathValid(s) { 108 | if (typeof s != 'string') 109 | return false; 110 | s = s.trim(); 111 | 112 | if (s == '') 113 | return true; 114 | 115 | if (s[0] == '.') 116 | return false; 117 | 118 | return pathRegExp.test(s); 119 | } 120 | 121 | var constructorIsPrivate = {}; 122 | 123 | function Path(s, privateToken) { 124 | if (privateToken !== constructorIsPrivate) 125 | throw Error('Use Path.get to retrieve path objects'); 126 | 127 | if (s.trim() == '') 128 | return this; 129 | 130 | if (isIndex(s)) { 131 | this.push(s); 132 | return this; 133 | } 134 | 135 | s.split(/\s*\.\s*/).filter(function(part) { 136 | return part; 137 | }).forEach(function(part) { 138 | this.push(part); 139 | }, this); 140 | 141 | if (hasEval && !hasObserve && this.length) { 142 | this.getValueFrom = this.compiledGetValueFromFn(); 143 | } 144 | } 145 | 146 | // TODO(rafaelw): Make simple LRU cache 147 | var pathCache = {}; 148 | 149 | function getPath(pathString) { 150 | if (pathString instanceof Path) 151 | return pathString; 152 | 153 | if (pathString == null) 154 | pathString = ''; 155 | 156 | if (typeof pathString !== 'string') 157 | pathString = String(pathString); 158 | 159 | var path = pathCache[pathString]; 160 | if (path) 161 | return path; 162 | if (!isPathValid(pathString)) 163 | return invalidPath; 164 | var path = new Path(pathString, constructorIsPrivate); 165 | pathCache[pathString] = path; 166 | return path; 167 | } 168 | 169 | Path.get = getPath; 170 | 171 | Path.prototype = createObject({ 172 | __proto__: [], 173 | valid: true, 174 | 175 | toString: function() { 176 | return this.join('.'); 177 | }, 178 | 179 | getValueFrom: function(obj, observedSet) { 180 | for (var i = 0; i < this.length; i++) { 181 | if (obj == null) 182 | return; 183 | if (observedSet) 184 | observedSet.observe(obj); 185 | obj = obj[this[i]]; 186 | } 187 | return obj; 188 | }, 189 | 190 | compiledGetValueFromFn: function() { 191 | var accessors = this.map(function(ident) { 192 | return isIndex(ident) ? '["' + ident + '"]' : '.' + ident; 193 | }); 194 | 195 | var str = ''; 196 | var pathString = 'obj'; 197 | str += 'if (obj != null'; 198 | var i = 0; 199 | for (; i < (this.length - 1); i++) { 200 | var ident = this[i]; 201 | pathString += accessors[i]; 202 | str += ' &&\n ' + pathString + ' != null'; 203 | } 204 | str += ')\n'; 205 | 206 | pathString += accessors[i]; 207 | 208 | str += ' return ' + pathString + ';\nelse\n return undefined;'; 209 | return new Function('obj', str); 210 | }, 211 | 212 | setValueFrom: function(obj, value) { 213 | if (!this.length) 214 | return false; 215 | 216 | for (var i = 0; i < this.length - 1; i++) { 217 | if (!isObject(obj)) 218 | return false; 219 | obj = obj[this[i]]; 220 | } 221 | 222 | if (!isObject(obj)) 223 | return false; 224 | 225 | obj[this[i]] = value; 226 | return true; 227 | } 228 | }); 229 | 230 | var invalidPath = new Path('', constructorIsPrivate); 231 | invalidPath.valid = false; 232 | invalidPath.getValueFrom = invalidPath.setValueFrom = function() {}; 233 | 234 | var MAX_DIRTY_CHECK_CYCLES = 1000; 235 | 236 | function dirtyCheck(observer) { 237 | var cycles = 0; 238 | while (cycles < MAX_DIRTY_CHECK_CYCLES && observer.check()) { 239 | observer.report(); 240 | cycles++; 241 | } 242 | if (global.testingExposeCycleCount) 243 | global.dirtyCheckCycleCount = cycles; 244 | } 245 | 246 | function objectIsEmpty(object) { 247 | for (var prop in object) 248 | return false; 249 | return true; 250 | } 251 | 252 | function diffIsEmpty(diff) { 253 | return objectIsEmpty(diff.added) && 254 | objectIsEmpty(diff.removed) && 255 | objectIsEmpty(diff.changed); 256 | } 257 | 258 | function diffObjectFromOldObject(object, oldObject) { 259 | var added = {}; 260 | var removed = {}; 261 | var changed = {}; 262 | var oldObjectHas = {}; 263 | 264 | for (var prop in oldObject) { 265 | var newValue = object[prop]; 266 | 267 | if (newValue !== undefined && newValue === oldObject[prop]) 268 | continue; 269 | 270 | if (!(prop in object)) { 271 | removed[prop] = undefined; 272 | continue; 273 | } 274 | 275 | if (newValue !== oldObject[prop]) 276 | changed[prop] = newValue; 277 | } 278 | 279 | for (var prop in object) { 280 | if (prop in oldObject) 281 | continue; 282 | 283 | added[prop] = object[prop]; 284 | } 285 | 286 | if (Array.isArray(object) && object.length !== oldObject.length) 287 | changed.length = object.length; 288 | 289 | return { 290 | added: added, 291 | removed: removed, 292 | changed: changed 293 | }; 294 | } 295 | 296 | function copyObject(object, opt_copy) { 297 | var copy = opt_copy || (Array.isArray(object) ? [] : {}); 298 | for (var prop in object) { 299 | copy[prop] = object[prop]; 300 | }; 301 | if (Array.isArray(object)) 302 | copy.length = object.length; 303 | return copy; 304 | } 305 | 306 | function Observer(object, callback, target, token) { 307 | this.closed = false; 308 | this.object = object; 309 | this.callback = callback; 310 | // TODO(rafaelw): Hold this.target weakly when WeakRef is available. 311 | this.target = target; 312 | this.token = token; 313 | this.reporting = true; 314 | if (hasObserve) { 315 | var self = this; 316 | this.boundInternalCallback = function(records) { 317 | self.internalCallback(records); 318 | }; 319 | } 320 | 321 | addToAll(this); 322 | } 323 | 324 | Observer.prototype = { 325 | internalCallback: function(records) { 326 | if (this.closed) 327 | return; 328 | if (this.reporting && this.check(records)) { 329 | this.report(); 330 | if (this.testingResults) 331 | this.testingResults.anyChanged = true; 332 | } 333 | }, 334 | 335 | close: function() { 336 | if (this.closed) 337 | return; 338 | if (this.object && typeof this.object.close === 'function') 339 | this.object.close(); 340 | 341 | this.disconnect(); 342 | this.object = undefined; 343 | this.closed = true; 344 | }, 345 | 346 | deliver: function(testingResults) { 347 | if (this.closed) 348 | return; 349 | if (hasObserve) { 350 | this.testingResults = testingResults; 351 | Object.deliverChangeRecords(this.boundInternalCallback); 352 | this.testingResults = undefined; 353 | } else { 354 | dirtyCheck(this); 355 | } 356 | }, 357 | 358 | report: function() { 359 | if (!this.reporting) 360 | return; 361 | 362 | this.sync(false); 363 | if (this.callback) { 364 | this.reportArgs.push(this.token); 365 | this.invokeCallback(this.reportArgs); 366 | } 367 | this.reportArgs = undefined; 368 | }, 369 | 370 | invokeCallback: function(args) { 371 | try { 372 | this.callback.apply(this.target, args); 373 | } catch (ex) { 374 | Observer._errorThrownDuringCallback = true; 375 | console.error('Exception caught during observer callback: ' + (ex.stack || ex)); 376 | } 377 | }, 378 | 379 | reset: function() { 380 | if (this.closed) 381 | return; 382 | 383 | if (hasObserve) { 384 | this.reporting = false; 385 | Object.deliverChangeRecords(this.boundInternalCallback); 386 | this.reporting = true; 387 | } 388 | 389 | this.sync(true); 390 | } 391 | } 392 | 393 | var collectObservers = !hasObserve || global.forceCollectObservers; 394 | var allObservers; 395 | Observer._allObserversCount = 0; 396 | 397 | if (collectObservers) { 398 | allObservers = []; 399 | } 400 | 401 | function addToAll(observer) { 402 | if (!collectObservers) 403 | return; 404 | 405 | allObservers.push(observer); 406 | Observer._allObserversCount++; 407 | } 408 | 409 | var runningMicrotaskCheckpoint = false; 410 | 411 | var hasDebugForceFullDelivery = typeof Object.deliverAllChangeRecords == 'function'; 412 | 413 | global.Platform = global.Platform || {}; 414 | 415 | global.Platform.performMicrotaskCheckpoint = function() { 416 | if (runningMicrotaskCheckpoint) 417 | return; 418 | 419 | if (hasDebugForceFullDelivery) { 420 | Object.deliverAllChangeRecords(); 421 | return; 422 | } 423 | 424 | if (!collectObservers) 425 | return; 426 | 427 | runningMicrotaskCheckpoint = true; 428 | 429 | var cycles = 0; 430 | var results = {}; 431 | 432 | do { 433 | cycles++; 434 | var toCheck = allObservers; 435 | allObservers = []; 436 | results.anyChanged = false; 437 | 438 | for (var i = 0; i < toCheck.length; i++) { 439 | var observer = toCheck[i]; 440 | if (observer.closed) 441 | continue; 442 | 443 | if (hasObserve) { 444 | observer.deliver(results); 445 | } else if (observer.check()) { 446 | results.anyChanged = true; 447 | observer.report(); 448 | } 449 | 450 | allObservers.push(observer); 451 | } 452 | } while (cycles < MAX_DIRTY_CHECK_CYCLES && results.anyChanged); 453 | 454 | if (global.testingExposeCycleCount) 455 | global.dirtyCheckCycleCount = cycles; 456 | 457 | Observer._allObserversCount = allObservers.length; 458 | runningMicrotaskCheckpoint = false; 459 | }; 460 | 461 | if (collectObservers) { 462 | global.Platform.clearObservers = function() { 463 | allObservers = []; 464 | }; 465 | } 466 | 467 | function ObjectObserver(object, callback, target, token) { 468 | Observer.call(this, object, callback, target, token); 469 | this.connect(); 470 | this.sync(true); 471 | } 472 | 473 | ObjectObserver.prototype = createObject({ 474 | __proto__: Observer.prototype, 475 | 476 | connect: function() { 477 | if (hasObserve) 478 | Object.observe(this.object, this.boundInternalCallback); 479 | }, 480 | 481 | sync: function(hard) { 482 | if (!hasObserve) 483 | this.oldObject = copyObject(this.object); 484 | }, 485 | 486 | check: function(changeRecords) { 487 | var diff; 488 | var oldValues; 489 | if (hasObserve) { 490 | if (!changeRecords) 491 | return false; 492 | 493 | oldValues = {}; 494 | diff = diffObjectFromChangeRecords(this.object, changeRecords, 495 | oldValues); 496 | } else { 497 | oldValues = this.oldObject; 498 | diff = diffObjectFromOldObject(this.object, this.oldObject); 499 | } 500 | 501 | if (diffIsEmpty(diff)) 502 | return false; 503 | 504 | this.reportArgs = 505 | [diff.added || {}, diff.removed || {}, diff.changed || {}]; 506 | this.reportArgs.push(function(property) { 507 | return oldValues[property]; 508 | }); 509 | 510 | return true; 511 | }, 512 | 513 | disconnect: function() { 514 | if (!hasObserve) 515 | this.oldObject = undefined; 516 | else if (this.object) 517 | Object.unobserve(this.object, this.boundInternalCallback); 518 | } 519 | }); 520 | 521 | function ArrayObserver(array, callback, target, token) { 522 | if (!Array.isArray(array)) 523 | throw Error('Provided object is not an Array'); 524 | ObjectObserver.call(this, array, callback, target, token); 525 | } 526 | 527 | ArrayObserver.prototype = createObject({ 528 | __proto__: ObjectObserver.prototype, 529 | 530 | connect: function() { 531 | if (hasObserve) 532 | Array.observe(this.object, this.boundInternalCallback); 533 | }, 534 | 535 | sync: function() { 536 | if (!hasObserve) 537 | this.oldObject = this.object.slice(); 538 | }, 539 | 540 | check: function(changeRecords) { 541 | var splices; 542 | if (hasObserve) { 543 | if (!changeRecords) 544 | return false; 545 | splices = projectArraySplices(this.object, changeRecords); 546 | } else { 547 | splices = calcSplices(this.object, 0, this.object.length, 548 | this.oldObject, 0, this.oldObject.length); 549 | } 550 | 551 | if (!splices || !splices.length) 552 | return false; 553 | 554 | this.reportArgs = [splices]; 555 | return true; 556 | } 557 | }); 558 | 559 | ArrayObserver.applySplices = function(previous, current, splices) { 560 | splices.forEach(function(splice) { 561 | var spliceArgs = [splice.index, splice.removed.length]; 562 | var addIndex = splice.index; 563 | while (addIndex < splice.index + splice.addedCount) { 564 | spliceArgs.push(current[addIndex]); 565 | addIndex++; 566 | } 567 | 568 | Array.prototype.splice.apply(previous, spliceArgs); 569 | }); 570 | }; 571 | 572 | function ObservedSet(callback) { 573 | this.arr = []; 574 | this.callback = callback; 575 | this.isObserved = true; 576 | } 577 | 578 | var objProto = Object.getPrototypeOf({}); 579 | var arrayProto = Object.getPrototypeOf([]); 580 | ObservedSet.prototype = { 581 | reset: function() { 582 | this.isObserved = !this.isObserved; 583 | }, 584 | 585 | observe: function(obj) { 586 | if (!isObject(obj) || obj === objProto || obj === arrayProto) 587 | return; 588 | var i = this.arr.indexOf(obj); 589 | if (i >= 0 && this.arr[i+1] === this.isObserved) 590 | return; 591 | 592 | if (i < 0) { 593 | i = this.arr.length; 594 | this.arr[i] = obj; 595 | Object.observe(obj, this.callback); 596 | } 597 | 598 | this.arr[i+1] = this.isObserved; 599 | this.observe(Object.getPrototypeOf(obj)); 600 | }, 601 | 602 | cleanup: function() { 603 | var i = 0, j = 0; 604 | var isObserved = this.isObserved; 605 | while(j < this.arr.length) { 606 | var obj = this.arr[j]; 607 | if (this.arr[j + 1] == isObserved) { 608 | if (i < j) { 609 | this.arr[i] = obj; 610 | this.arr[i + 1] = isObserved; 611 | } 612 | i += 2; 613 | } else { 614 | Object.unobserve(obj, this.callback); 615 | } 616 | j += 2; 617 | } 618 | 619 | this.arr.length = i; 620 | } 621 | }; 622 | 623 | function PathObserver(object, path, callback, target, token, valueFn, 624 | setValueFn) { 625 | var path = path instanceof Path ? path : getPath(path); 626 | if (!path || !path.length || !isObject(object)) { 627 | this.value_ = path ? path.getValueFrom(object) : undefined; 628 | this.value = valueFn ? valueFn(this.value_) : this.value_; 629 | this.closed = true; 630 | return; 631 | } 632 | 633 | Observer.call(this, object, callback, target, token); 634 | this.valueFn = valueFn; 635 | this.setValueFn = setValueFn; 636 | this.path = path; 637 | 638 | this.connect(); 639 | this.sync(true); 640 | } 641 | 642 | PathObserver.prototype = createObject({ 643 | __proto__: Observer.prototype, 644 | 645 | connect: function() { 646 | if (hasObserve) 647 | this.observedSet = new ObservedSet(this.boundInternalCallback); 648 | }, 649 | 650 | disconnect: function() { 651 | this.value = undefined; 652 | this.value_ = undefined; 653 | if (this.observedSet) { 654 | this.observedSet.reset(); 655 | this.observedSet.cleanup(); 656 | this.observedSet = undefined; 657 | } 658 | }, 659 | 660 | check: function() { 661 | // Note: Extracting this to a member function for use here and below 662 | // regresses dirty-checking path perf by about 25% =-(. 663 | if (this.observedSet) 664 | this.observedSet.reset(); 665 | 666 | this.value_ = this.path.getValueFrom(this.object, this.observedSet); 667 | 668 | if (this.observedSet) 669 | this.observedSet.cleanup(); 670 | 671 | if (areSameValue(this.value_, this.oldValue_)) 672 | return false; 673 | 674 | this.value = this.valueFn ? this.valueFn(this.value_) : this.value_; 675 | this.reportArgs = [this.value, this.oldValue]; 676 | return true; 677 | }, 678 | 679 | sync: function(hard) { 680 | if (hard) { 681 | if (this.observedSet) 682 | this.observedSet.reset(); 683 | 684 | this.value_ = this.path.getValueFrom(this.object, this.observedSet); 685 | this.value = this.valueFn ? this.valueFn(this.value_) : this.value_; 686 | 687 | if (this.observedSet) 688 | this.observedSet.cleanup(); 689 | } 690 | 691 | this.oldValue_ = this.value_; 692 | this.oldValue = this.value; 693 | }, 694 | 695 | setValue: function(newValue) { 696 | if (!this.path) 697 | return; 698 | if (typeof this.setValueFn === 'function') 699 | newValue = this.setValueFn(newValue); 700 | this.path.setValueFrom(this.object, newValue); 701 | } 702 | }); 703 | 704 | function CompoundPathObserver(callback, target, token, valueFn) { 705 | Observer.call(this, undefined, callback, target, token); 706 | this.valueFn = valueFn; 707 | 708 | this.observed = []; 709 | this.values = []; 710 | this.value = undefined; 711 | this.oldValue = undefined; 712 | this.oldValues = undefined; 713 | this.changeFlags = undefined; 714 | this.started = false; 715 | } 716 | 717 | CompoundPathObserver.prototype = createObject({ 718 | __proto__: PathObserver.prototype, 719 | 720 | addPath: function(object, path) { 721 | if (this.started) 722 | throw Error('Cannot add more paths once started.'); 723 | 724 | var path = path instanceof Path ? path : getPath(path); 725 | var value = path ? path.getValueFrom(object) : undefined; 726 | 727 | this.observed.push(object, path); 728 | this.values.push(value); 729 | }, 730 | 731 | start: function() { 732 | this.connect(); 733 | this.sync(true); 734 | }, 735 | 736 | getValues: function() { 737 | if (this.observedSet) 738 | this.observedSet.reset(); 739 | 740 | var anyChanged = false; 741 | for (var i = 0; i < this.observed.length; i = i+2) { 742 | var path = this.observed[i+1]; 743 | if (!path) 744 | continue; 745 | var object = this.observed[i]; 746 | var value = path.getValueFrom(object, this.observedSet); 747 | var oldValue = this.values[i/2]; 748 | if (!areSameValue(value, oldValue)) { 749 | if (!anyChanged && !this.valueFn) { 750 | this.oldValues = this.oldValues || []; 751 | this.changeFlags = this.changeFlags || []; 752 | for (var j = 0; j < this.values.length; j++) { 753 | this.oldValues[j] = this.values[j]; 754 | this.changeFlags[j] = false; 755 | } 756 | } 757 | 758 | if (!this.valueFn) 759 | this.changeFlags[i/2] = true; 760 | 761 | this.values[i/2] = value; 762 | anyChanged = true; 763 | } 764 | } 765 | 766 | if (this.observedSet) 767 | this.observedSet.cleanup(); 768 | 769 | return anyChanged; 770 | }, 771 | 772 | check: function() { 773 | if (!this.getValues()) 774 | return; 775 | 776 | if (this.valueFn) { 777 | this.value = this.valueFn(this.values); 778 | 779 | if (areSameValue(this.value, this.oldValue)) 780 | return false; 781 | 782 | this.reportArgs = [this.value, this.oldValue]; 783 | } else { 784 | this.reportArgs = [this.values, this.oldValues, this.changeFlags]; 785 | } 786 | 787 | return true; 788 | }, 789 | 790 | sync: function(hard) { 791 | if (hard) { 792 | this.getValues(); 793 | if (this.valueFn) 794 | this.value = this.valueFn(this.values); 795 | } 796 | 797 | if (this.valueFn) 798 | this.oldValue = this.value; 799 | }, 800 | 801 | close: function() { 802 | if (this.observed) { 803 | for (var i = 0; i < this.observed.length; i = i + 2) { 804 | var object = this.observed[i]; 805 | if (object && typeof object.close === 'function') 806 | object.close(); 807 | } 808 | this.observed = undefined; 809 | this.values = undefined; 810 | } 811 | 812 | Observer.prototype.close.call(this); 813 | } 814 | }); 815 | 816 | var knownRecordTypes = { 817 | 'new': true, 818 | 'updated': true, 819 | 'deleted': true 820 | }; 821 | 822 | function notifyFunction(object, name) { 823 | if (typeof Object.observe !== 'function') 824 | return; 825 | 826 | var notifier = Object.getNotifier(object); 827 | return function(type, oldValue) { 828 | var changeRecord = { 829 | object: object, 830 | type: type, 831 | name: name 832 | }; 833 | if (arguments.length === 2) 834 | changeRecord.oldValue = oldValue; 835 | notifier.notify(changeRecord); 836 | } 837 | } 838 | 839 | // TODO(rafaelw): It should be possible for the Object.observe case to have 840 | // every PathObserver used by defineProperty share a single Object.observe 841 | // callback, and thus get() can simply call observer.deliver() and any changes 842 | // to any dependent value will be observed. 843 | PathObserver.defineProperty = function(object, name, descriptor) { 844 | // TODO(rafaelw): Validate errors 845 | var obj = descriptor.object; 846 | var path = getPath(descriptor.path); 847 | var notify = notifyFunction(object, name); 848 | 849 | var observer = new PathObserver(obj, descriptor.path, 850 | function(newValue, oldValue) { 851 | if (notify) 852 | notify('updated', oldValue); 853 | } 854 | ); 855 | 856 | Object.defineProperty(object, name, { 857 | get: function() { 858 | return path.getValueFrom(obj); 859 | }, 860 | set: function(newValue) { 861 | path.setValueFrom(obj, newValue); 862 | }, 863 | configurable: true 864 | }); 865 | 866 | return { 867 | close: function() { 868 | var oldValue = path.getValueFrom(obj); 869 | if (notify) 870 | observer.deliver(); 871 | observer.close(); 872 | Object.defineProperty(object, name, { 873 | value: oldValue, 874 | writable: true, 875 | configurable: true 876 | }); 877 | } 878 | }; 879 | } 880 | 881 | function diffObjectFromChangeRecords(object, changeRecords, oldValues) { 882 | var added = {}; 883 | var removed = {}; 884 | 885 | for (var i = 0; i < changeRecords.length; i++) { 886 | var record = changeRecords[i]; 887 | if (!knownRecordTypes[record.type]) { 888 | console.error('Unknown changeRecord type: ' + record.type); 889 | console.error(record); 890 | continue; 891 | } 892 | 893 | if (!(record.name in oldValues)) 894 | oldValues[record.name] = record.oldValue; 895 | 896 | if (record.type == 'updated') 897 | continue; 898 | 899 | if (record.type == 'new') { 900 | if (record.name in removed) 901 | delete removed[record.name]; 902 | else 903 | added[record.name] = true; 904 | 905 | continue; 906 | } 907 | 908 | // type = 'deleted' 909 | if (record.name in added) { 910 | delete added[record.name]; 911 | delete oldValues[record.name]; 912 | } else { 913 | removed[record.name] = true; 914 | } 915 | } 916 | 917 | for (var prop in added) 918 | added[prop] = object[prop]; 919 | 920 | for (var prop in removed) 921 | removed[prop] = undefined; 922 | 923 | var changed = {}; 924 | for (var prop in oldValues) { 925 | if (prop in added || prop in removed) 926 | continue; 927 | 928 | var newValue = object[prop]; 929 | if (oldValues[prop] !== newValue) 930 | changed[prop] = newValue; 931 | } 932 | 933 | return { 934 | added: added, 935 | removed: removed, 936 | changed: changed 937 | }; 938 | } 939 | 940 | function newSplice(index, removed, addedCount) { 941 | return { 942 | index: index, 943 | removed: removed, 944 | addedCount: addedCount 945 | }; 946 | } 947 | 948 | var EDIT_LEAVE = 0; 949 | var EDIT_UPDATE = 1; 950 | var EDIT_ADD = 2; 951 | var EDIT_DELETE = 3; 952 | 953 | function ArraySplice() {} 954 | 955 | ArraySplice.prototype = { 956 | 957 | // Note: This function is *based* on the computation of the Levenshtein 958 | // "edit" distance. The one change is that "updates" are treated as two 959 | // edits - not one. With Array splices, an update is really a delete 960 | // followed by an add. By retaining this, we optimize for "keeping" the 961 | // maximum array items in the original array. For example: 962 | // 963 | // 'xxxx123' -> '123yyyy' 964 | // 965 | // With 1-edit updates, the shortest path would be just to update all seven 966 | // characters. With 2-edit updates, we delete 4, leave 3, and add 4. This 967 | // leaves the substring '123' intact. 968 | calcEditDistances: function(current, currentStart, currentEnd, 969 | old, oldStart, oldEnd) { 970 | // "Deletion" columns 971 | var rowCount = oldEnd - oldStart + 1; 972 | var columnCount = currentEnd - currentStart + 1; 973 | var distances = new Array(rowCount); 974 | 975 | // "Addition" rows. Initialize null column. 976 | for (var i = 0; i < rowCount; i++) { 977 | distances[i] = new Array(columnCount); 978 | distances[i][0] = i; 979 | } 980 | 981 | // Initialize null row 982 | for (var j = 0; j < columnCount; j++) 983 | distances[0][j] = j; 984 | 985 | for (var i = 1; i < rowCount; i++) { 986 | for (var j = 1; j < columnCount; j++) { 987 | if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1])) 988 | distances[i][j] = distances[i - 1][j - 1]; 989 | else { 990 | var north = distances[i - 1][j] + 1; 991 | var west = distances[i][j - 1] + 1; 992 | distances[i][j] = north < west ? north : west; 993 | } 994 | } 995 | } 996 | 997 | return distances; 998 | }, 999 | 1000 | // This starts at the final weight, and walks "backward" by finding 1001 | // the minimum previous weight recursively until the origin of the weight 1002 | // matrix. 1003 | spliceOperationsFromEditDistances: function(distances) { 1004 | var i = distances.length - 1; 1005 | var j = distances[0].length - 1; 1006 | var current = distances[i][j]; 1007 | var edits = []; 1008 | while (i > 0 || j > 0) { 1009 | if (i == 0) { 1010 | edits.push(EDIT_ADD); 1011 | j--; 1012 | continue; 1013 | } 1014 | if (j == 0) { 1015 | edits.push(EDIT_DELETE); 1016 | i--; 1017 | continue; 1018 | } 1019 | var northWest = distances[i - 1][j - 1]; 1020 | var west = distances[i - 1][j]; 1021 | var north = distances[i][j - 1]; 1022 | 1023 | var min; 1024 | if (west < north) 1025 | min = west < northWest ? west : northWest; 1026 | else 1027 | min = north < northWest ? north : northWest; 1028 | 1029 | if (min == northWest) { 1030 | if (northWest == current) { 1031 | edits.push(EDIT_LEAVE); 1032 | } else { 1033 | edits.push(EDIT_UPDATE); 1034 | current = northWest; 1035 | } 1036 | i--; 1037 | j--; 1038 | } else if (min == west) { 1039 | edits.push(EDIT_DELETE); 1040 | i--; 1041 | current = west; 1042 | } else { 1043 | edits.push(EDIT_ADD); 1044 | j--; 1045 | current = north; 1046 | } 1047 | } 1048 | 1049 | edits.reverse(); 1050 | return edits; 1051 | }, 1052 | 1053 | /** 1054 | * Splice Projection functions: 1055 | * 1056 | * A splice map is a representation of how a previous array of items 1057 | * was transformed into a new array of items. Conceptually it is a list of 1058 | * tuples of 1059 | * 1060 | * 1061 | * 1062 | * which are kept in ascending index order of. The tuple represents that at 1063 | * the |index|, |removed| sequence of items were removed, and counting forward 1064 | * from |index|, |addedCount| items were added. 1065 | */ 1066 | 1067 | /** 1068 | * Lacking individual splice mutation information, the minimal set of 1069 | * splices can be synthesized given the previous state and final state of an 1070 | * array. The basic approach is to calculate the edit distance matrix and 1071 | * choose the shortest path through it. 1072 | * 1073 | * Complexity: O(l * p) 1074 | * l: The length of the current array 1075 | * p: The length of the old array 1076 | */ 1077 | calcSplices: function(current, currentStart, currentEnd, 1078 | old, oldStart, oldEnd) { 1079 | var prefixCount = 0; 1080 | var suffixCount = 0; 1081 | 1082 | var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart); 1083 | if (currentStart == 0 && oldStart == 0) 1084 | prefixCount = this.sharedPrefix(current, old, minLength); 1085 | 1086 | if (currentEnd == current.length && oldEnd == old.length) 1087 | suffixCount = this.sharedSuffix(current, old, minLength - prefixCount); 1088 | 1089 | currentStart += prefixCount; 1090 | oldStart += prefixCount; 1091 | currentEnd -= suffixCount; 1092 | oldEnd -= suffixCount; 1093 | 1094 | if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) 1095 | return []; 1096 | 1097 | if (currentStart == currentEnd) { 1098 | var splice = newSplice(currentStart, [], 0); 1099 | while (oldStart < oldEnd) 1100 | splice.removed.push(old[oldStart++]); 1101 | 1102 | return [ splice ]; 1103 | } else if (oldStart == oldEnd) 1104 | return [ newSplice(currentStart, [], currentEnd - currentStart) ]; 1105 | 1106 | var ops = this.spliceOperationsFromEditDistances( 1107 | this.calcEditDistances(current, currentStart, currentEnd, 1108 | old, oldStart, oldEnd)); 1109 | 1110 | var splice = undefined; 1111 | var splices = []; 1112 | var index = currentStart; 1113 | var oldIndex = oldStart; 1114 | for (var i = 0; i < ops.length; i++) { 1115 | switch(ops[i]) { 1116 | case EDIT_LEAVE: 1117 | if (splice) { 1118 | splices.push(splice); 1119 | splice = undefined; 1120 | } 1121 | 1122 | index++; 1123 | oldIndex++; 1124 | break; 1125 | case EDIT_UPDATE: 1126 | if (!splice) 1127 | splice = newSplice(index, [], 0); 1128 | 1129 | splice.addedCount++; 1130 | index++; 1131 | 1132 | splice.removed.push(old[oldIndex]); 1133 | oldIndex++; 1134 | break; 1135 | case EDIT_ADD: 1136 | if (!splice) 1137 | splice = newSplice(index, [], 0); 1138 | 1139 | splice.addedCount++; 1140 | index++; 1141 | break; 1142 | case EDIT_DELETE: 1143 | if (!splice) 1144 | splice = newSplice(index, [], 0); 1145 | 1146 | splice.removed.push(old[oldIndex]); 1147 | oldIndex++; 1148 | break; 1149 | } 1150 | } 1151 | 1152 | if (splice) { 1153 | splices.push(splice); 1154 | } 1155 | return splices; 1156 | }, 1157 | 1158 | sharedPrefix: function(current, old, searchLength) { 1159 | for (var i = 0; i < searchLength; i++) 1160 | if (!this.equals(current[i], old[i])) 1161 | return i; 1162 | return searchLength; 1163 | }, 1164 | 1165 | sharedSuffix: function(current, old, searchLength) { 1166 | var index1 = current.length; 1167 | var index2 = old.length; 1168 | var count = 0; 1169 | while (count < searchLength && this.equals(current[--index1], old[--index2])) 1170 | count++; 1171 | 1172 | return count; 1173 | }, 1174 | 1175 | calculateSplices: function(current, previous) { 1176 | return this.calcSplices(current, 0, current.length, previous, 0, 1177 | previous.length); 1178 | }, 1179 | 1180 | equals: function(currentValue, previousValue) { 1181 | return currentValue === previousValue; 1182 | } 1183 | }; 1184 | 1185 | var arraySplice = new ArraySplice(); 1186 | 1187 | function calcSplices(current, currentStart, currentEnd, 1188 | old, oldStart, oldEnd) { 1189 | return arraySplice.calcSplices(current, currentStart, currentEnd, 1190 | old, oldStart, oldEnd); 1191 | } 1192 | 1193 | function intersect(start1, end1, start2, end2) { 1194 | // Disjoint 1195 | if (end1 < start2 || end2 < start1) 1196 | return -1; 1197 | 1198 | // Adjacent 1199 | if (end1 == start2 || end2 == start1) 1200 | return 0; 1201 | 1202 | // Non-zero intersect, span1 first 1203 | if (start1 < start2) { 1204 | if (end1 < end2) 1205 | return end1 - start2; // Overlap 1206 | else 1207 | return end2 - start2; // Contained 1208 | } else { 1209 | // Non-zero intersect, span2 first 1210 | if (end2 < end1) 1211 | return end2 - start1; // Overlap 1212 | else 1213 | return end1 - start1; // Contained 1214 | } 1215 | } 1216 | 1217 | function mergeSplice(splices, index, removed, addedCount) { 1218 | 1219 | var splice = newSplice(index, removed, addedCount); 1220 | 1221 | var inserted = false; 1222 | var insertionOffset = 0; 1223 | 1224 | for (var i = 0; i < splices.length; i++) { 1225 | var current = splices[i]; 1226 | current.index += insertionOffset; 1227 | 1228 | if (inserted) 1229 | continue; 1230 | 1231 | var intersectCount = intersect(splice.index, 1232 | splice.index + splice.removed.length, 1233 | current.index, 1234 | current.index + current.addedCount); 1235 | 1236 | if (intersectCount >= 0) { 1237 | // Merge the two splices 1238 | 1239 | splices.splice(i, 1); 1240 | i--; 1241 | 1242 | insertionOffset -= current.addedCount - current.removed.length; 1243 | 1244 | splice.addedCount += current.addedCount - intersectCount; 1245 | var deleteCount = splice.removed.length + 1246 | current.removed.length - intersectCount; 1247 | 1248 | if (!splice.addedCount && !deleteCount) { 1249 | // merged splice is a noop. discard. 1250 | inserted = true; 1251 | } else { 1252 | var removed = current.removed; 1253 | 1254 | if (splice.index < current.index) { 1255 | // some prefix of splice.removed is prepended to current.removed. 1256 | var prepend = splice.removed.slice(0, current.index - splice.index); 1257 | Array.prototype.push.apply(prepend, removed); 1258 | removed = prepend; 1259 | } 1260 | 1261 | if (splice.index + splice.removed.length > current.index + current.addedCount) { 1262 | // some suffix of splice.removed is appended to current.removed. 1263 | var append = splice.removed.slice(current.index + current.addedCount - splice.index); 1264 | Array.prototype.push.apply(removed, append); 1265 | } 1266 | 1267 | splice.removed = removed; 1268 | if (current.index < splice.index) { 1269 | splice.index = current.index; 1270 | } 1271 | } 1272 | } else if (splice.index < current.index) { 1273 | // Insert splice here. 1274 | 1275 | inserted = true; 1276 | 1277 | splices.splice(i, 0, splice); 1278 | i++; 1279 | 1280 | var offset = splice.addedCount - splice.removed.length 1281 | current.index += offset; 1282 | insertionOffset += offset; 1283 | } 1284 | } 1285 | 1286 | if (!inserted) 1287 | splices.push(splice); 1288 | } 1289 | 1290 | function createInitialSplices(array, changeRecords) { 1291 | var splices = []; 1292 | 1293 | for (var i = 0; i < changeRecords.length; i++) { 1294 | var record = changeRecords[i]; 1295 | switch(record.type) { 1296 | case 'splice': 1297 | mergeSplice(splices, record.index, record.removed.slice(), record.addedCount); 1298 | break; 1299 | case 'new': 1300 | case 'updated': 1301 | case 'deleted': 1302 | if (!isIndex(record.name)) 1303 | continue; 1304 | var index = toNumber(record.name); 1305 | if (index < 0) 1306 | continue; 1307 | mergeSplice(splices, index, [record.oldValue], 1); 1308 | break; 1309 | default: 1310 | console.error('Unexpected record type: ' + JSON.stringify(record)); 1311 | break; 1312 | } 1313 | } 1314 | 1315 | return splices; 1316 | } 1317 | 1318 | function projectArraySplices(array, changeRecords) { 1319 | var splices = []; 1320 | 1321 | createInitialSplices(array, changeRecords).forEach(function(splice) { 1322 | if (splice.addedCount == 1 && splice.removed.length == 1) { 1323 | if (splice.removed[0] !== array[splice.index]) 1324 | splices.push(splice); 1325 | 1326 | return 1327 | }; 1328 | 1329 | splices = splices.concat(calcSplices(array, splice.index, splice.index + splice.addedCount, 1330 | splice.removed, 0, splice.removed.length)); 1331 | }); 1332 | 1333 | return splices; 1334 | } 1335 | 1336 | global.Observer = Observer; 1337 | global.Observer.hasObjectObserve = hasObserve; 1338 | global.ArrayObserver = ArrayObserver; 1339 | global.ArrayObserver.calculateSplices = function(current, previous) { 1340 | return arraySplice.calculateSplices(current, previous); 1341 | }; 1342 | 1343 | global.ArraySplice = ArraySplice; 1344 | global.ObjectObserver = ObjectObserver; 1345 | global.PathObserver = PathObserver; 1346 | global.CompoundPathObserver = CompoundPathObserver; 1347 | global.Path = Path; 1348 | })(typeof global !== 'undefined' && global ? global : this); -------------------------------------------------------------------------------- /bower_components/gss/vendor/sidetable.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The Polymer Authors. All rights reserved. 3 | * Use of this source code is goverened by a BSD-style 4 | * license that can be found in the LICENSE file. 5 | */ 6 | 7 | // SideTable is a weak map where possible. If WeakMap is not available the 8 | // association is stored as an expando property. 9 | var SideTable; 10 | // TODO(arv): WeakMap does not allow for Node etc to be keys in Firefox 11 | if (typeof WeakMap !== 'undefined' && navigator.userAgent.indexOf('Firefox/') < 0) { 12 | SideTable = WeakMap; 13 | } else { 14 | (function() { 15 | var defineProperty = Object.defineProperty; 16 | var hasOwnProperty = Object.hasOwnProperty; 17 | var counter = new Date().getTime() % 1e9; 18 | 19 | SideTable = function() { 20 | this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__'); 21 | }; 22 | 23 | SideTable.prototype = { 24 | set: function(key, value) { 25 | defineProperty(key, this.name, {value: value, writable: true}); 26 | }, 27 | get: function(key) { 28 | return hasOwnProperty.call(key, this.name) ? key[this.name] : undefined; 29 | }, 30 | delete: function(key) { 31 | this.set(key, undefined); 32 | } 33 | } 34 | })(); 35 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | 3 | var cloneWithProps = require('react/lib/cloneWithProps'); 4 | 5 | function invariant(cond, message) { 6 | if (!cond) { 7 | throw new Error('Invariant Violation: ' + message); 8 | } 9 | } 10 | 11 | function merge() { 12 | var a = {}; 13 | Array.prototype.slice.call(arguments).forEach(function(x) { 14 | for (var k in x) { 15 | if (!x.hasOwnProperty(k)) { 16 | continue; 17 | } 18 | a[k] = x[k]; 19 | } 20 | }); 21 | return a; 22 | } 23 | 24 | var LAYOUT_KEYS = { 25 | 'width': 'width', 26 | 'height': 'height', 27 | 'left': 'left', 28 | 'right': 'right', 29 | 'top': 'top', 30 | 'bottom': 'bottom', 31 | 'centerX': 'center-x', 32 | 'centerY': 'center-y', 33 | 'intrinsicHeight': 'intrinsic-height', 34 | 'intrinsicWidth': 'intrinsic-width' 35 | }; 36 | 37 | function interpolateIDsAndNormalizeKeys(constraints, mapping) { 38 | // TODO: use a real parser for better errors etc 39 | return constraints.replace(/(\w[\w\d_-]+)\.(\w[\w\d_-]+)/g, function(match, name, propertyName) { 40 | invariant(LAYOUT_KEYS[propertyName], 'Invalid layout property name: ' + propertyName); 41 | invariant(mapping[name], 'Unknown Box or AutoLayout name: ' + name); 42 | return mapping[name] + '[' + LAYOUT_KEYS[propertyName] + ']'; 43 | }); 44 | } 45 | 46 | var Box = React.createClass({ 47 | render: function() { 48 | return React.Children.only(this.props.children); 49 | } 50 | }); 51 | 52 | var idSeed = 0; 53 | 54 | var AutoLayout = React.createClass({ 55 | getInitialState: function() { 56 | return {layoutCompleted: false}; 57 | }, 58 | 59 | componentWillMount: function() { 60 | invariant(typeof GSS !== 'undefined', 'GSS not set up on the page'); 61 | var engine = GSS.engines[0]; 62 | invariant(engine, 'GSS is not ready yet. Did you forget GSS.once(\'afterLoaded\', ...) ?'); 63 | invariant(!GSS.config.observe, 'You cannot use GSS in observe mode. Did you set observe: false in GSS_CONFIG?'); 64 | this.styleSheet = new GSS.StyleSheet({engine: engine, engineId: engine.id}); 65 | }, 66 | 67 | componentDidMount: function() { 68 | var constraints = this.getConstraints(); 69 | this.styleSheet.addRules(GSS.compile(constraints)); 70 | this.lastConstraints = constraints; 71 | 72 | GSS.on('display', this.handleDisplay); 73 | }, 74 | 75 | handleDisplay: function() { 76 | if (this.isMounted() && !this.state.layoutCompleted) { 77 | this.setState({layoutCompleted: true}); 78 | } 79 | }, 80 | 81 | componentDidUpdate: function() { 82 | var constraints = this.getConstraints(); 83 | if (this.lastConstraints != constraints) { 84 | this.styleSheet.destroyRules(); 85 | this.styleSheet.addRules(GSS.compile(constraints)); 86 | this.lastConstraints = constraints; 87 | } 88 | }, 89 | 90 | componentWillUnmount: function() { 91 | this.styleSheet.destroyRules(); 92 | }, 93 | 94 | getDefaultProps: function() { 95 | return {name: 'this', constraints: ''}; 96 | }, 97 | 98 | getConstraintsForProps: function(props, layoutKeysOnly) { 99 | var constraints = ''; 100 | for (var key in props) { 101 | // TODO: warn about this where the descriptor is constructed (in 0.12?) 102 | invariant( 103 | !layoutKeysOnly || (key === 'name' || key === 'children' || LAYOUT_KEYS[key]), 104 | 'Unknown layout prop: ' + key 105 | ); 106 | if (LAYOUT_KEYS[key]) { 107 | var value = props[key].trim(); 108 | var beginning = value.length >= 2 ? value.slice(0, 2) : ''; 109 | 110 | if (beginning !== '==' && beginning !== '>=' && beginning !== '<=') { 111 | value = '== ' + value; 112 | } 113 | 114 | constraints += props.name + '.' + key + ' ' + value + ';\n'; 115 | } 116 | } 117 | constraints = interpolateIDsAndNormalizeKeys(constraints, this.getMapping()); 118 | return constraints; 119 | }, 120 | 121 | getConstraints: function() { 122 | // lets build up the stylesheet mmkay 123 | var constraints = this.props.constraints; 124 | 125 | constraints += this.getConstraintsForProps(this.props, false); 126 | 127 | React.Children.forEach(this.props.children, function(box) { 128 | constraints += this.getConstraintsForProps(box.props, true); 129 | }, this); 130 | 131 | return constraints; 132 | }, 133 | 134 | getSelector: function(component) { 135 | var node = component.getDOMNode(); 136 | 137 | if (!node.hasAttribute('id')) { 138 | node.id = 'autoLayout' + (idSeed++); 139 | } 140 | 141 | return '#' + node.id; 142 | }, 143 | 144 | getMapping: function() { 145 | var mapping = { 146 | 'window': '::window' 147 | }; 148 | React.Children.forEach(this.props.children, function(box) { 149 | invariant(box.props.name, 'Box requires a name'); 150 | mapping[box.props.name] = this.getSelector(this.refs[box.props.name]); 151 | }, this); 152 | 153 | mapping[this.props.name] = this.getSelector(this); 154 | 155 | return mapping; 156 | }, 157 | 158 | render: function() { 159 | var children = React.Children.map(this.props.children, function(box) { 160 | return cloneWithProps(box, { 161 | children: box.props.children, 162 | key: box.props.name, 163 | ref: box.props.name 164 | }); 165 | }); 166 | 167 | return this.transferPropsTo( 168 | React.DOM.div({style: {visibility: this.state.layoutCompleted ? 'visible' : 'hidden'}}, children) 169 | ); 170 | } 171 | }); 172 | 173 | module.exports = { 174 | AutoLayout: AutoLayout, 175 | Box: Box 176 | }; 177 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-gss", 3 | "version": "0.2.0", 4 | "description": "Grid stylesheets for React", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/petehunt/react-gss.git" 13 | }, 14 | "author": "Pete Hunt", 15 | "license": "Apache 2", 16 | "bugs": { 17 | "url": "https://github.com/petehunt/react-gss/issues" 18 | }, 19 | "homepage": "https://github.com/petehunt/react-gss", 20 | "peerDependencies": { 21 | "react": ">=0.11.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | // webpack.config.js 2 | module.exports = { 3 | entry: './app.js', 4 | output: { 5 | filename: 'bundle.js' 6 | }, 7 | module: { 8 | loaders: [ 9 | { test: /\.js$/, loader: 'jsx-loader?harmony' } 10 | ] 11 | } 12 | }; 13 | --------------------------------------------------------------------------------