UNPKG

state

Version:

First-class states

1,506 lines (1,400 loc) 48.5 kB
// Generated by CoffeeScript 1.6.3 (function() { var O, STATE_ATTRIBUTES, State, StateEventEmitter, StateExpression, TRAVERSAL_FLAGS, TransitionExpression, state, __hasProp = {}.hasOwnProperty, __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, __slice = [].slice; O = require('omicron'); state = require('./state-function'); StateEventEmitter = null; StateExpression = null; TransitionExpression = null; STATE_ATTRIBUTES = state.STATE_ATTRIBUTES, TRAVERSAL_FLAGS = state.TRAVERSAL_FLAGS; module.exports = State = (function() { var ABSTRACT, ABSTRACT_OR_CONCRETE, ATOMIC, CONCLUSIVE, CONCRETE, CONCURRENT, DEFAULT, DESTROYED, FINAL, FINITE, HISTORY, IMMUTABLE, INCIPIENT, INCIPIENT_OR_MUTABLE, INCIPIENT_OR_VIRTUAL, INITIAL, MUTABLE, MUTABLE_OR_FINITE, NIL, NORMAL, PARASTATIC, PROTO_HERITABLE_ATTRIBUTES, REFLECTIVE, RETAINED, SHALLOW, STATIC, VIA_ALL, VIA_NONE, VIA_PROTO, VIA_SUB, VIA_SUPER, VIRTUAL, assign, clone, createDispatcher, delta, edit, env, flatten, has, hasOwn, isArray, isEmpty, lookup, memoizeProtostates, useDispatchTables, _ref, _ref1, _ref2; _ref = state.options, memoizeProtostates = _ref.memoizeProtostates, useDispatchTables = _ref.useDispatchTables; env = O.env, NIL = O.NIL, isArray = O.isArray, isEmpty = O.isEmpty, has = O.has, hasOwn = O.hasOwn; assign = O.assign, edit = O.edit, delta = O.delta, clone = O.clone, lookup = O.lookup, flatten = O.flatten; _ref1 = assign(State, STATE_ATTRIBUTES), INCIPIENT = _ref1.INCIPIENT, ATOMIC = _ref1.ATOMIC, DESTROYED = _ref1.DESTROYED, VIRTUAL = _ref1.VIRTUAL, PARASTATIC = _ref1.PARASTATIC, MUTABLE = _ref1.MUTABLE, FINITE = _ref1.FINITE, STATIC = _ref1.STATIC, IMMUTABLE = _ref1.IMMUTABLE, INITIAL = _ref1.INITIAL, CONCLUSIVE = _ref1.CONCLUSIVE, FINAL = _ref1.FINAL, ABSTRACT = _ref1.ABSTRACT, CONCRETE = _ref1.CONCRETE, DEFAULT = _ref1.DEFAULT, REFLECTIVE = _ref1.REFLECTIVE, HISTORY = _ref1.HISTORY, RETAINED = _ref1.RETAINED, SHALLOW = _ref1.SHALLOW, CONCURRENT = _ref1.CONCURRENT, NORMAL = _ref1.NORMAL; _ref2 = assign(State, TRAVERSAL_FLAGS), VIA_NONE = _ref2.VIA_NONE, VIA_SUB = _ref2.VIA_SUB, VIA_SUPER = _ref2.VIA_SUPER, VIA_PROTO = _ref2.VIA_PROTO, VIA_ALL = _ref2.VIA_ALL; MUTABLE_OR_FINITE = MUTABLE | FINITE; ABSTRACT_OR_CONCRETE = ABSTRACT | CONCRETE; INCIPIENT_OR_VIRTUAL = INCIPIENT | VIRTUAL; INCIPIENT_OR_MUTABLE = INCIPIENT | MUTABLE; PROTO_HERITABLE_ATTRIBUTES = PARASTATIC | MUTABLE | FINITE | STATIC | IMMUTABLE | INITIAL | CONCLUSIVE | FINAL | ABSTRACT | CONCRETE | DEFAULT | REFLECTIVE | HISTORY | RETAINED | SHALLOW | CONCURRENT | NORMAL; State.prototype.Metaobject = null; State.prototype.Expression = null; function State(base, name, expression) { var attributes, owner, protoAttr, protostate, root, superAttr, superstate; this.name = name; if (base instanceof State) { superstate = base; root = superstate.root; owner = root.owner; } else { superstate = null; root = this; owner = base; } this.owner = owner; this.root = root; this.superstate = superstate; this.protostate = protostate = this.getProtostate() || null; this.order = null; attributes = (expression != null ? expression.attributes : void 0) || NORMAL; if (superstate != null) { superAttr = superstate.attributes; attributes |= superAttr & MUTABLE_OR_FINITE; } if (protostate != null) { protoAttr = protostate.attributes & PROTO_HERITABLE_ATTRIBUTES; if (attributes & CONCRETE) { attributes &= ~ABSTRACT; } if (attributes & ABSTRACT_OR_CONCRETE) { protoAttr &= ~ABSTRACT_OR_CONCRETE; } attributes |= protoAttr; } if (~attributes & ABSTRACT) { attributes |= CONCRETE; } attributes |= (superAttr | protoAttr) & IMMUTABLE; if (attributes & IMMUTABLE) { attributes = attributes & ~MUTABLE | FINITE; } this.attributes = attributes; if (!(attributes & VIRTUAL)) { this.initialize(expression); } if (env.debug) { this[' <path>'] = this.path(); this['<attributes>'] = StateExpression.decodeAttributes(attributes); } } createDispatcher = (function() { var toString; toString = function() { return "[dispatcher]"; }; return function(accessorName, methodName, original) { var dispatcher; dispatcher = function() { return this[accessorName]().apply(methodName, arguments); }; dispatcher.isDispatcher = true; if (env.debug) { dispatcher.toString = toString; } if (original) { dispatcher.original = original; } return dispatcher; }; })(); State.prototype.initialize = function(expression) { var attributes; attributes = this.attributes; if (attributes & VIRTUAL) { return; } this.attributes |= INCIPIENT; this.realize(expression); this.attributes &= ~INCIPIENT; this.emit('construct', expression, VIA_PROTO); return this; }; State.prototype.realize = function(expression) { var attributes, key, method, name, parastates, ss, substates, _base, _ref3; attributes = this.attributes, name = this.name; if (!(attributes & INCIPIENT_OR_VIRTUAL)) { return this; } if (attributes & VIRTUAL) { if (ss = this.superstate) { if (ss.attributes & VIRTUAL) { ss.realize(); } substates = (_base = ss._).substates != null ? (_base = ss._).substates : _base.substates = {}; if (substates[name] != null) { substates[name].destroy(); } substates[name] = this; } this.attributes &= ~VIRTUAL; } if (this._ == null) { this._ = new this.Metaobject; } if (parastates = expression != null ? expression.parastates : void 0) { if (isArray(parastates)) { parastates = parastates.join(','); } if (typeof parastates !== 'string') { throw TypeError; } parastates = parastates.split(/\s*,\s*/); if (parastates.length) { this._.parastates = parastates; this.attributes |= PARASTATIC; } } if (expression != null) { this.mutate(expression); } if (this === this.root) { _ref3 = this.owner; for (key in _ref3) { if (!__hasProp.call(_ref3, key)) continue; method = _ref3[key]; if (key !== 'constructor' && typeof method === 'function' && !method.isDispatcher && this.method(key, VIA_PROTO)) { this.addMethod(key, method); } } } if (this === this.root || ~attributes & INCIPIENT) { this.linearize(VIA_SUB); } return this; }; State.prototype.virtualize = function(inheritor) { var derivation, expr, i, name, real, s; if (!(inheritor instanceof State && this.owner.isPrototypeOf(inheritor.owner))) { return null; } if (!(derivation = this.derivation(true)).length) { return null; } i = 0; s = inheritor.root; while (name = derivation[i++]) { if (!(real = s.substate(name, VIA_NONE))) { break; } s = real; } expr = { attributes: VIRTUAL }; while (name) { s = new State(s, name, expr); name = derivation[i++]; } return s; }; State.prototype.linearize = (function() { var getParastateDeclarations, linearize, merge; getParastateDeclarations = function() { var head, ps, tail, _ref3, _ref4; head = (_ref3 = this._) != null ? _ref3.parastates : void 0; if (ps = this.protostate) { tail = getParastateDeclarations.call(ps); } if (tail != null) { return (_ref4 = head != null ? head.concat(tail) : void 0) != null ? _ref4 : tail; } else { return head; } }; merge = function(out, lists) { var bad, head, headList, i, index, item, list, otherList, remainingLists, _i, _j, _k, _len, _len1, _len2; if (!lists.length) { return out; } for (index = _i = 0, _len = lists.length; _i < _len; index = ++_i) { headList = lists[index]; if (!(headList != null)) { continue; } head = headList[0]; bad = false; for (_j = 0, _len1 = lists.length; _j < _len1; _j++) { otherList = lists[_j]; if (!(otherList !== headList)) { continue; } i = 1; while (item = otherList[i++]) { if (item === head) { bad = true; break; } } if (bad) { break; } } if (bad) { continue; } out.push(head); remainingLists = []; for (_k = 0, _len2 = lists.length; _k < _len2; _k++) { list = lists[_k]; if (list[0] === head) { list.shift(); } if (list.length) { remainingLists.push(list); } } return merge(out, remainingLists); } throw new TypeError("Ambiguous resolution order for '" + (out.pop()) + "'"); }; return linearize = function(via) { var lists, name, order, owner, parastate, parent, parents, path, paths, s, _i, _j, _len, _len1, _ref3, _ref4; if (via == null) { via = VIA_NONE; } if (this === this.root) { order = [this]; } else { parents = []; if (paths = getParastateDeclarations.call(this)) { owner = this.owner; for (_i = 0, _len = paths.length; _i < _len; _i++) { path = paths[_i]; if (!(parastate = state.own(owner, path))) { throw new ReferenceError("Unresolvable parastate '" + path + "'"); } if (__indexOf.call(parents, parastate) < 0) { parents.push(parastate); } } } parents.push(this.superstate); lists = []; for (_j = 0, _len1 = parents.length; _j < _len1; _j++) { parent = parents[_j]; lists.push(((_ref3 = parent.order) != null ? _ref3 : parent.linearize()).slice(0)); } lists.push(parents); order = merge([this], lists); } this.order = order; if (via & VIA_SUB) { _ref4 = this._.substates; for (name in _ref4) { if (!__hasProp.call(_ref4, name)) continue; s = _ref4[name]; s.linearize(via); } } return order; }; })(); State.prototype.express = (function() { var cloneCategory, cloneEvents, cloneSubstates, express; cloneCategory = function(object) { var key, out, value; if (object == null) { return; } for (key in object) { out = {}; break; } if (out) { for (key in object) { value = object[key]; out[key] = value && typeof value === 'object' ? clone(value) : value; } } return out; }; cloneEvents = function(events) { var emitter, out, type; if (events == null) { return; } for (type in events) { emitter = events[type]; if (emitter) { out = {}; break; } } for (type in events) { emitter = events[type]; if (emitter) { out[type] = clone(emitter.items); } } return out; }; cloneSubstates = function(substates, typed) { var name, out, substate; if (substates == null) { return; } for (name in substates) { out = {}; break; } for (name in substates) { substate = substates[name]; out[name] = substate.express(typed); } return out; }; return express = function(typed) { var expression, _; if (_ = this._) { expression = edit({}, { attributes: this.attributes, data: cloneCategory(_.data), methods: cloneCategory(_.methods), events: cloneEvents(_.events), guards: cloneCategory(_.guards), states: cloneSubstates(_.substates, typed), transitions: cloneCategory(_.transitions) }); } if (typed) { return new this.Expression(expression); } else { return expression; } }; })(); State.prototype.mutate = (function() { var diff, editEvent, isPlainObject, mutate; NIL = O.NIL, isArray = O.isArray, isEmpty = O.isEmpty, isPlainObject = O.isPlainObject, edit = O.edit, diff = O.diff; editEvent = function(object, emitter) { var items, key, value, _results; items = emitter.items; _results = []; for (key in object) { if (!__hasProp.call(object, key)) continue; value = object[key]; if (value === NIL) { _results.push(emitter.remove(key)); } else if (value && value !== items[key]) { _results.push(emitter.set(key, value)); } else { _results.push(void 0); } } return _results; }; return mutate = function(expr) { var Expression, after, attributes, before, data, element, emitter, event, events, guards, incipient, method, methods, mutable, name, residue, stateExpr, substates, transitionExpr, transitions, type, _base, _base1, _i, _len, _ref3, _ref4, _ref5, _ref6, _ref7; attributes = this.attributes, Expression = this.Expression; incipient = attributes & INCIPIENT; if (!incipient && attributes & IMMUTABLE) { return; } mutable = incipient || attributes & MUTABLE; if (attributes & VIRTUAL) { this.realize(); } _ref3 = this._, data = _ref3.data, methods = _ref3.methods, events = _ref3.events, guards = _ref3.guards, substates = _ref3.substates, transitions = _ref3.transitions; if (!(expr instanceof Expression)) { expr = new Expression(expr); } if (!incipient) { before = this.express(); } this.attributes |= ATOMIC; if (expr.data) { this.data(expr.data); } if (mutable) { _ref4 = expr.methods; for (name in _ref4) { if (!__hasProp.call(_ref4, name)) continue; method = _ref4[name]; if (method !== NIL) { this.addMethod(name, method); } else { this.removeMethod(name); } } } if (mutable) { _ref5 = expr.events; for (type in _ref5) { if (!__hasProp.call(_ref5, type)) continue; event = _ref5[type]; events || (events = (_base = this._).events || (_base.events = {})); emitter = events[type]; if (event === NIL) { if (emitter != null) { emitter.empty(); } continue; } if (!emitter && event && !isEmpty(event)) { emitter = events[type] = new StateEventEmitter(this, type); } if (isArray(event)) { for (_i = 0, _len = event.length; _i < _len; _i++) { element = event[_i]; if ((element != null) && element !== NIL) { if (isPlainObject(element)) { editEvent(element, emitter); } else { this.addEvent(type, element); } } } } else { if (isPlainObject(event)) { editEvent(event, emitter); } } if (!emitter.length) { emitter.destroy(); delete events[type]; } } } if (mutable && expr.guards) { guards || (guards = (_base1 = this._).guards || (_base1.guards = {})); edit('deep', guards, expr.guards); } _ref6 = expr.substates; for (name in _ref6) { if (!__hasProp.call(_ref6, name)) continue; stateExpr = _ref6[name]; if (substates && name in substates) { if (stateExpr === NIL) { this.removeSubstate(name); } else { substates[name].mutate(stateExpr); } } else { if (stateExpr !== NIL) { this.addSubstate(name, stateExpr); } } } if (mutable) { _ref7 = expr.transitions; for (name in _ref7) { if (!__hasProp.call(_ref7, name)) continue; transitionExpr = _ref7[name]; if (transitions && name in transitions) { if (transitionExpr === NIL) { delete transitions[name]; } else { transitions[name] = new TransitionExpression(transitionExpr); } } else { if (transitionExpr !== NIL) { this.addTransition(name, transitionExpr); } } } } this.attributes &= ~ATOMIC; if (!incipient) { after = this.express(); residue = diff(before, after); if (!isEmpty(residue)) { this.emit('mutate', [expr, residue, before, after], VIA_PROTO); } } return this; }; })(); State.prototype.destroy = function() { var dispatcher, event, events, key, methods, name, owner, ownerMethod, root, substate, substates, superstate, transition, _; owner = this.owner, root = this.root, superstate = this.superstate, _ = this._; if (_) { methods = _.methods, events = _.events, substates = _.substates; } if (transition = root._transition) { if (this === root) { transition.abort(); } else { if ((transition.origin.isIn(this)) || (transition.target.isIn(this))) { return false; } } } for (name in substates) { if (!__hasProp.call(substates, name)) continue; substate = substates[name]; substate.destroy(); } this.emit('destroy', VIA_PROTO); if (events) { for (key in events) { event = events[key]; event.destroy(); delete events[key]; } } if (this === root) { for (name in methods) { if (!(dispatcher = owner[name])) { continue; } if (!dispatcher.isDispatcher) { continue; } if (ownerMethod = dispatcher.original) { owner[name] = ownerMethod; } else { delete owner[name]; } } delete owner[this.accessorName]; } this._ = null; this.attributes |= DESTROYED; if (superstate != null) { superstate.removeSubstate(this.name); } return true; }; State.prototype.isVirtual = function() { return !!(this.attributes & VIRTUAL); }; State.prototype.isMutable = function() { return !!(this.attributes & MUTABLE); }; State.prototype.isFinite = function() { return !!(this.attributes & FINITE); }; State.prototype.isStatic = function() { return !!(this.attributes & STATIC); }; State.prototype.isImmutable = function() { return !!(this.attributes & IMMUTABLE); }; State.prototype.isInitial = function() { return !!(this.attributes & INITIAL); }; State.prototype.isConclusive = function() { return !!(this.attributes & CONCLUSIVE); }; State.prototype.isFinal = function() { return !!(this.attributes & FINAL); }; State.prototype.isAbstract = function() { return !!(this.attributes & ABSTRACT); }; State.prototype.isConcrete = function() { return !!(this.attributes & CONCRETE); }; State.prototype.isDefault = function() { return !!(this.attributes & DEFAULT); }; State.prototype.isReflective = function() { return !!(this.attributes & REFLECTIVE); }; State.prototype.hasHistory = function() { return !!(this.attributes & HISTORY); }; State.prototype.isRetained = function() { return !!(this.attributes & RETAINED); }; State.prototype.isShallow = function() { return !!(this.attributes & SHALLOW); }; State.prototype.isConcurrent = function() { return !!(this.attributes & CONCURRENT); }; State.prototype.substate = function(name, via) { var s, ss, _ref3, _ref4, _ref5; if (via == null) { via = VIA_PROTO; } s = this.root._current; while ((s != null ? s.attributes : void 0) & VIRTUAL && (ss = s.superstate)) { if (ss === this && s.name === name) { return s; } s = ss; } return ((_ref3 = this._) != null ? (_ref4 = _ref3.substates) != null ? _ref4[name] : void 0 : void 0) || via & VIA_PROTO && ((_ref5 = this.protostate) != null ? _ref5.substate(name) : void 0); }; State.prototype.substates = function(virtual, deep) { var name, result, s, ss, substate, _ref3, _ref4; result = []; if (virtual && (s = this.root._current) && s.attributes & VIRTUAL && this.isSuperstateOf(s)) { while (s && s !== this && s.attributes & VIRTUAL && (ss = s.superstate)) { if (deep || ss === this) { result.unshift(s); } s = ss; } } _ref4 = (_ref3 = this._) != null ? _ref3.substates : void 0; for (name in _ref4) { if (!__hasProp.call(_ref4, name)) continue; substate = _ref4[name]; result.push(substate); if (deep) { result = result.concat(substate.substates(void 0, true)); } } return result; }; State.prototype.descendants = function(virtual) { return this.substates(virtual, true); }; State.prototype.addSubstate = function(name, expression) { var attributes, substate, substates, _base; attributes = this.attributes; if (!(attributes & INCIPIENT)) { if (attributes & FINITE) { return; } if (!(attributes & MUTABLE)) { return; } } if (attributes & VIRTUAL) { this.realize(); } substates = (_base = this._).substates || (_base.substates = {}); if (substate = substates[name]) { substate.destroy(); } substate = expression instanceof State ? expression.superstate === this ? expression.realize() : void 0 : new State(this, name, expression); if (!substate) { return null; } return substates[name] = substate; }; State.prototype.removeSubstate = function(name) { var attributes, substate, substates, transition, _ref3; attributes = this.attributes; if (attributes & VIRTUAL) { return; } substates = (_ref3 = this._) != null ? _ref3.substates : void 0; if (!(substate = substates != null ? substates[name] : void 0)) { return; } if (!(attributes & MUTABLE || (substate != null ? substate.attributes : void 0) & DESTROYED)) { return; } if ((transition = this.root._transition) && (substate.isSuperstateOf(transition) || substate === transition.origin || substate === transition.target)) { return false; } if (this.root._current.isIn(substate)) { this.change(this, { forced: true }); } delete substates[name]; return substate; }; State.prototype.derivation = function(byName) { var results, s, ss; results = []; ss = this; while ((s = ss) && (ss = s.superstate)) { results.push(byName ? s.name || '' : s); } return results.reverse(); }; State.prototype.path = function() { return this.derivation(true).join('.'); }; State.prototype.toString = State.prototype.path; State.prototype.depth = function() { var n, s; n = 0; s = this; while (s = s.superstate) { n += 1; } return n; }; State.prototype.common = function(other) { var s; if (!(other instanceof State)) { other = this.query(other); } if (this.depth() > other.depth()) { s = other; other = this; } else { s = this; } while (s) { if (s === other || s.isSuperstateOf(other)) { return s; } s = s.superstate; } return null; }; State.prototype.is = function(other) { if (!(other instanceof State)) { other = this.query(other); } return other === this; }; State.prototype.isIn = function(other) { if (!(other instanceof State)) { other = this.query(other); } return other === this || other.isSuperstateOf(this); }; State.prototype.hasSubstate = function(other) { if (!(other instanceof State)) { other = this.query(other); } return other === this || this.isSuperstateOf(other); }; State.prototype.isSuperstateOf = function(other) { var superstate; if (!(other instanceof State)) { other = this.query(other); } if (superstate = other.superstate) { return this === superstate || this.isSuperstateOf(superstate); } else { return false; } }; State.prototype.defaultSubstate = function(via, first) { var protostate, s, substates, _i, _len, _ref3; if (via == null) { via = VIA_PROTO; } _ref3 = substates = this.substates(); for (_i = 0, _len = _ref3.length; _i < _len; _i++) { s = _ref3[_i]; if (s.attributes & DEFAULT) { return s; } } first || substates.length && (first = substates[0]); if (via & VIA_PROTO && (protostate = this.protostate)) { return protostate.defaultSubstate(VIA_PROTO); } return first; }; State.prototype.initialSubstate = function(via) { var i, protostate, queue, s, subject, substates, _i, _len, _ref3; if (via == null) { via = VIA_PROTO; } i = 0; queue = [this]; while (subject = queue[i++]) { _ref3 = substates = subject.substates(void 0, !!VIA_PROTO); for (_i = 0, _len = _ref3.length; _i < _len; _i++) { s = _ref3[_i]; if (s.attributes & INITIAL) { return s.initialSubstate(VIA_NONE) || s; } queue.push(s); } } if (via & VIA_PROTO && (protostate = this.protostate)) { return protostate.initialSubstate(VIA_PROTO); } }; State.prototype.getProtostate = function() { var accessorName, getPrototypeOf, owner, path, protostate, prototype, root; getPrototypeOf = O.getPrototypeOf; owner = this.owner, root = this.root; accessorName = root.accessorName; path = this.path(); prototype = getPrototypeOf(owner); while (prototype) { if (protostate = typeof prototype[accessorName] === "function" ? prototype[accessorName](path, VIA_NONE) : void 0) { return protostate; } prototype = getPrototypeOf(prototype); } return null; }; State.prototype.isProtostateOf = function(other) { var protostate; if (!(other instanceof State)) { other = this.query(other); } if (protostate = other.protostate) { return this === protostate || this.isProtostateOf(protostate); } else { return false; } }; State.prototype.query = function(selector, against, via, toBeSkipped) { var cursor, i, l, name, next, parts, queue, result, subject, substate, _i, _len, _ref3, _ref4, _ref5; if (typeof against === 'number') { toBeSkipped = via; via = against; against = void 0; } if (via == null) { via = VIA_ALL; } if (selector == null) { if (against === void 0) { return null; } else { return false; } } if (selector === '.') { if (against === void 0) { return this; } else { return against === this; } } if (selector === '') { if (against === void 0) { return this.root; } else { return against === this.root; } } if (against && against === this.root && /^\*+$/.test(selector)) { return true; } if (/^\.*\**$/.test(selector)) { via &= ~(VIA_SUB | VIA_SUPER); } if (selector.charAt(0) !== '.') { return this.root.query('.' + selector, against, VIA_SUB | VIA_PROTO); } selector = selector.replace(/^(\.+)\.$/, '$1'); parts = selector.split('.'); i = 0; l = parts.length; cursor = this; while (cursor) { i += 1; if (i >= l) { return (against ? against === cursor : cursor); } name = parts[i]; if (name === '*') { if (!against) { return cursor.substates(); } if (cursor === against.superstate) { return true; } break; } if (name === '**') { if (!against) { return cursor.substates(void 0, true); } if (cursor.isSuperstateOf(against)) { return true; } break; } if (name === '') { cursor = cursor.superstate; } else if (next = cursor.substate(name)) { cursor = next; } else { break; } } if (via & VIA_SUB) { i = 0; queue = [this]; while (subject = queue[i++]) { _ref3 = subject.substates(true); for (_i = 0, _len = _ref3.length; _i < _len; _i++) { substate = _ref3[_i]; if (substate === toBeSkipped) { continue; } result = substate.query(selector, against, VIA_NONE); if (result) { return result; } queue.push(substate); } } } if (via & VIA_SUPER) { if (result = (_ref4 = this.superstate) != null ? _ref4.query(selector, against, via & VIA_SUB | VIA_SUPER, via & VIA_SUB ? this : void 0) : void 0) { return result; } } if (via & VIA_PROTO) { if (result = (_ref5 = this.protostate) != null ? _ref5.query(selector, against, via) : void 0) { return result; } } if (against) { return false; } else { return null; } }; State.prototype.$ = function() { var args, expr, match, method; expr = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; if (typeof expr === 'function') { if (expr = expr()) { return this.change.apply(this, [expr].concat(args)); } } else if (typeof expr === 'string' && (match = expr.match(rxTransitionArrow)) && (method = transitionArrowMethods[match[1]])) { if (args.length) { return this[method].apply(this, [match[2]].concat(args)); } else { return this[method](match[2]); } } }; State.prototype.current = function() { return this.root._current; }; State.prototype.isCurrent = function() { return this === this.current(); }; State.prototype.isActive = function() { var current; return this === (current = this.current()) || this.isSuperstateOf(current); }; State.prototype.change = function(target, options) { var root; return (root = this.root).change.apply(root, arguments); }; State.prototype.go = State.prototype.change; State.prototype.be = State.prototype.change; State.prototype.data = function(via, out) { var attributes, mutation, relative, residue, _base, _i, _ref3, _ref4, _ref5, _ref6; if (via == null) { via = VIA_ALL; } if (via !== via << 0) { mutation = via; } if (mutation) { attributes = this.attributes; if (attributes & INCIPIENT_OR_MUTABLE && !isEmpty(mutation)) { if (attributes & VIRTUAL) { return this.realize().data(mutation); } residue = delta((_base = this._).data != null ? (_base = this._).data : _base.data = {}, mutation); if (~attributes & ATOMIC && residue && !isEmpty(residue)) { this.emit('mutate', [mutation, residue], VIA_PROTO); } } return this; } else { if (out == null) { out = {}; } _ref4 = (_ref3 = this.order) != null ? _ref3 : this.linearize(); for (_i = _ref4.length - 1; _i >= 0; _i += -1) { relative = _ref4[_i]; if (!(via & VIA_SUPER || relative === this)) { continue; } edit('deep all', out, (via & VIA_PROTO ? (_ref5 = relative.protostate) != null ? _ref5.data(VIA_PROTO, out) : void 0 : void 0), (_ref6 = relative._) != null ? _ref6.data : void 0); } return out; } }; State.prototype.has = function(key, via) { var data, relative, s, viaProto, viaSuper, _i, _len, _ref3, _ref4, _ref5; if (via == null) { via = VIA_ALL; } viaSuper = via & VIA_SUPER; viaProto = via & VIA_PROTO; _ref4 = (_ref3 = this.order) != null ? _ref3 : this.linearize(); for (_i = 0, _len = _ref4.length; _i < _len; _i++) { relative = _ref4[_i]; s = relative; while (s != null) { if (((data = (_ref5 = s._) != null ? _ref5.data : void 0) != null) && hasOwn.call(data, key)) { return true; } if (viaProto) { s = s.protostate; } else { break; } if (viaSuper) { continue; } } } return false; }; State.prototype.get = function(key, via) { var data, relative, s, viaProto, viaSuper, _i, _len, _ref3, _ref4, _ref5; if (via == null) { via = VIA_ALL; } viaSuper = via & VIA_SUPER; viaProto = via & VIA_PROTO; _ref4 = (_ref3 = this.order) != null ? _ref3 : this.linearize(); for (_i = 0, _len = _ref4.length; _i < _len; _i++) { relative = _ref4[_i]; s = relative; while (s != null) { if (((data = (_ref5 = s._) != null ? _ref5.data : void 0) != null) && hasOwn.call(data, key)) { return data[key]; } if (viaProto) { s = s.protostate; } else { break; } } if (viaSuper) { continue; } } }; State.prototype["let"] = function(key, value) { var attributes, data, displaced, mutation, residue, _base; attributes = this.attributes; if (!(attributes & INCIPIENT_OR_MUTABLE)) { return; } if (attributes & VIRTUAL) { this.realize(); } data = (_base = this._).data || (_base.data = {}); if (value !== (displaced = lookup(data, key))) { assign(data, key, value); assign((mutation = {}).data = {}, key, value); assign((residue = {}).data = {}, key, displaced); this.emit('mutate', [mutation, residue], VIA_PROTO); } return value; }; State.prototype.set = function(key, value) { var attributes, data, relative, _i, _len, _ref3, _ref4, _ref5; attributes = this.attributes; if (!(attributes & INCIPIENT_OR_MUTABLE)) { return; } if (attributes & VIRTUAL) { this.realize(); } _ref4 = (_ref3 = this.order) != null ? _ref3 : this.linearize(); for (_i = 0, _len = _ref4.length; _i < _len; _i++) { relative = _ref4[_i]; if (((data = (_ref5 = relative._) != null ? _ref5.data : void 0) != null) && hasOwn.call(data, key)) { if (relative.attributes & MUTABLE) { return relative["let"](key, value); } break; } } return this["let"](key, value); }; State.prototype["delete"] = function(key) { if (!(this.attributes & MUTABLE)) { return; } return NIL === this["let"](key, NIL); }; State.prototype.method = function(methodName, via, out, returnBoxed) { var attributes, context, inherited, method, realized, record, relative, table, viaProto, _base, _i, _len, _ref10, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9; if (via == null) { via = VIA_ALL; } attributes = this.attributes; realized = ~attributes & VIRTUAL; while (true) { if (realized) { if (method = (_ref3 = this._) != null ? (_ref4 = _ref3.methods) != null ? _ref4[methodName] : void 0 : void 0) { context = this; break; } if (record = (_ref5 = this._) != null ? (_ref6 = _ref5.__dispatch_table__) != null ? _ref6[methodName] : void 0 : void 0) { method = record[0], context = record[1]; if (method != null) { break; } } } if (viaProto = via & VIA_PROTO) { if (method = (_ref7 = this.protostate) != null ? _ref7.method(methodName, VIA_PROTO, out, true) : void 0) { context = this; inherited = true; break; } } if (via & VIA_SUPER) { _ref9 = (_ref8 = this.order) != null ? _ref8 : this.linearize(); for (_i = 0, _len = _ref9.length; _i < _len; _i++) { relative = _ref9[_i]; if (relative !== this) { if (method = relative.method(methodName, viaProto, out, true)) { context = (_ref10 = out != null ? out.context : void 0) != null ? _ref10 : null; inherited = true; break; } } } if (method != null) { break; } } context = null; break; } if (method != null) { if (typeof method === 'function') { context = null; } if (realized && inherited && useDispatchTables) { table = (_base = this._).__dispatch_table__ != null ? (_base = this._).__dispatch_table__ : _base.__dispatch_table__ = {}; table[methodName] = [method, context]; } if (!returnBoxed) { if (method.type === 'state-bound-function') { method = method.fn; } } } if (out != null) { out.method = method; out.context = context; } return method; }; State.prototype.methodNames = function() { var methods, _ref3; if (methods = (_ref3 = this._) != null ? _ref3.methods : void 0) { return keys(methods); } }; State.prototype.addMethod = function(methodName, fn) { var methods, owner, ownerMethod, root, _ref3, _ref4, _ref5; if (!(this.attributes & INCIPIENT_OR_MUTABLE)) { return; } if (typeof fn === 'object' && fn.type === 'state-fixed-function') { fn = fn.fn(this, this.protostate); } if (!(typeof fn === 'function' || (fn != null ? fn.type : void 0) === 'state-bound-function')) { throw new TypeError("Must supply a plain, bound, or fixed function"); } owner = this.owner; if (!((_ref3 = (ownerMethod = owner[methodName])) != null ? _ref3.isDispatcher : void 0)) { root = this.root; owner[methodName] = createDispatcher(root.accessorName, methodName, ownerMethod); if ((ownerMethod != null) && this !== root) { methods = (_ref4 = root._) != null ? _ref4.methods || (_ref4.methods = {}) : void 0; methods[methodName] = ownerMethod; } } methods = (_ref5 = this._) != null ? _ref5.methods || (_ref5.methods = {}) : void 0; return methods[methodName] = fn; }; State.prototype.removeMethod = function(methodName) { var fn, methods, _ref3; if (!(this.attributes & MUTABLE && (methods = (_ref3 = this._) != null ? _ref3.methods : void 0) && (fn = methods[methodName]))) { return; } delete methods[methodName]; return fn; }; State.prototype.hasMethod = function(methodName) { var method; return method = this.method(methodName); }; State.prototype.hasOwnMethod = function(methodName) { return !!this.method(methodName, VIA_NONE); }; State.prototype.apply = function(methodName, args) { var context, method, out, record, _ref3, _ref4; if (record = (_ref3 = this._) != null ? (_ref4 = _ref3.__dispatch_table__) != null ? _ref4[methodName] : void 0 : void 0) { method = record[0], context = record[1]; if ((method != null ? method.type : void 0) === 'state-bound-function') { method = method.fn; } } if (method == null) { if (method = this.method(methodName, VIA_ALL, out = {})) { context = out.context; } else { this.emit('noSuchMethod', [methodName, args]); this.emit('noSuchMethod:' + methodName, args); return; } } return method.apply(context || this.owner, args); }; State.prototype.call = function() { var args, methodName; methodName = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; return this.apply(methodName, args); }; State.prototype.event = function(eventType, id) { var emitter, _ref3, _ref4; if (!(emitter = (_ref3 = this._) != null ? (_ref4 = _ref3.events) != null ? _ref4[eventType] : void 0 : void 0)) { return; } if (id === void 0) { return emitter.length; } if (typeof id === 'function') { id = emitter.key(id); } return emitter.get(id); }; State.prototype.addEvent = function(eventType, fn, context) { var events, _base; if (this.attributes & VIRTUAL) { this.realize(); } events = (_base = this._).events || (_base.events = {}); if (!hasOwn.call(events, eventType)) { events[eventType] = new StateEventEmitter(this); } if (fn.type === 'state-fixed-function') { fn = fn.fn(this, this.protostate); } return events[eventType].add(fn, context); }; State.prototype.on = State.prototype.addEvent; State.prototype.removeEvent = function(eventType, id) { var _ref3, _ref4; return (_ref3 = this._) != null ? (_ref4 = _ref3.events) != null ? _ref4[eventType].remove(id) : void 0 : void 0; }; State.prototype.off = State.prototype.removeEvent; State.prototype.emit = function(eventType, args, context, via) { var relative, _i, _len, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8; if (via == null) { via = VIA_ALL; } if (typeof eventType !== 'string') { return; } if (typeof args === 'number') { via = context; context = args; args = void 0; } if (typeof context === 'number') { via = context; context = void 0; } if ((args != null) && !isArray(args)) { args = [args]; } if ((_ref3 = this._) != null) { if ((_ref4 = _ref3.events) != null) { if ((_ref5 = _ref4[eventType]) != null) { _ref5.emit(args, context != null ? context : this); } } } if (via & VIA_PROTO) { if ((_ref6 = this.protostate) != null) { _ref6.emit(eventType, args, context != null ? context : this, VIA_PROTO); } } if (via & VIA_SUPER) { _ref8 = (_ref7 = this.order) != null ? _ref7 : this.linearize(); for (_i = 0, _len = _ref8.length; _i < _len; _i++) { relative = _ref8[_i]; if (relative !== this) { relative.emit(eventType, args, context != null ? context : relative); } } } }; State.prototype.trigger = State.prototype.emit; State.prototype.guard = function(guardType) { var guard, _ref3, _ref4, _ref5; if (guard = (_ref3 = this._) != null ? (_ref4 = _ref3.guards) != null ? _ref4[guardType] : void 0 : void 0) { return clone(guard); } else { return ((_ref5 = this.protostate) != null ? _ref5.guard(guardType) : void 0) || void 0; } }; State.prototype.addGuard = function(guardType, guard) { var attributes, guards, _base; attributes = this.attributes; if (!(attributes & INCIPIENT_OR_MUTABLE)) { return; } if (attributes & VIRTUAL) { this.realize(); } guards = (_base = this._).guards || (_base.guards = {}); return edit(guards[guardType] || (guards[guardType] = {}), guard); }; State.prototype.removeGuard = function() { var args, attributes, entry, guard, guardType, guards, key, _i, _len, _ref3; guardType = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; attributes = this.attributes; if (attributes & VIRTUAL) { return; } if (!(attributes & MUTABLE && (guards = this._.guards))) { return; } if (!(guard = guards[guardType])) { return null; } if (!args.length) { return (delete guards[guardType] ? guard : void 0); } _ref3 = flatten(args); for (_i = 0, _len = _ref3.length; _i < _len; _i++) { key = _ref3[_i]; if (!(typeof key === 'string')) { continue; } entry = guard[key]; if (delete guard[key]) { return entry; } } }; State.prototype.transition = function(name) { var _ref3, _ref4; return (_ref3 = this._) != null ? (_ref4 = _ref3.transitions) != null ? _ref4[name] : void 0 : void 0; }; State.prototype.transitions = function() { var _ref3; return clone((_ref3 = this._) != null ? _ref3.transitions : void 0); }; State.prototype.addTransition = function(name, expression) { var attributes, transitions, _base; attributes = this.attributes; if (!(attributes & INCIPIENT_OR_MUTABLE)) { return; } if (attributes & VIRTUAL) { this.realize(); } if (!(expression instanceof TransitionExpression)) { expression = new TransitionExpression(expression); } transitions = (_base = this._).transitions || (_base.transitions = {}); return transitions[name] = expression; }; State.prototype.removeTransition = function(name) { var attributes, transition, transitions; attributes = this.attributes; if (attributes & VIRTUAL) { return; } if (!(attributes & MUTABLE && (transitions = this._.transitions))) { return; } transition = transitions[name]; if (transition) { delete transitions[name]; } return transition; }; return State; })(); State.prototype.Metaobject = require('./state-metaobject'); State.prototype.Expression = StateExpression = require('./state-expression'); StateEventEmitter = require('./state-event-emitter'); TransitionExpression = require('./transition-expression'); }).call(this);