Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,28 @@
{
"name": "fast-list",
"homepage": "https://github.com/gaia-components/fast-list",
"authors": [
"Etienne Segonzac <etienne@segonzac.info>",
"Wilson Page <wilsonpage@me.com>"
],
"description": "No, really.",
"main": "fast-list.js",
"keywords": [
"web",
"performance",
"virtual",
"list"
],
"license": "MPL",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"examples",
"test",
"tests"
],
"dependencies": {
"dom-scheduler": "etiennesegonzac/dom-scheduler#~1.0.1"
}
}

View file

@ -0,0 +1,445 @@
!(function(define){'use strict';define(function(require,exports,module){
/**
* Mini logger
* @type {Function}
*/
var debug = 0 ? console.log.bind(console, '[FastList<>Edit]') : function() {};
// Pointer/touch abstraction
var startEvent = ('ontouchstart' in window) ? 'touchstart' : 'mousedown';
var moveEvent = ('ontouchstart' in window) ? 'touchmove' : 'mousemove';
var endEvent = ('ontouchstart' in window) ? 'touchend' : 'mouseup';
var schedule = FastList.scheduler;
/**
* Exports
*/
exports = module.exports = fastListEdit;
function fastListEdit(list) {
list.editing = false;
/**
* Toggles the edit mode on and off
*
* Returns the DomScheduler promise of the edit mode transition
*
* @return {Promise}
*/
list.toggleEditMode = function() {
list.editing = !list.editing;
if (list.editing) list._startTouchListeners();
else list._stopTouchListeners();
return toggleEditClass(
list.els.itemContainer,
list.els.itemsInDOM,
list.editing
);
};
list._startTouchListeners = function() {
on(list.els.itemContainer, startEvent, list.handleEventEdit);
on(list.els.itemContainer, endEvent, list.handleEventEdit);
};
list._stopTouchListeners = function() {
off(list.els.itemContainer, startEvent, list.handleEventEdit);
off(list.els.itemContainer, endEvent, list.handleEventEdit);
};
list.handleEventEdit = function(evt) {
switch (evt.type) {
case startEvent:
if (!evt.target.classList.contains('cursor')) {
return;
}
evt.preventDefault();
list._reorderStart(evt);
break;
case endEvent:
if (!evt.target.classList.contains('cursor') &&
endEvent === 'touchend') {
return;
}
evt.preventDefault();
list._reorderEnd(evt);
break;
}
};
/**
* Starts the reordering gestures
*
* - initializes the reordering context (state)
* - attaches (see DomScheduler) a block to the move events
* - sets up the css to make the dragged element pop up
*
* @param {TouchEvent} evt the touchstart event
*/
list._reorderStart = function(evt) {
debug('reorder start');
var ctx = list.reorderingContext;
// Already tracking an item, bailing out
if (ctx.item) return;
var li = evt.target.parentNode.parentNode;
var touch = evt.touches && evt.touches[0] || evt;
ctx.item = li;
ctx.initialY = touch.pageY;
ctx.identifier = touch.identifier;
ctx.moveUp = new Set();
ctx.moveDown = new Set();
ctx.moveHandler = list._reorderMove.bind(list);
var listenToMove = (function() {
schedule.attachDirect(
list.els.itemContainer,
moveEvent,
ctx.moveHandler);
}).bind(list);
setupForDragging(li, true)
.then(listenToMove)
.then(toggleDraggingClass.bind(null, li, true));
};
/**
* Scheduled callback for move events during reordering
*
* - updates the position of the dragged item
* - rearranges the other items
*
* @param {TouchEvent} evt the touchmove event
*/
list._reorderMove = function(evt) {
debug('reorder move');
var ctx = list.reorderingContext;
if (!ctx.item) return;
// Multi touch
if (evt.touches && evt.touches.length > 1) return;
var li = ctx.item;
var touch = evt.touches && evt.touches[0] || evt;
var position = touch.pageY;
var delta = position - ctx.initialY;
list._rearrange(delta);
tweakTransform(li, delta);
// TODO: scroll when close to the beginning/end of the viewport
};
/**
* Rearranges the items below te dragged one
*
* - computes the transitions needed based on the context
* - triggers scheduled transitions for each one
*
* @param {Number} delta the distance traveled by the reordering gesture
*/
list._rearrange = function(delta) {
debug('rearrange', delta);
var ctx = list.reorderingContext;
var upCount = ctx.moveUp.size;
var downCount = ctx.moveDown.size;
computeChanges(
list.reorderingContext,
list.geometry,
list.els.itemsInDOM,
delta
);
if (ctx.moveUp.size === upCount &&
ctx.moveDown.size === downCount) {
return;
}
applyChanges(
list.reorderingContext,
list.geometry,
list.els.itemsInDOM
);
debug('rearranged');
};
/**
* Ends the reordering gesture
*
* - computes any remaining pending changes
* - detaches the block from the move events
* - schedules a transition to move the dragged item in place
* - schedules a transition to move other items in place
*
* @param {TouchEvent} evt the touchend event
*/
list._reorderEnd = function(evt) {
debug('reorder end');
var ctx = list.reorderingContext;
var li = ctx.item;
if (!li) return;
schedule.detachDirect(
list.els.itemContainer,
moveEvent,
ctx.moveHandler);
var touch = evt.touches && evt.touches[0] || evt;
if (touch.identifier == ctx.identifier) {
var position = touch.pageY;
var delta = position - ctx.initialY;
computeChanges(ctx, list.geometry, list.els.itemsInDOM, delta);
}
Promise.all([
applyChanges(ctx, list.geometry, list.els.itemsInDOM),
moveInPlace(ctx, list.geometry)
]).then(list._reorderFinish.bind(list, li))
.then(toggleDraggingClass.bind(null, li, false));
};
/**
* Final stage of the reordering
*
* In parallell
* - Commits the change to the document
* - cleans up the css on the dragged element
*
*/
list._reorderFinish = function(li) {
return Promise.all([
list._commitToDocument(),
setupForDragging(li, false)
]);
};
/**
* Commits the reordering changes to the document
*
* Inside a scheduled mutation
* - re-renders the list with the new ordering
* - cleans up the reordering context
*
*/
list._commitToDocument = function() {
debug('commit to document');
var ctx = list.reorderingContext;
var li = ctx.item;
var itemsInDOM = list.els.itemsInDOM;
var items = list.els.items;
var source = list.source;
return schedule.mutation((function() {
// Nothing to do
if (!ctx.moveUp && !ctx.moveDown) {
return;
}
var index = items.indexOf(li);
var section = li.dataset.section;
var newIndex = index + ctx.moveUp.size - ctx.moveDown.size;
items.splice(index, 1);
items.splice(newIndex, 0, li);
var c = source.removeAtIndex(index);
source.insertAtIndex(newIndex, c, section);
itemsInDOM.forEach(function(item) {
resetTransition(item);
resetTransform(item);
});
list.updateSections();
list.render();
ctx.item = null;
ctx.initialY = null;
ctx.identifier = null;
ctx.moveUp = null;
ctx.moveDown = null;
ctx.moveHandler = null;
}).bind(list));
};
}
/**
* Internals
*/
function resetTransform(item) {
debug('reset transform');
var position = parseInt(item.dataset.position);
item.style.webkitTransform =
item.style.transform = 'translateY(' + position + 'px)';
item.dataset.tweakDelta = '';
}
function tweakTransform(item, delta) {
debug('tweak transform', delta);
var position = ~~item.dataset.position + delta;
item.style.webkitTransform =
item.style.transform = 'translateY(' + position + 'px)';
item.dataset.tweakDelta = delta;
}
function resetTransition(item) {
item.style.transition = '';
item.style.webkitTransition = '';
}
function tweakAndTransition(item, tweak) {
return schedule.feedback(function() {
debug('tweak and transition', item, tweak);
item.style.transition = 'transform 0.15s ease';
item.style.webkitTransition = '-webkit-transform 0.15s ease';
if (tweak === 0) {
setTimeout(resetTransform.bind(null, item));
return;
}
setTimeout(tweakTransform.bind(null, item, tweak));
}, item, 'transitionend')
.then(resetTransition.bind(null, item));
}
function toggleEditClass(list, domItems, editing) {
if (!domItems.length) return Promise.resolve();
return schedule.feedback(function() {
for (var i = 0; i < domItems.length; i++) {
var item = domItems[i];
var overlay = item.querySelector('.overlay');
overlay.dataset.anim = editing ? 'reveal' : 'hide';
item.classList.toggle('edit', editing);
}
}, list, 'animationend');
}
function setupForDragging(item, on) {
return schedule.mutation(function() {
item.parentNode.classList.toggle('reordering', on);
item.style.zIndex = on ? '1000' : '';
item.style.boxShadow = on ? '0 0 3px 1px #bcbcbc' : '';
});
}
function toggleDraggingClass(item, on) {
return schedule.feedback(function() {
var overlay = item.querySelector('.overlay');
overlay.dataset.anim = on ? 'hide' : 'reveal';
}, item, 'animationend');
}
function computeChanges(context, geometry, domItems, delta) {
if (!context.item) return;
var draggedItem = context.item;
var draggedOriginal = parseInt(draggedItem.dataset.position);
var draggedTweaked = draggedOriginal + delta;
for (var i = 0; i < domItems.length; i++) {
var item = domItems[i];
if (item === draggedItem) continue;
// TODO: support re-ordering accross sections
if (item.dataset.section !== draggedItem.dataset.section) continue;
var itemOriginal = parseInt(item.dataset.position);
var itemTweaked = itemOriginal + parseInt(item.dataset.tweakDelta);
if ((itemOriginal < draggedOriginal) && (draggedTweaked < itemOriginal)) {
context.moveDown.add(item);
} else {
if (draggedTweaked > itemTweaked) {
context.moveDown.delete(item);
}
}
if ((itemOriginal > draggedOriginal) && (draggedTweaked > itemOriginal)) {
context.moveUp.add(item);
} else {
if (draggedTweaked < itemTweaked) {
context.moveUp.delete(item);
}
}
}
}
function applyChanges(context, geometry, domItems) {
debug('apply changes');
if (!context.item) return Promise.resolve();
var itemHeight = geometry.itemHeight;
var draggedItem = context.item;
var promises = [];
for (var i = 0; i < domItems.length; i++) {
var item = domItems[i];
if (item === draggedItem) continue;
// Reset
if (item.dataset.tweakDelta &&
!context.moveUp.has(item) && !context.moveDown.has(item)) {
promises.push(tweakAndTransition(item, 0));
}
// Moving down
if (context.moveDown.has(item)) {
if (parseInt(item.dataset.tweakDelta) !== itemHeight) {
promises.push(tweakAndTransition(item, itemHeight));
}
}
// Moving up
if (context.moveUp.has(item)) {
if (parseInt(item.dataset.tweakDelta) !== itemHeight * -1) {
promises.push(tweakAndTransition(item, itemHeight * -1));
}
}
}
return Promise.all(promises);
}
function moveInPlace(context, geometry) {
debug('move in place');
var li = context.item;
// We're already in place
if (!li.dataset.tweakDelta) return Promise.resolve();
var position = parseInt(li.dataset.position);
var taintedPosition = position + parseInt(li.dataset.tweakDelta);
var itemHeight = geometry.itemHeight;
var newPosition = position + context.moveUp.size * itemHeight -
context.moveDown.size * itemHeight;
var duration = (Math.abs(taintedPosition - newPosition) / itemHeight) * 150;
return schedule.feedback(function() {
li.style.transition = 'transform ' + duration + 'ms linear';
li.style.webkitTransition = '-webkit-transform ' + duration + 'ms linear';
setTimeout(tweakTransform.bind(null, li, (newPosition - position)));
}, li, 'transitionend');
}
// Shorthand
function on(el, name, fn) { el.addEventListener(name, fn); }
function off(el, name, fn) { el.removeEventListener(name, fn); }
});})((typeof define)[0]=='f'&&define.amd?define:(function(n,n2,w){'use strict';
return(typeof module)[0]=='o'?function(c){c(require,exports,module);}:
function(c){var m={exports:{}};c(function(n){w[n];},m.exports,m);
w[n]=w[n2]=m.exports;};})('fastListEdit','fast-list-edit',this));

View file

@ -0,0 +1,47 @@
;;;;;;;!(function(define){'use strict';define(function(require,exports,module){var debug=0?console.log.bind(console,'[FastList]'):function(){};var schedule=(window.scheduler&&typeof window.scheduler.mutation==="function"?window.scheduler:schedulerShim());exports=module.exports=FastList;exports.scheduler=schedule;function FastList(source){debug('initialize');this._scrollStopTimeout=null;this.source=source;this.els={itemContainer:source.itemContainer,container:source.container,list:source.list,sections:[],items:[],itemsInDOM:[]};this.geometry={topPosition:0,forward:true,busy:false,idle:true,hasScrolled:false,itemHeight:source.getItemHeight(),viewportHeight:0,maxItemCount:0,switchWindow:0};this.reorderingContext={item:null,initialY:null,identifier:null,moveUp:null,moveDown:null,};on(this.els.container,'click',this);on(window,'resize',this);if(!this.els.list)this.els.list=document.createElement('ul');if(!this.els.itemContainer)this.els.itemContainer=this.els.list;this.rendered=schedule.mutation(this.setupPhase1.bind(this));this.complete=this.rendered.then(this.setupPhase2.bind(this));}
FastList.prototype={PRERENDER_MULTIPLIER:3.5,setupPhase1:function(){debug('setup phase 1');var fragment=document.createDocumentFragment();var container=this.els.container;this.updateContainerGeometry();container.style.overflowX='hidden';container.style.overflowY='scroll';this.updateListHeight();if(!this.els.list.parentNode)container.appendChild(this.els.list);if(this.source.initialScrollTop){container.scrollTop=this.source.initialScrollTop;this.geometry.topPosition=container.scrollTop;}
this.updateSections({fragment:fragment});this.render({fragment:fragment,criticalOnly:true,skipDetail:true});this.els.itemContainer.appendChild(fragment);this.handleScroll=this.handleScroll.bind(this);schedule.attachDirect(this.els.container,'scroll',this.handleScroll);},setupPhase2:function(){return new Promise(function(resolve){setTimeout(function(){debug('setup phase 2');var fragment=document.createDocumentFragment();this.render({fragment:fragment});this.els.itemContainer.appendChild(fragment);resolve();}.bind(this),360);}.bind(this));},updateContainerGeometry:function(){var geo=this.geometry;var viewportHeight=this.getViewportHeight();var itemPerScreen=viewportHeight/geo.itemHeight;geo.viewportHeight=viewportHeight;geo.maxItemCount=Math.floor(itemPerScreen*this.PRERENDER_MULTIPLIER);geo.switchWindow=Math.floor(itemPerScreen/2);debug('maxItemCount: '+geo.maxItemCount);},getViewportHeight:function(){return this.source.getViewportHeight?this.source.getViewportHeight():this.els.container.offsetHeight;},processScrollPosition:function(instant){var position=this.els.container.scrollTop;var geo=this.geometry;if(!geo.hasScrolled){geo.topPosition=position;geo.hasScrolled=true;}
var viewportHeight=geo.viewportHeight;var previousTop=geo.topPosition;var delta=position-previousTop;geo.forward=isForward(geo.forward,delta);geo.topPosition=position;var onTop=geo.topPosition===0;var topReached=onTop&&previousTop!==0;var fullHeight=this.source.getFullHeight();var maxScrollTop=fullHeight-viewportHeight;var atBottom=geo.topPosition===maxScrollTop;if(topReached)this.emit('top-reached');if(onTop||atBottom||instant){geo.busy=false;geo.idle=true;return;}
var moved=Math.abs(delta);geo.busy=isBusy(geo.busy,moved,viewportHeight);geo.idle=isIdle(geo.idle,moved,viewportHeight);},render:function(options){debug('render');options=options||{};var changedIndex=options.changedIndex;var criticalOnly=options.criticalOnly;var skipDetail=options.skipDetail;var fragment=options.fragment;var reload=options.reload;var itemContainer=fragment||this.els.itemContainer;var itemsInDOM=this.els.itemsInDOM;var items=this.els.items;var source=this.source;var geo=this.geometry;var indices=computeIndices(this.source,this.geometry);var fullLength=source.getFullLength();var criticalStart=indices.cStart;var criticalEnd=indices.cEnd;var startIndex=indices.start;var endIndex=indices.end;var self=this;if(criticalOnly){startIndex=criticalStart;endIndex=criticalEnd;}
var recyclableItems=recycle(items,criticalStart,criticalEnd,geo.forward?endIndex:startIndex);if(fullLength){if(geo.forward){for(var i=startIndex;i<=endIndex;++i)renderItem(i);}else{for(var j=endIndex;j>=startIndex;--j)renderItem(j);}}
if(reload)cleanUpPrerenderedItems(items,source);function findItemFor(index){var item;if(recyclableItems.length>0){var recycleIndex=recyclableItems.pop();item=items[recycleIndex];delete items[recycleIndex];debug('found node to recycle',recycleIndex,recyclableItems);}else if(itemsInDOM.length<geo.maxItemCount){item=self.createItem();itemContainer.appendChild(item);itemsInDOM.push(item);}else{console.warn('missing a cell');return;}
items[index]=item;return item;}
function renderItem(i){var item=items[i];if(!item){item=findItemFor(i);self.unpopulateItemDetail(item);tryToPopulate(item,i,source,true);item.classList.toggle('new',i===changedIndex);}else if(reload){self.unpopulateItemDetail(item);source.populateItem(item,i);item.dataset.populated=true;if(item.style.display==='none'){item.style.removeProperty('display');}}
var section=source.getSectionFor(i);placeItem(item,i,section,geo,source,reload);if(skipDetail||!source.populateItemDetail)return;if(!geo.idle)return;if(item.dataset.detailPopulated==='true')return;var result=source.populateItemDetail(item,i);if(result!==false)item.dataset.detailPopulated=true;}
debugViewport(items,geo.forward,criticalStart,criticalEnd,startIndex,endIndex);},unpopulateItemDetail:function(item){var shouldUnpopulate=this.source.unpopulateItemDetail&&item.dataset.detailPopulated==='true';if(shouldUnpopulate){this.source.unpopulateItemDetail(item);item.dataset.detailPopulated=false;}},createItem:function(){var el=this.source.createItem();el.style.position='absolute';el.style.left=el.style.top=0;el.style.overflow='hidden';return el;},createSection:function(name){var el=this.source.createSection(name);el.classList.add('fl-section');return el;},reloadData:function(){return schedule.mutation(function(){this.updateSections();this.updateListHeight();this.render({reload:true});}.bind(this));},updateSections:function(options){debug('update sections');var fragment=(options&&options.fragment);var nodes=this.els.itemContainer.querySelectorAll('.fl-section');var items=fragment||document.createDocumentFragment();var source=this.source;for(var i=0;i<nodes.length;i++){var toRemove=nodes[i];toRemove.remove();}
var headerHeight=source.getSectionHeaderHeight();var sections=this.source.getSections();for(var j=0;j<sections.length;j++){var height=source.getFullSectionHeight(sections[j]);var el=this.createSection(sections[j]);el.style.height=headerHeight+height+'px';this.source.populateSection(el,sections[j],j);items.appendChild(el);}
if(!fragment)this.els.itemContainer.appendChild(items);},handleScroll:function(evt){clearTimeout(this._scrollStopTimeout);this.processScrollPosition();if(this.geometry.busy)debug('[x] ---------- faaaaassssstttt');else this.render();if(this.geometry.idle)return;var self=this;this._scrollStopTimeout=setTimeout(function(){self.processScrollPosition(true);self.render();},200);},updateListHeight:function(){this.els.list.style.height=this.source.getFullHeight()+'px';debug('updated list height',this.els.list.style.height);},get scrollTop(){return this.geometry.topPosition;},scrollInstantly:function(position){debug('scroll instantly',position);this.els.container.scrollTop=position;this.processScrollPosition(true);this.render();},insertedAtIndex:function(index){debug('inserted at index',index);if(index!==0){return;}
if(this.geometry.topPosition>this.geometry.itemHeight||this.editing){this._insertOnTop(true);return;}
var domItems=this.els.itemsInDOM;var list=this.els.itemContainer;list.classList.add('reordering');pushDown(domItems,this.geometry).then(this._insertOnTop.bind(this,false)).then(cleanInlineStyles.bind(null,domItems)).then(reveal.bind(null,list)).then(function(){list.classList.remove('reordering');});},_insertOnTop:function(keepScrollPosition){debug('insert on top',keepScrollPosition);return schedule.mutation((function(){this.els.items.unshift(null);delete this.els.items[0];this.updateSections();if(keepScrollPosition){var scrollTop=this.els.container.scrollTop;this.scrollInstantly(scrollTop+this.geometry.itemHeight);this.els.container.dispatchEvent(new CustomEvent('hidden-new-content'));}else{this.render({changedIndex:0});}
this.updateListHeight();}).bind(this));},handleEvent:function(evt){switch(evt.type){case'resize':this.updateContainerGeometry();break;case'click':if(this.editing){break;}
var li=evt.target;var index=this.els.items.indexOf(li);this.els.itemContainer.dispatchEvent(new CustomEvent('item-selected',{bubbles:true,detail:{index:index,clickEvt:evt,}}));break;}},plugin:function(fn){fn(this);return this;},emit:function(name,detail){var e=new CustomEvent(name,{bubbles:false,detail:detail});this.els.container.dispatchEvent(e);},destroy:function(){this.els.itemContainer.innerHTML='';schedule.detachDirect(this.els.container,'scroll',this.handleScroll);}};function debugViewport(items,forward,cStart,cEnd,start,end){if(!debug.name){return;}
var str='['+(forward?'v':'^')+']';for(var i=0;i<items.length;i++){if(i==start)str+='|';if(i==cStart)str+='[';if(items[i])str+='x';else str+='-';if(i==cEnd)str+=']';if(i==end)str+='|';}
debug(str);}
function computeIndices(source,geometry){debug('compute indices',geometry.topPosition);var criticalStart=source.getIndexAtPosition(geometry.topPosition);var criticalEnd=source.getIndexAtPosition(geometry.topPosition+
geometry.viewportHeight);var canPrerender=geometry.maxItemCount-
(criticalEnd-criticalStart)-1;var before=geometry.switchWindow;var after=canPrerender-before;var fullLength=source.getFullLength();var lastIndex=fullLength&&fullLength-1;var startIndex;var endIndex;var extra;if(geometry.forward){startIndex=criticalStart-before;endIndex=criticalEnd+after;}else{startIndex=criticalStart-after;endIndex=criticalEnd+before;}
if(startIndex<0){extra=-startIndex;startIndex=0;endIndex=Math.min(lastIndex,endIndex+extra);}
if(endIndex>lastIndex){extra=endIndex-lastIndex;endIndex=lastIndex;startIndex=Math.max(0,startIndex-extra);}
return{cStart:criticalStart,cEnd:criticalEnd,start:startIndex,end:endIndex};}
function recycle(items,start,end,action){debug('recycle',start,end,action);var recyclableItems=[];for(var i in items){if((i<start)||(i>end))recyclableItems.push(i);}
recyclableItems.sort(function(a,b){return Math.abs(a-action)-Math.abs(b-action);});return recyclableItems;}
function cleanUpPrerenderedItems(items,source){var fullLength=source.getFullLength();for(var i in items){if(i>=fullLength){var item=items[i];item.dataset.populated=false;item.style.display='none';}}}
function tryToPopulate(item,index,source,first){if(item.dataset.index!=index&&!first)return;var populateResult=source.populateItem(item,index);if(populateResult instanceof Promise){item.dataset.populated=false;populateResult.then(tryToPopulate.bind(null,item,index,source));return;}
if(first){item.dataset.populated=true;return;}
if(source.populateItemDetail&&item.dataset.detailPopulated!=='true'){source.populateItemDetail(item,index);item.dataset.detailPopulated=true;}
debug('revealing populated item');item.style.transition='opacity 0.2s linear';schedule.transition(function(){item.dataset.populated=true;},item,'transitionend').then(function(){debug('populated item revealed');item.style.transition='';});}
function placeItem(item,index,section,geometry,source,reload){if(item.dataset.index==index&&!reload){return;}
item.dataset.position=source.getPositionForIndex(index);item.dataset.index=index;item.dataset.section=section;var tweakedBy=item.dataset.tweakDelta;if(tweakedBy)tweakTransform(item,tweakedBy);else resetTransform(item);}
function resetTransform(item){var position=item.dataset.position;var transform='translateY('+position+'px)';style(item,'webkitTransform',transform);style(item,'transform',transform);}
function tweakTransform(item,delta){debug('tweak transform',item,delta);var position=~~item.dataset.position+~~delta;var transform='translateY('+position+'px)';style(item,'webkitTransform',transform);style(item,'transform',transform);item.dataset.tweakDelta=delta;}
function cleanInlineStyles(domItems){return schedule.mutation(function(){for(var i=0;i<domItems.length;i++){var item=domItems[i];item.style.transition='';item.style.webkitTransition='';resetTransform(item);}
domItems[0]&&domItems[0].scrollTop;});}
function pushDown(domItems,geometry){if(!domItems.length)return Promise.resolve();return schedule.transition(function(){for(var i=0;i<domItems.length;i++){var item=domItems[i];item.style.transition='transform 0.15s ease-in';item.style.webkitTransition='-webkit-transform 0.15s ease-in';tweakTransform(item,geometry.itemHeight);}},domItems[0],'transitionend');}
function reveal(list){var newEl=list.querySelector('li.new');return schedule.transition(function(){newEl.style.transition='opacity 0.25s ease-out';newEl.style.webkitTransition='opacity 0.25s ease-out';setTimeout(function(){newEl.classList.remove('new');});},newEl,'transitionend').then(function(){newEl.style.transition='';newEl.style.webkitTransition='';});}
function isBusy(wasBusy,moved,viewportHeight){if(!wasBusy&&moved>viewportHeight*2)return true;else if(wasBusy&&moved&&moved<viewportHeight/2)return false;else return wasBusy;}
function isIdle(wasIdle,moved,viewportHeight){if(!wasIdle&&moved&&moved<viewportHeight/16)return true;else if(wasIdle&&moved&&moved>viewportHeight/4)return false;else return wasIdle;}
function isForward(wasForward,delta){if(!delta)return wasForward;else return delta>0;}
function schedulerShim(){var raf=window.requestAnimationFrame;return{mutation:function(block){return Promise.resolve().then(block);},transition:function(block,el,event,timeout){block();return after(el,event,timeout||500);},feedback:function(block,el,event,timeout){block();return after(el,event,timeout||500);},attachDirect:function(el,event,fn){fn._raffed=function(e){raf(function(){fn(e);});};on(el,event,fn._raffed);},detachDirect:function(el,event,fn){off(el,event,fn._raffed);}};function after(target,event,timeout){return new Promise(function(resolve){var timer=timeout&&setTimeout(cb,timeout);on(target,event,cb);function cb(){off(target,event,cb);clearTimeout(timer);resolve();}});}}
function on(el,name,fn){el.addEventListener(name,fn);}
function off(el,name,fn){el.removeEventListener(name,fn);}
function style(el,key,value){if(el.style[key]!==value)el.style[key]=value;}});})((typeof define)[0]=='f'&&define.amd?define:(function(n,n2,w){return(typeof module)[0]=='o'?function(c){c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){w[n];},m.exports,m);w[n]=w[n2]=m.exports;};})('FastList','fast-list',this));