gif.js

gif.js from https://github.com/jnordberg/gif.js

Versión del día 2/7/2014. Echa un vistazo a la versión más reciente.

Este script no debería instalarse directamente. Es una biblioteca que utilizan otros scripts mediante la meta-directiva de inclusión // @require https://update.greasyfork.org/scripts/2963/8458/gifjs.js

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name        gif.js
// @namespace   http://mfish.twbbs.org/
// @version     0.1.6
// @grant       none
// ==/UserScript==

/**
 * 
 * I didn't create this, just modified it to allow it running in userscript.
 * Auther : https://github.com/jnordberg/gif.js
 *
 */

var GIF_worker_URL = (function () {
    var workerScript = "(function(b){function a(b,d){if({}.hasOwnProperty.call(a.cache,b))return a.cache[b];var e=a.resolve(b);if(!e)throw new Error('Failed to resolve module '+b);var c={id:b,require:a,filename:b,exports:{},loaded:!1,parent:d,children:[]};d&&d.children.push(c);var f=b.slice(0,b.lastIndexOf('/')+1);return a.cache[b]=c.exports,e.call(c.exports,c,c.exports,f,b),c.loaded=!0,a.cache[b]=c.exports}a.modules={},a.cache={},a.resolve=function(b){return{}.hasOwnProperty.call(a.modules,b)?a.modules[b]:void 0},a.define=function(b,c){a.modules[b]=c},a.define('/gif.worker.coffee',function(d,e,f,g){var b,c;b=a('/GIFEncoder.js',d),c=function(a){var c,e,d,f;return c=new b(a.width,a.height),a.index===0?c.writeHeader():c.firstFrame=!1,c.setTransparent(a.transparent),c.setRepeat(a.repeat),c.setDelay(a.delay),c.setQuality(a.quality),c.setDither(a.dither),c.setGlobalPalette(a.globalPalette),c.addFrame(a.data),a.last&&c.finish(),a.globalPalette===!0&&(a.globalPalette=c.getGlobalPalette()),d=c.stream(),a.data=d.pages,a.cursor=d.cursor,a.pageSize=d.constructor.pageSize,a.canTransfer?(f=function(c){for(var b=0,d=a.data.length;b<d;++b)e=a.data[b],c.push(e.buffer);return c}.call(this,[]),self.postMessage(a,f)):self.postMessage(a)},self.onmessage=function(a){return c(a.data)}}),a.define('/GIFEncoder.js',function(e,h,i,j){function c(){this.page=-1,this.pages=[],this.newPage()}function b(a,b){this.width=~~a,this.height=~~b,this.transparent=null,this.transIndex=0,this.repeat=-1,this.delay=0,this.image=null,this.pixels=null,this.indexedPixels=null,this.colorDepth=null,this.colorTab=null,this.usedEntry=new Array,this.palSize=7,this.dispose=-1,this.firstFrame=!0,this.sample=10,this.dither=!1,this.globalPalette=!1,this.out=new c}var f=a('/TypedNeuQuant.js',e),g=a('/LZWEncoder.js',e);c.pageSize=4096,c.charMap={};for(var d=0;d<256;d++)c.charMap[d]=String.fromCharCode(d);c.prototype.newPage=function(){this.pages[++this.page]=new Uint8Array(c.pageSize),this.cursor=0},c.prototype.getData=function(){var d='';for(var a=0;a<this.pages.length;a++)for(var b=0;b<c.pageSize;b++)d+=c.charMap[this.pages[a][b]];return d},c.prototype.writeByte=function(a){this.cursor>=c.pageSize&&this.newPage(),this.pages[this.page][this.cursor++]=a},c.prototype.writeUTFBytes=function(b){for(var c=b.length,a=0;a<c;a++)this.writeByte(b.charCodeAt(a))},c.prototype.writeBytes=function(b,d,e){for(var c=e||b.length,a=d||0;a<c;a++)this.writeByte(b[a])},b.prototype.setDelay=function(a){this.delay=Math.round(a/10)},b.prototype.setFrameRate=function(a){this.delay=Math.round(100/a)},b.prototype.setDispose=function(a){a>=0&&(this.dispose=a)},b.prototype.setRepeat=function(a){this.repeat=a},b.prototype.setTransparent=function(a){this.transparent=a},b.prototype.addFrame=function(a){this.image=a,this.colorTab=this.globalPalette.slice?this.globalPalette:null,this.getImagePixels(),this.analyzePixels(),this.globalPalette===!0&&(this.globalPalette=this.colorTab),this.firstFrame&&(this.writeLSD(),this.writePalette(),this.repeat>=0&&this.writeNetscapeExt()),this.writeGraphicCtrlExt(),this.writeImageDesc(),this.firstFrame||this.globalPalette||this.writePalette(),this.writePixels(),this.firstFrame=!1},b.prototype.finish=function(){this.out.writeByte(59)},b.prototype.setQuality=function(a){a<1&&(a=1),this.sample=a},b.prototype.setDither=function(a){a===!0&&(a='FloydSteinberg'),this.dither=a},b.prototype.setGlobalPalette=function(a){this.globalPalette=a},b.prototype.getGlobalPalette=function(){return this.globalPalette.slice&&this.globalPalette.slice(0)||this.globalPalette},b.prototype.writeHeader=function(){this.out.writeUTFBytes('GIF89a')},b.prototype.analyzePixels=function(){if(!this.colorTab){var a=new f(this.pixels,this.sample);a.buildColormap(),this.colorTab=a.getColormap()}this.dither?this.ditherPixels(this.dither.replace('-serpentine',''),this.dither.match(/-serpentine/)!==null):this.indexPixels(),this.pixels=null,this.colorDepth=8,this.palSize=7,this.transparent!==null&&(this.transIndex=this.findClosest(this.transparent,!0))},b.prototype.indexPixels=function(e){var c=this.pixels.length/3;this.indexedPixels=new Uint8Array(c);var a=0;for(var b=0;b<c;b++){var d=this.findClosestRGB(this.pixels[a++]&255,this.pixels[a++]&255,this.pixels[a++]&255);this.usedEntry[d]=!0,this.indexedPixels[b]=d}},b.prototype.ditherPixels=function(l,A){var o={FalseFloydSteinberg:[[.375,1,0],[.375,0,1],[.25,1,1]],FloydSteinberg:[[.4375,1,0],[.1875,-1,1],[.3125,0,1],[.0625,1,1]],Stucki:[[.19047619047619047,1,0],[.09523809523809523,2,0],[.047619047619047616,-2,1],[.09523809523809523,-1,1],[.19047619047619047,0,1],[.09523809523809523,1,1],[.047619047619047616,2,1],[.023809523809523808,-2,2],[.047619047619047616,-1,2],[.09523809523809523,0,2],[.047619047619047616,1,2],[.023809523809523808,2,2]],Atkinson:[[.125,1,0],[.125,2,0],[.125,-1,1],[.125,0,1],[.125,1,1],[.125,0,2]]};if(!(l&&o[l]))throw'Unknown dithering kernel: '+l;var f=o[l],i=0,r=this.height,e=this.width,b=this.pixels,c=A?-1:1;this.indexedPixels=new Uint8Array(this.pixels.length/3);for(var h=0;h<r;h++){A&&(c*=-1);for(var g=c==1?0:e-1,z=c==1?e:0;g!==z;g+=c){i=h*e+g;var a=i*3,n=b[a],p=b[a+1],q=b[a+2];a=this.findClosestRGB(n,p,q),this.usedEntry[a]=!0,this.indexedPixels[i]=a,a*=3;var x=this.colorTab[a],s=this.colorTab[a+1],t=this.colorTab[a+2],u=n-x,v=p-s,w=q-t;for(var d=c==1?0:f.length-1,y=c==1?f.length:0;d!==y;d+=c){var k=f[d][1],j=f[d][2];if(k+g>=0&&k+g<e&&j+h>=0&&j+h<r){var m=f[d][0];a=i+k+j*e,a*=3,b[a]=Math.max(0,Math.min(255,b[a]+u*m)),b[a+1]=Math.max(0,Math.min(255,b[a+1]+v*m)),b[a+2]=Math.max(0,Math.min(255,b[a+2]+w*m))}}}}},b.prototype.findClosest=function(a,b){return this.findClosestRGB((a&16711680)>>16,(a&65280)>>8,a&255,b)},b.prototype.findClosestRGB=function(j,l,k,n){if(this.colorTab===null)return-1;var m=k|l<<8|j<<16,g=0,b=16777216,i=this.colorTab.length;for(var a=0;a<i;){var f=j-(this.colorTab[a++]&255),e=l-(this.colorTab[a++]&255),d=k-(this.colorTab[a]&255),c=f*f+e*e+d*d,h=parseInt(a/3);(!n||this.usedEntry[h])&&c<b&&(b=c,g=h),a++}return g},b.prototype.getImagePixels=function(){var a=this.width,g=this.height;this.pixels=new Uint8Array(a*g*3);var b=this.image,c=0;for(var d=0;d<g;d++)for(var e=0;e<a;e++){var f=d*a*4+e*4;this.pixels[c++]=b[f],this.pixels[c++]=b[f+1],this.pixels[c++]=b[f+2]}},b.prototype.writeGraphicCtrlExt=function(){this.out.writeByte(33),this.out.writeByte(249),this.out.writeByte(4);var b,a;this.transparent===null?(b=0,a=0):(b=1,a=2),this.dispose>=0&&(a=dispose&7),a<<=2,this.out.writeByte(0|a|0|b),this.writeShort(this.delay),this.out.writeByte(this.transIndex),this.out.writeByte(0)},b.prototype.writeImageDesc=function(){this.out.writeByte(44),this.writeShort(0),this.writeShort(0),this.writeShort(this.width),this.writeShort(this.height),this.firstFrame||this.globalPalette?this.out.writeByte(0):this.out.writeByte(128|this.palSize)},b.prototype.writeLSD=function(){this.writeShort(this.width),this.writeShort(this.height),this.out.writeByte(240|this.palSize),this.out.writeByte(0),this.out.writeByte(0)},b.prototype.writeNetscapeExt=function(){this.out.writeByte(33),this.out.writeByte(255),this.out.writeByte(11),this.out.writeUTFBytes('NETSCAPE2.0'),this.out.writeByte(3),this.out.writeByte(1),this.writeShort(this.repeat),this.out.writeByte(0)},b.prototype.writePalette=function(){this.out.writeBytes(this.colorTab);var b=768-this.colorTab.length;for(var a=0;a<b;a++)this.out.writeByte(0)},b.prototype.writeShort=function(a){this.out.writeByte(a&255),this.out.writeByte(a>>8&255)},b.prototype.writePixels=function(){var a=new g(this.width,this.height,this.indexedPixels,this.colorDepth);a.encode(this.out)},b.prototype.stream=function(){return this.out},e.exports=b}),a.define('/LZWEncoder.js',function(e,g,h,i){function f(y,D,C,B){function w(a,b){r[f++]=a,f>=254&&t(b)}function x(b){u(a),k=i+2,j=!0,l(i,b)}function u(b){for(var a=0;a<b;++a)h[a]=-1}function A(z,r){var g,t,d,e,y,w,s;for(q=z,j=!1,n_bits=q,m=p(n_bits),i=1<<z-1,o=i+1,k=i+2,f=0,e=v(),s=0,g=a;g<65536;g*=2)++s;s=8-s,w=a,u(w),l(i,r);a:while((t=v())!=c){if(g=(t<<b)+e,d=t<<s^e,h[d]===g){e=n[d];continue}if(h[d]>=0){y=w-d,d===0&&(y=1);do if((d-=y)<0&&(d+=w),h[d]===g){e=n[d];continue a}while(h[d]>=0)}l(e,r),e=t,k<1<<b?(n[d]=k++,h[d]=g):x(r)}l(e,r),l(o,r)}function z(a){a.writeByte(s),remaining=y*D,curPixel=0,A(s+1,a),a.writeByte(0)}function t(a){f>0&&(a.writeByte(f),a.writeBytes(r,0,f),f=0)}function p(a){return(1<<a)-1}function v(){if(remaining===0)return c;--remaining;var a=C[curPixel++];return a&255}function l(a,c){g&=d[e],e>0?g|=a<<e:g=a,e+=n_bits;while(e>=8)w(g&255,c),g>>=8,e-=8;if((k>m||j)&&(j?(m=p(n_bits=q),j=!1):(++n_bits,n_bits==b?m=1<<b:m=p(n_bits))),a==o){while(e>0)w(g&255,c),g>>=8,e-=8;t(c)}}var s=Math.max(2,B),r=new Uint8Array(256),h=new Int32Array(a),n=new Int32Array(a),g,e=0,f,k=0,m,j=!1,q,i,o;this.encode=z}var c=-1,b=12,a=5003,d=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535];e.exports=f}),a.define('/TypedNeuQuant.js',function(A,F,E,D){function C(A,B){function I(){o=[],q=new Int32Array(256),t=new Int32Array(a),y=new Int32Array(a),z=new Int32Array(a>>3);var c,d;for(c=0;c<a;c++)d=(c<<b+8)/a,o[c]=new Float64Array([d,d,d,0]),y[c]=e/a,t[c]=0}function J(){for(var c=0;c<a;c++)o[c][0]>>=b,o[c][1]>>=b,o[c][2]>>=b,o[c][3]=c}function K(b,a,c,e,f){o[a][0]-=b*(o[a][0]-c)/d,o[a][1]-=b*(o[a][1]-e)/d,o[a][2]-=b*(o[a][2]-f)/d}function L(j,e,n,l,k){var h=Math.abs(e-j),i=Math.min(e+j,a),g=e+1,f=e-1,m=1,b,d;while(g<i||f>h)d=z[m++],g<i&&(b=o[g++],b[0]-=d*(b[0]-n)/c,b[1]-=d*(b[1]-l)/c,b[2]-=d*(b[2]-k)/c),f>h&&(b=o[f--],b[0]-=d*(b[0]-n)/c,b[1]-=d*(b[1]-l)/c,b[2]-=d*(b[2]-k)/c)}function C(p,s,q){var h=2147483647,k=h,d=-1,m=d,c,j,e,n,l;for(c=0;c<a;c++)j=o[c],e=Math.abs(j[0]-p)+Math.abs(j[1]-s)+Math.abs(j[2]-q),e<h&&(h=e,d=c),n=e-(t[c]>>i-b),n<k&&(k=n,m=c),l=y[c]>>g,y[c]-=l,t[c]+=l<<f;return y[d]+=x,t[d]-=r,m}function D(){var d,b,e,c,h,g,f=0,i=0;for(d=0;d<a;d++){for(e=o[d],h=d,g=e[1],b=d+1;b<a;b++)c=o[b],c[1]<g&&(h=b,g=c[1]);if(c=o[h],d!=h&&(b=c[0],c[0]=e[0],e[0]=b,b=c[1],c[1]=e[1],e[1]=b,b=c[2],c[2]=e[2],e[2]=b,b=c[3],c[3]=e[3],e[3]=b),g!=f){for(q[f]=i+d>>1,b=f+1;b<g;b++)q[b]=d;f=g,i=d}}for(q[f]=i+n>>1,b=f+1;b<256;b++)q[b]=n}function E(j,i,k){var b,d,c,e=1e3,h=-1,f=q[i],g=f-1;while(f<a||g>=0)f<a&&(d=o[f],c=d[1]-i,c>=e?f=a:(f++,c<0&&(c=-c),b=d[0]-j,b<0&&(b=-b),c+=b,c<e&&(b=d[2]-k,b<0&&(b=-b),c+=b,c<e&&(e=c,h=d[3])))),g>=0&&(d=o[g],c=i-d[1],c>=e?g=-1:(g--,c<0&&(c=-c),b=d[0]-j,b<0&&(b=-b),c+=b,c<e&&(b=d[2]-k,b<0&&(b=-b),c+=b,c<e&&(e=c,h=d[3]))));return h}function F(){var c,f=A.length,D=30+(B-1)/3,y=f/(3*B),q=~~(y/w),n=d,o=u,a=o>>h;for(a<=1&&(a=0),c=0;c<a;c++)z[c]=n*((a*a-c*c)*m/(a*a));var i;f<s?(B=1,i=3):f%l!==0?i=3*l:f%k!==0?i=3*k:f%p!==0?i=3*p:i=3*j;var r,t,x,e,g=0;c=0;while(c<y)if(r=(A[g]&255)<<b,t=(A[g+1]&255)<<b,x=(A[g+2]&255)<<b,e=C(r,t,x),K(n,e,r,t,x),a!==0&&L(a,e,r,t,x),g+=i,g>=f&&(g-=f),c++,q===0&&(q=1),c%q===0)for(n-=n/D,o-=o/v,a=o>>h,a<=1&&(a=0),e=0;e<a;e++)z[e]=n*((a*a-e*e)*m/(a*a))}function G(){I(),F(),J(),D()}function H(){var b=[],g=[];for(var c=0;c<a;c++)g[o[c][3]]=c;var d=0;for(var e=0;e<a;e++){var f=g[e];b[d++]=o[f][0],b[d++]=o[f][1],b[d++]=o[f][2]}return b}var o,q,t,y,z;this.buildColormap=G,this.getColormap=H,this.lookupRGB=E}var w=100,a=256,n=a-1,b=4,i=16,e=1<<i,f=10,B=1<<f,g=10,x=e>>g,r=e<<f-g,z=a>>3,h=6,t=1<<h,u=z*t,v=30,o=10,d=1<<o,q=8,m=1<<q,y=o+q,c=1<<y,l=499,k=491,p=487,j=503,s=3*j;A.exports=C}),a('/gif.worker.coffee')}.call(this,this))";
    function getUrl (blob) {
        return URL.createObjectURL(blob);
    }
    function createBlob (text, MIME) {
        var aFileParts = [text];
        var oMyBlob = new Blob(aFileParts, {type : MIME});
        return oMyBlob;
    }
    var workerURL = getUrl(createBlob(workerScript, 'application/x-javascript'));
    return workerURL;
}())
// Generated by CommonJS Everywhere 0.9.7
(function (global) {
  function require(file, parentModule) {
    if ({}.hasOwnProperty.call(require.cache, file))
      return require.cache[file];
    var resolved = require.resolve(file);
    if (!resolved)
      throw new Error('Failed to resolve module ' + file);
    var module$ = {
        id: file,
        require: require,
        filename: file,
        exports: {},
        loaded: false,
        parent: parentModule,
        children: []
      };
    if (parentModule)
      parentModule.children.push(module$);
    var dirname = file.slice(0, file.lastIndexOf('/') + 1);
    require.cache[file] = module$.exports;
    resolved.call(module$.exports, module$, module$.exports, dirname, file);
    module$.loaded = true;
    return require.cache[file] = module$.exports;
  }
  require.modules = {};
  require.cache = {};
  require.resolve = function (file) {
    return {}.hasOwnProperty.call(require.modules, file) ? require.modules[file] : void 0;
  };
  require.define = function (file, fn) {
    require.modules[file] = fn;
  };
  var process = function () {
      var cwd = '/';
      return {
        title: 'browser',
        version: 'v0.10.26',
        browser: true,
        env: {},
        argv: [],
        nextTick: global.setImmediate || function (fn) {
          setTimeout(fn, 0);
        },
        cwd: function () {
          return cwd;
        },
        chdir: function (dir) {
          cwd = dir;
        }
      };
    }();
  require.define('/gif.coffee', function (module, exports, __dirname, __filename) {
    var browser, defaults, EventEmitter, frameDefaults, GIF;
    EventEmitter = require('events', module).EventEmitter;
    browser = require('/browser.coffee', module);
    GIF = function (super$) {
      extends$(GIF, super$);
      defaults = {
        workerScript: 'gif.worker.js',
        workers: 2,
        repeat: 0,
        background: '#fff',
        quality: 10,
        width: null,
        height: null,
        transparent: null
      };
      frameDefaults = {
        delay: 500,
        copy: false
      };
      function GIF(options) {
        var key, value;
        this.running = false;
        this.options = {};
        this.frames = [];
        this.freeWorkers = [];
        this.activeWorkers = [];
        this.setOptions(options);
        for (key in defaults) {
          value = defaults[key];
          if (null != this.options[key])
            this.options[key];
          else
            this.options[key] = value;
        }
      }
      GIF.prototype.setOption = function (key, value) {
        this.options[key] = value;
        if (null != this._canvas && (key === 'width' || key === 'height'))
          return this._canvas[key] = value;
      };
      GIF.prototype.setOptions = function (options) {
        var key, value;
        return function (accum$) {
          for (key in options) {
            if (!isOwn$(options, key))
              continue;
            value = options[key];
            accum$.push(this.setOption(key, value));
          }
          return accum$;
        }.call(this, []);
      };
      GIF.prototype.addFrame = function (image, options) {
        var frame, key;
        if (null == options)
          options = {};
        frame = {};
        frame.transparent = this.options.transparent;
        for (key in frameDefaults) {
          frame[key] = options[key] || frameDefaults[key];
        }
        if (!(null != this.options.width))
          this.setOption('width', image.width);
        if (!(null != this.options.height))
          this.setOption('height', image.height);
        if ('undefined' !== typeof ImageData && null != ImageData && image instanceof ImageData) {
          frame.data = image.data;
        } else if ('undefined' !== typeof CanvasRenderingContext2D && null != CanvasRenderingContext2D && image instanceof CanvasRenderingContext2D || 'undefined' !== typeof WebGLRenderingContext && null != WebGLRenderingContext && image instanceof WebGLRenderingContext) {
          if (options.copy) {
            frame.data = this.getContextData(image);
          } else {
            frame.context = image;
          }
        } else if (null != image.childNodes) {
          if (options.copy) {
            frame.data = this.getImageData(image);
          } else {
            frame.image = image;
          }
        } else {
          throw new Error('Invalid image');
        }
        return this.frames.push(frame);
      };
      GIF.prototype.render = function () {
        var i, numWorkers;
        if (this.running)
          throw new Error('Already running');
        if (!(null != this.options.width) || !(null != this.options.height))
          throw new Error('Width and height must be set prior to rendering');
        this.running = true;
        this.nextFrame = 0;
        this.finishedFrames = 0;
        this.imageParts = function (accum$) {
          for (var cache$ = function () {
                var accum$1;
                accum$1 = [];
                for (var i$ = 0; 0 <= this.frames.length ? i$ < this.frames.length : i$ > this.frames.length; 0 <= this.frames.length ? ++i$ : --i$)
                  accum$1.push(i$);
                return accum$1;
              }.apply(this, arguments), i$ = 0, length$ = cache$.length; i$ < length$; ++i$) {
            i = cache$[i$];
            accum$.push(null);
          }
          return accum$;
        }.call(this, []);
        numWorkers = this.spawnWorkers();
        if (this.options.globalPalette === true) {
          this.renderNextFrame();
        } else {
          for (var cache$1 = function () {
                var accum$1;
                accum$1 = [];
                for (var i$1 = 0; 0 <= numWorkers ? i$1 < numWorkers : i$1 > numWorkers; 0 <= numWorkers ? ++i$1 : --i$1)
                  accum$1.push(i$1);
                return accum$1;
              }.apply(this, arguments), i$1 = 0, length$1 = cache$1.length; i$1 < length$1; ++i$1) {
            i = cache$1[i$1];
            this.renderNextFrame();
          }
        }
        this.emit('start');
        return this.emit('progress', 0);
      };
      GIF.prototype.abort = function () {
        var worker;
        while (true) {
          worker = this.activeWorkers.shift();
          if (!(null != worker))
            break;
          console.log('killing active worker');
          worker.terminate();
        }
        this.running = false;
        return this.emit('abort');
      };
      GIF.prototype.spawnWorkers = function () {
        var numWorkers;
        numWorkers = Math.min(this.options.workers, this.frames.length);
        (function () {
          var accum$;
          accum$ = [];
          for (var i$ = this.freeWorkers.length; this.freeWorkers.length <= numWorkers ? i$ < numWorkers : i$ > numWorkers; this.freeWorkers.length <= numWorkers ? ++i$ : --i$)
            accum$.push(i$);
          return accum$;
        }.apply(this, arguments).forEach(function (this$) {
          return function (i) {
            var worker;
            console.log('spawning worker ' + i);
            worker = new Worker(this$.options.workerScript);
            worker.onmessage = function (this$1) {
              return function (event) {
                this$1.activeWorkers.splice(this$1.activeWorkers.indexOf(worker), 1);
                this$1.freeWorkers.push(worker);
                return this$1.frameFinished(event.data);
              };
            }(this$);
            return this$.freeWorkers.push(worker);
          };
        }(this)));
        return numWorkers;
      };
      GIF.prototype.frameFinished = function (frame) {
        var i;
        console.log('frame ' + frame.index + ' finished - ' + this.activeWorkers.length + ' active');
        this.finishedFrames++;
        this.emit('progress', this.finishedFrames / this.frames.length);
        this.imageParts[frame.index] = frame;
        if (this.options.globalPalette === true) {
          this.options.globalPalette = frame.globalPalette;
          console.log('global palette analyzed');
          if (this.frames.length > 2)
            for (var cache$ = function () {
                  var accum$;
                  accum$ = [];
                  for (var i$ = 1; 1 <= this.freeWorkers.length ? i$ < this.freeWorkers.length : i$ > this.freeWorkers.length; 1 <= this.freeWorkers.length ? ++i$ : --i$)
                    accum$.push(i$);
                  return accum$;
                }.apply(this, arguments), i$ = 0, length$ = cache$.length; i$ < length$; ++i$) {
              i = cache$[i$];
              this.renderNextFrame();
            }
        }
        if (in$(null, this.imageParts)) {
          return this.renderNextFrame();
        } else {
          return this.finishRendering();
        }
      };
      GIF.prototype.finishRendering = function () {
        var data, frame, i, image, len, offset, page;
        len = 0;
        for (var i$ = 0, length$ = this.imageParts.length; i$ < length$; ++i$) {
          frame = this.imageParts[i$];
          len += (frame.data.length - 1) * frame.pageSize + frame.cursor;
        }
        len += frame.pageSize - frame.cursor;
        console.log('rendering finished - filesize ' + Math.round(len / 1e3) + 'kb');
        data = new Uint8Array(len);
        offset = 0;
        for (var i$1 = 0, length$1 = this.imageParts.length; i$1 < length$1; ++i$1) {
          frame = this.imageParts[i$1];
          for (var i$2 = 0, length$2 = frame.data.length; i$2 < length$2; ++i$2) {
            page = frame.data[i$2];
            i = i$2;
            data.set(page, offset);
            if (i === frame.data.length - 1) {
              offset += frame.cursor;
            } else {
              offset += frame.pageSize;
            }
          }
        }
        image = new Blob([data], { type: 'image/gif' });
        return this.emit('finished', image, data);
      };
      GIF.prototype.renderNextFrame = function () {
        var frame, task, worker;
        if (this.freeWorkers.length === 0)
          throw new Error('No free workers');
        if (this.nextFrame >= this.frames.length)
          return;
        frame = this.frames[this.nextFrame++];
        worker = this.freeWorkers.shift();
        task = this.getTask(frame);
        console.log('starting frame ' + (task.index + 1) + ' of ' + this.frames.length);
        this.activeWorkers.push(worker);
        return worker.postMessage(task);
      };
      GIF.prototype.getContextData = function (ctx) {
        return ctx.getImageData(0, 0, this.options.width, this.options.height).data;
      };
      GIF.prototype.getImageData = function (image) {
        var ctx;
        if (!(null != this._canvas)) {
          this._canvas = document.createElement('canvas');
          this._canvas.width = this.options.width;
          this._canvas.height = this.options.height;
        }
        ctx = this._canvas.getContext('2d');
        ctx.setFill = this.options.background;
        ctx.fillRect(0, 0, this.options.width, this.options.height);
        ctx.drawImage(image, 0, 0);
        return this.getContextData(ctx);
      };
      GIF.prototype.getTask = function (frame) {
        var index, task;
        index = this.frames.indexOf(frame);
        task = {
          index: index,
          last: index === this.frames.length - 1,
          delay: frame.delay,
          transparent: frame.transparent,
          width: this.options.width,
          height: this.options.height,
          quality: this.options.quality,
          dither: this.options.dither,
          globalPalette: this.options.globalPalette,
          repeat: this.options.repeat,
          canTransfer: browser.name === 'chrome'
        };
        if (null != frame.data) {
          task.data = frame.data;
        } else if (null != frame.context) {
          task.data = this.getContextData(frame.context);
        } else if (null != frame.image) {
          task.data = this.getImageData(frame.image);
        } else {
          throw new Error('Invalid frame');
        }
        return task;
      };
      return GIF;
    }(EventEmitter);
    module.exports = GIF;
    function isOwn$(o, p) {
      return {}.hasOwnProperty.call(o, p);
    }
    function in$(member, list) {
      for (var i = 0, length = list.length; i < length; ++i)
        if (i in list && list[i] === member)
          return true;
      return false;
    }
    function extends$(child, parent) {
      for (var key in parent)
        if (isOwn$(parent, key))
          child[key] = parent[key];
      function ctor() {
        this.constructor = child;
      }
      ctor.prototype = parent.prototype;
      child.prototype = new ctor;
      child.__super__ = parent.prototype;
      return child;
    }
  });
  require.define('/browser.coffee', function (module, exports, __dirname, __filename) {
    var browser, mode, platform, ua, UA;
    ua = navigator.userAgent.toLowerCase();
    platform = navigator.platform.toLowerCase();
    UA = ua.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/) || [
      null,
      'unknown',
      0
    ];
    mode = UA[1] === 'ie' && document.documentMode;
    browser = {
      name: UA[1] === 'version' ? UA[3] : UA[1],
      version: mode || parseFloat(UA[1] === 'opera' && UA[4] ? UA[4] : UA[2]),
      platform: { name: ua.match(/ip(?:ad|od|hone)/) ? 'ios' : (ua.match(/(?:webos|android)/) || platform.match(/mac|win|linux/) || ['other'])[0] }
    };
    browser[browser.name] = true;
    browser[browser.name + parseInt(browser.version, 10)] = true;
    browser.platform[browser.platform.name] = true;
    module.exports = browser;
    function isOwn$(o, p) {
      return {}.hasOwnProperty.call(o, p);
    }
    function in$(member, list) {
      for (var i = 0, length = list.length; i < length; ++i)
        if (i in list && list[i] === member)
          return true;
      return false;
    }
    function extends$(child, parent) {
      for (var key in parent)
        if (isOwn$(parent, key))
          child[key] = parent[key];
      function ctor() {
        this.constructor = child;
      }
      ctor.prototype = parent.prototype;
      child.prototype = new ctor;
      child.__super__ = parent.prototype;
      return child;
    }
  });
  require.define('events', function (module, exports, __dirname, __filename) {
    if (!process.EventEmitter)
      process.EventEmitter = function () {
      };
    var EventEmitter = exports.EventEmitter = process.EventEmitter;
    var isArray = typeof Array.isArray === 'function' ? Array.isArray : function (xs) {
        return Object.prototype.toString.call(xs) === '[object Array]';
      };
    var defaultMaxListeners = 10;
    EventEmitter.prototype.setMaxListeners = function (n) {
      if (!this._events)
        this._events = {};
      this._events.maxListeners = n;
    };
    EventEmitter.prototype.emit = function (type) {
      if (type === 'error') {
        if (!this._events || !this._events.error || isArray(this._events.error) && !this._events.error.length) {
          if (arguments[1] instanceof Error) {
            throw arguments[1];
          } else {
            throw new Error("Uncaught, unspecified 'error' event.");
          }
          return false;
        }
      }
      if (!this._events)
        return false;
      var handler = this._events[type];
      if (!handler)
        return false;
      if (typeof handler == 'function') {
        switch (arguments.length) {
        case 1:
          handler.call(this);
          break;
        case 2:
          handler.call(this, arguments[1]);
          break;
        case 3:
          handler.call(this, arguments[1], arguments[2]);
          break;
        default:
          var args = Array.prototype.slice.call(arguments, 1);
          handler.apply(this, args);
        }
        return true;
      } else if (isArray(handler)) {
        var args = Array.prototype.slice.call(arguments, 1);
        var listeners = handler.slice();
        for (var i = 0, l = listeners.length; i < l; i++) {
          listeners[i].apply(this, args);
        }
        return true;
      } else {
        return false;
      }
    };
    EventEmitter.prototype.addListener = function (type, listener) {
      if ('function' !== typeof listener) {
        throw new Error('addListener only takes instances of Function');
      }
      if (!this._events)
        this._events = {};
      this.emit('newListener', type, listener);
      if (!this._events[type]) {
        this._events[type] = listener;
      } else if (isArray(this._events[type])) {
        if (!this._events[type].warned) {
          var m;
          if (this._events.maxListeners !== undefined) {
            m = this._events.maxListeners;
          } else {
            m = defaultMaxListeners;
          }
          if (m && m > 0 && this._events[type].length > m) {
            this._events[type].warned = true;
            console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length);
            console.trace();
          }
        }
        this._events[type].push(listener);
      } else {
        this._events[type] = [
          this._events[type],
          listener
        ];
      }
      return this;
    };
    EventEmitter.prototype.on = EventEmitter.prototype.addListener;
    EventEmitter.prototype.once = function (type, listener) {
      var self = this;
      self.on(type, function g() {
        self.removeListener(type, g);
        listener.apply(this, arguments);
      });
      return this;
    };
    EventEmitter.prototype.removeListener = function (type, listener) {
      if ('function' !== typeof listener) {
        throw new Error('removeListener only takes instances of Function');
      }
      if (!this._events || !this._events[type])
        return this;
      var list = this._events[type];
      if (isArray(list)) {
        var i = list.indexOf(listener);
        if (i < 0)
          return this;
        list.splice(i, 1);
        if (list.length == 0)
          delete this._events[type];
      } else if (this._events[type] === listener) {
        delete this._events[type];
      }
      return this;
    };
    EventEmitter.prototype.removeAllListeners = function (type) {
      if (type && this._events && this._events[type])
        this._events[type] = null;
      return this;
    };
    EventEmitter.prototype.listeners = function (type) {
      if (!this._events)
        this._events = {};
      if (!this._events[type])
        this._events[type] = [];
      if (!isArray(this._events[type])) {
        this._events[type] = [this._events[type]];
      }
      return this._events[type];
    };
  });
  global.GIF = require('/gif.coffee');
}.call(this, this));
//# sourceMappingURL=gif.js.map 
// gif.js 0.1.6 - https://github.com/jnordberg/gif.js