<commit_before>(function(timbre) {
    "use strict";

    function FFTListener(_args) {
        timbre.Object.call(this, _args);
        timbre.fn.listener(this);
        timbre.fn.fixAR(this);

        this._.status  = 0;
        this._.samples = 0;
        this._.samplesIncr = 0;
        this._.writeIndex  = 0;

        this._.plotFlush = true;
        this._.plotRange = [0, 0.5];
        this._.plotBarStyle = true;

        this.once("init", oninit);
    }
    timbre.fn.extend(FFTListener, timbre.Object);

    var oninit = function() {
        var _ = this._;
        if (!_.fft) {
            this.size = 512;
        }
        if (!_.interval) {
            this.interval = 500;
        }
    };

    var $ = FFTListener.prototype;

    Object.defineProperties($, {
        size: {
            set: function(value) {
                var _ = this._;
                if (!_.fft) {
                    if (typeof value === "number") {
                        var n = (value < 256) ? 256 : (value > 2048) ? 2048 : value;
                        _.fft    = new FFT(n);
                        _.buffer = new Float32Array(_.fft.length);
                        if (_.reservedwindow) {
                            _.fft.setWindow(_.reservedwindow);
                            _.reservedwindow = null;
                        }
                        if (_.reservedinterval) {
                            this.interval = _.reservedinterval;
                            _.reservedinterval = null;
                        }
                    }
                }
            },
            get: function() {
                return this._.buffer.length;
            }
        },
        window: {
            set: function(value) {
                if (!this._.fft) {
                    this._.reservedwindow = value;
                } else {
                   this._.fft.setWindow(value);
                }
            },
            get: function() {
                return this._.fft.windowName;
            }
        },
        interval: {
            set: function(value) {
                var _ = this._;
                if (typeof value === "number" && value > 0) {
                    if (!_.buffer) {
                        _.reservedinterval = value;
                    } else {
                        _.interval = value;
                        _.samplesIncr = (value * 0.001 * timbre.samplerate);
                        if (_.samplesIncr < _.buffer.length) {
                            _.samplesIncr = _.buffer.length;
                            _.interval = _.samplesIncr * 1000 / timbre.samplerate;
                        }
                    }
                }
            },
            get: function() {
                return this._.interval;
            }
        },
        spectrum: {
            get: function() {
                return this._.fft.spectrum;
            }
        },
        real: {
            get: function() {
                return this._.fft.real;
            }
        },
        imag: {
            get: function() {
                return this._.fft.imag;
            }
        }
    });

    $.bang = function() {
        this._.samples    = 0;
        this._.writeIndex = 0;
        this.emit("bang");
        return this;
    };

    $.seq = function(seq_id) {
        var _ = this._;
        var cell = this.cell;

        if (this.seq_id !== seq_id) {
            this.seq_id = seq_id;

            var inputs = this.inputs;
            var i, imax = inputs.length;
            var j, jmax = cell.length;
            var tmp;

            for (j = jmax; j--; ) {
                cell[j] = 0;
            }

            for (i = 0; i < imax; ++i) {
                tmp = inputs[i].seq(seq_id);
                for (j = jmax; j--; ) {
                    cell[j] += tmp[j];
                }
            }

            var status  = _.status;
            var samples = _.samples;
            var samplesIncr = _.samplesIncr;
            var writeIndex  = _.writeIndex;
            var buffer = _.buffer;
            var bufferLength = buffer.length;
            var mul = _.mul, add = _.add;
            var emit;

            for (j = 0; j < jmax; ++j) {
                if (samples <= 0) {
                    if (status === 0) {
                        status = 1;
                        writeIndex  = 0;
                        samples += samplesIncr;
                    }
                }
                if (status === 1) {
                    buffer[writeIndex++] = cell[j];
                    if (bufferLength <= writeIndex) {
                        _.fft.forward(buffer);
                        emit = _.plotFlush = true;
                        status = 0;
                    }
                }
                cell[j] = cell[j] * mul + add;
                --samples;
            }

            _.samples = samples;
            _.status  = status;
            _.writeIndex = writeIndex;

            if (emit) {
                this.emit("fft");
            }
        }
        return cell;
    };

    $.plot = function(opts) {
        if (this._.plotFlush) {
            var fft = this._.fft;

            var spectrum = fft.spectrum;
            var step     = fft.length >> 6;
            var istep    = 1 / step;
            var data    = new Float32Array(spectrum.length * istep);
            var i, imax = spectrum.length;
            var j, jmax = step;

            var v, k = 0;
            for (i = 0; i < imax; i += step) {
                v = 0;
                for (j = 0; j < jmax; ++j) {
                    v += spectrum[i + j];
                }
                data[k++] = v * istep;
            }

            this._.plotData  = data;
            this._.plotFlush = null;
        }
        return FFTListener.__super__.plot.call(this, opts);
    };

    function FFT(n) {
        n = (typeof n === "number") ? n : 512;
        n = 1 << Math.ceil(Math.log(n) * Math.LOG2E);

        this.length  = n;
        this.buffer  = new Float32Array(n);
        this.real    = new Float32Array(n);
        this.imag    = new Float32Array(n);
        this._real   = new Float32Array(n);
        this._imag   = new Float32Array(n);
        this.spectrum = new Float32Array(n>>1);

        var params = FFTParams.get(n);
        this._bitrev   = params.bitrev;
        this._sintable = params.sintable;
        this._costable = params.costable;
    }

    FFT.prototype.setWindow = function(key) {
        if (typeof key === "string") {
            var m = /([A-Za-z]+)(?:\(([01]\.?\d*)\))?/.exec(key);
            if (m !== null) {
                var name = m[1].toLowerCase(), a = m[2] !== undefined ? +m[2] : 0.25;
                var f = WindowFunctions[name];
                if (f) {
                    if (!this._window) {
                        this._window = new Float32Array(this.length);
                    }
                    var w = this._window, n = 0, N = this.length;
                    a = (a < 0) ? 0 : (a > 1) ? 1 : a;
                    for (; n < N; ++n) {
                        w[n] = f(n, N, a);
                    }
                    this.windowName = key;
                }
            }
        }
    };

    FFT.prototype.forward = function(_buffer) {
        var buffer = this.buffer;
        var real   = this.real;
        var imag   = this.imag;
        var window = this._window;
        var bitrev = this._bitrev;
        var sintable = this._sintable;
        var costable = this._costable;
        var n = buffer.length;
        var i, j, k, k2, h, d, c, s, ik, dx, dy;

        if (window) {
            for (i = n; i--; ) {
                buffer[i] = _buffer[i] * window[i];
            }
        } else {
            for (i = n; i--; ) {
                buffer[i] = _buffer[i];
            }
        }

        for (i = n; i--; ) {
            real[i] = buffer[bitrev[i]];
            imag[i] = 0.0;
        }

        for (k = 1; k < n; k = k2) {
            h = 0; k2 = k + k; d = n / k2;
            for (j = 0; j < k; j++) {
                c = costable[h];
                s = sintable[h];
                for (i = j; i < n; i += k2) {
                    ik = i + k;
                    dx = s * imag[ik] + c * real[ik];
                    dy = c * imag[ik] - s * real[ik];
                    real[ik] = real[i] - dx; real[i] += dx;
                    imag[ik] = imag[i] - dy; imag[i] += dy;
                }
                h += d;
            }
        }

        if (!this.noSpectrum) {
            var spectrum = this.spectrum;
            var rval, ival, mag;
            var max = 0;
            for (i = n; i--; ) {
                rval = real[i];
                ival = imag[i];
                mag  = n * Math.sqrt(rval * rval + ival * ival);
                spectrum[i] = mag;
                if (max < mag) {
                    max = mag;
                }
            }
            if (max > 0) {
                max = 1 / max;
                for (i = n; i--; ) {
                    spectrum[i] *= max;
                }
            }
        }

        return {real:real, imag:imag};
    };

    FFT.prototype.inverse = function(_real, _imag) {
        var buffer = this.buffer;
        var real   = this._real;
        var imag   = this._imag;
        var bitrev = this._bitrev;
        var sintable = this._sintable;
        var costable = this._costable;
        var n = buffer.length;
        var i, j, k, k2, h, d, c, s, ik, dx, dy;

        for (i = n; i--; ) {
            j = bitrev[i];
            real[i] = +_real[j];
            imag[i] = -_imag[j];
        }

        for (k = 1; k < n; k = k2) {
            h = 0; k2 = k + k; d = n / k2;
            for (j = 0; j < k; j++) {
                c = costable[h];
                s = sintable[h];
                for (i = j; i < n; i += k2) {
                    ik = i + k;
                    dx = s * imag[ik] + c * real[ik];
                    dy = c * imag[ik] - s * real[ik];
                    real[ik] = real[i] - dx; real[i] += dx;
                    imag[ik] = imag[i] - dy; imag[i] += dy;
                }
                h += d;
            }
        }

        for (i = n; i--; ) {
            buffer[i] = real[i] / n;
        }
        return buffer;
    };

    var FFTParams = {
        get: function(n) {
            return FFTParams[n] || (function() {
                var bitrev = (function() {
                    var x, i, j, k, n2;
                    x = new Int16Array(n);
                    n2 = n >> 1;
                    i = j = 0;
                    for (;;) {
                        x[i] = j;
                        if (++i >= n) {
                            break;
                        }
                        k = n2;
                        while (k <= j) {
                            j -= k;
                            k >>= 1;
                        }
                        j += k;
                    }
                    return x;
                }());
                var i, k = Math.floor(Math.log(n) / Math.LN2);
                var sintable = new Float32Array((1<<k)-1);
                var costable = new Float32Array((1<<k)-1);
                var PI2 = Math.PI * 2;

                for (i = sintable.length; i--; ) {
                    sintable[i] = Math.sin(PI2 * (i / n));
                    costable[i] = Math.cos(PI2 * (i / n));
                }
                return FFTParams[n] = {
                    bitrev: bitrev, sintable:sintable, costable:costable
                };
            }());
        }
    };

    var WindowFunctions = (function() {
        var PI   = Math.PI;
        var PI2  = Math.PI * 2;
        var abs  = Math.abs;
        var pow  = Math.pow;
        var cos  = Math.cos;
        var sin  = Math.sin;
        var sinc = function(x) { return sin(PI*x) / (PI*x); };
        var E    = Math.E;

        return {
            rectangular: function() {
                return 1;
            },
            hann: function(n, N) {
                return 0.5 * (1 - cos((PI2*n) / (N-1)));
            },
            hamming: function(n, N) {
                return 0.54 - 0.46 * cos((PI2*n) / (N-1));
            },
            tukery: function(n, N, a) {
                if ( n < (a * (N-1))/2 ) {
                    return 0.5 * ( 1 + cos(PI * (((2*n)/(a*(N-1))) - 1)) );
                } else if ( (N-1)*(1-(a/2)) < n ) {
                    return 0.5 * ( 1 + cos(PI * (((2*n)/(a*(N-1))) - (2/a) + 1)) );
                } else {
                    return 1;
                }
            },
            cosine: function(n, N) {
                return sin((PI*n) / (N-1));
            },
            lanczos: function(n, N) {
                return sinc(((2*n) / (N-1)) - 1);
            },
            triangular: function(n, N) {
                return (2/(N+1)) * (((N+1)/2) - abs(n - ((N-1)/2)));
            },
            bartlett: function(n, N) {
                return (2/(N-1)) * (((N-1)/2) - abs(n - ((N-1)/2)));
            },
            gaussian: function(n, N, a) {
                return pow(E, -0.5 * pow((n - (N-1) / 2) / (a * (N-1) / 2), 2));
            },
            bartlettHann: function(n, N) {
                return 0.62 - 0.48 * abs((n / (N-1)) - 0.5) - 0.38 * cos((PI2*n) / (N-1));
            },
            blackman: function(n, N, a) {
                var a0 = (1 - a) / 2, a1 = 0.5, a2 = a / 2;
                return a0 - a1 * cos((PI2*n) / (N-1)) + a2 * cos((4*PI*n) / (N-1));
            }
        };
    }());

    timbre.fn.register("fft", FFTListener);

    timbre.utils.FFT = FFT;
})(timbre);
<commit_msg>update T("fft")<commit_after>(function(timbre) {
    "use strict";

    function FFTListener(_args) {
        timbre.Object.call(this, _args);
        timbre.fn.listener(this);
        timbre.fn.stereo(this);
        timbre.fn.fixAR(this);

        this.real = this.L;
        this.imag = this.R;

        this._.fft = new FFT(timbre.cellsize * 2);
        this._.fftCell  = new Float32Array(this._.fft.length);
        this._.prevCell = new Float32Array(timbre.cellsize);

        this._.plotFlush = true;
        this._.plotRange = [0, 0.5];
        this._.plotBarStyle = true;
    }
    timbre.fn.extend(FFTListener, timbre.Object);

    var $ = FFTListener.prototype;

    Object.defineProperties($, {
        window: {
            set: function(value) {
                this._.fft.setWindow(value);
            },
            get: function() {
                return this._.fft.windowName;
            }
        },
        spectrum: {
            get: function() {
                return this._.fft.spectrum;
            }
        }
    });

    $.seq = function(seq_id) {
        var _ = this._;
        var cell = this.cell;

        if (this.seq_id !== seq_id) {
            this.seq_id = seq_id;

            var inputs = this.inputs;
            var i, imax = inputs.length;
            var j, jmax = cell.length;
            var tmp;

            for (j = jmax; j--; ) {
                cell[j] = 0;
            }

            for (i = 0; i < imax; ++i) {
                tmp = inputs[i].seq(seq_id);
                for (j = jmax; j--; ) {
                    cell[j] += tmp[j];
                }
            }

            _.fftCell.set(_.prevCell);
            _.fftCell.set(cell, jmax);
            _.fft.forward(_.fftCell);
            _.prevCell.set(cell);

            var real = this.cellL;
            var imag = this.cellR;
            var _real = _.fft.real;
            var _imag = _.fft.imag;
            var mul = _.mul, add = _.add;

            for (j = jmax; j--; ) {
                real[j] = _real[j];
                imag[j] = _imag[j];
                cell[j] = cell[j] * mul + add;
            }

            this._.plotFlush = true;
        }
        return cell;
    };

    $.plot = function(opts) {
        if (this._.plotFlush) {
            var fft = this._.fft;

            var spectrum = fft.spectrum;
            var step     = fft.length >> 6;
            var istep    = 1 / step;
            var data    = new Float32Array(spectrum.length * istep);
            var i, imax = spectrum.length;
            var j, jmax = step;

            var v, k = 0;
            for (i = 0; i < imax; i += step) {
                v = 0;
                for (j = 0; j < jmax; ++j) {
                    v += spectrum[i + j];
                }
                data[k++] = v * istep;
            }

            this._.plotData  = data;
            this._.plotFlush = null;
        }
        return FFTListener.__super__.plot.call(this, opts);
    };

    function FFT(n) {
        n = (typeof n === "number") ? n : 512;
        n = 1 << Math.ceil(Math.log(n) * Math.LOG2E);

        this.length  = n;
        this.buffer  = new Float32Array(n);
        this.real    = new Float32Array(n);
        this.imag    = new Float32Array(n);
        this._real   = new Float32Array(n);
        this._imag   = new Float32Array(n);
        this.spectrum = new Float32Array(n>>1);

        var params = FFTParams.get(n);
        this._bitrev   = params.bitrev;
        this._sintable = params.sintable;
        this._costable = params.costable;
    }

    FFT.prototype.setWindow = function(key) {
        if (typeof key === "string") {
            var m = /([A-Za-z]+)(?:\(([01]\.?\d*)\))?/.exec(key);
            if (m !== null) {
                var name = m[1].toLowerCase(), a = m[2] !== undefined ? +m[2] : 0.25;
                var f = WindowFunctions[name];
                if (f) {
                    if (!this._window) {
                        this._window = new Float32Array(this.length);
                    }
                    var w = this._window, n = 0, N = this.length;
                    a = (a < 0) ? 0 : (a > 1) ? 1 : a;
                    for (; n < N; ++n) {
                        w[n] = f(n, N, a);
                    }
                    this.windowName = key;
                }
            }
        }
    };

    FFT.prototype.forward = function(_buffer) {
        var buffer = this.buffer;
        var real   = this.real;
        var imag   = this.imag;
        var window = this._window;
        var bitrev = this._bitrev;
        var sintable = this._sintable;
        var costable = this._costable;
        var n = buffer.length;
        var i, j, k, k2, h, d, c, s, ik, dx, dy;

        if (window) {
            for (i = n; i--; ) {
                buffer[i] = _buffer[i] * window[i];
            }
        } else {
            for (i = n; i--; ) {
                buffer[i] = _buffer[i];
            }
        }

        for (i = n; i--; ) {
            real[i] = buffer[bitrev[i]];
            imag[i] = 0.0;
        }

        for (k = 1; k < n; k = k2) {
            h = 0; k2 = k + k; d = n / k2;
            for (j = 0; j < k; j++) {
                c = costable[h];
                s = sintable[h];
                for (i = j; i < n; i += k2) {
                    ik = i + k;
                    dx = s * imag[ik] + c * real[ik];
                    dy = c * imag[ik] - s * real[ik];
                    real[ik] = real[i] - dx; real[i] += dx;
                    imag[ik] = imag[i] - dy; imag[i] += dy;
                }
                h += d;
            }
        }

        if (!this.noSpectrum) {
            var spectrum = this.spectrum;
            var rval, ival, mag;
            var max = 0;
            for (i = n; i--; ) {
                rval = real[i];
                ival = imag[i];
                mag  = n * Math.sqrt(rval * rval + ival * ival);
                spectrum[i] = mag;
                if (max < mag) {
                    max = mag;
                }
            }
            if (max > 0) {
                max = 1 / max;
                for (i = n; i--; ) {
                    spectrum[i] *= max;
                }
            }
        }

        return {real:real, imag:imag};
    };

    FFT.prototype.inverse = function(_real, _imag) {
        var buffer = this.buffer;
        var real   = this._real;
        var imag   = this._imag;
        var bitrev = this._bitrev;
        var sintable = this._sintable;
        var costable = this._costable;
        var n = buffer.length;
        var i, j, k, k2, h, d, c, s, ik, dx, dy;

        for (i = n; i--; ) {
            j = bitrev[i];
            real[i] = +_real[j];
            imag[i] = -_imag[j];
        }

        for (k = 1; k < n; k = k2) {
            h = 0; k2 = k + k; d = n / k2;
            for (j = 0; j < k; j++) {
                c = costable[h];
                s = sintable[h];
                for (i = j; i < n; i += k2) {
                    ik = i + k;
                    dx = s * imag[ik] + c * real[ik];
                    dy = c * imag[ik] - s * real[ik];
                    real[ik] = real[i] - dx; real[i] += dx;
                    imag[ik] = imag[i] - dy; imag[i] += dy;
                }
                h += d;
            }
        }

        for (i = n; i--; ) {
            buffer[i] = real[i] / n;
        }
        return buffer;
    };

    var FFTParams = {
        get: function(n) {
            return FFTParams[n] || (function() {
                var bitrev = (function() {
                    var x, i, j, k, n2;
                    x = new Int16Array(n);
                    n2 = n >> 1;
                    i = j = 0;
                    for (;;) {
                        x[i] = j;
                        if (++i >= n) {
                            break;
                        }
                        k = n2;
                        while (k <= j) {
                            j -= k;
                            k >>= 1;
                        }
                        j += k;
                    }
                    return x;
                }());
                var i, k = Math.floor(Math.log(n) / Math.LN2);
                var sintable = new Float32Array((1<<k)-1);
                var costable = new Float32Array((1<<k)-1);
                var PI2 = Math.PI * 2;

                for (i = sintable.length; i--; ) {
                    sintable[i] = Math.sin(PI2 * (i / n));
                    costable[i] = Math.cos(PI2 * (i / n));
                }
                return FFTParams[n] = {
                    bitrev: bitrev, sintable:sintable, costable:costable
                };
            }());
        }
    };

    var WindowFunctions = (function() {
        var PI   = Math.PI;
        var PI2  = Math.PI * 2;
        var abs  = Math.abs;
        var pow  = Math.pow;
        var cos  = Math.cos;
        var sin  = Math.sin;
        var sinc = function(x) { return sin(PI*x) / (PI*x); };
        var E    = Math.E;

        return {
            rectangular: function() {
                return 1;
            },
            hann: function(n, N) {
                return 0.5 * (1 - cos((PI2*n) / (N-1)));
            },
            hamming: function(n, N) {
                return 0.54 - 0.46 * cos((PI2*n) / (N-1));
            },
            tukery: function(n, N, a) {
                if ( n < (a * (N-1))/2 ) {
                    return 0.5 * ( 1 + cos(PI * (((2*n)/(a*(N-1))) - 1)) );
                } else if ( (N-1)*(1-(a/2)) < n ) {
                    return 0.5 * ( 1 + cos(PI * (((2*n)/(a*(N-1))) - (2/a) + 1)) );
                } else {
                    return 1;
                }
            },
            cosine: function(n, N) {
                return sin((PI*n) / (N-1));
            },
            lanczos: function(n, N) {
                return sinc(((2*n) / (N-1)) - 1);
            },
            triangular: function(n, N) {
                return (2/(N+1)) * (((N+1)/2) - abs(n - ((N-1)/2)));
            },
            bartlett: function(n, N) {
                return (2/(N-1)) * (((N-1)/2) - abs(n - ((N-1)/2)));
            },
            gaussian: function(n, N, a) {
                return pow(E, -0.5 * pow((n - (N-1) / 2) / (a * (N-1) / 2), 2));
            },
            bartlettHann: function(n, N) {
                return 0.62 - 0.48 * abs((n / (N-1)) - 0.5) - 0.38 * cos((PI2*n) / (N-1));
            },
            blackman: function(n, N, a) {
                var a0 = (1 - a) / 2, a1 = 0.5, a2 = a / 2;
                return a0 - a1 * cos((PI2*n) / (N-1)) + a2 * cos((4*PI*n) / (N-1));
            }
        };
    }());

    timbre.fn.register("fft", FFTListener);

    timbre.utils.FFT = FFT;
})(timbre);
<|endoftext|>


<commit_before>var multiparty = require('multiparty'),
    xlsx = require('node-xlsx'),
    util = require('util'),
    path = require('path');

var processGRNmap = function (path, res, app) {
  var sheet,
      network;
  try {
    sheet = xlsx.parse(path);
  } catch (err) {
    return res.json(400, "Unable to read input. The file may be corrupt.");
  }

  // For the time being, send the result in a form readable by people
  //TODO: Optimize the result for D3
  res.header('Access-Control-Allow-Origin', app.get('corsOrigin'));

  network = parseSheet(sheet);

  if(network.errors.length === 0) {
    // If all looks well, return the network with an all clear
    return res.json(network);
  } else {
    // If all does not look well, return the network with an error 400
    return res.json(400, network);
  }

};

var parseSheet = function(sheet) {
  var currentSheet,
      network = {
        genes: [],
        links: [],
        errors: [],
        warnings: [],
        positiveWeights: [],
        negativeWeights: [],
        sheetType: "unweighted",
      },
      currentLink,
      currentGene,
      sourceGene,
      targetGene,
      sourceGeneNumber,
      targetGeneNumber,
      genesList = [], // This will contain all of the genes in upper case for use in error checking
      sourceGenes = [],
      targetGenes = [];

  //Look for the worksheet containing the network data
  for (var i = 0; i < sheet.worksheets.length; i++) {
    if (sheet.worksheets[i].name === "network") {
      //Here we have found a sheet containing simple data. We keep looking
      //in case there is also a sheet with optimized weights
      currentSheet = sheet.worksheets[i];
    } else if (sheet.worksheets[i].name === "network_optimized_weights") {
      //We found a sheet with optimized weights, which is the ideal data source.
      //So we stop looking.
      currentSheet = sheet.worksheets[i];
      network.sheetType = "weighted";
      break;
    }
  }

  // If it didn't find a network/network_optimized_weights sheet
  if (currentSheet === undefined) {
    network.errors.push(errorList.missingNetworkError)
    return network;
  }

  for (var row = 0, column = 1; row < currentSheet.data.length; row++) {
    if(currentSheet.data[row] === undefined) { // if the current row is empty
      network.warnings.push(warningsList.emptyRowWarning(row));
    } else { // if the row has data...
      // Genes found when row = 0 are targets. Genes found when column = 0 are source genes.
      // We set column = 1 in the for loop so it skips row 0 column 0, since that contains no matrix data.
      // Yes, the rows and columns use array numbering. That is, they start at 0, not 1.
      try { // This prevents the server from crashing if something goes wrong anywhere in here
        while(column < currentSheet.data[row].length) { // While we haven't gone through all of the columns in this row...
          if (row === 0) { // If we are at the top of a new column...
            // These genes are the source genes
            try {
              currentGene = {name: currentSheet.data[0][column]};
              // Set genes to upper case so case doesn't matter in error checking; ie: Cin5 is the same as cin5
              if(currentGene.name === undefined) {
                network.warnings.push(warningsList.missingSourceGeneWarning("undefined", column));
              } else if(isNaN(currentGene.name.value) && typeof currentGene.name.value != "string") {
                network.warnings.push(warningsList.missingSourceGeneWarning("NaN", column));
              } else {
                sourceGenes.push(String(currentGene.name.value.toUpperCase()));
                genesList.push(String(currentGene.name.value.toUpperCase()));
                currentGene.name = currentGene.name.value;
                network.genes.push(currentGene);
              }
            } catch (err) {
              network.errors.push(errorList.corruptGeneError(row, column));
              return network;
            }
          } else if (column === 0) { // If we are at the far left of a new row...
            // These genes are the target genes
            try {
              currentGene = {name: currentSheet.data[row][0]};
              if(currentGene.name === undefined) {
                network.warnings.push(warningsList.missingTargetGeneWarning("undefined", row));
              } else if(isNaN(currentGene.name.value) && typeof currentGene.name.value != "string") {
                network.warnings.push(warningsList.missingTargetGeneWarning("NaN", row));
              } else {
                targetGenes.push(String(currentGene.name.value.toUpperCase()));
                // Here we check to see if we've already seen the gene name that we're about to store
                // Genes may or may not be present due to asymmetry or unorderedness
                // If it's in the genesList, it will return a number > 0, so we won't store it
                // If it's not there, it will return -1, so we add it.
                if(genesList.indexOf(String(currentGene.name.value.toUpperCase())) === -1) {
                  genesList.push(String(currentGene.name.value.toUpperCase()));
                  currentGene.name = currentGene.name.value;
                  network.genes.push(currentGene);
                }
              }
            } catch (err) {
              network.errors.push(errorList.corruptGeneError(row, column));
              return network;
            };
          } else { // If we're within the matrix and lookin' at the data...
            try {
              if(currentSheet.data[row][column] === undefined) {
                network.warnings.push(warningsList.invalidMatrixDataWarning(row, column));
              } else {
                if (currentSheet.data[row][column].value != 0) { // We only care about non-zero values
                  // Grab the source and target genes' names
                  sourceGene = currentSheet.data[0][column];
                  targetGene = currentSheet.data[row][0];
                  if(sourceGene === undefined || targetGene === undefined) {
                    network.warnings.push(warningsList.randomDataWarning("undefined", row, column));
                  } else if((isNaN(sourceGene.value) && typeof sourceGene.value != "string") || (isNaN(targetGene.value) && typeof targetGene.value != "string")) {
                    network.warnings.push(warningsList.randomDataWarning("NaN", row, column));
                  } else {
                    // Grab the source and target genes' numbers
                    sourceGeneNumber = genesList.indexOf(sourceGene.value.toUpperCase());
                    targetGeneNumber = genesList.indexOf(targetGene.value.toUpperCase());
                    currentLink = {source: sourceGeneNumber, target: targetGeneNumber, value: currentSheet.data[row][column].value};
                    // Here we set the properties of the current link before we push them to the network
                    if (currentLink.value > 0) { // If it's a positive number, mark it as an activator
                      currentLink.type = "arrowhead";
                      currentLink.stroke = "MediumVioletRed";
                      network.positiveWeights.push(currentLink.value);
                    } else { // if it's a negative number, mark it as a repressor
                      currentLink.type = "repressor";
                      currentLink.stroke = "DarkTurquoise";
                      network.negativeWeights.push(currentLink.value);
                    }
                    network.links.push(currentLink);
                  }
                };
              }
            } catch (err) {
              // TO DO: Customize this error message to the specific issue that occurred.
              network.errors.push(errorList.missingValueError(row, column));
              return network;
            };
          };
          column++; // Let's move on to the next column!
        }; // Once we finish with the current row...
      column = 0; // let's go back to column 0 on the next row!
      } catch (err) {
        // We only get here if something goes drastically wrong. We don't want to get here.
        network.errors.push(errorList.unknownError);
        return network;
      }
    };
  };

  // We sort them here because gene order is not relevant before this point
  // Sorting them now means duplicates will be right next to each other
  sourceGenes.sort();
  targetGenes.sort();

  // Final error checks!
  checkDuplicates(network.errors, sourceGenes, targetGenes);
  checkGeneLength(network.errors, genesList);

  // We're done. Return the network.
  return network;
};

var checkDuplicates = function(errorArray, sourceGenes, targetGenes) {
  // Run through the source genes and check if the gene in slot i is the same as the one next to it
  for(var i = 0; i < sourceGenes.length - 1; i++) {
    if(sourceGenes[i] === sourceGenes[i + 1]) {
      errorArray.push(errorList.duplicateGeneError("source", sourceGenes[i]));
    }
  }
  // Run through the target genes and check if the gene in slot j is the same as the one next to it
  for(var j = 0; j < targetGenes.length - 1; j++) {
    if(targetGenes[j] === targetGenes[j + 1]) {
      errorArray.push(errorList.duplicateGeneError("target", targetGenes[j]));
    }
  }
}

var checkGeneLength = function(errorArray, genesList) {
  // Check if any genes are over the gene length (currently 12)
  var maxGeneLength = 12
  for(var i = 0; i < genesList.length; i++) {
    if(genesList[i].length > maxGeneLength) {
      errorArray.push(errorList.geneLengthError(genesList[i]));
    }
  }
}

// This is the massive list of errors. Yay!
// The graph will not load if an error is detected.
var errorList = {
  missingNetworkError: {
    errorCode: "MISSING_NETWORK",
    possibleCause: "This file does not have a 'network' sheet or a 'network_optimized_weights' sheet.",
    suggestedFix: "Please select another file, or rename the sheet containing the adjacency matrix accordingly. Please refer to the " +
    "Documentation page for more information."
  },

  corruptGeneError: function (row, column) {
    return {
      errorCode: "CORRUPT_GENE",
      possibleCause: "The gene name in row " + row + ", column " + column + " appears to be invalid.",
      suggestedFix: "Please fix the error and try uploading again."
    };
  },

  missingValueError: function (row, column) {
    return {
      errorCode: "MISSING_VALUE",
      possibleCause: "The cell at row " + row + ", column " + column + " in the adjacency matrix appears to have a missing value.",
      suggestedFix: "Please ensure that all cells have a value, then upload the file again."
    };
  },

  duplicateGeneError: function(geneType, geneName) {
    return {
      errorCode: "DUPLICATE_GENE",
      possibleCause: "There exists a duplicate for " + geneType + " gene " + geneName + ".",
      suggestedFix: "Please remove the duplicate gene and submit again."
    };
  },

  geneLengthError: function (geneName) {
    return {
      errorCode: "INVALID_GENE_LENGTH",
      possibleCause: "Gene " + geneName + " is more than 12 characters in length.",
      suggestedFix: "Genes may only be between 1 and 12 characters in length. Please shorten the name and submit again."
    };
  },

  unknownError: {
    errorCode: "UNKNOWN_ERROR",
    possibleCause: "An unexpected error occurred.",
    suggestedFix: "" // There is none, because we don't actually know what happened.
    // TODO: Put in a message saying to contact the GRNsight team.
  }
}

// This is the list of warnings.
// The graph will still load if warnings are detected, but these will be reported to the user.
var warningsList = {
  missingSourceGeneWarning: function (type, column) {
    return {
      warningCode: "MISSING_SOURCE",
      errorDescription: "A source gene was detected as " + type + " in column " + column + "."
    }
  },

  missingTargetGeneWarning: function (type, row) {
    return {
      warningCode: "MISSING_TARGET",
      errorDescription: "A target gene was detected as " + type + " in row " + row + "."
    }
  },

  invalidMatrixDataWarning: function (row, column) {
    return {
      warningCode: "INVALID_DATA",
      errorDescription: "The value in row " + row + ", column " + column + ", was detected as being undefined."
    }
  },

  randomDataWarning: function (type, row, column) {
    return {
      warning: "RANDOM_DATA",
      errorDescription: "The value in row " + row + ", column " + column + ", has a corresponding source and/or target gene that is detected as " + type + "."
    }
  },

  emptyRowWarning: function (row) {
    return {
      warningCode: "EMPTY_ROW",
      errorDescription: "Row " + row + " was found to contain no data."
    }
  }
}

module.exports = function (app) {
  if (app) {

    //parse the incoming form data, then parse the spreadsheet. Finally, send back json.
    app.post('/upload', function (req, res) {
      //TODO: Add file validation
      (new multiparty.Form()).parse(req, function (err, fields, files) {
        if (err) {
          return res.json(400, "There was a problem uploading your file. Please try again.");
        }

        try {
          var input = files.file[0].path;
        } catch (err) {
          return res.json(400, "No upload file selected.");
        }

        if (path.extname(input) !== ".xlsx") {
          return res.json(400, "This file cannot be loaded because:

 The file is not in a format GRnsight can read." +
            "
Please select an Excel Workbook (.xlsx) file. Note that Excel 97-2003 Workbook (.xls) files are not " +
            " able to be read by GRNsight.");
        }

        return processGRNmap(input, res, app);
      });
    });

    // Load the demos
    app.get('/demo/unweighted', function (req, res) {
      return processGRNmap("../test-files/demo-files/21-genes_50-edges_Dahlquist-data_input.xlsx", res, app);
    });

    app.get('/demo/weighted', function (req, res) {
      return processGRNmap("../test-files/demo-files/21-genes_50-edges_Dahlquist-data_estimation_output.xlsx", res, app);x
    });

    app.get('/demo/schadeInput', function (req, res) {
      return processGRNmap("../test-files/demo-files/21-genes_31-edges_Schade-data_input.xlsx", res, app);
    });

    app.get('/demo/schadeOutput', function (req, res) {
      return processGRNmap("../test-files/demo-files/21-genes_31-edges_Schade-data_estimation_output.xlsx", res, app);
    });
  }

  //exporting parseSheet for use in testing. Do not remove!
  return {
    parseSheet: parseSheet
  };
}
<commit_msg>Added network size error and warning to bank of errors/warnings<commit_after>var multiparty = require('multiparty'),
    xlsx = require('node-xlsx'),
    util = require('util'),
    path = require('path');

var processGRNmap = function (path, res, app) {
  var sheet,
      network;
  try {
    sheet = xlsx.parse(path);
  } catch (err) {
    return res.json(400, "Unable to read input. The file may be corrupt.");
  }

  // For the time being, send the result in a form readable by people
  //TODO: Optimize the result for D3
  res.header('Access-Control-Allow-Origin', app.get('corsOrigin'));

  network = parseSheet(sheet);

  if(network.errors.length === 0) {
    // If all looks well, return the network with an all clear
    return res.json(network);
  } else {
    // If all does not look well, return the network with an error 400
    return res.json(400, network);
  }

};

var parseSheet = function(sheet) {
  var currentSheet,
      network = {
        genes: [],
        links: [],
        errors: [],
        warnings: [],
        positiveWeights: [],
        negativeWeights: [],
        sheetType: "unweighted",
      },
      currentLink,
      currentGene,
      sourceGene,
      targetGene,
      sourceGeneNumber,
      targetGeneNumber,
      genesList = [], // This will contain all of the genes in upper case for use in error checking
      sourceGenes = [],
      targetGenes = [];

  //Look for the worksheet containing the network data
  for (var i = 0; i < sheet.worksheets.length; i++) {
    if (sheet.worksheets[i].name === "network") {
      //Here we have found a sheet containing simple data. We keep looking
      //in case there is also a sheet with optimized weights
      currentSheet = sheet.worksheets[i];
    } else if (sheet.worksheets[i].name === "network_optimized_weights") {
      //We found a sheet with optimized weights, which is the ideal data source.
      //So we stop looking.
      currentSheet = sheet.worksheets[i];
      network.sheetType = "weighted";
      break;
    }
  }

  // If it didn't find a network/network_optimized_weights sheet
  if (currentSheet === undefined) {
    network.errors.push(errorList.missingNetworkError)
    return network;
  }

  for (var row = 0, column = 1; row < currentSheet.data.length; row++) {
    if(currentSheet.data[row] === undefined) { // if the current row is empty
      network.warnings.push(warningsList.emptyRowWarning(row));
    } else { // if the row has data...
      // Genes found when row = 0 are targets. Genes found when column = 0 are source genes.
      // We set column = 1 in the for loop so it skips row 0 column 0, since that contains no matrix data.
      // Yes, the rows and columns use array numbering. That is, they start at 0, not 1.
      try { // This prevents the server from crashing if something goes wrong anywhere in here
        while(column < currentSheet.data[row].length) { // While we haven't gone through all of the columns in this row...
          if (row === 0) { // If we are at the top of a new column...
            // These genes are the source genes
            try {
              currentGene = {name: currentSheet.data[0][column]};
              // Set genes to upper case so case doesn't matter in error checking; ie: Cin5 is the same as cin5
              if(currentGene.name === undefined) {
                network.warnings.push(warningsList.missingSourceGeneWarning("undefined", column));
              } else if(isNaN(currentGene.name.value) && typeof currentGene.name.value != "string") {
                network.warnings.push(warningsList.missingSourceGeneWarning("NaN", column));
              } else {
                sourceGenes.push(String(currentGene.name.value.toUpperCase()));
                genesList.push(String(currentGene.name.value.toUpperCase()));
                currentGene.name = currentGene.name.value;
                network.genes.push(currentGene);
              }
            } catch (err) {
              network.errors.push(errorList.corruptGeneError(row, column));
              return network;
            }
          } else if (column === 0) { // If we are at the far left of a new row...
            // These genes are the target genes
            try {
              currentGene = {name: currentSheet.data[row][0]};
              if(currentGene.name === undefined) {
                network.warnings.push(warningsList.missingTargetGeneWarning("undefined", row));
              } else if(isNaN(currentGene.name.value) && typeof currentGene.name.value != "string") {
                network.warnings.push(warningsList.missingTargetGeneWarning("NaN", row));
              } else {
                targetGenes.push(String(currentGene.name.value.toUpperCase()));
                // Here we check to see if we've already seen the gene name that we're about to store
                // Genes may or may not be present due to asymmetry or unorderedness
                // If it's in the genesList, it will return a number > 0, so we won't store it
                // If it's not there, it will return -1, so we add it.
                if(genesList.indexOf(String(currentGene.name.value.toUpperCase())) === -1) {
                  genesList.push(String(currentGene.name.value.toUpperCase()));
                  currentGene.name = currentGene.name.value;
                  network.genes.push(currentGene);
                }
              }
            } catch (err) {
              network.errors.push(errorList.corruptGeneError(row, column));
              return network;
            };
          } else { // If we're within the matrix and lookin' at the data...
            try {
              if(currentSheet.data[row][column] === undefined) {
                network.warnings.push(warningsList.invalidMatrixDataWarning(row, column));
              } else {
                if (currentSheet.data[row][column].value != 0) { // We only care about non-zero values
                  // Grab the source and target genes' names
                  sourceGene = currentSheet.data[0][column];
                  targetGene = currentSheet.data[row][0];
                  if(sourceGene === undefined || targetGene === undefined) {
                    network.warnings.push(warningsList.randomDataWarning("undefined", row, column));
                  } else if((isNaN(sourceGene.value) && typeof sourceGene.value != "string") || (isNaN(targetGene.value) && typeof targetGene.value != "string")) {
                    network.warnings.push(warningsList.randomDataWarning("NaN", row, column));
                  } else {
                    // Grab the source and target genes' numbers
                    sourceGeneNumber = genesList.indexOf(sourceGene.value.toUpperCase());
                    targetGeneNumber = genesList.indexOf(targetGene.value.toUpperCase());
                    currentLink = {source: sourceGeneNumber, target: targetGeneNumber, value: currentSheet.data[row][column].value};
                    // Here we set the properties of the current link before we push them to the network
                    if (currentLink.value > 0) { // If it's a positive number, mark it as an activator
                      currentLink.type = "arrowhead";
                      currentLink.stroke = "MediumVioletRed";
                      network.positiveWeights.push(currentLink.value);
                    } else { // if it's a negative number, mark it as a repressor
                      currentLink.type = "repressor";
                      currentLink.stroke = "DarkTurquoise";
                      network.negativeWeights.push(currentLink.value);
                    }
                    network.links.push(currentLink);
                  }
                };
              }
            } catch (err) {
              // TO DO: Customize this error message to the specific issue that occurred.
              network.errors.push(errorList.missingValueError(row, column));
              return network;
            };
          };
          column++; // Let's move on to the next column!
        }; // Once we finish with the current row...
      column = 0; // let's go back to column 0 on the next row!
      } catch (err) {
        // We only get here if something goes drastically wrong. We don't want to get here.
        network.errors.push(errorList.unknownError);
        return network;
      }
    };
  };

  // We sort them here because gene order is not relevant before this point
  // Sorting them now means duplicates will be right next to each other
  sourceGenes.sort();
  targetGenes.sort();

  // Final error checks!
  checkDuplicates(network.errors, sourceGenes, targetGenes);
  checkGeneLength(network.errors, genesList);

  // We're done. Return the network.
  return network;
};

var checkDuplicates = function(errorArray, sourceGenes, targetGenes) {
  // Run through the source genes and check if the gene in slot i is the same as the one next to it
  for(var i = 0; i < sourceGenes.length - 1; i++) {
    if(sourceGenes[i] === sourceGenes[i + 1]) {
      errorArray.push(errorList.duplicateGeneError("source", sourceGenes[i]));
    }
  }
  // Run through the target genes and check if the gene in slot j is the same as the one next to it
  for(var j = 0; j < targetGenes.length - 1; j++) {
    if(targetGenes[j] === targetGenes[j + 1]) {
      errorArray.push(errorList.duplicateGeneError("target", targetGenes[j]));
    }
  }
}

var checkGeneLength = function(errorArray, genesList) {
  // Check if any genes are over the gene length (currently 12)
  var maxGeneLength = 12
  for(var i = 0; i < genesList.length; i++) {
    if(genesList[i].length > maxGeneLength) {
      errorArray.push(errorList.geneLengthError(genesList[i]));
    }
  }
}

// This is the massive list of errors. Yay!
// The graph will not load if an error is detected.
var errorList = {
  missingNetworkError: {
    errorCode: "MISSING_NETWORK",
    possibleCause: "This file does not have a 'network' sheet or a 'network_optimized_weights' sheet.",
    suggestedFix: "Please select another file, or rename the sheet containing the adjacency matrix accordingly. Please refer to the " +
    "Documentation page for more information."
  },

  corruptGeneError: function (row, column) {
    return {
      errorCode: "CORRUPT_GENE",
      possibleCause: "The gene name in row " + row + ", column " + column + " appears to be invalid.",
      suggestedFix: "Please fix the error and try uploading again."
    };
  },

  missingValueError: function (row, column) {
    return {
      errorCode: "MISSING_VALUE",
      possibleCause: "The cell at row " + row + ", column " + column + " in the adjacency matrix appears to have a missing value.",
      suggestedFix: "Please ensure that all cells have a value, then upload the file again."
    };
  },

  duplicateGeneError: function(geneType, geneName) {
    return {
      errorCode: "DUPLICATE_GENE",
      possibleCause: "There exists a duplicate for " + geneType + " gene " + geneName + ".",
      suggestedFix: "Please remove the duplicate gene and submit again."
    };
  },

  geneLengthError: function (geneName) {
    return {
      errorCode: "INVALID_GENE_LENGTH",
      possibleCause: "Gene " + geneName + " is more than 12 characters in length.",
      suggestedFix: "Genes may only be between 1 and 12 characters in length. Please shorten the name and submit again."
    };
  },

/*
  networkSizeError: function (genesList) {
    return {
      errorCode: "INVALID_NETWORK_SIZE",
      possibleCause: "Network has " + genesList.length() + " genes."
      suggestedFix: "Networks may not have more than 75 genes or 150 edges. Please reduce the size of your network and submit again."
    };
  },
*/

  unknownError: {
    errorCode: "UNKNOWN_ERROR",
    possibleCause: "An unexpected error occurred.",
    suggestedFix: "" // There is none, because we don't actually know what happened.
    // TODO: Put in a message saying to contact the GRNsight team.
  }
}

// This is the list of warnings.
// The graph will still load if warnings are detected, but these will be reported to the user.
var warningsList = {
  missingSourceGeneWarning: function (type, column) {
    return {
      warningCode: "MISSING_SOURCE",
      errorDescription: "A source gene was detected as " + type + " in column " + column + "."
    }
  },

  missingTargetGeneWarning: function (type, row) {
    return {
      warningCode: "MISSING_TARGET",
      errorDescription: "A target gene was detected as " + type + " in row " + row + "."
    }
  },

  invalidMatrixDataWarning: function (row, column) {
    return {
      warningCode: "INVALID_DATA",
      errorDescription: "The value in row " + row + ", column " + column + ", was detected as being undefined."
    }
  },

  randomDataWarning: function (type, row, column) {
    return {
      warning: "RANDOM_DATA",
      errorDescription: "The value in row " + row + ", column " + column + ", has a corresponding source and/or target gene that is detected as " + type + "."
    }
  },

  emptyRowWarning: function (row) {
    return {
      warningCode: "EMPTY_ROW",
      errorDescription: "Row " + row + " was found to contain no data."
    }
  }

  networkSizeWarning: function (genesList) {
    return {
      warningCode: "INVALID_NETWORK_SIZE",
      errorDescription: "Networks are recommended to have less than 50 genes and 100 edges."
    }
  }

}

module.exports = function (app) {
  if (app) {

    //parse the incoming form data, then parse the spreadsheet. Finally, send back json.
    app.post('/upload', function (req, res) {
      //TODO: Add file validation
      (new multiparty.Form()).parse(req, function (err, fields, files) {
        if (err) {
          return res.json(400, "There was a problem uploading your file. Please try again.");
        }

        try {
          var input = files.file[0].path;
        } catch (err) {
          return res.json(400, "No upload file selected.");
        }

        if (path.extname(input) !== ".xlsx") {
          return res.json(400, "This file cannot be loaded because:

 The file is not in a format GRnsight can read." +
            "
Please select an Excel Workbook (.xlsx) file. Note that Excel 97-2003 Workbook (.xls) files are not " +
            " able to be read by GRNsight.");
        }

        return processGRNmap(input, res, app);
      });
    });

    // Load the demos
    app.get('/demo/unweighted', function (req, res) {
      return processGRNmap("../test-files/demo-files/21-genes_50-edges_Dahlquist-data_input.xlsx", res, app);
    });

    app.get('/demo/weighted', function (req, res) {
      return processGRNmap("../test-files/demo-files/21-genes_50-edges_Dahlquist-data_estimation_output.xlsx", res, app);x
    });

    app.get('/demo/schadeInput', function (req, res) {
      return processGRNmap("../test-files/demo-files/21-genes_31-edges_Schade-data_input.xlsx", res, app);
    });

    app.get('/demo/schadeOutput', function (req, res) {
      return processGRNmap("../test-files/demo-files/21-genes_31-edges_Schade-data_estimation_output.xlsx", res, app);
    });
  }

  //exporting parseSheet for use in testing. Do not remove!
  return {
    parseSheet: parseSheet
  };
}
<|endoftext|>


<commit_before>describe('The dp-parent-relations directive', function () {
    var $compile,
        $rootScope,
        mockedContent;

    beforeEach(function () {
        angular.mock.module(
            'dpDetail',
            function ($provide) {
                $provide.constant('PARENT_RELATIONS_CONFIG', [
                    'universe',
                    'planet',
                    'verblijfsobject'
                ]);
                $provide.factory('dpLinkDirective', function () {
                    return {};
                });
            }
        );

        angular.mock.inject(function (_$compile_, _$rootScope_) {
            $compile = _$compile_;
            $rootScope = _$rootScope_;
        });

        mockedContent = {
            universe: {
                _display: 'Het allerhoogste niveau',
                _links: {
                    self: {
                        href: 'http://www.example.com/bag/universe/1'
                    }
                }
            },
            planet: {
                _display: 'Aarde',
                _links: {
                    self: {
                        href: 'http://www.example.com/bag/planet/1'
                    }
                }
            },
            verblijfsobject: {
                _display: 'Weesperstraat 113',
                _links: {
                    self: {
                        href: 'http://www.example.com/bag/addresseerbaar-object/114'
                    }
                }
            }
        };
    });

    function getDirective (content) {
        var directive,
            element,
            scope;

        element = document.createElement('dp-parent-relations');
        element.setAttribute('content', 'content');

        scope = $rootScope.$new();
        scope.content = content;

        directive = $compile(element)(scope);
        scope.$apply();

        return directive;
    }

    it('creates a list of parent entities', function () {
        var directive,
            content = angular.copy(mockedContent);

        directive = getDirective(content);

        expect(directive.find('dl').length).toBe(1);
        expect(directive.find('dt').length).toBe(3);
        expect(directive.find('dd').length).toBe(3);

        expect(directive.find('dt:nth-of-type(1)').text().trim()).toBe('Universe');
        expect(directive.find('dd:nth-of-type(1)').text().trim()).toBe('Het allerhoogste niveau');

        expect(directive.find('dt:nth-of-type(2)').text().trim()).toBe('Planet');
        expect(directive.find('dd:nth-of-type(2)').text().trim()).toBe('Aarde');

        expect(directive.find('dt:nth-of-type(3)').text().trim()).toBe('Verblijfsobject');
        expect(directive.find('dd:nth-of-type(3)').text().trim()).toBe('Weesperstraat 113');
    });

    it('doesn\'t show missing relations', function () {
        var directive,
            content = angular.copy(mockedContent);

        delete content.verblijfsobject;
        directive = getDirective(content);

        expect(directive.find('dl').length).toBe(1);
        expect(directive.find('dt').length).toBe(2);
        expect(directive.find('dd').length).toBe(2);
    });

    it('supports API data with and without prefix underscores', function () {
        var directive,
            content = angular.copy(mockedContent),
            verblijfsobjectData = angular.copy(content.verblijfsobject);

        delete content.verblijfsobject;
        content._verblijfsobject = verblijfsobjectData;
        directive = getDirective(content);

        expect(directive.find('dl').length).toBe(1);
        expect(directive.find('dt').length).toBe(3);
        expect(directive.find('dd').length).toBe(3);

        expect(directive.find('dt:nth-of-type(3)').text().trim()).toBe('Verblijfsobject');
        expect(directive.find('dd:nth-of-type(3)').text().trim()).toBe('Weesperstraat 113');
    });
});
<commit_msg>added unit tests tg-3551<commit_after>describe('The dp-parent-relations directive', function () {
    var $compile,
        $rootScope,
        mockedContent;

    beforeEach(function () {
        angular.mock.module(
            'dpDetail',
            function ($provide) {
                $provide.constant('PARENT_RELATIONS_CONFIG', [
                    'universe',
                    'planet',
                    'buurtcombinatie',
                    'verblijfsobject'
                ]);
                $provide.factory('dpLinkDirective', function () {
                    return {};
                });
            }
        );

        angular.mock.inject(function (_$compile_, _$rootScope_) {
            $compile = _$compile_;
            $rootScope = _$rootScope_;
        });

        mockedContent = {
            universe: {
                _display: 'Het allerhoogste niveau',
                _links: {
                    self: {
                        href: 'http://www.example.com/bag/universe/1'
                    }
                }
            },
            planet: {
                _display: 'Aarde',
                _links: {
                    self: {
                        href: 'http://www.example.com/bag/planet/1'
                    }
                }
            },
            buurtcombinatie: {
                _display: 'Oost',
                _links: {
                    self: {
                        href: 'http://www.example.com/bag/_display/666'
                    }
                }
            },
            verblijfsobject: {
                _display: 'Weesperstraat 113',
                _links: {
                    self: {
                        href: 'http://www.example.com/bag/addresseerbaar-object/114'
                    }
                }
            }
        };
    });

    function getDirective (content) {
        var directive,
            element,
            scope;

        element = document.createElement('dp-parent-relations');
        element.setAttribute('content', 'content');

        scope = $rootScope.$new();
        scope.content = content;

        directive = $compile(element)(scope);
        scope.$apply();

        return directive;
    }

    it('creates a list of parent entities', function () {
        var directive,
            content = angular.copy(mockedContent);

        directive = getDirective(content);

        expect(directive.find('dl').length).toBe(1);
        expect(directive.find('dt').length).toBe(4);
        expect(directive.find('dd').length).toBe(4);

        expect(directive.find('dt:nth-of-type(1)').text().trim()).toBe('Universe');
        expect(directive.find('dd:nth-of-type(1)').text().trim()).toBe('Het allerhoogste niveau');

        expect(directive.find('dt:nth-of-type(2)').text().trim()).toBe('Planet');
        expect(directive.find('dd:nth-of-type(2)').text().trim()).toBe('Aarde');

        expect(directive.find('dt:nth-of-type(3)').text().trim()).toBe('Wijk');
        expect(directive.find('dd:nth-of-type(3)').text().trim()).toBe('Oost');

        expect(directive.find('dt:nth-of-type(4)').text().trim()).toBe('Verblijfsobject');
        expect(directive.find('dd:nth-of-type(4)').text().trim()).toBe('Weesperstraat 113');
    });

    it('doesn\'t show missing relations', function () {
        var directive,
            content = angular.copy(mockedContent);

        delete content.verblijfsobject;
        directive = getDirective(content);

        expect(directive.find('dl').length).toBe(1);
        expect(directive.find('dt').length).toBe(3);
        expect(directive.find('dd').length).toBe(3);
    });

    it('supports API data with and without prefix underscores', function () {
        var directive,
            content = angular.copy(mockedContent),
            verblijfsobjectData = angular.copy(content.verblijfsobject);

        delete content.verblijfsobject;
        content._verblijfsobject = verblijfsobjectData;
        directive = getDirective(content);

        expect(directive.find('dl').length).toBe(1);
        expect(directive.find('dt').length).toBe(4);
        expect(directive.find('dd').length).toBe(4);

        expect(directive.find('dt:nth-of-type(4)').text().trim()).toBe('Verblijfsobject');
        expect(directive.find('dd:nth-of-type(4)').text().trim()).toBe('Weesperstraat 113');
    });
});
<|endoftext|>


<commit_before>
#pragma strict

public var aimingDirection : AimingDirection;

function Update () {
	transform.localScale = Vector3.one * Random.Range(0.5,1.5);

    transform.rotation = Quaternion.FromToRotation(transform.parent.forward, aimingDirection.ray.direction);
	transform.localEulerAngles.z = Random.Range(0,90.0);
}
<commit_msg>Fixed muzzle flash animation to be properly oriented even after the character turned.<commit_after>
#pragma strict

public var aimingDirection : AimingDirection;

function Update () {
	transform.localScale = Vector3.one * Random.Range(0.5,1.5);

    transform.rotation = Quaternion.FromToRotation(Vector3.forward, aimingDirection.ray.direction);
	transform.localEulerAngles.z = Random.Range(0,90.0);
}
<|endoftext|>


<commit_before>const DrawCard = require('../../drawcard');

class TheIronThrone extends DrawCard {
    setupCardAbilities(ability) {
        this.reaction({
            when: {
                onPhaseStarted: () => true
            },
            cost: ability.costs.kneelSelf(),
            handler: () => {
                this.game.promptWithMenu(this.controller, this, {
                    activePrompt: {
                        menuTitle: 'Name a card',
                        controls: [
                            { type: 'card-name', command: 'menuButton', method: 'selectCardName' }
                        ]
                    }
                });
            }
        });
    }

    selectCardName(player, cardName) {
        this.game.addMessage('{0} kneels {1} to name {2}', player, this, cardName);
        this.untilEndOfPhase(ability => ({
            effect: [
                ability.effects.cannotMarshal(card => card.name.toLowerCase() === cardName.toLowerCase()),
                ability.effects.cannotPlay(card => card.name.toLowerCase() === cardName.toLowerCase()),
                ability.effects.cannotPutIntoPlay(card => card.name.toLowerCase() === cardName.toLowerCase())
            ]
        }));
        return true;
    }
}

TheIronThrone.code = '13117';

module.exports = TheIronThrone;
<commit_msg>Apply The Iron Throne effect to all players (#2768)<commit_after>const DrawCard = require('../../drawcard');

class TheIronThrone extends DrawCard {
    setupCardAbilities(ability) {
        this.reaction({
            when: {
                onPhaseStarted: () => true
            },
            cost: ability.costs.kneelSelf(),
            handler: () => {
                this.game.promptWithMenu(this.controller, this, {
                    activePrompt: {
                        menuTitle: 'Name a card',
                        controls: [
                            { type: 'card-name', command: 'menuButton', method: 'selectCardName' }
                        ]
                    }
                });
            }
        });
    }

    selectCardName(player, cardName) {
        this.game.addMessage('{0} kneels {1} to name {2}', player, this, cardName);
        this.untilEndOfPhase(ability => ({
            targetController: 'any',
            effect: [
                ability.effects.cannotMarshal(card => card.name.toLowerCase() === cardName.toLowerCase()),
                ability.effects.cannotPlay(card => card.name.toLowerCase() === cardName.toLowerCase()),
                ability.effects.cannotPutIntoPlay(card => card.name.toLowerCase() === cardName.toLowerCase())
            ]
        }));
        return true;
    }
}

TheIronThrone.code = '13117';

module.exports = TheIronThrone;
<|endoftext|>


<commit_before>var sakai = sakai || {};
var $ = $ || function() { throw "JQuery undefined"; };
var sdata = sdata || function() { throw "SDATA undefined"; };
var json_parse = json_parse || function() { throw "json_parse undefined"; };

sakai.remotecontent = function(tuid, placement, showSettings){
    var rootel = $("#" + tuid);
    var me = false;
    var bAdvancedSettingsDisplayed = false;
    var selectedBorderColor = "#cccccc";
    var iFrameStandardWidth = 550;
    var iFrameStandardHeight = 200;

    var iFramePreviewMaxWidth = 600;
    var iFramePreviewMaxHeight = 300;

	var defaultBoxBorderSize = 2;

    var selectedWidth;
    var selectedHeight;

    /**
     * Called when the data has been saved to the JCR.
     */
    var savedDataToJCR = function() {
    	sdata.container.informFinish(tuid);
    };

    /**
     * The function that fills in the input fields in the settings tab.
     * @param A JSON object that contains the necessary information.
     */
    var displaySettings = function(parameters) {
    	 if (parameters.url) {
	    	$("#remotecontent_settingsUrl").val(parameters.url);
	    	$("#remotecontent_previewFrame").attr('src', parameters.url);
	    	$("#remotecontent_width").val(parameters.width);
	    	$("#remotecontent_height").val(parameters.height);
	    	$("#remotecontent_borders").val(parameters.borderSize);
	    	selectedBorderColor = parameters.borderColor;

	    	var iWidth = (parseInt(parameters.width, 10) < iFramePreviewMaxWidth) ? parseInt(parameters.width, 10) : iFramePreviewMaxWidth;
	    	var iHeight = (parseInt(parameters.height, 10) < iFramePreviewMaxHeight) ? parseInt(parameters.height, 10) : iFramePreviewMaxHeight;

	    	$("#remotecontent_previewFrame").css({'width' : iWidth + 'px', 'height' : iHeight + 'px'});

	    	$(".remotecontent_colourBox").each(function() {
				if ($(this).css('background-color') === parameters.borderColor) {
					$(this).css({'border-width' : '2px'});
				}
			});

	    	//    	adjust the frame
	    	if (/^\d+$/.test(parameters.borderSize)) {
	        	//	give the selected one a nice border.
	        	$("#remotecontent_previewFrame").css({'border-width' : parameters.borderSize + 'px'});
	    	}
	    	$("#remotecontent_previewFrame").css({'border-color' : selectedBorderColor});
    	 }
    };

    /**
     * Will display the iframe.
     * @param A JSON object that contains the necessary information.
     */
    var displayRemoteContent = function(parameters) {

    	var sFrame = '';

		// show the iframe on the page.
		$("#remotecontent_mainContainer", rootel).append(sFrame);
    };

    /**
     * Will fetch the URL and other parameters from the JCR and according to which
     * view we are in, fill in the settings or display an iframe.
     */
    var getRemoteContent = function() {
    	sdata.Ajax.request({
   			url :"/sdata/f/" + placement + "/" + tuid + "/remotecontent?sid=" + Math.random(),
   			httpMethod : "GET",
   			onSuccess : function(data) {
    			//	We will get a JSON string that will contain the necessary information.
    			var parameters = json_parse(data);

    			if (showSettings) {
    		    	//	Fill in the settings page.
    		    	displaySettings(parameters);
    		    }
    		    else {
    		    	//	show the frame
    		    	displayRemoteContent(parameters);
    		    }
    		}

    	});
    };

    /**
     * This function shall save the settings too the jcr or
     * in case the user didn't fill in everything correctly show a remark.
     */
    var saveRemoteContent = function() {
    	//	Get all the values
    	var sURL = $("#remotecontent_settingsUrl").val();
    	var sWidth = $("#remotecontent_width").val() || iFrameStandardWidth;
    	var sHeight = $("#remotecontent_height").val() || iFrameStandardHeight;
    	var sBorderSize = $("#remotecontent_borders").val();

    	//	Check if all the necessary fields are filled in.
    	var bOK = true;
    	//	clear any errors that we might have.
    	$("#urlError").html("");
    	$("#sizeError").html("");
    	$("#borderError").html("");

    	if (sURL === "") {
    		bOK = false;
    		$("#urlError").html("Please enter an URL.
");
    	}
    	if ((sWidth !== "" && sHeight === "") || (sWidth === "" && sHeight !== "")) {
    		bOK = false;
    		$("#sizeError").append("Please enter a valid number for both input fields.
");
    	}
    	if (sWidth !== "" && sHeight !== "") {
    		if (!/^\d+$/.test(sWidth) || !/^\d+$/.test(sHeight)) {
        		bOK = false;
        		$("#sizeError").append("Please enter valid numbers only.
");
    		}
    	}
    	if (sBorderSize !== "" && !/^\d+$/.test(sBorderSize)) {
    		bOK = false;
    		$("#borderError").append("Please enter valid numbers only.
");
    	}

    	if (bOK) {

    		if (!sURL.match('http://')) {
    			sURL = 'http://' + sURL;
    		}

    		//	Everything is OK, save it to JCR.
    		var parameters = {"url" : sURL, "width" : sWidth, "height" : sHeight, "borderSize" : sBorderSize, "borderColor" : selectedBorderColor};

        	var str = sdata.JSON.stringify(parameters); // Convert the posts to a JSON string

    		sdata.widgets.WidgetPreference.save("/sdata/f/" + placement + "/" + tuid, "remotecontent", str, savedDataToJCR);
    	}
    };

	/**************************
	 * 	ALL THE BINDINGS
	 */

    //	set the standard width & height
    //$("#remotecontent_previewFrame").css({'width' : iFrameStandardWidth, 'height' : iFrameStandardHeight});

    $("#remotecontent_settingsUrl").change(function() {
    	//	Start fetch url
    	var sURL = $(this).val();
    	if (sURL !== "") {
    		if (!sURL.match('http://')) {
    			sURL = 'http://' + sURL;
    		}
        	$("#remotecontent_previewFrame").attr('src', sURL);
    	}
    });
    $("#remotecontent_width,#remotecontent_height").change(function() {
    	var sWidth = $("#remotecontent_width").val();
    	var sHeight = $("#remotecontent_height").val();
    	//	if the selected width is smaller then the allowed max width then we show it
    	//	if it is not then we will show a small warning

		$("#sizeError").html('');
    	if (/^\d+$/.test(sWidth)) {
	    	if (sWidth < iFramePreviewMaxWidth) {
	    		$("#remotecontent_previewFrame").css({'width' : sWidth + 'px'});
	    	}
	    	else {
	    		$("#sizeError").append('Don\'t worry! The width will be changed in the page, but won\'t be displayed in this preview.
');
	    	}
    	}
    	if (/^\d+$/.test(sHeight)) {
	    	if (sHeight < iFramePreviewMaxHeight) {
	    		$("#remotecontent_previewFrame").css({'height' : sHeight + 'px'});
	    	}
	    	else {
	    		$("#sizeError").append('Don\'t worry! The height will be changed in the page, but won\'t be displayed in this preview.
');
	    	}
    	}
    });

    $("#remotecontent_borders").change(function() {
    	if (/^\d+$/.test($("#remotecontent_borders").val())) {
    		$("#remotecontent_previewFrame").css({'border-width' : $("#remotecontent_borders").val() + 'px'});
    	}
    });

    //	toggle the advanced view
    $("#remotecontent_settingsBtnAdvanced").click(function(){
    	$("#remotecontent_settingsAdvanced").toggle();

    	bAdvancedSettingsDisplayed = !bAdvancedSettingsDisplayed;
    	//	change the picture up or down
    	if (bAdvancedSettingsDisplayed) {
    		$("#remotecontent_settingsBtnAdvanced").html("Advanced Settings ↑");
    	}
    	else {
    		$("#remotecontent_settingsBtnAdvanced").html("Advanced Settings ↓");
    	}
    });

    //	When you push the save button..
    $("#remotecontent_view_insert").click(function()  {
    	saveRemoteContent();
    });

	//	Cancel it
    $("#remotecontent_view_cancel").click(function()  {
    	sdata.container.informFinish(tuid);
    });

    //colourboxes animation
    $(".remotecontent_colourBox").click(function() {
    	//	save the selected color
    	selectedBorderColor = $(this).css('background-color');
    	//	remove all borders
    	$(".remotecontent_colourBox").css({'border-width' : '0'} );

    	//	give the selected one a nice border.
    	$(this).css({'border-width' : defaultBoxBorderSize + 'px'});

    	//	adjust the frame
    	var sBorderSize = $("#remotecontent_borders").val();
    	if (/^\d+$/.test(sBorderSize)) {
        	//	give the selected one a nice border.
        	$("#remotecontent_previewFrame").css({'border-width' : sBorderSize + 'px'});
    	}
    	$("#remotecontent_previewFrame").css({'border-color' : selectedBorderColor});
    });

    //	show settings or not?
    if (showSettings) {
    	$("#remotecontent_mainContainer").hide();
    	$("#remotecontent_settings").show();
    }
    else {
    	$("#remotecontent_settings").hide();
    	$("#remotecontent_mainContainer").show();
    }

	getRemoteContent();
};

sdata.widgets.WidgetLoader.informOnLoad("remotecontent");<commit_msg>NOJIRA Allowing 100% width<commit_after>var sakai = sakai || {};
var $ = $ || function() { throw "JQuery undefined"; };
var sdata = sdata || function() { throw "SDATA undefined"; };
var json_parse = json_parse || function() { throw "json_parse undefined"; };

sakai.remotecontent = function(tuid, placement, showSettings){
    var rootel = $("#" + tuid);
    var me = false;
    var bAdvancedSettingsDisplayed = false;
    var selectedBorderColor = "#cccccc";
    var iFrameStandardWidth = 550;
    var iFrameStandardHeight = 200;

    var iFramePreviewMaxWidth = 600;
    var iFramePreviewMaxHeight = 300;

	var defaultBoxBorderSize = 2;

    var selectedWidth;
    var selectedHeight;

    /**
     * Called when the data has been saved to the JCR.
     */
    var savedDataToJCR = function() {
    	sdata.container.informFinish(tuid);
    };

    /**
     * The function that fills in the input fields in the settings tab.
     * @param A JSON object that contains the necessary information.
     */
    var displaySettings = function(parameters) {
    	 if (parameters.url) {
	    	$("#remotecontent_settingsUrl").val(parameters.url);
	    	$("#remotecontent_previewFrame").attr('src', parameters.url);
	    	$("#remotecontent_width").val(parameters.width);
	    	$("#remotecontent_height").val(parameters.height);
	    	$("#remotecontent_borders").val(parameters.borderSize);
	    	selectedBorderColor = parameters.borderColor;

	    	var iWidth = (parseInt(parameters.width, 10) < iFramePreviewMaxWidth) ? parseInt(parameters.width, 10) : iFramePreviewMaxWidth;
	    	var iHeight = (parseInt(parameters.height, 10) < iFramePreviewMaxHeight) ? parseInt(parameters.height, 10) : iFramePreviewMaxHeight;

	    	$("#remotecontent_previewFrame").css({'width' : iWidth + 'px', 'height' : iHeight + 'px'});

	    	$(".remotecontent_colourBox").each(function() {
				if ($(this).css('background-color') === parameters.borderColor) {
					$(this).css({'border-width' : '2px'});
				}
			});

	    	//    	adjust the frame
	    	if (/^\d+$/.test(parameters.borderSize)) {
	        	//	give the selected one a nice border.
	        	$("#remotecontent_previewFrame").css({'border-width' : parameters.borderSize + 'px'});
	    	}
	    	$("#remotecontent_previewFrame").css({'border-color' : selectedBorderColor});
    	 }
    };

    /**
     * Will display the iframe.
     * @param A JSON object that contains the necessary information.
     */
    var displayRemoteContent = function(parameters) {

    	var sFrame = '';

		// show the iframe on the page.
		$("#remotecontent_mainContainer", rootel).append(sFrame);
    };

    /**
     * Will fetch the URL and other parameters from the JCR and according to which
     * view we are in, fill in the settings or display an iframe.
     */
    var getRemoteContent = function() {
    	sdata.Ajax.request({
   			url :"/sdata/f/" + placement + "/" + tuid + "/remotecontent?sid=" + Math.random(),
   			httpMethod : "GET",
   			onSuccess : function(data) {
    			//	We will get a JSON string that will contain the necessary information.
    			var parameters = json_parse(data);

    			if (showSettings) {
    		    	//	Fill in the settings page.
    		    	displaySettings(parameters);
    		    }
    		    else {
    		    	//	show the frame
    		    	displayRemoteContent(parameters);
    		    }
    		}

    	});
    };

    /**
     * This function shall save the settings too the jcr or
     * in case the user didn't fill in everything correctly show a remark.
     */
    var saveRemoteContent = function() {
    	//	Get all the values
    	var sURL = $("#remotecontent_settingsUrl").val();
    	var sWidth = $("#remotecontent_width").val() || iFrameStandardWidth;
    	var sHeight = $("#remotecontent_height").val() || iFrameStandardHeight;
    	var sBorderSize = $("#remotecontent_borders").val();

    	//	Check if all the necessary fields are filled in.
    	var bOK = true;
    	//	clear any errors that we might have.
    	$("#urlError").html("");
    	$("#sizeError").html("");
    	$("#borderError").html("");

    	if (sURL === "") {
    		bOK = false;
    		$("#urlError").html("Please enter an URL.
");
    	}
    	if ((sWidth !== "" && sHeight === "") || (sWidth === "" && sHeight !== "")) {
    		bOK = false;
    		$("#sizeError").append("Please enter a valid number for both input fields.
");
    	}
    	if (sWidth !== "" && sHeight !== "") {
    		//if (!/^\d+$/.test(sWidth) || !/^\d+$/.test(sHeight)) {
        	//	bOK = false;
        	//	$("#sizeError").append("Please enter valid numbers only.
");
    		//}
    	}
    	if (sBorderSize !== "" && !/^\d+$/.test(sBorderSize)) {
    		bOK = false;
    		$("#borderError").append("Please enter valid numbers only.
");
    	}

    	if (bOK) {

    		if (!sURL.match('http://')) {
    			sURL = 'http://' + sURL;
    		}

    		//	Everything is OK, save it to JCR.
    		var parameters = {"url" : sURL, "width" : sWidth, "height" : sHeight, "borderSize" : sBorderSize, "borderColor" : selectedBorderColor};

        	var str = sdata.JSON.stringify(parameters); // Convert the posts to a JSON string

    		sdata.widgets.WidgetPreference.save("/sdata/f/" + placement + "/" + tuid, "remotecontent", str, savedDataToJCR);
    	}
    };

	/**************************
	 * 	ALL THE BINDINGS
	 */

    //	set the standard width & height
    //$("#remotecontent_previewFrame").css({'width' : iFrameStandardWidth, 'height' : iFrameStandardHeight});

    $("#remotecontent_settingsUrl").change(function() {
    	//	Start fetch url
    	var sURL = $(this).val();
    	if (sURL !== "") {
    		if (!sURL.match('http://')) {
    			sURL = 'http://' + sURL;
    		}
        	$("#remotecontent_previewFrame").attr('src', sURL);
    	}
    });
    $("#remotecontent_width,#remotecontent_height").change(function() {
    	var sWidth = $("#remotecontent_width").val();
    	var sHeight = $("#remotecontent_height").val();
    	//	if the selected width is smaller then the allowed max width then we show it
    	//	if it is not then we will show a small warning

		$("#sizeError").html('');
    	if (/^\d+$/.test(sWidth)) {
	    	if (sWidth < iFramePreviewMaxWidth) {
	    		$("#remotecontent_previewFrame").css({'width' : sWidth + 'px'});
	    	}
	    	else {
	    		$("#sizeError").append('Don\'t worry! The width will be changed in the page, but won\'t be displayed in this preview.
');
	    	}
    	}
    	if (/^\d+$/.test(sHeight)) {
	    	if (sHeight < iFramePreviewMaxHeight) {
	    		$("#remotecontent_previewFrame").css({'height' : sHeight + 'px'});
	    	}
	    	else {
	    		$("#sizeError").append('Don\'t worry! The height will be changed in the page, but won\'t be displayed in this preview.
');
	    	}
    	}
    });

    $("#remotecontent_borders").change(function() {
    	if (/^\d+$/.test($("#remotecontent_borders").val())) {
    		$("#remotecontent_previewFrame").css({'border-width' : $("#remotecontent_borders").val() + 'px'});
    	}
    });

    //	toggle the advanced view
    $("#remotecontent_settingsBtnAdvanced").click(function(){
    	$("#remotecontent_settingsAdvanced").toggle();

    	bAdvancedSettingsDisplayed = !bAdvancedSettingsDisplayed;
    	//	change the picture up or down
    	if (bAdvancedSettingsDisplayed) {
    		$("#remotecontent_settingsBtnAdvanced").html("Advanced Settings ↑");
    	}
    	else {
    		$("#remotecontent_settingsBtnAdvanced").html("Advanced Settings ↓");
    	}
    });

    //	When you push the save button..
    $("#remotecontent_view_insert").click(function()  {
    	saveRemoteContent();
    });

	//	Cancel it
    $("#remotecontent_view_cancel").click(function()  {
    	sdata.container.informFinish(tuid);
    });

    //colourboxes animation
    $(".remotecontent_colourBox").click(function() {
    	//	save the selected color
    	selectedBorderColor = $(this).css('background-color');
    	//	remove all borders
    	$(".remotecontent_colourBox").css({'border-width' : '0'} );

    	//	give the selected one a nice border.
    	$(this).css({'border-width' : defaultBoxBorderSize + 'px'});

    	//	adjust the frame
    	var sBorderSize = $("#remotecontent_borders").val();
    	if (/^\d+$/.test(sBorderSize)) {
        	//	give the selected one a nice border.
        	$("#remotecontent_previewFrame").css({'border-width' : sBorderSize + 'px'});
    	}
    	$("#remotecontent_previewFrame").css({'border-color' : selectedBorderColor});
    });

    //	show settings or not?
    if (showSettings) {
    	$("#remotecontent_mainContainer").hide();
    	$("#remotecontent_settings").show();
    }
    else {
    	$("#remotecontent_settings").hide();
    	$("#remotecontent_mainContainer").show();
    }

	getRemoteContent();
};

sdata.widgets.WidgetLoader.informOnLoad("remotecontent");<|endoftext|>


<commit_before>"use strict";

var KEY = require('./keys.js'),
    rubix = require('../action/rubix.js');

module.exports = {
    // Is this action active
    active: false,

    // What to use to process this aciton
    rubix: rubix[KEY.RUBIX.TIME],

    // Multiply output value by
    amp: 1,

    // Multiply output value outside min/max by
    escapeAmp: 0,

    // Delay this action by x ms
    delay: 0,

    // Time of animation (if animating) in ms
    duration: 400,

    // Ease animation
    ease: 'easeInOut',

    // Round output value?
    round: false,

    // Divide animation into this many steps
    steps: 0,

    //
    dilate: 1,

    playhead: 0,

    // The object we're checking
    input: undefined,

    // Input origin on tracking start
    inputOrigin: undefined,

    // Use the progress of this property of linked input
    link: undefined,

    // Loop animation x number of times (true for ETERNALLY)
    loop: false,

    // Number of times animation has looped
    loopCount: 0,

    // Play animation and reverse x number of times (true for forever)
    yoyo: false,

    // Number of times animation has yoyoed
    yoyoCount: 0,

    // Run this callback on action start
    onStart: undefined,

    // Run this on action end
    onEnd: undefined,

    // Run this every frame
    onFrame: undefined,

    // Run this when action changes
    onChange: undefined
};<commit_msg>removing rubix default<commit_after>"use strict";

module.exports = {
    // Is this action active
    active: false,

    // What to use to process this aciton
    rubix: undefined,

    // Multiply output value by
    amp: 1,

    // Multiply output value outside min/max by
    escapeAmp: 0,

    // Delay this action by x ms
    delay: 0,

    // Time of animation (if animating) in ms
    duration: 400,

    // Ease animation
    ease: 'easeInOut',

    // Round output value?
    round: false,

    // Divide animation into this many steps
    steps: 0,

    //
    dilate: 1,

    playhead: 0,

    // The object we're checking
    input: undefined,

    // Input origin on tracking start
    inputOrigin: undefined,

    // Use the progress of this property of linked input
    link: undefined,

    // Loop animation x number of times (true for ETERNALLY)
    loop: false,

    // Number of times animation has looped
    loopCount: 0,

    // Play animation and reverse x number of times (true for forever)
    yoyo: false,

    // Number of times animation has yoyoed
    yoyoCount: 0,

    // Run this callback on action start
    onStart: undefined,

    // Run this on action end
    onEnd: undefined,

    // Run this every frame
    onFrame: undefined,

    // Run this when action changes
    onChange: undefined
};<|endoftext|>


<commit_before><commit_msg>commit<commit_after><|endoftext|>


<commit_before>/*
 * Copyright © 2016 Cask Data, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

class HydratorPlusPlusPreConfiguredCtrl {
  constructor (rTemplateType, GLOBALS, myPipelineTemplatesApi, HydratorPlusPlusHydratorService, HydratorPlusPlusCanvasFactory, DAGPlusPlusNodesActionsFactory, $state, HydratorPlusPlusConfigStore, myAlertOnValium) {
    this.currentPage = 1;
    this.templates = [];
    this.HydratorPlusPlusHydratorService = HydratorPlusPlusHydratorService;
    this.HydratorPlusPlusCanvasFactory = HydratorPlusPlusCanvasFactory;
    this.myPipelineTemplatesApi = myPipelineTemplatesApi;
    this.DAGPlusPlusNodesActionsFactory = DAGPlusPlusNodesActionsFactory;
    this.HydratorPlusPlusConfigStore = HydratorPlusPlusConfigStore;
    this.GLOBALS = GLOBALS;
    this.$state = $state;
    this.myAlertOnValium = myAlertOnValium;

    this.typeFilter = rTemplateType;
    this.fetchTemplates().then((plugins) => {
      this.templates = plugins;
    });
  }

  selectTemplate(template) {
    this.HydratorPlusPlusConfigStore.setState(this.HydratorPlusPlusConfigStore.getDefaults());
    this.$state.go('hydratorplusplus.create', {
      data: template._properties
    });
  }

  fetchTemplates() {
    return this.myPipelineTemplatesApi.list({
      apptype: this.typeFilter
    })
      .$promise
      .then( (res) => {
        let plugins = res.map( (plugin) => {
          return {
            name: plugin.name,
            description: plugin.description,
            type: this.typeFilter
          };
        });

        angular.forEach(plugins, (plugin) => {
          this.myPipelineTemplatesApi.get({
            apptype: this.typeFilter,
            appname: plugin.name
          })
            .$promise
            .then( (res) => {
              plugin._properties = res;
              delete plugin._properties.$promise;
              delete plugin._properties.$resolved;

              plugin._source = res.config.stages.filter( (stage) => {
                return this.GLOBALS.pluginConvert[stage.plugin.type] === 'source';
              });
              plugin._sinks = res.config.stages.filter( (stage) => {
                return this.GLOBALS.pluginConvert[stage.plugin.type] === 'sink';
              });
            });
        });

        return plugins;
      });
  }

}

HydratorPlusPlusPreConfiguredCtrl.$inject = ['rTemplateType', 'GLOBALS', 'myPipelineTemplatesApi', 'HydratorPlusPlusHydratorService', 'HydratorPlusPlusCanvasFactory', 'DAGPlusPlusNodesActionsFactory', '$state', 'HydratorPlusPlusConfigStore', 'myAlertOnValium'];
angular.module(`${PKG.name}.feature.hydratorplusplus`)
  .controller('HydratorPlusPlusPreConfiguredCtrl', HydratorPlusPlusPreConfiguredCtrl);
<commit_msg>fix reloading studio when clicking on template gallery while editing draft<commit_after>/*
 * Copyright © 2016 Cask Data, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

class HydratorPlusPlusPreConfiguredCtrl {
  constructor (rTemplateType, GLOBALS, myPipelineTemplatesApi, HydratorPlusPlusHydratorService, HydratorPlusPlusCanvasFactory, DAGPlusPlusNodesActionsFactory, $state, HydratorPlusPlusConfigStore, myAlertOnValium) {
    this.currentPage = 1;
    this.templates = [];
    this.HydratorPlusPlusHydratorService = HydratorPlusPlusHydratorService;
    this.HydratorPlusPlusCanvasFactory = HydratorPlusPlusCanvasFactory;
    this.myPipelineTemplatesApi = myPipelineTemplatesApi;
    this.DAGPlusPlusNodesActionsFactory = DAGPlusPlusNodesActionsFactory;
    this.HydratorPlusPlusConfigStore = HydratorPlusPlusConfigStore;
    this.GLOBALS = GLOBALS;
    this.$state = $state;
    this.myAlertOnValium = myAlertOnValium;

    this.typeFilter = rTemplateType;
    this.fetchTemplates().then((plugins) => {
      this.templates = plugins;
    });
  }

  selectTemplate(template) {
    this.HydratorPlusPlusConfigStore.setState(this.HydratorPlusPlusConfigStore.getDefaults());
    this.$state.go('hydratorplusplus.create', {
      data: template._properties,
      draftId: null
    });
  }

  fetchTemplates() {
    return this.myPipelineTemplatesApi.list({
      apptype: this.typeFilter
    })
      .$promise
      .then( (res) => {
        let plugins = res.map( (plugin) => {
          return {
            name: plugin.name,
            description: plugin.description,
            type: this.typeFilter
          };
        });

        angular.forEach(plugins, (plugin) => {
          this.myPipelineTemplatesApi.get({
            apptype: this.typeFilter,
            appname: plugin.name
          })
            .$promise
            .then( (res) => {
              plugin._properties = res;
              delete plugin._properties.$promise;
              delete plugin._properties.$resolved;

              plugin._source = res.config.stages.filter( (stage) => {
                return this.GLOBALS.pluginConvert[stage.plugin.type] === 'source';
              });
              plugin._sinks = res.config.stages.filter( (stage) => {
                return this.GLOBALS.pluginConvert[stage.plugin.type] === 'sink';
              });
            });
        });

        return plugins;
      });
  }

}

HydratorPlusPlusPreConfiguredCtrl.$inject = ['rTemplateType', 'GLOBALS', 'myPipelineTemplatesApi', 'HydratorPlusPlusHydratorService', 'HydratorPlusPlusCanvasFactory', 'DAGPlusPlusNodesActionsFactory', '$state', 'HydratorPlusPlusConfigStore', 'myAlertOnValium'];
angular.module(`${PKG.name}.feature.hydratorplusplus`)
  .controller('HydratorPlusPlusPreConfiguredCtrl', HydratorPlusPlusPreConfiguredCtrl);
<|endoftext|>