| 'use strict'; | 
|   | 
| var callable, byObserver; | 
|   | 
| callable = function (fn) { | 
|     if (typeof fn !== 'function') throw new TypeError(fn + " is not a function"); | 
|     return fn; | 
| }; | 
|   | 
| byObserver = function (Observer) { | 
|     var node = document.createTextNode(''), queue, currentQueue, i = 0; | 
|     new Observer(function () { | 
|         var callback; | 
|         if (!queue) { | 
|             if (!currentQueue) return; | 
|             queue = currentQueue; | 
|         } else if (currentQueue) { | 
|             queue = currentQueue.concat(queue); | 
|         } | 
|         currentQueue = queue; | 
|         queue = null; | 
|         if (typeof currentQueue === 'function') { | 
|             callback = currentQueue; | 
|             currentQueue = null; | 
|             callback(); | 
|             return; | 
|         } | 
|         node.data = (i = ++i % 2); // Invoke other batch, to handle leftover callbacks in case of crash | 
|         while (currentQueue) { | 
|             callback = currentQueue.shift(); | 
|             if (!currentQueue.length) currentQueue = null; | 
|             callback(); | 
|         } | 
|     }).observe(node, { characterData: true }); | 
|     return function (fn) { | 
|         callable(fn); | 
|         if (queue) { | 
|             if (typeof queue === 'function') queue = [queue, fn]; | 
|             else queue.push(fn); | 
|             return; | 
|         } | 
|         queue = fn; | 
|         node.data = (i = ++i % 2); | 
|     }; | 
| }; | 
|   | 
| module.exports = (function () { | 
|     // Node.js | 
|     if ((typeof process === 'object') && process && (typeof process.nextTick === 'function')) { | 
|         return process.nextTick; | 
|     } | 
|   | 
|     // MutationObserver | 
|     if ((typeof document === 'object') && document) { | 
|         if (typeof MutationObserver === 'function') return byObserver(MutationObserver); | 
|         if (typeof WebKitMutationObserver === 'function') return byObserver(WebKitMutationObserver); | 
|     } | 
|   | 
|     // W3C Draft | 
|     // http://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html | 
|     if (typeof setImmediate === 'function') { | 
|         return function (cb) { setImmediate(callable(cb)); }; | 
|     } | 
|   | 
|     // Wide available standard | 
|     if ((typeof setTimeout === 'function') || (typeof setTimeout === 'object')) { | 
|         return function (cb) { setTimeout(callable(cb), 0); }; | 
|     } | 
|   | 
|     return null; | 
| }()); |