/*
Ractive.js v0.9.0-edge
Mon Nov 21 2016 22:14:50 GMT+0000 (UTC) - commit 8ee32a31d9fa054c3ffbbd8c9731e250c2e04495
http://ractivejs.org
http://twitter.com/RactiveJS
Released under the MIT License.
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
((function() { var current = global.Ractive; var next = factory(); next.noConflict = function() { global.Ractive = current; return next; }; return global.Ractive = next; })());
}(this, (function () { 'use strict';
var defaults = {
// render placement:
el: void 0,
append: false,
// template:
template: null,
// parse:
delimiters: [ '{{', '}}' ],
tripleDelimiters: [ '{{{', '}}}' ],
staticDelimiters: [ '[[', ']]' ],
staticTripleDelimiters: [ '[[[', ']]]' ],
csp: true,
interpolate: false,
preserveWhitespace: false,
sanitize: false,
stripComments: true,
contextLines: 0,
// data & binding:
data: {},
computed: {},
syncComputedChildren: false,
resolveInstanceMembers: true,
warnAboutAmbiguity: false,
magic: false,
modifyArrays: false,
adapt: [],
isolated: false,
twoway: true,
lazy: false,
// transitions:
noIntro: false,
transitionsEnabled: true,
complete: void 0,
// css:
css: null,
noCssTransform: false
};
// These are a subset of the easing equations found at
// https://raw.github.com/danro/easing-js - license info
// follows:
// --------------------------------------------------
// easing.js v0.5.4
// Generic set of easing functions with AMD support
// https://github.com/danro/easing-js
// This code may be freely distributed under the MIT license
// http://danro.mit-license.org/
// --------------------------------------------------
// All functions adapted from Thomas Fuchs & Jeremy Kahn
// Easing Equations (c) 2003 Robert Penner, BSD license
// https://raw.github.com/danro/easing-js/master/LICENSE
// --------------------------------------------------
// In that library, the functions named easeIn, easeOut, and
// easeInOut below are named easeInCubic, easeOutCubic, and
// (you guessed it) easeInOutCubic.
//
// You can add additional easing functions to this list, and they
// will be globally available.
var easing = {
linear: function linear ( pos ) { return pos; },
easeIn: function easeIn ( pos ) { return Math.pow( pos, 3 ); },
easeOut: function easeOut ( pos ) { return ( Math.pow( ( pos - 1 ), 3 ) + 1 ); },
easeInOut: function easeInOut ( pos ) {
if ( ( pos /= 0.5 ) < 1 ) { return ( 0.5 * Math.pow( pos, 3 ) ); }
return ( 0.5 * ( Math.pow( ( pos - 2 ), 3 ) + 2 ) );
}
};
var legacy = null;
/* global console, navigator */
/* eslint no-console:"off" */
var win = typeof window !== 'undefined' ? window : null;
var doc = win ? document : null;
var isClient = !!doc;
var isJsdom = ( typeof navigator !== 'undefined' && /jsDom/.test( navigator.appName ) );
var hasConsole = ( typeof console !== 'undefined' && typeof console.warn === 'function' && typeof console.warn.apply === 'function' );
var magic;
try {
Object.defineProperty({}, 'test', { value: 0 });
magic = true;
} catch ( e ) {
magic = false;
}
var svg = doc ?
doc.implementation.hasFeature( 'http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1' ) :
false;
var vendors = [ 'o', 'ms', 'moz', 'webkit' ];
var html = 'http://www.w3.org/1999/xhtml';
var mathml = 'http://www.w3.org/1998/Math/MathML';
var svg$1 = 'http://www.w3.org/2000/svg';
var xlink = 'http://www.w3.org/1999/xlink';
var xml = 'http://www.w3.org/XML/1998/namespace';
var xmlns = 'http://www.w3.org/2000/xmlns';
var namespaces = { html: html, mathml: mathml, svg: svg$1, xlink: xlink, xml: xml, xmlns: xmlns };
var createElement;
var matches;
var div;
var methodNames;
var unprefixed;
var prefixed;
var i;
var j;
var makeFunction;
// Test for SVG support
if ( !svg ) {
createElement = function ( type, ns, extend ) {
if ( ns && ns !== html ) {
throw 'This browser does not support namespaces other than http://www.w3.org/1999/xhtml. The most likely cause of this error is that you\'re trying to render SVG in an older browser. See http://docs.ractivejs.org/latest/svg-and-older-browsers for more information';
}
return extend ?
doc.createElement( type, extend ) :
doc.createElement( type );
};
} else {
createElement = function ( type, ns, extend ) {
if ( !ns || ns === html ) {
return extend ?
doc.createElement( type, extend ) :
doc.createElement( type );
}
return extend ?
doc.createElementNS( ns, type, extend ) :
doc.createElementNS( ns, type );
};
}
function createDocumentFragment () {
return doc.createDocumentFragment();
}
function getElement ( input ) {
var output;
if ( !input || typeof input === 'boolean' ) { return; }
if ( !win || !doc || !input ) {
return null;
}
// We already have a DOM node - no work to do. (Duck typing alert!)
if ( input.nodeType ) {
return input;
}
// Get node from string
if ( typeof input === 'string' ) {
// try ID first
output = doc.getElementById( input );
// then as selector, if possible
if ( !output && doc.querySelector ) {
output = doc.querySelector( input );
}
// did it work?
if ( output && output.nodeType ) {
return output;
}
}
// If we've been given a collection (jQuery, Zepto etc), extract the first item
if ( input[0] && input[0].nodeType ) {
return input[0];
}
return null;
}
if ( !isClient ) {
matches = null;
} else {
div = createElement( 'div' );
methodNames = [ 'matches', 'matchesSelector' ];
makeFunction = function ( methodName ) {
return function ( node, selector ) {
return node[ methodName ]( selector );
};
};
i = methodNames.length;
while ( i-- && !matches ) {
unprefixed = methodNames[i];
if ( div[ unprefixed ] ) {
matches = makeFunction( unprefixed );
} else {
j = vendors.length;
while ( j-- ) {
prefixed = vendors[i] + unprefixed.substr( 0, 1 ).toUpperCase() + unprefixed.substring( 1 );
if ( div[ prefixed ] ) {
matches = makeFunction( prefixed );
break;
}
}
}
}
// IE8...
if ( !matches ) {
matches = function ( node, selector ) {
var parentNode, i;
parentNode = node.parentNode;
if ( !parentNode ) {
// empty dummy
div.innerHTML = '';
parentNode = div;
node = node.cloneNode();
div.appendChild( node );
}
var nodes = parentNode.querySelectorAll( selector );
i = nodes.length;
while ( i-- ) {
if ( nodes[i] === node ) {
return true;
}
}
return false;
};
}
}
function detachNode ( node ) {
// stupid ie
if ( node && typeof node.parentNode !== 'unknown' && node.parentNode ) { // eslint-disable-line valid-typeof
node.parentNode.removeChild( node );
}
return node;
}
function safeToStringValue ( value ) {
return ( value == null || !value.toString ) ? '' : '' + value;
}
function safeAttributeString ( string ) {
return safeToStringValue( string )
.replace( /&/g, '&' )
.replace( /"/g, '"' )
.replace( /'/g, ''' );
}
var camel = /(-.)/g;
function camelize ( string ) {
return string.replace( camel, function (s) { return s.charAt( 1 ).toUpperCase(); } );
}
var decamel = /[A-Z]/g;
function decamelize ( string ) {
return string.replace( decamel, function (s) { return ("-" + (s.toLowerCase())); } );
}
var create;
var defineProperty;
var defineProperties;
try {
Object.defineProperty({}, 'test', { get: function get() {}, set: function set() {} });
if ( doc ) {
Object.defineProperty( createElement( 'div' ), 'test', { value: 0 });
}
defineProperty = Object.defineProperty;
} catch ( err ) {
// Object.defineProperty doesn't exist, or we're in IE8 where you can
// only use it with DOM objects (what were you smoking, MSFT?)
defineProperty = function ( obj, prop, desc ) {
if ( desc.get ) { obj[ prop ] = desc.get(); }
else { obj[ prop ] = desc.value; }
};
}
try {
try {
Object.defineProperties({}, { test: { value: 0 } });
} catch ( err ) {
// TODO how do we account for this? noMagic = true;
throw err;
}
if ( doc ) {
Object.defineProperties( createElement( 'div' ), { test: { value: 0 } });
}
defineProperties = Object.defineProperties;
} catch ( err ) {
defineProperties = function ( obj, props ) {
var prop;
for ( prop in props ) {
if ( props.hasOwnProperty( prop ) ) {
defineProperty( obj, prop, props[ prop ] );
}
}
};
}
try {
Object.create( null );
create = Object.create;
} catch ( err ) {
// sigh
create = (function () {
var F = function () {};
return function ( proto, props ) {
if ( proto === null ) {
return {};
}
F.prototype = proto;
var obj = new F();
if ( props ) {
Object.defineProperties( obj, props );
}
return obj;
};
}());
}
function extend$1 ( target ) {
var sources = [], len = arguments.length - 1;
while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ];
var prop;
sources.forEach( function (source) {
for ( prop in source ) {
if ( hasOwn.call( source, prop ) ) {
target[ prop ] = source[ prop ];
}
}
});
return target;
}
function fillGaps ( target ) {
var sources = [], len = arguments.length - 1;
while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ];
sources.forEach( function (s) {
for ( var key in s ) {
if ( hasOwn.call( s, key ) && !( key in target ) ) {
target[ key ] = s[ key ];
}
}
});
return target;
}
var hasOwn = Object.prototype.hasOwnProperty;
function toPairs ( obj ) {
if ( obj === void 0 ) obj = {};
var res = [];
for ( var k in obj ) {
if ( hasOwn.call( obj, k ) ) { res.push( [ k, obj[k] ] ); }
}
return res;
}
var toString$1$1 = Object.prototype.toString;
var arrayLikePattern = /^\[object (?:Array|FileList)\]$/;
// thanks, http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
function isArray ( thing ) {
return toString$1$1.call( thing ) === '[object Array]';
}
function isEqual ( a, b ) {
if ( a === null && b === null ) {
return true;
}
if ( typeof a === 'object' || typeof b === 'object' ) {
return false;
}
return a === b;
}
// http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric
function isNumeric ( thing ) {
return !isNaN( parseFloat( thing ) ) && isFinite( thing );
}
function isObject ( thing ) {
return ( thing && toString$1$1.call( thing ) === '[object Object]' );
}
function isObjectLike ( thing ) {
if ( !thing ) { return false; }
var type = typeof thing;
if ( type === 'object' || type === 'function' ) { return true; }
}
var noop = function () {};
/* global console */
/* eslint no-console:"off" */
var alreadyWarned = {};
var log;
var printWarning;
var welcome;
if ( hasConsole ) {
var welcomeIntro = [
"%cRactive.js %c0.9.0-edge-8ee32a31d9fa054c3ffbbd8c9731e250c2e04495 %cin debug mode, %cmore...",
'color: rgb(114, 157, 52); font-weight: normal;',
'color: rgb(85, 85, 85); font-weight: normal;',
'color: rgb(85, 85, 85); font-weight: normal;',
'color: rgb(82, 140, 224); font-weight: normal; text-decoration: underline;'
];
var welcomeMessage = "You're running Ractive 0.9.0-edge-8ee32a31d9fa054c3ffbbd8c9731e250c2e04495 in debug mode - messages will be printed to the console to help you fix problems and optimise your application.\n\nTo disable debug mode, add this line at the start of your app:\n Ractive.DEBUG = false;\n\nTo disable debug mode when your app is minified, add this snippet:\n Ractive.DEBUG = /unminified/.test(function(){/*unminified*/});\n\nGet help and support:\n http://docs.ractivejs.org\n http://stackoverflow.com/questions/tagged/ractivejs\n http://groups.google.com/forum/#!forum/ractive-js\n http://twitter.com/ractivejs\n\nFound a bug? Raise an issue:\n https://github.com/ractivejs/ractive/issues\n\n";
welcome = function () {
if ( Ractive.WELCOME_MESSAGE === false ) {
welcome = noop;
return;
}
var message = 'WELCOME_MESSAGE' in Ractive ? Ractive.WELCOME_MESSAGE : welcomeMessage;
var hasGroup = !!console.groupCollapsed;
if ( hasGroup ) { console.groupCollapsed.apply( console, welcomeIntro ); }
console.log( message );
if ( hasGroup ) {
console.groupEnd( welcomeIntro );
}
welcome = noop;
};
printWarning = function ( message, args ) {
welcome();
// extract information about the instance this message pertains to, if applicable
if ( typeof args[ args.length - 1 ] === 'object' ) {
var options = args.pop();
var ractive = options ? options.ractive : null;
if ( ractive ) {
// if this is an instance of a component that we know the name of, add
// it to the message
var name;
if ( ractive.component && ( name = ractive.component.name ) ) {
message = "<" + name + "> " + message;
}
var node;
if ( node = ( options.node || ( ractive.fragment && ractive.fragment.rendered && ractive.find( '*' ) ) ) ) {
args.push( node );
}
}
}
console.warn.apply( console, [ '%cRactive.js: %c' + message, 'color: rgb(114, 157, 52);', 'color: rgb(85, 85, 85);' ].concat( args ) );
};
log = function () {
console.log.apply( console, arguments );
};
} else {
printWarning = log = welcome = noop;
}
function format ( message, args ) {
return message.replace( /%s/g, function () { return args.shift(); } );
}
function fatal ( message ) {
var args = [], len = arguments.length - 1;
while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
message = format( message, args );
throw new Error( message );
}
function logIfDebug () {
if ( Ractive.DEBUG ) {
log.apply( null, arguments );
}
}
function warn ( message ) {
var args = [], len = arguments.length - 1;
while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
message = format( message, args );
printWarning( message, args );
}
function warnOnce ( message ) {
var args = [], len = arguments.length - 1;
while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
message = format( message, args );
if ( alreadyWarned[ message ] ) {
return;
}
alreadyWarned[ message ] = true;
printWarning( message, args );
}
function warnIfDebug () {
if ( Ractive.DEBUG ) {
warn.apply( null, arguments );
}
}
function warnOnceIfDebug () {
if ( Ractive.DEBUG ) {
warnOnce.apply( null, arguments );
}
}
// Error messages that are used (or could be) in multiple places
var badArguments = 'Bad arguments';
var noRegistryFunctionReturn = 'A function was specified for "%s" %s, but no %s was returned';
var missingPlugin = function ( name, type ) { return ("Missing \"" + name + "\" " + type + " plugin. You may need to download a plugin via http://docs.ractivejs.org/latest/plugins#" + type + "s"); };
function findInViewHierarchy ( registryName, ractive, name ) {
var instance = findInstance( registryName, ractive, name );
return instance ? instance[ registryName ][ name ] : null;
}
function findInstance ( registryName, ractive, name ) {
while ( ractive ) {
if ( name in ractive[ registryName ] ) {
return ractive;
}
if ( ractive.isolated ) {
return null;
}
ractive = ractive.parent;
}
}
function interpolate ( from, to, ractive, type ) {
if ( from === to ) { return null; }
if ( type ) {
var interpol = findInViewHierarchy( 'interpolators', ractive, type );
if ( interpol ) { return interpol( from, to ) || null; }
fatal( missingPlugin( type, 'interpolator' ) );
}
return interpolators.number( from, to ) ||
interpolators.array( from, to ) ||
interpolators.object( from, to ) ||
null;
}
function snap ( to ) {
return function () { return to; };
}
var interpolators = {
number: function number ( from, to ) {
if ( !isNumeric( from ) || !isNumeric( to ) ) {
return null;
}
from = +from;
to = +to;
var delta = to - from;
if ( !delta ) {
return function () { return from; };
}
return function ( t ) {
return from + ( t * delta );
};
},
array: function array ( from, to ) {
var len, i;
if ( !isArray( from ) || !isArray( to ) ) {
return null;
}
var intermediate = [];
var interpolators = [];
i = len = Math.min( from.length, to.length );
while ( i-- ) {
interpolators[i] = interpolate( from[i], to[i] );
}
// surplus values - don't interpolate, but don't exclude them either
for ( i=len; i> j ) ? '*' : parts[j] );
}
result.unshift( join.join( '.' ) );
}
if ( base ) {
// include non-this-namespaced versions
if ( parts.length > 2 ) {
result.push.apply( result, variants( name, false ) );
} else {
result.push( '*' );
result.push( name );
}
}
map[ name ] = result;
return result;
}
function fireEvent ( ractive, eventName, options ) {
if ( options === void 0 ) options = {};
if ( !eventName ) { return; }
if ( !options.event ) {
options.event = {
name: eventName,
// until event not included as argument default
_noArg: true
};
} else {
options.event.name = eventName;
}
var eventNames = variants( eventName, true );
return fireEventAs( ractive, eventNames, options.event, options.args, true );
}
function fireEventAs ( ractive, eventNames, event, args, initialFire ) {
if ( initialFire === void 0 ) initialFire = false;
var subscribers, i;
var bubble = true;
enqueue( ractive, event );
for ( i = eventNames.length; i >= 0; i-- ) {
subscribers = ractive._subs[ eventNames[ i ] ];
if ( subscribers ) {
bubble = notifySubscribers( ractive, subscribers, event, args ) && bubble;
}
}
dequeue( ractive );
if ( ractive.parent && bubble ) {
if ( initialFire && ractive.component ) {
var fullName = ractive.component.name + '.' + eventNames[ eventNames.length - 1 ];
eventNames = variants( fullName, false );
if ( event && !event.component ) {
event.component = ractive;
}
}
fireEventAs( ractive.parent, eventNames, event, args );
}
return bubble;
}
function notifySubscribers ( ractive, subscribers, event, args ) {
var originalEvent = null;
var stopEvent = false;
if ( event && !event._noArg ) {
args = [ event ].concat( args );
}
// subscribers can be modified inflight, e.g. "once" functionality
// so we need to copy to make sure everyone gets called
subscribers = subscribers.slice();
for ( var i = 0, len = subscribers.length; i < len; i += 1 ) {
if ( !subscribers[ i ].off && subscribers[ i ].apply( ractive, args ) === false ) {
stopEvent = true;
}
}
if ( event && !event._noArg && stopEvent && ( originalEvent = event.original ) ) {
originalEvent.preventDefault && originalEvent.preventDefault();
originalEvent.stopPropagation && originalEvent.stopPropagation();
}
return !stopEvent;
}
var Hook = function Hook ( event ) {
this.event = event;
this.method = 'on' + event;
};
Hook.prototype.fire = function fire ( ractive, arg ) {
if ( ractive[ this.method ] ) {
arg ? ractive[ this.method ]( arg ) : ractive[ this.method ]();
}
var options = { args: [] };
if ( arg ) { options.args.push( arg ); }
options.args.push( ractive );
fireEvent( ractive, this.event, options );
};
function addToArray ( array, value ) {
var index = array.indexOf( value );
if ( index === -1 ) {
array.push( value );
}
}
function arrayContains ( array, value ) {
for ( var i = 0, c = array.length; i < c; i++ ) {
if ( array[i] == value ) {
return true;
}
}
return false;
}
function arrayContentsMatch ( a, b ) {
var i;
if ( !isArray( a ) || !isArray( b ) ) {
return false;
}
if ( a.length !== b.length ) {
return false;
}
i = a.length;
while ( i-- ) {
if ( a[i] !== b[i] ) {
return false;
}
}
return true;
}
function ensureArray ( x ) {
if ( typeof x === 'string' ) {
return [ x ];
}
if ( x === undefined ) {
return [];
}
return x;
}
function lastItem ( array ) {
return array[ array.length - 1 ];
}
function removeFromArray ( array, member ) {
if ( !array ) {
return;
}
var index = array.indexOf( member );
if ( index !== -1 ) {
array.splice( index, 1 );
}
}
function combine ( first ) {
var rest = [], len = arguments.length - 1;
while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];
var res = first.slice();
rest = rest.concat.apply( [], rest );
var i = rest.length;
while ( i-- ) {
if ( !~res.indexOf( rest[i] ) ) {
res.push( rest[i] );
}
}
return res;
}
function toArray ( arrayLike ) {
var array = [];
var i = arrayLike.length;
while ( i-- ) {
array[i] = arrayLike[i];
}
return array;
}
function find$1 ( array, fn ) {
var len = array.length;
for ( var i = 0; i < len; i++ ) {
if ( fn( array[i] ) ) { return array[i]; }
}
}
function findMap ( array, fn ) {
var len = array.length;
for ( var i = 0; i < len; i++ ) {
var result = fn( array[i] );
if ( result ) { return result; }
}
}
var _Promise;
var PENDING = {};
var FULFILLED = {};
var REJECTED = {};
if ( typeof Promise === 'function' ) {
// use native Promise
_Promise = Promise;
} else {
_Promise = function ( callback ) {
var fulfilledHandlers = [];
var rejectedHandlers = [];
var state = PENDING;
var result, dispatchHandlers;
var makeResolver = function ( newState ) {
return function ( value ) {
if ( state !== PENDING ) {
return;
}
result = value;
state = newState;
dispatchHandlers = makeDispatcher( ( state === FULFILLED ? fulfilledHandlers : rejectedHandlers ), result );
// dispatch onFulfilled and onRejected handlers asynchronously
wait( dispatchHandlers );
};
};
var fulfil = makeResolver( FULFILLED );
var reject = makeResolver( REJECTED );
try {
callback( fulfil, reject );
} catch ( err ) {
reject( err );
}
var promise = {
// `then()` returns a Promise - 2.2.7
then: function then ( onFulfilled, onRejected ) {
var promise2 = new _Promise( function ( fulfil, reject ) {
var processResolutionHandler = function ( handler, handlers, forward ) {
// 2.2.1.1
if ( typeof handler === 'function' ) {
handlers.push( function ( p1result ) {
var x;
try {
x = handler( p1result );
resolve$1( promise2, x, fulfil, reject );
} catch ( err ) {
reject( err );
}
});
} else {
// Forward the result of promise1 to promise2, if resolution handlers
// are not given
handlers.push( forward );
}
};
// 2.2
processResolutionHandler( onFulfilled, fulfilledHandlers, fulfil );
processResolutionHandler( onRejected, rejectedHandlers, reject );
if ( state !== PENDING ) {
// If the promise has resolved already, dispatch the appropriate handlers asynchronously
wait( dispatchHandlers );
}
});
return promise2;
}
};
promise[ 'catch' ] = function ( onRejected ) {
return this.then( null, onRejected );
};
return promise;
};
_Promise.all = function ( promises ) {
return new _Promise( function ( fulfil, reject ) {
var result = [];
var pending, i;
if ( !promises.length ) {
fulfil( result );
return;
}
var processPromise = function ( promise, i ) {
if ( promise && typeof promise.then === 'function' ) {
promise.then( function (value) {
result[i] = value;
--pending || fulfil( result );
}, reject );
}
else {
result[i] = promise;
--pending || fulfil( result );
}
};
pending = i = promises.length;
while ( i-- ) {
processPromise( promises[i], i );
}
});
};
_Promise.resolve = function ( value ) {
return new _Promise( function ( fulfil ) {
fulfil( value );
});
};
_Promise.reject = function ( reason ) {
return new _Promise( function ( fulfil, reject ) {
reject( reason );
});
};
}
var Promise$1 = _Promise;
// TODO use MutationObservers or something to simulate setImmediate
function wait ( callback ) {
setTimeout( callback, 0 );
}
function makeDispatcher ( handlers, result ) {
return function () {
var handler;
while ( handler = handlers.shift() ) {
handler( result );
}
};
}
function resolve$1 ( promise, x, fulfil, reject ) {
// Promise Resolution Procedure
var then;
// 2.3.1
if ( x === promise ) {
throw new TypeError( 'A promise\'s fulfillment handler cannot return the same promise' );
}
// 2.3.2
if ( x instanceof _Promise ) {
x.then( fulfil, reject );
}
// 2.3.3
else if ( x && ( typeof x === 'object' || typeof x === 'function' ) ) {
try {
then = x.then; // 2.3.3.1
} catch ( e ) {
reject( e ); // 2.3.3.2
return;
}
// 2.3.3.3
if ( typeof then === 'function' ) {
var called;
var resolvePromise = function ( y ) {
if ( called ) {
return;
}
called = true;
resolve$1( promise, y, fulfil, reject );
};
var rejectPromise = function ( r ) {
if ( called ) {
return;
}
called = true;
reject( r );
};
try {
then.call( x, resolvePromise, rejectPromise );
} catch ( e ) {
if ( !called ) { // 2.3.3.3.4.1
reject( e ); // 2.3.3.3.4.2
called = true;
return;
}
}
}
else {
fulfil( x );
}
}
else {
fulfil( x );
}
}
var TransitionManager = function TransitionManager ( callback, parent ) {
this.callback = callback;
this.parent = parent;
this.intros = [];
this.outros = [];
this.children = [];
this.totalChildren = this.outroChildren = 0;
this.detachQueue = [];
this.outrosComplete = false;
if ( parent ) {
parent.addChild( this );
}
};
TransitionManager.prototype.add = function add ( transition ) {
var list = transition.isIntro ? this.intros : this.outros;
list.push( transition );
};
TransitionManager.prototype.addChild = function addChild ( child ) {
this.children.push( child );
this.totalChildren += 1;
this.outroChildren += 1;
};
TransitionManager.prototype.decrementOutros = function decrementOutros () {
this.outroChildren -= 1;
check( this );
};
TransitionManager.prototype.decrementTotal = function decrementTotal () {
this.totalChildren -= 1;
check( this );
};
TransitionManager.prototype.detachNodes = function detachNodes () {
this.detachQueue.forEach( detach$1 );
this.children.forEach( _detachNodes );
};
TransitionManager.prototype.ready = function ready () {
detachImmediate( this );
};
TransitionManager.prototype.remove = function remove ( transition ) {
var list = transition.isIntro ? this.intros : this.outros;
removeFromArray( list, transition );
check( this );
};
TransitionManager.prototype.start = function start () {
this.children.forEach( function (c) { return c.start(); } );
this.intros.concat( this.outros ).forEach( function (t) { return t.start(); } );
this.ready = true;
check( this );
};
function detach$1 ( element ) {
element.detach();
}
function _detachNodes ( tm ) { // _ to avoid transpiler quirk
tm.detachNodes();
}
function check ( tm ) {
if ( !tm.ready || tm.outros.length || tm.outroChildren ) { return; }
// If all outros are complete, and we haven't already done this,
// we notify the parent if there is one, otherwise
// start detaching nodes
if ( !tm.outrosComplete ) {
tm.outrosComplete = true;
if ( tm.parent && !tm.parent.outrosComplete ) {
tm.parent.decrementOutros( tm );
} else {
tm.detachNodes();
}
}
// Once everything is done, we can notify parent transition
// manager and call the callback
if ( !tm.intros.length && !tm.totalChildren ) {
if ( typeof tm.callback === 'function' ) {
tm.callback();
}
if ( tm.parent && !tm.notifiedTotal ) {
tm.notifiedTotal = true;
tm.parent.decrementTotal();
}
}
}
// check through the detach queue to see if a node is up or downstream from a
// transition and if not, go ahead and detach it
function detachImmediate ( manager ) {
var queue = manager.detachQueue;
var outros = collectAllOutros( manager );
var i = queue.length;
var j = 0;
var node, trans;
start: while ( i-- ) {
node = queue[i].node;
j = outros.length;
while ( j-- ) {
trans = outros[j].element.node;
// check to see if the node is, contains, or is contained by the transitioning node
if ( trans === node || trans.contains( node ) || node.contains( trans ) ) { continue start; }
}
// no match, we can drop it
queue[i].detach();
queue.splice( i, 1 );
}
}
function collectAllOutros ( manager, list ) {
if ( !list ) {
list = [];
var parent = manager;
while ( parent.parent ) { parent = parent.parent; }
return collectAllOutros( parent, list );
} else {
var i = manager.children.length;
while ( i-- ) {
list = collectAllOutros( manager.children[i], list );
}
list = list.concat( manager.outros );
return list;
}
}
var changeHook = new Hook( 'change' );
var batch;
var runloop = {
start: function start ( instance ) {
var fulfilPromise;
var promise = new Promise$1( function (f) { return ( fulfilPromise = f ); } );
batch = {
previousBatch: batch,
transitionManager: new TransitionManager( fulfilPromise, batch && batch.transitionManager ),
fragments: [],
tasks: [],
immediateObservers: [],
deferredObservers: [],
ractives: [],
instance: instance,
promise: promise
};
return promise;
},
end: function end () {
flushChanges();
if ( !batch.previousBatch ) { batch.transitionManager.start(); }
batch = batch.previousBatch;
},
addFragment: function addFragment ( fragment ) {
addToArray( batch.fragments, fragment );
},
// TODO: come up with a better way to handle fragments that trigger their own update
addFragmentToRoot: function addFragmentToRoot ( fragment ) {
if ( !batch ) { return; }
var b = batch;
while ( b.previousBatch ) {
b = b.previousBatch;
}
addToArray( b.fragments, fragment );
},
addInstance: function addInstance ( instance ) {
if ( batch ) { addToArray( batch.ractives, instance ); }
},
addObserver: function addObserver ( observer, defer ) {
addToArray( defer ? batch.deferredObservers : batch.immediateObservers, observer );
},
registerTransition: function registerTransition ( transition ) {
transition._manager = batch.transitionManager;
batch.transitionManager.add( transition );
},
// synchronise node detachments with transition ends
detachWhenReady: function detachWhenReady ( thing ) {
batch.transitionManager.detachQueue.push( thing );
},
scheduleTask: function scheduleTask ( task, postRender ) {
var _batch;
if ( !batch ) {
task();
} else {
_batch = batch;
while ( postRender && _batch.previousBatch ) {
// this can't happen until the DOM has been fully updated
// otherwise in some situations (with components inside elements)
// transitions and decorators will initialise prematurely
_batch = _batch.previousBatch;
}
_batch.tasks.push( task );
}
},
promise: function promise () {
if ( !batch ) { return Promise$1.resolve(); }
var target = batch;
while ( target.previousBatch ) {
target = target.previousBatch;
}
return target.promise || Promise$1.resolve();
}
};
function dispatch$1 ( observer ) {
observer.dispatch();
}
function flushChanges () {
var which = batch.immediateObservers;
batch.immediateObservers = [];
which.forEach( dispatch$1 );
// Now that changes have been fully propagated, we can update the DOM
// and complete other tasks
var i = batch.fragments.length;
var fragment;
which = batch.fragments;
batch.fragments = [];
var ractives = batch.ractives;
batch.ractives = [];
while ( i-- ) {
fragment = which[i];
// TODO deprecate this. It's annoying and serves no useful function
var ractive = fragment.ractive;
if ( Object.keys( ractive.viewmodel.changes ).length ) {
changeHook.fire( ractive, ractive.viewmodel.changes );
}
ractive.viewmodel.changes = {};
removeFromArray( ractives, ractive );
fragment.update();
}
i = ractives.length;
while ( i-- ) {
var ractive$1 = ractives[i];
changeHook.fire( ractive$1, ractive$1.viewmodel.changes );
ractive$1.viewmodel.changes = {};
}
batch.transitionManager.ready();
which = batch.deferredObservers;
batch.deferredObservers = [];
which.forEach( dispatch$1 );
var tasks = batch.tasks;
batch.tasks = [];
for ( i = 0; i < tasks.length; i += 1 ) {
tasks[i]();
}
// If updating the view caused some model blowback - e.g. a triple
// containing