<commit_before>/** Initialization code for the project overview page. */
'use strict';

var $ = require('jquery');
require('../../vendor/bower_components/jquery.tagsinput/jquery.tagsinput.css');
require('jquery-tagsinput');
require('bootstrap-editable');

var m = require('mithril');
var Fangorn = require('js/fangorn');
var Raven = require('raven-js');
require('truncate');

var LogFeed = require('js/logFeed');
var pointers = require('js/pointers');
var Comment = require('js/comment');
var NodeControl = require('js/nodeControl');
var CitationList = require('js/citationList');
var CitationWidget = require('js/citationWidget');
var mathrender = require('js/mathrender');
var md = require('js/markdown').full;

var ctx = window.contextVars;
var nodeApiUrl = ctx.node.urls.api;

// Initialize controller for "Add Links" modal
new pointers.PointerManager('#addPointer', window.contextVars.node.title);

// Listen for the nodeLoad event (prevents multiple requests for data)
$('body').on('nodeLoad', function(event, data) {
    new LogFeed('#logScope', nodeApiUrl + 'log/');
    // Initialize nodeControl
    new NodeControl.NodeControl('#projectScope', data);
});

// Initialize comment pane w/ it's viewmodel
var $comments = $('#comments');
if ($comments.length) {
    var userName = window.contextVars.currentUser.name;
    var canComment = window.contextVars.currentUser.canComment;
    var hasChildren = window.contextVars.node.hasChildren;
    Comment.init('#commentPane', userName, canComment, hasChildren);
}

// Initialize CitationWidget if user isn't viewing through an anonymized VOL
if (!ctx.node.anonymous) {
    new CitationList('#citationList');
    new CitationWidget('#citationStyleInput', '#citationText');
}

$(document).ready(function() {
    // Treebeard Files view
    $.ajax({
        url:  nodeApiUrl + 'files/grid/'
    })
    .done(function( data ) {
        var fangornOpts = {
            divID: 'treeGrid',
            filesData: data.data,
            uploads : true,
            showFilter : true,
            placement: 'dashboard',
            title : undefined,
            filterFullWidth : true, // Make the filter span the entire row for this view
            columnTitles : function(){
                return [
                    {
                        title : '',
                        width: '10%',
                        sort: false
                    },
                    {
                    title: 'Name',
                    width : '90%',
                    sort : true,
                    sortType : 'text'
                    }
                ];
            },
            resolveRows : function(item){
                var defaultColumns = [
                {
                    data : null,
                    folderIcons: false,
                    filter : false,
                    custom : function(){
                        return m('div.fangorn-select-toggle', m('i.fa.fa-square-o'));
                    }
                },
                {
                    data: 'name',
                    folderIcons: true,
                    filter: true,
                    custom: Fangorn.DefaultColumns._fangornTitleColumn
                }];
                this.options.defineToolbar.call(this,item);
                if (item.parentID) {
                    item.data.permissions = item.data.permissions || item.parent().data.permissions;
                    if (item.data.kind === 'folder') {
                        item.data.accept = item.data.accept || item.parent().data.accept;
                    }
                }

                if(item.data.tmpID){
                    defaultColumns = [
                        {
                            data : '',  // Data field name
                            custom : function(){ return m('span', ''); }
                        },
                        {
                            data : 'name',  // Data field name
                            folderIcons : true,
                            filter : true,
                            custom : function(){ return m('span.text-muted', 'Uploading ' + item.data.name + '...'); }
                        }
                    ];
                }

                var configOption = Fangorn.Utils.resolveconfigOption.call(this, item, 'resolveRows', [item]);
                return configOption || defaultColumns;
            }
        };
        var filebrowser = new Fangorn(fangornOpts);
    });

    // Tooltips
    $('[data-toggle="tooltip"]').tooltip({container: 'body'});

    // Tag input
    $('#node-tags').tagsInput({
        width: '100%',
        interactive: window.contextVars.currentUser.canEdit,
        maxChars: 128,
        onAddTag: function(tag){
            var url = window.contextVars.node.urls.api + 'addtag/' + tag + '/';
            var request = $.ajax({
                url: url,
                type: 'POST',
                contentType: 'application/json'
            });
            request.fail(function(xhr, textStatus, error) {
                Raven.captureMessage('Failed to add tag', {
                    tag: tag, url: url, textStatus: textStatus, error: error
                });
            });
        },
        onRemoveTag: function(tag){
            var url = window.contextVars.node.urls.api + 'removetag/' + tag + '/';
            var request = $.ajax({
                url: url,
                type: 'POST',
                contentType: 'application/json'
            });
            request.fail(function(xhr, textStatus, error) {
                Raven.captureMessage('Failed to remove tag', {
                    tag: tag, url: url, textStatus: textStatus, error: error
                });
            });
        }
    });

    // Limit the maximum length that you can type when adding a tag
    $('#node-tags_tag').attr('maxlength', '128');

    // Wiki widget markdown rendering
    if (ctx.wikiWidget) {
        // Render math in the wiki widget
        var markdownElement = $('#markdownRender');
        mathrender.mathjaxify(markdownElement);

        // Render the raw markdown of the wiki
        if (!ctx.usePythonRender) {
            var request = $.ajax({
                url: ctx.urls.wikiContent
            });
            request.done(function(resp) {
                var rawText = resp.wiki_content || '*No wiki content*';
                var renderedText = md.render(rawText);
                var truncatedText = $.truncate(renderedText, {length: 400});
                markdownElement.html(truncatedText);
                mathrender.mathjaxify(markdownElement);
            });
        }
    }

    // Remove delete UI if not contributor
    if (!window.contextVars.currentUser.canEdit || window.contextVars.node.isRegistration) {
        $('a[title="Removing tag"]').remove();
        $('span.tag span').each(function(idx, elm) {
            $(elm).text($(elm).text().replace(/\s*$/, ''));
        });
    }

    if (window.contextVars.node.isRegistration && window.contextVars.node.tags.length === 0) {
        $('div.tags').remove();
    }
});
<commit_msg>Remove checkboxes from project overview page [skip ci]<commit_after>/** Initialization code for the project overview page. */
'use strict';

var $ = require('jquery');
require('../../vendor/bower_components/jquery.tagsinput/jquery.tagsinput.css');
require('jquery-tagsinput');
require('bootstrap-editable');

var m = require('mithril');
var Fangorn = require('js/fangorn');
var Raven = require('raven-js');
require('truncate');

var LogFeed = require('js/logFeed');
var pointers = require('js/pointers');
var Comment = require('js/comment');
var NodeControl = require('js/nodeControl');
var CitationList = require('js/citationList');
var CitationWidget = require('js/citationWidget');
var mathrender = require('js/mathrender');
var md = require('js/markdown').full;

var ctx = window.contextVars;
var nodeApiUrl = ctx.node.urls.api;

// Initialize controller for "Add Links" modal
new pointers.PointerManager('#addPointer', window.contextVars.node.title);

// Listen for the nodeLoad event (prevents multiple requests for data)
$('body').on('nodeLoad', function(event, data) {
    new LogFeed('#logScope', nodeApiUrl + 'log/');
    // Initialize nodeControl
    new NodeControl.NodeControl('#projectScope', data);
});

// Initialize comment pane w/ it's viewmodel
var $comments = $('#comments');
if ($comments.length) {
    var userName = window.contextVars.currentUser.name;
    var canComment = window.contextVars.currentUser.canComment;
    var hasChildren = window.contextVars.node.hasChildren;
    Comment.init('#commentPane', userName, canComment, hasChildren);
}

// Initialize CitationWidget if user isn't viewing through an anonymized VOL
if (!ctx.node.anonymous) {
    new CitationList('#citationList');
    new CitationWidget('#citationStyleInput', '#citationText');
}

$(document).ready(function() {
    // Treebeard Files view
    $.ajax({
        url:  nodeApiUrl + 'files/grid/'
    })
    .done(function( data ) {
        var fangornOpts = {
            divID: 'treeGrid',
            filesData: data.data,
            uploads : true,
            showFilter : true,
            placement: 'dashboard',
            title : undefined,
            filterFullWidth : true, // Make the filter span the entire row for this view
            columnTitles : function(){
                return [
                    {
                    title: 'Name',
                    width : '90%',
                    sort : true,
                    sortType : 'text'
                    }
                ];
            },
            resolveRows : function(item){
                var defaultColumns = [
                {
                    data: 'name',
                    folderIcons: true,
                    filter: true,
                    custom: Fangorn.DefaultColumns._fangornTitleColumn
                }];
                this.options.defineToolbar.call(this,item);
                if (item.parentID) {
                    item.data.permissions = item.data.permissions || item.parent().data.permissions;
                    if (item.data.kind === 'folder') {
                        item.data.accept = item.data.accept || item.parent().data.accept;
                    }
                }

                if(item.data.tmpID){
                    defaultColumns = [
                        {
                            data : '',  // Data field name
                            custom : function(){ return m('span', ''); }
                        },
                        {
                            data : 'name',  // Data field name
                            folderIcons : true,
                            filter : true,
                            custom : function(){ return m('span.text-muted', 'Uploading ' + item.data.name + '...'); }
                        }
                    ];
                }

                var configOption = Fangorn.Utils.resolveconfigOption.call(this, item, 'resolveRows', [item]);
                return configOption || defaultColumns;
            }
        };
        var filebrowser = new Fangorn(fangornOpts);
    });

    // Tooltips
    $('[data-toggle="tooltip"]').tooltip({container: 'body'});

    // Tag input
    $('#node-tags').tagsInput({
        width: '100%',
        interactive: window.contextVars.currentUser.canEdit,
        maxChars: 128,
        onAddTag: function(tag){
            var url = window.contextVars.node.urls.api + 'addtag/' + tag + '/';
            var request = $.ajax({
                url: url,
                type: 'POST',
                contentType: 'application/json'
            });
            request.fail(function(xhr, textStatus, error) {
                Raven.captureMessage('Failed to add tag', {
                    tag: tag, url: url, textStatus: textStatus, error: error
                });
            });
        },
        onRemoveTag: function(tag){
            var url = window.contextVars.node.urls.api + 'removetag/' + tag + '/';
            var request = $.ajax({
                url: url,
                type: 'POST',
                contentType: 'application/json'
            });
            request.fail(function(xhr, textStatus, error) {
                Raven.captureMessage('Failed to remove tag', {
                    tag: tag, url: url, textStatus: textStatus, error: error
                });
            });
        }
    });

    // Limit the maximum length that you can type when adding a tag
    $('#node-tags_tag').attr('maxlength', '128');

    // Wiki widget markdown rendering
    if (ctx.wikiWidget) {
        // Render math in the wiki widget
        var markdownElement = $('#markdownRender');
        mathrender.mathjaxify(markdownElement);

        // Render the raw markdown of the wiki
        if (!ctx.usePythonRender) {
            var request = $.ajax({
                url: ctx.urls.wikiContent
            });
            request.done(function(resp) {
                var rawText = resp.wiki_content || '*No wiki content*';
                var renderedText = md.render(rawText);
                var truncatedText = $.truncate(renderedText, {length: 400});
                markdownElement.html(truncatedText);
                mathrender.mathjaxify(markdownElement);
            });
        }
    }

    // Remove delete UI if not contributor
    if (!window.contextVars.currentUser.canEdit || window.contextVars.node.isRegistration) {
        $('a[title="Removing tag"]').remove();
        $('span.tag span').each(function(idx, elm) {
            $(elm).text($(elm).text().replace(/\s*$/, ''));
        });
    }

    if (window.contextVars.node.isRegistration && window.contextVars.node.tags.length === 0) {
        $('div.tags').remove();
    }
});
<|endoftext|>


<commit_before>cjsRequire('whatwg-fetch')
const tenaciousFetch = cjsRequire('tenacious-fetch').default

const { HttpRangeFetcher } = cjsRequire('http-range-fetcher')
const { Buffer } = cjsRequire('buffer')

define( [ 'dojo/_base/declare',
          'JBrowse/Util',
          'JBrowse/Model/FileBlob',
        ],
        function( declare, Util, FileBlob  ) {

//throw 404 errors for plain-old-fetch xref https://github.com/github/fetch/issues/155
function fetchwrapper(f) {
  return function(url, options) {
    return f(url, options).then(function(res) {
        if (res.status >= 200 && res.status < 300) {
          return Promise.resolve(res)
        } else {
          const error = new Error(`HTTP ${res.status} when fetching ${res.url}`)
          error.response = res
          return Promise.reject(error)
        }
      })
  }
}
function getfetch(url, opts = {}) {
    let mfetch
    if(Util.isElectron()) {
        if(url.slice(0, 4) === 'http') {
            mfetch = fetchwrapper(electronRequire('node-fetch'))
        } else {
            url = url.replace('%20', ' ')
            mfetch = fetchwrapper(fetch)
        }
    } else {
        mfetch = tenaciousFetch // already throws on 404
    }
    return mfetch(url, Object.assign({
        method: 'GET',
        credentials: 'same-origin',
        retries: 5,
        retryDelay: 1000, // 1 sec, 2 sec, 3 sec
        retryStatus: [500, 404, 503],
        onRetry: ({retriesLeft, retryDelay}) => {
            console.warn(`${url} request failed, retrying (${retriesLeft} retries left)`)
        }
    }, opts))
}

function fetchBinaryRange(url, start, end) {
    const requestDate = new Date()
    const headers = {
        headers: { range: `bytes=${start}-${end}` },
        onRetry: ({retriesLeft, retryDelay}) => {
            console.warn(`${url} bytes ${start}-${end} request failed, retrying (${retriesLeft} retries left)`)
        }
    }

    return getfetch(url, headers).then(res => {
      const responseDate = new Date()
      if (res.status !== 206 && res.status !== 200)
        throw new Error(
          `HTTP ${res.status} when fetching ${url} bytes ${start}-${end}`,
        )

      // translate the Headers object into a regular key -> value object.
      // will miss duplicate headers of course
      const headers = {}
      for (let entry of res.headers.entries()) {
          headers[entry[0]] = entry[1]
      }

      if (Util.isElectron()) {
        // electron charmingly returns HTTP 200 for byte range requests,
        // and does not fill in content-range. so we will fill it in
        try {
            if(!headers['content-range']) {
                const fs = electronRequire("fs"); //Load the filesystem module
                const stats = fs.statSync(Util.unReplacePath(url))
                headers['content-range'] = `${start}-${end}/${stats.size}`
            }
        } catch(e) {
            console.error('Could not get size of file', url, e)
        }
      } else if(res.status === 200) {
        throw new Error(
          `HTTP ${res.status} when fetching ${url} bytes ${start}-${end}`,
        )
      }

      // return the response headers, and the data buffer
      return res.arrayBuffer()
        .then(arrayBuffer => ({
            headers,
            requestDate,
            responseDate,
            buffer: Buffer.from(arrayBuffer),
        }))
    }, res => {
        throw new Error(`HTTP ${res.status} when fetching ${url} bytes ${start}-${end}`)
    })
}
const globalCache = new HttpRangeFetcher({
    fetch: fetchBinaryRange,
    size: 50 * 1024 * 1024, // 50MB
    chunkSize: Math.pow(2,18), // 256KB
    aggregationTime: 50,
})

var XHRBlob = declare( FileBlob,
/**
 * @lends JBrowse.Model.XHRBlob.prototype
 */
{

    /**
     * Blob of binary data fetched with an XMLHTTPRequest.
     *
     * Adapted by Robert Buels from the URLFetchable object in the
     * Dalliance Genome Explorer, which was is copyright Thomas Down
     * 2006-2011.
     * @constructs
     */
    constructor(url, start, end, opts) {
        if (!opts) {
            if (typeof start === 'object') {
                opts = start;
                start = undefined;
            } else {
                opts = {};
            }
        }

        this.url = url;
        this.start = start || 0;
        if (end) {
            this.end = end;
        }
        this.opts = opts;
    },

    slice(s, l) {
        var ns = this.start, ne = this.end;
        if (ns && s) {
            ns = ns + s;
        } else {
            ns = s || ns;
        }
        if (l && ns) {
            ne = ns + l - 1;
        } else {
            ne = ne || l - 1;
        }
        return new XHRBlob(this.url, ns, ne, this.opts);
    },

    fetch( callback, failCallback ) {
        const length = this.end === undefined ? undefined : this.end - this.start + 1
        if (length < 0) {
            throw new Error('Length less than 0 received')
        } else if(length == undefined && this.start == 0) {
            getfetch(this.url)
                .then(res => res.arrayBuffer())
                .then(callback)
                .catch(failCallback)
        } else {
            globalCache.getRange(this.url, this.start, length)
                .then(
                    this._getResponseArrayBuffer.bind(this,callback),
                    failCallback,
                )
        }
    },

    async fetchBufferPromise() {
        const length = this.end === undefined ? undefined : this.end - this.start + 1
        try {
            if (length < 0) {
                throw new Error('Length less than 0 received')
            } else if(length == undefined && this.start == 0) {
                const range = await getfetch(this.url)
                return new Buffer(await range.arrayBuffer())
            } else {
                var range = await globalCache.getRange(this.url, this.start, length)
                return range.buffer
            }
        } catch(e) {
            if(!e.message) {
                const bytes = length? ` bytes ${this.start}-${this.end}` : ''
                throw new Error(
                    `HTTP ${e.status} when fetching ${e.url} ${bytes}`
                )
            }
            throw e
        }
    },

    _getResponseArrayBuffer(callback,{buffer}) {
        if (buffer.buffer) {
            const arrayBuffer = buffer.buffer.slice(
                buffer.byteOffset, buffer.byteOffset + buffer.byteLength
            )
            callback(arrayBuffer)
        } else throw new Error('could not convert response to ArrayBuffer')

    },

    read( offset = 0, length, callback, failCallback ) {
        globalCache.getRange(this.url, this.start + offset, length)
            .then(
                this._getResponseArrayBuffer.bind(this,callback),
                failCallback,
            )
    },

    async readBufferPromise(offset = 0, length) {
        const range = await globalCache.getRange(this.url, this.start + offset, length)
        return range.buffer
    },

    stat(callback, failCallback) {
        this.statPromise().then(callback, failCallback)
    },

    statPromise() {
        return globalCache.stat(this.url)
    }
});
return XHRBlob;
});
<commit_msg>Make XHRBlob perform a throw if response.ok false (#1491)<commit_after>cjsRequire('whatwg-fetch')
const tenaciousFetch = cjsRequire('tenacious-fetch').default

const { HttpRangeFetcher } = cjsRequire('http-range-fetcher')
const { Buffer } = cjsRequire('buffer')

define( [ 'dojo/_base/declare',
          'JBrowse/Util',
          'JBrowse/Model/FileBlob',
        ],
        function( declare, Util, FileBlob  ) {

//throw 404 errors for plain-old-fetch xref https://github.com/github/fetch/issues/155
function fetchwrapper(f) {
  return function(url, options) {
    return f(url, options).then(function(res) {
        if (res.status >= 200 && res.status < 300) {
          return Promise.resolve(res)
        } else {
          const error = new Error(`HTTP ${res.status} when fetching ${res.url}`)
          error.response = res
          return Promise.reject(error)
        }
      })
  }
}
function getfetch(url, opts = {}) {
    let mfetch
    if(Util.isElectron()) {
        if(url.slice(0, 4) === 'http') {
            mfetch = fetchwrapper(electronRequire('node-fetch'))
        } else {
            url = url.replace('%20', ' ')
            mfetch = fetchwrapper(fetch)
        }
    } else {
        mfetch = tenaciousFetch // already throws on 404
    }
    return mfetch(url, Object.assign({
        method: 'GET',
        credentials: 'same-origin',
        retries: 5,
        retryDelay: 1000, // 1 sec, 2 sec, 3 sec
        retryStatus: [500, 404, 503],
        onRetry: ({retriesLeft, retryDelay}) => {
            console.warn(`${url} request failed, retrying (${retriesLeft} retries left)`)
        }
    }, opts))
}

function fetchBinaryRange(url, start, end) {
    const requestDate = new Date()
    const headers = {
        headers: { range: `bytes=${start}-${end}` },
        onRetry: ({retriesLeft, retryDelay}) => {
            console.warn(`${url} bytes ${start}-${end} request failed, retrying (${retriesLeft} retries left)`)
        }
    }

    return getfetch(url, headers).then(res => {
      const responseDate = new Date()
      if (res.status !== 206 && res.status !== 200)
        throw new Error(
          `HTTP ${res.status} when fetching ${url} bytes ${start}-${end}`,
        )

      // translate the Headers object into a regular key -> value object.
      // will miss duplicate headers of course
      const headers = {}
      for (let entry of res.headers.entries()) {
          headers[entry[0]] = entry[1]
      }

      if (Util.isElectron()) {
        // electron charmingly returns HTTP 200 for byte range requests,
        // and does not fill in content-range. so we will fill it in
        try {
            if(!headers['content-range']) {
                const fs = electronRequire("fs"); //Load the filesystem module
                const stats = fs.statSync(Util.unReplacePath(url))
                headers['content-range'] = `${start}-${end}/${stats.size}`
            }
        } catch(e) {
            console.error('Could not get size of file', url, e)
        }
      } else if(res.status === 200) {
        throw new Error(
          `HTTP ${res.status} when fetching ${url} bytes ${start}-${end}`,
        )
      }

      // return the response headers, and the data buffer
      return res.arrayBuffer()
        .then(arrayBuffer => ({
            headers,
            requestDate,
            responseDate,
            buffer: Buffer.from(arrayBuffer),
        }))
    }, res => {
        throw new Error(`HTTP ${res.status} when fetching ${url} bytes ${start}-${end}`)
    })
}
const globalCache = new HttpRangeFetcher({
    fetch: fetchBinaryRange,
    size: 50 * 1024 * 1024, // 50MB
    chunkSize: Math.pow(2,18), // 256KB
    aggregationTime: 50,
})

var XHRBlob = declare( FileBlob,
/**
 * @lends JBrowse.Model.XHRBlob.prototype
 */
{

    /**
     * Blob of binary data fetched with an XMLHTTPRequest.
     *
     * Adapted by Robert Buels from the URLFetchable object in the
     * Dalliance Genome Explorer, which was is copyright Thomas Down
     * 2006-2011.
     * @constructs
     */
    constructor(url, start, end, opts) {
        if (!opts) {
            if (typeof start === 'object') {
                opts = start;
                start = undefined;
            } else {
                opts = {};
            }
        }

        this.url = url;
        this.start = start || 0;
        if (end) {
            this.end = end;
        }
        this.opts = opts;
    },

    slice(s, l) {
        var ns = this.start, ne = this.end;
        if (ns && s) {
            ns = ns + s;
        } else {
            ns = s || ns;
        }
        if (l && ns) {
            ne = ns + l - 1;
        } else {
            ne = ne || l - 1;
        }
        return new XHRBlob(this.url, ns, ne, this.opts);
    },

    fetch( callback, failCallback ) {
        const length = this.end === undefined ? undefined : this.end - this.start + 1
        if (length < 0) {
            throw new Error('Length less than 0 received')
        } else if(length == undefined && this.start == 0) {
            getfetch(this.url)
                .then(res => res.arrayBuffer())
                .then(callback)
                .catch(failCallback)
        } else {
            globalCache.getRange(this.url, this.start, length)
                .then(
                    this._getResponseArrayBuffer.bind(this,callback),
                    failCallback,
                )
        }
    },

    async fetchBufferPromise() {
        const length = this.end === undefined ? undefined : this.end - this.start + 1
        try {
            if (length < 0) {
                throw new Error('Length less than 0 received')
            } else if(length == undefined && this.start == 0) {
                const range = await getfetch(this.url)
                if(!range.ok) {
                    throw new Error(
                        `HTTP ${range.status} when fetching ${this.url}`
                    )
                }
                return new Buffer(await range.arrayBuffer())
            } else {
                var range = await globalCache.getRange(this.url, this.start, length)
                return range.buffer
            }
        } catch(e) {
            if(!e.message) {
                const bytes = length? ` bytes ${this.start}-${this.end}` : ''
                throw new Error(
                    `HTTP ${e.status} when fetching ${e.url} ${bytes}`
                )
            }
            throw e
        }
    },

    _getResponseArrayBuffer(callback,{buffer}) {
        if (buffer.buffer) {
            const arrayBuffer = buffer.buffer.slice(
                buffer.byteOffset, buffer.byteOffset + buffer.byteLength
            )
            callback(arrayBuffer)
        } else throw new Error('could not convert response to ArrayBuffer')

    },

    read( offset = 0, length, callback, failCallback ) {
        globalCache.getRange(this.url, this.start + offset, length)
            .then(
                this._getResponseArrayBuffer.bind(this,callback),
                failCallback,
            )
    },

    async readBufferPromise(offset = 0, length) {
        const range = await globalCache.getRange(this.url, this.start + offset, length)
        return range.buffer
    },

    stat(callback, failCallback) {
        this.statPromise().then(callback, failCallback)
    },

    statPromise() {
        return globalCache.stat(this.url)
    }
});
return XHRBlob;
});
<|endoftext|>


<commit_before>'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _invariant = require('invariant');

var _invariant2 = _interopRequireDefault(_invariant);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Verify that a given variable is of a particular type.
 * @param {*} variable - the variable being verified
 * @param {String} type - the expected type of the variable
 */
function verifyVariableIsType(variable, type) {
  (0, _invariant2.default)((typeof variable === 'undefined' ? 'undefined' : _typeof(variable)) === type, variable + ' must be a ' + type);
}

/**
 * Created by hunterhodnett on 7/24/17.
 */

var Logger = function () {
  /**
   * Conctructor
   * @param {String} moduleName - name of the module that is consuming Logger
   */
  function Logger(moduleName) {
    _classCallCheck(this, Logger);

    verifyVariableIsType(moduleName, 'string');
    this.moduleName = moduleName;
  }

  /**
   * Log a message to the browser console
   * @param {String} message - message to be logged
   */

  _createClass(Logger, [{
    key: 'log',
    value: function log(message) {
      verifyVariableIsType(message, 'string');
      console.log(this.moduleName + ': ' + message);
    }

    /**
     * Log a warning to the console
     * @param {String} message
     */

  }, {
    key: 'warn',
    value: function warn(message) {
      verifyVariableIsType(message, 'string');
      console.warn(this.moduleName + ': ' + message);
    }

    /**
     * Log an error to the console
     * @param {String} message
     */

  }, {
    key: 'error',
    value: function error(message) {
      verifyVariableIsType(message, 'string');
      console.error(this.moduleName + ': ' + message);
    }
  }]);

  return Logger;
}();

exports.default = Logger;
<commit_msg>Building the source code.<commit_after>'use strict';

var _logger = require('../src/logger.js');

var _logger2 = _interopRequireDefault(_logger);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Replace a function in the console object with another function.
 * @param {String} consoleFuncName - the name of the console function to be replaced
 * @param {Function} newFunc - the new function which will replace a console function
 * @return {Function} origFunction;
 */
function replaceConsoleFunc(consoleFuncName, newFunc) {
    var origFunction = console[consoleFuncName];
    console[consoleFuncName] = newFunc;
    return origFunction;
} /**
   * This module contains unit tests for the Logger class.
   *
   * Created by hunterhodnett on 7/24/17.
   */

describe('Logger', function () {
    var origLog = void 0;
    var origWarn = void 0;
    var origError = void 0;
    var mockLog = void 0;
    var mockWarn = void 0;
    var mockError = void 0;

    beforeEach(function () {
        mockLog = jasmine.createSpy('log');
        mockWarn = jasmine.createSpy('warn');
        mockError = jasmine.createSpy('error');

        origLog = replaceConsoleFunc('log', mockLog);
        origWarn = replaceConsoleFunc('warn', mockWarn);
        origError = replaceConsoleFunc('error', mockError);
    });

    afterEach(function () {
        replaceConsoleFunc('log', origLog);
        replaceConsoleFunc('warn', origWarn);
        replaceConsoleFunc('error', origError);
    });

    describe('constructor', function () {
        it('should create a new Logger object without crashing', function () {
            new _logger2.default('test');
        });

        it('should throw an error if a module name is not provided', function () {
            expect(function () {
                new _logger2.default();
            }).toThrow();
        });
    });

    describe('log', function () {
        it('should call console.log with a module name and a message', function () {
            var moduleName = 'moduleName';
            var message = 'message';
            var logger = new _logger2.default(moduleName);

            logger.log(message);

            expect(mockLog).toHaveBeenCalledWith(moduleName + ': ' + message);
        });
    });

    describe('warn', function () {
        it('should call console.warn with a module name and a message', function () {
            var moduleName = 'moduleName';
            var message = 'message';
            var logger = new _logger2.default(moduleName);

            logger.warn(message);

            expect(mockWarn).toHaveBeenCalledWith(moduleName + ': ' + message);
        });
    });

    describe('error', function () {
        it('should call console.error with a module name and a message', function () {
            var moduleName = 'moduleName';
            var message = 'message';
            var logger = new _logger2.default(moduleName);

            logger.error(message);

            expect(mockError).toHaveBeenCalledWith(moduleName + ': ' + message);
        });
    });
});
<|endoftext|>


<commit_before>var express = require('express'),
    http = require('http'),
    path = require('path'),
    git = require('git-rev'),
    spawn = require('child_process').spawn,
    crypto = require('crypto'),
    fs = require('fs');

var app = express(),
    tag;

app.configure(function(){
    app.set('host', process.env.HOST || '127.0.0.1');
    app.set('port', process.env.PORT || 2652);
    app.use(express.logger());
    app.use(express.compress());
});

git.tag(function (str) {
    tag = str;
});

var bundleBuilder = function(req, res, min){
    var version = req.params.version || tag;
    var query = req.query;

    var filename;
    if (Object.keys(query).length > 0) {
        // User want a custom bundle
        var patterns = Object.keys(query).sort().join('&'),
            shasum = crypto.createHash('sha1');
        shasum.update(tag + '?' + patterns);

        var hex = shasum.digest('hex').substr(0,8);
        filename = 'patterns-' + version + '-' + hex + (min?'.min':'') + '.js';
    } else {
        filename = 'patterns-' + version + (min?'.min':'') + '.js';
    }

    // Generate args that are passed to jam
    var fullname = path.join(__dirname, 'bundles', filename);

    // The CLI interface is:
    // jam compile -i pat1 [-i pat2 [-i pat3]] -o outfile
    var args = [ 'compile' ].concat(Object.keys(query).sort())
        .join(' -i ').split(' ').concat(['-o', fullname, '-v']);

    if (!min)
        args.push('--no-minify');

    if (!fs.existsSync(fullname)) {
        // Not in cache, so generate
        var p = spawn('jam', args);

        p.on('exit', function(code) {
            if (code === 0) {
                return res.download(fullname);
            } else {
                res.send('Something went wrong build the package');
            }
        });
        return;
    }
    return res.download(fullname);
};

app.get('/getBundle', function(req, res){
    var minify = req.query.minify === 'minify';
    delete req.query.minify;
    bundleBuilder(req, res, minify);
});

app.get('/bundles/:name', function(req, res){
    var fullname = path.join(__dirname, 'bundles', req.params.name);
    return res.download(fullname);
});

app.use(express.static(path.join(__dirname)));

http.createServer(app).listen(app.get('port'), app.get('host'), function(){
    console.log("Express server listening on: http://" + app.get('host') + ':' + app.get('port'));
});

<commit_msg>bundler: take jam from node_modules<commit_after>var express = require('express'),
    http = require('http'),
    path = require('path'),
    git = require('git-rev'),
    spawn = require('child_process').spawn,
    crypto = require('crypto'),
    fs = require('fs');

var app = express(),
    tag;

app.configure(function(){
    app.set('host', process.env.HOST || '127.0.0.1');
    app.set('port', process.env.PORT || 2652);
    app.use(express.logger());
    app.use(express.compress());
});

git.tag(function (str) {
    tag = str;
});

var bundleBuilder = function(req, res, min){
    var version = req.params.version || tag;
    var query = req.query;

    var filename;
    if (Object.keys(query).length > 0) {
        // User want a custom bundle
        var patterns = Object.keys(query).sort().join('&'),
            shasum = crypto.createHash('sha1');
        shasum.update(tag + '?' + patterns);

        var hex = shasum.digest('hex').substr(0,8);
        filename = 'patterns-' + version + '-' + hex + (min?'.min':'') + '.js';
    } else {
        filename = 'patterns-' + version + (min?'.min':'') + '.js';
    }

    // Generate args that are passed to jam
    var fullname = path.join(__dirname, 'bundles', filename);

    // The CLI interface is:
    // jam compile -i pat1 [-i pat2 [-i pat3]] -o outfile
    var args = [ 'compile' ].concat(Object.keys(query).sort())
        .join(' -i ').split(' ').concat(['-o', fullname, '-v']);

    if (!min)
        args.push('--no-minify');

    if (!fs.existsSync(fullname)) {
        // Not in cache, so generate
        var p = spawn('./node_modules/.bin/jam', args);

        p.on('exit', function(code) {
            if (code === 0) {
                return res.download(fullname);
            } else {
                res.send('Something went wrong build the package');
            }
        });
        return;
    }
    return res.download(fullname);
};

app.get('/getBundle', function(req, res){
    var minify = req.query.minify === 'minify';
    delete req.query.minify;
    bundleBuilder(req, res, minify);
});

app.get('/bundles/:name', function(req, res){
    var fullname = path.join(__dirname, 'bundles', req.params.name);
    return res.download(fullname);
});

app.use(express.static(path.join(__dirname)));

http.createServer(app).listen(app.get('port'), app.get('host'), function(){
    console.log("Express server listening on: http://" + app.get('host') + ':' + app.get('port'));
});

<|endoftext|>


<commit_before>
  var deep = "autonomias";
  var createdBubbles = false;
  var procesos_electorales;
  var animate_interval;
  var previous_year;
  var failCircle;

  var years_nodata = {};

  function getDeepLevelFromZoomLevel(zoom_level) {
    if (zoom_level == 6) {
      return "autonomias";
    } else if (zoom_level > 6 && zoom_level < 11) {
      return "provincias";
    } else {
      return "municipios";
    }
  }

  function initializeHeader() {
    deep = getDeepLevelFromZoomLevel(start_zoom);

    /* Receive all the vars without data */
    getUnavailableData(deep);

    // Graph - Map
    if (state == "grafico") {
      $('div#tab_menu a.map').removeClass('selected');
      $('div#tab_menu a.stats').addClass('selected');
      restartGraph();
      $('div#map').css('zIndex',0);
      $('div#graph').css('zIndex',10);
    }

    // Initialize select
    $('div.option_list ul li a.'+compare).closest('li').addClass('selected');
    $('div.option_list ul li a.'+compare).closest('div.select').addClass('selected');
    var value = $('div.option_list ul li a.'+compare).text();
    $('div.option_list ul li a.'+compare).closest('div.select').find('span.inner_select a').text(value);

    //Control tab menu - map or graph
    $('div#tab_menu a').click(function(ev){
      ev.stopPropagation();
      ev.preventDefault();
      var className = ($(this).hasClass('map'))?'map':'graph';
      if (!$(this).hasClass('selected')) {
        infoTooltip.hide();
        $('div#tab_menu a').removeClass('selected');
        if (className == 'map') {
          $("#graph").hide();
          state = "mapa";
          // This element belongs to body, not to graph container
          graphBubbleInfowindow.hide();
          $('div#map').css('zIndex',10);
          $('div#graph').css('zIndex',0);

          setTimeout(function(){
            refreshBubbles();
            refreshTiles();
          },500);

        } else {
          $("#graph").show();
          // Hide the legend if this is visible...
          graphLegend.hideFast();
          state = "grafico";
          restartGraph();
          $('div#map').css('zIndex',0);
          $('div#graph').css('zIndex',10);
        }
        // Stop the slider animation if it is playing
        clearInterval(animate_interval);

        $(this).addClass('selected');
        changeHash();
      }
    });

    /* Animate electoral slider process */
    // Play animation process
    $('a.play').live('click',function(ev){
      ev.stopPropagation();
      ev.preventDefault();
      //Remove play class and add pause class
      $(this).removeClass('play').addClass('stop');
      $(this).attr('href','#stop');
      animate_interval = setInterval(function(){animateSlider();},2000);
    });

    // Stop animation process
    $('a.stop').live('click',function(ev){
      ev.stopPropagation();
      ev.preventDefault();
      clearInterval(animate_interval);
      $(this).removeClass('stop').addClass('play');
      $(this).attr('href','#play');
    });

    // Next - before
    $('div.years_content a.left').click(function(ev){
      ev.stopPropagation();
      ev.preventDefault();
      graphBubbleInfowindow.hide();
      updateNewSliderValue(year-1,year);
    });
    $('div.years_content a.right').click(function(ev){
      ev.stopPropagation();
      ev.preventDefault();
      updateNewSliderValue(year+1,year);
    });

    // Year Slider
    $("div.year_slider").slider({
      range: "min",
      min: 1987,
      max: 2011,
      value: year,
      step: 1,
      create: function(event,ui) {
        $(this).find('a.ui-slider-handle').text(year);
      },
      slide: function( event, ui ) {
        $(this).find('a.ui-slider-handle').text(ui.value);
        year = ui.value;
      },
      change: function( event, ui ) {
        $(this).find('a.ui-slider-handle').text(ui.value);
        year = ui.value;
      },
      start: function(event, ui) {
        if (state === "grafico" && graphBubbleInfowindow.isOpen()) {
          graphBubbleInfowindow.hide();
        }
        previous_year = ui.value;
      },
      stop: function( event, ui ) {
        if (ui.value!=previous_year) {
          updateNewSliderValue(ui.value,previous_year);
        }
      }
    });

    /*Info tooltip when you select a variable*/
    var infoTooltip = (function() {

      $('div.info_tooltip a.close').click(function(ev){
        ev.stopPropagation();
        ev.preventDefault();
        hideTooltip();
      });

      $('div.info_tooltip a.more').click(function(ev){
        ev.stopPropagation();
        ev.preventDefault();
        hideTooltip();
        explanationwindow.show();
      });

      function hideTooltip() {
        $("div.info_tooltip").fadeOut("slow");
        $('body').unbind("click");
      }

      function showInfoTooltip(title, position) {
        $("div.info_tooltip").fadeOut("slow", function() {

          var info = tooltipInfo[title];

          if (info !== undefined) {
            $("div.info_tooltip h5").text(title);
            $("div.info_tooltip p").text(info.content);
            $("div.info_tooltip ul li.left").html("+25" + info.left);
            $("div.info_tooltip ul li.right").html("-25" + info.right);

            $("div.info_tooltip").css("left", position-7);
            $("div.info_tooltip").fadeIn("slow", function() {
              $('body').click(function(event) {
                if (!$(event.target).closest('div.info_tooltip').length) { hideTooltip(); }
              });
            });
            refreshHeight();
          }
        });
      }

      function refreshHeight() {
        var height = $("div.info_tooltip div.content").height() + 50;
        height = (height > 231) ? 231 : height;
        $("div.info_tooltip").css("height", height + "px");
      }

      return {
        hide: hideTooltip,
        show: showInfoTooltip
      };
    }());

    /*SELECTS*/
    /*Select event*/
    $('div.select div.outer_select').click(function(ev){
      ev.stopPropagation();
      ev.preventDefault();

      $('div.select').each(function(i,ele){$(ele).removeClass('opened');});

      if (!$(this).closest('div.select').hasClass('opened')) {
        infoTooltip.hide();
        if ($(this).parent().find('li.selected').length) {
          var index = $(this).parent().find('li.selected').index();
          $(this).parent().find('div.option_list').css('top',-(index*24)+'px');
        } else {
          $(this).parent().find('div.option_list').css('top','0px');
        }
        $(this).closest('div.select').addClass('opened');
      } else {
        $(this).closest('div.select').removeClass('opened');
      }

      $('body').click(function(event) {
        if (!$(event.target).closest('div.option_list').length) {
          $('div.select').each(function(i,ele){$(ele).removeClass('opened');});
          $('body').unbind('click');
        }
      });
    });

    /*Select list events*/
    $('div.option_list ul li a').click(function(ev){
      ev.stopPropagation();
      ev.preventDefault();

      var value = $(this).text();

      if (!$(this).parent().hasClass('selected') && !$(this).parent().hasClass('disabled')) {
        compare = $(this).attr('class').replace(/_/g,' ');
        axisLegend.update(tooltipInfo[value]);
        graphBubbleInfowindow.hide();

        if (state == 'mapa') {
          refreshBubbles();
        } else {
          console.log(deep);
          setValue(global_url + "/graphs/"+deep+"/"+graph_version+"/"+((name=="España")?'':name+'_')+normalization[compare]+"_"+year+".json");
        }

        drawNoDataBars();
        changeHash();

        $('div.select span.inner_select a').each(function(i,ele){$(this).text($(this).attr('title'));});
        $('div.option_list ul li').each(function(i,ele){$(ele).removeClass('selected');});
        $('div.select').each(function(i,ele){$(ele).removeClass('selected');});

        infoTooltip.show(value, $(this).closest('div.select').position().left);

        $(this).parent().addClass('selected');
        $(this).closest('div.select').addClass('selected').removeClass('opened');
        $(this).closest('div.select').find('span.inner_select a').text(value);
        $('body').unbind('click');
      }
    });

    /*failCircle*/
    failCircle = (function() {
      var data_not_found = false;

      $("div.fail a.why").live("click", function(ev) {
        ev.stopPropagation();
        ev.preventDefault();
        explanationwindow.show();
      });

      $("div.fail a.next").live("click", function(ev) {
        ev.stopPropagation();
        ev.preventDefault();
        goToNextYear();
      });

      function showError() {
        if (state == "mapa") {
          var $state = $("#map");
          var deep_level = getDeepLevelFromZoomLevel(peninsula.getZoom());
        } else {
          var $state = $("#graph");
          var deep_level = deep;
        }

        if (data_not_found != true) {
          $state.find('div.fail').fadeIn("slow", function() { data_not_found = true; });
        }
      }

      function hideError() {
        var $state = (state == "mapa") ? $("#map") : $("#graph");
        $state.find('div.fail').fadeOut("slow", function() { data_not_found = undefined; })
      }

      function getNextAvailableYear(deep_level) {
        var data = availableData[deep_level][normalization[compare]];
        if (year > data[data.length - 1]) {
          return data[data.length - 1];
        } else {
          return _.detect(data, function(num){ return year < num; }); // next election year to the current year
        }
      }

      function goToNextYear() {

        if (state == "mapa") {
          var deep_level = getDeepLevelFromZoomLevel(peninsula.getZoom());
          updateNewSliderValue(getNextAvailableYear(deep_level));
          failCircle.hide();
        } else {
          updateNewSliderValue(getNextAvailableYear(deep));
          setValue(global_url + "/graphs/"+deep+"/"+graph_version+"/"+((name=="España")?'':name+'_')+normalization[compare]+"_"+year+".json");
        }
      }

      function hasFailed() {
        return data_not_found;
      }

      return {
        show: showError,
        hide: hideError,
        failed: hasFailed
      }
    })();

  }

  function animateSlider() {
    var new_value = $("div.year_slider").slider('value') + 1;
    if (new_value>2011) {
      $('a.action').removeClass('stop').addClass('play');
      $('a.action.play').attr('href','#play');
      clearInterval(animate_interval);
      return false;
    } else {
      updateNewSliderValue(new_value);
    }
  }

  function getUnavailableData(deep) {
    $.getJSON(global_url + "/graphs/meta/" + deep + ".json", function(data) {
      years_nodata[deep] = new Object();
      _.each(data,function(ele,i){
        years_nodata[deep][i] = new Array();
        years_nodata[deep][i] = ele;
      });
      drawNoDataBars();
    });
  }

  function drawNoDataBars() {
    $('span.slider_no_data_left').hide();
    $('span.slider_no_data_right').hide();

    var deep;
    var zoom = peninsula.getZoom();
    if (zoom==6) {
      deep = "autonomias";
      if (years_nodata["autonomias"]==undefined) {
        getUnavailableData('autonomias');
        return false;
      }
    } else if (zoom>6 && zoom<11) {
      deep = "provincias";
      if (years_nodata["provincias"]==undefined) {
        getUnavailableData('provincias');
        return false;
      }
    } else {
      deep = "municipios";
      if (years_nodata["municipios"]==undefined) {
        getUnavailableData('municipios');
        return false;
      }
    }

    if (years_nodata[deep][normalization[compare]]!=undefined) {
      var left_no = years_nodata[deep][normalization[compare]][0] - 1987;
      var lenght_array = years_nodata[deep][normalization[compare]].length;
      var right_no = 2011 - years_nodata[deep][normalization[compare]][lenght_array-1];

      if (left_no!=0) {
        $('span.slider_no_data_left').css({width:(left_no*4.16)+"%"});
        $('span.slider_no_data_left').show();
      } else {
        $('span.slider_no_data_left').hide();
      }

      if (right_no!=0) {
        $('span.slider_no_data_right').css({width:(right_no*4.16)+"%"});
        $('span.slider_no_data_right').show();
      } else {
        $('span.slider_no_data_right').hide();
      }
    }

    if (!checkFailYear(year)) {
      failCircle.show();
    } else {
      failCircle.hide();
    }
  }

  function checkFailYear(year) {
    if (years_nodata[deep]!=undefined && years_nodata[deep][normalization[compare]]!=undefined) {
    var deep = getDeepLevelFromZoomLevel(peninsula.getZoom());
      var length_array = years_nodata[deep][normalization[compare]].length;
      return (year>=years_nodata[deep][normalization[compare]][0]) && (year<=years_nodata[deep][normalization[compare]][length_array-1]);
    } else {
      return false;
    }
  }

  function updateNewSliderValue(new_year,previous_year) {
    if (state == 'mapa') {
      if (previous_year!=undefined) {
        if (graph_hack_year[previous_year] != graph_hack_year[new_year]) {
          refreshTiles();
        }
      } else {
        refreshTiles();
      }
      if (!checkFailYear(new_year)) {
        failCircle.show();
      } else {
        failCircle.hide();
      }
      refreshBubbles();
    } else {

      var url = global_url + "/graphs/"+deep+"/"+graph_version+"/"+((name=="España")?'':name+'_')+normalization[compare]+"_"+year+".json";

      // Let's decide if we must update (setValue) or create the bubbles
      if (createdBubbles == true) {
        setValue(url);
      } else {
        createBubbles(url);
      }
    }

    $("div.year_slider").slider('value', new_year);
    changeHash();
  }

<commit_msg>last changes<commit_after>
  var deep = "autonomias";
  var createdBubbles = false;
  var procesos_electorales;
  var animate_interval;
  var previous_year;
  var failCircle;

  var years_nodata = {};

  function getDeepLevelFromZoomLevel(zoom_level) {
    if (zoom_level == 6) {
      return "autonomias";
    } else if (zoom_level > 6 && zoom_level < 11) {
      return "provincias";
    } else {
      return "municipios";
    }
  }

  function initializeHeader() {
    deep = getDeepLevelFromZoomLevel(start_zoom);

    /* Receive all the vars without data */
    getUnavailableData(deep);

    // Graph - Map
    if (state == "grafico") {
      $('div#tab_menu a.map').removeClass('selected');
      $('div#tab_menu a.stats').addClass('selected');
      restartGraph();
      $('div#map').css('zIndex',0);
      $('div#graph').css('zIndex',10);
    }

    // Initialize select
    $('div.option_list ul li a.'+compare).closest('li').addClass('selected');
    $('div.option_list ul li a.'+compare).closest('div.select').addClass('selected');
    var value = $('div.option_list ul li a.'+compare).text();
    $('div.option_list ul li a.'+compare).closest('div.select').find('span.inner_select a').text(value);

    //Control tab menu - map or graph
    $('div#tab_menu a').click(function(ev){
      ev.stopPropagation();
      ev.preventDefault();
      var className = ($(this).hasClass('map'))?'map':'graph';
      if (!$(this).hasClass('selected')) {
        infoTooltip.hide();
        $('div#tab_menu a').removeClass('selected');
        if (className == 'map') {
          $("#graph").hide();
          state = "mapa";
          // This element belongs to body, not to graph container
          graphBubbleInfowindow.hide();
          $('div#map').css('zIndex',10);
          $('div#graph').css('zIndex',0);

          setTimeout(function(){
            refreshBubbles();
            refreshTiles();
          },500);

        } else {
          $("#graph").show();
          // Hide the legend if this is visible...
          graphLegend.hideFast();
          state = "grafico";
          restartGraph();
          $('div#map').css('zIndex',0);
          $('div#graph').css('zIndex',10);
        }
        // Stop the slider animation if it is playing
        clearInterval(animate_interval);

        $(this).addClass('selected');
        changeHash();
      }
    });

    /* Animate electoral slider process */
    // Play animation process
    $('a.play').live('click',function(ev){
      ev.stopPropagation();
      ev.preventDefault();
      //Remove play class and add pause class
      $(this).removeClass('play').addClass('stop');
      $(this).attr('href','#stop');
      animate_interval = setInterval(function(){animateSlider();},2000);
    });

    // Stop animation process
    $('a.stop').live('click',function(ev){
      ev.stopPropagation();
      ev.preventDefault();
      clearInterval(animate_interval);
      $(this).removeClass('stop').addClass('play');
      $(this).attr('href','#play');
    });

    // Next - before
    $('div.years_content a.left').click(function(ev){
      ev.stopPropagation();
      ev.preventDefault();
      graphBubbleInfowindow.hide();
      updateNewSliderValue(year-1,year);
    });
    $('div.years_content a.right').click(function(ev){
      ev.stopPropagation();
      ev.preventDefault();
      updateNewSliderValue(year+1,year);
    });

    // Year Slider
    $("div.year_slider").slider({
      range: "min",
      min: 1987,
      max: 2011,
      value: year,
      step: 1,
      create: function(event,ui) {
        $(this).find('a.ui-slider-handle').text(year);
      },
      slide: function( event, ui ) {
        $(this).find('a.ui-slider-handle').text(ui.value);
        year = ui.value;
      },
      change: function( event, ui ) {
        $(this).find('a.ui-slider-handle').text(ui.value);
        year = ui.value;
      },
      start: function(event, ui) {
        if (state === "grafico" && graphBubbleInfowindow.isOpen()) {
          graphBubbleInfowindow.hide();
        }
        previous_year = ui.value;
      },
      stop: function( event, ui ) {
        if (ui.value!=previous_year) {
          updateNewSliderValue(ui.value,previous_year);
        }
      }
    });

    /*Info tooltip when you select a variable*/
    var infoTooltip = (function() {

      $('div.info_tooltip a.close').click(function(ev){
        ev.stopPropagation();
        ev.preventDefault();
        hideTooltip();
      });

      $('div.info_tooltip a.more').click(function(ev){
        ev.stopPropagation();
        ev.preventDefault();
        hideTooltip();
        explanationwindow.show();
      });

      function hideTooltip() {
        $("div.info_tooltip").fadeOut("slow");
        $('body').unbind("click");
      }

      function showInfoTooltip(title, position) {
        $("div.info_tooltip").fadeOut("slow", function() {

          var info = tooltipInfo[title];

          if (info !== undefined) {
            $("div.info_tooltip h5").text(title);
            $("div.info_tooltip p").text(info.content);
            $("div.info_tooltip ul li.left").html("+25" + info.left);
            $("div.info_tooltip ul li.right").html("-25" + info.right);

            $("div.info_tooltip").css("left", position-7);
            $("div.info_tooltip").fadeIn("slow", function() {
              $('body').click(function(event) {
                if (!$(event.target).closest('div.info_tooltip').length) { hideTooltip(); }
              });
            });
            refreshHeight();
          }
        });
      }

      function refreshHeight() {
        var height = $("div.info_tooltip div.content").height() + 50;
        height = (height > 231) ? 231 : height;
        $("div.info_tooltip").css("height", height + "px");
      }

      return {
        hide: hideTooltip,
        show: showInfoTooltip
      };
    }());

    /*SELECTS*/
    /*Select event*/
    $('div.select div.outer_select').click(function(ev){
      ev.stopPropagation();
      ev.preventDefault();

      $('div.select').each(function(i,ele){$(ele).removeClass('opened');});

      if (!$(this).closest('div.select').hasClass('opened')) {
        infoTooltip.hide();
        if ($(this).parent().find('li.selected').length) {
          var index = $(this).parent().find('li.selected').index();
          $(this).parent().find('div.option_list').css('top',-(index*24)+'px');
        } else {
          $(this).parent().find('div.option_list').css('top','0px');
        }
        $(this).closest('div.select').addClass('opened');
      } else {
        $(this).closest('div.select').removeClass('opened');
      }

      $('body').click(function(event) {
        if (!$(event.target).closest('div.option_list').length) {
          $('div.select').each(function(i,ele){$(ele).removeClass('opened');});
          $('body').unbind('click');
        }
      });
    });

    /*Select list events*/
    $('div.option_list ul li a').click(function(ev){
      ev.stopPropagation();
      ev.preventDefault();

      var value = $(this).text();

      if (!$(this).parent().hasClass('selected') && !$(this).parent().hasClass('disabled')) {
        compare = $(this).attr('class').replace(/_/g,' ');
        axisLegend.update(tooltipInfo[value]);
        graphBubbleInfowindow.hide();

        if (state == 'mapa') {
          refreshBubbles();
        } else {
          console.log(deep);
          setValue(global_url + "/graphs/"+deep+"/"+graph_version+"/"+((name=="España")?'':name+'_')+normalization[compare]+"_"+year+".json");
        }

        drawNoDataBars();
        changeHash();

        $('div.select span.inner_select a').each(function(i,ele){$(this).text($(this).attr('title'));});
        $('div.option_list ul li').each(function(i,ele){$(ele).removeClass('selected');});
        $('div.select').each(function(i,ele){$(ele).removeClass('selected');});

        infoTooltip.show(value, $(this).closest('div.select').position().left);

        $(this).parent().addClass('selected');
        $(this).closest('div.select').addClass('selected').removeClass('opened');
        $(this).closest('div.select').find('span.inner_select a').text(value);
        $('body').unbind('click');
      }
    });

    /*failCircle*/
    failCircle = (function() {
      var data_not_found = false;

      $("div.fail a.why").live("click", function(ev) {
        ev.stopPropagation();
        ev.preventDefault();
        explanationwindow.show();
      });

      $("div.fail a.next").live("click", function(ev) {
        ev.stopPropagation();
        ev.preventDefault();
        goToNextYear();
      });

      function showError() {
        if (state == "mapa") {
          var $state = $("#map");
          var deep_level = getDeepLevelFromZoomLevel(peninsula.getZoom());
        } else {
          var $state = $("#graph");
          var deep_level = deep;
        }

        if (data_not_found != true) {
          $state.find('div.fail').fadeIn("slow", function() { data_not_found = true; });
        }
      }

      function hideError() {
        var $state = (state == "mapa") ? $("#map") : $("#graph");
        $state.find('div.fail').fadeOut("slow", function() { data_not_found = undefined; })
      }

      function getNextAvailableYear(deep_level) {
        var data = availableData[deep_level][normalization[compare]];
        if (year > data[data.length - 1]) {
          return data[data.length - 1];
        } else {
          return _.detect(data, function(num){ return year < num; }); // next election year to the current year
        }
      }

      function goToNextYear() {

        if (state == "mapa") {
          var deep_level = getDeepLevelFromZoomLevel(peninsula.getZoom());
          updateNewSliderValue(getNextAvailableYear(deep_level));
          failCircle.hide();
        } else {
          updateNewSliderValue(getNextAvailableYear(deep));
          setValue(global_url + "/graphs/"+deep+"/"+graph_version+"/"+((name=="España")?'':name+'_')+normalization[compare]+"_"+year+".json");
        }
      }

      function hasFailed() {
        return data_not_found;
      }

      return {
        show: showError,
        hide: hideError,
        failed: hasFailed
      }
    })();

  }

  function animateSlider() {
    var new_value = $("div.year_slider").slider('value') + 1;
    if (new_value>2011) {
      $('a.action').removeClass('stop').addClass('play');
      $('a.action.play').attr('href','#play');
      clearInterval(animate_interval);
      return false;
    } else {
      updateNewSliderValue(new_value);
    }
  }

  function getUnavailableData(deep) {
    $.getJSON(global_url + "/graphs/meta/" + deep + ".json", function(data) {
      years_nodata[deep] = new Object();
      _.each(data,function(ele,i){
        years_nodata[deep][i] = new Array();
        years_nodata[deep][i] = ele;
      });
      drawNoDataBars();
    });
  }

  function drawNoDataBars() {
    $('span.slider_no_data_left').hide();
    $('span.slider_no_data_right').hide();

    var deep;
    var zoom = peninsula.getZoom();
    if (zoom==6) {
      deep = "autonomias";
      if (years_nodata["autonomias"]==undefined) {
        getUnavailableData('autonomias');
        return false;
      }
    } else if (zoom>6 && zoom<11) {
      deep = "provincias";
      if (years_nodata["provincias"]==undefined) {
        getUnavailableData('provincias');
        return false;
      }
    } else {
      deep = "municipios";
      if (years_nodata["municipios"]==undefined) {
        getUnavailableData('municipios');
        return false;
      }
    }

    if (years_nodata[deep][normalization[compare]]!=undefined) {
      var left_no = years_nodata[deep][normalization[compare]][0] - 1987;
      var lenght_array = years_nodata[deep][normalization[compare]].length;
      var right_no = 2011 - years_nodata[deep][normalization[compare]][lenght_array-1];

      if (left_no!=0) {
        $('span.slider_no_data_left').css({width:(left_no*4.16)+"%"});
        $('span.slider_no_data_left').show();
      } else {
        $('span.slider_no_data_left').hide();
      }

      if (right_no!=0) {
        $('span.slider_no_data_right').css({width:(right_no*4.16)+"%"});
        $('span.slider_no_data_right').show();
      } else {
        $('span.slider_no_data_right').hide();
      }
    }

    if (!checkFailYear(year)) {
      failCircle.show();
    } else {
      failCircle.hide();
    }
  }

  function checkFailYear(year) {
    var deep = getDeepLevelFromZoomLevel(peninsula.getZoom());
    if (years_nodata[deep]!=undefined) {
      if ( years_nodata[deep][normalization[compare]]!=undefined) {
        var deep = getDeepLevelFromZoomLevel(peninsula.getZoom());
        var length_array = years_nodata[deep][normalization[compare]].length;
        return (year>=years_nodata[deep][normalization[compare]][0]) && (year<=years_nodata[deep][normalization[compare]][length_array-1]);
      } else {
        return false;
      }
    } else {
      return false;
    }
  }

  function updateNewSliderValue(new_year,previous_year) {
    if (state == 'mapa') {
      if (previous_year!=undefined) {
        if (graph_hack_year[previous_year] != graph_hack_year[new_year]) {
          refreshTiles();
        }
      } else {
        refreshTiles();
      }
      if (!checkFailYear(new_year)) {
        failCircle.show();
      } else {
        failCircle.hide();
      }
      refreshBubbles();
    } else {

      var url = global_url + "/graphs/"+deep+"/"+graph_version+"/"+((name=="España")?'':name+'_')+normalization[compare]+"_"+year+".json";

      // Let's decide if we must update (setValue) or create the bubbles
      if (createdBubbles == true) {
        setValue(url);
      } else {
        createBubbles(url);
      }
    }

    $("div.year_slider").slider('value', new_year);
    changeHash();
  }

<|endoftext|>


<commit_before>if (PAYLOAD.action === 'opened') {

    request.get(GET.template, function templateReceived(err, httpResponse, body) {

        var options = {
            url:      PAYLOAD.pull_request.url,
            headers: {
                'Content-Type':  'application/json',
                'User-Agent':    'pr-editor',
                'Authorization': 'token ' + ACCESS_TOKEN
            },
            json: {
                "body": PAYLOAD.pull_request.body + "\n" + body
            }
        };

        console.log(options);

        request.post(options, function templatePosted(err, httpResponse, body) {
            if (err) {
                fail('Could not send POST request: ' + err);
            }
            else {
                succeed('Template POST message successful. Response:' + body);
            }
        });

    });
}
else {
    succeed(PAYLOAD.action + ' (payload action) was not "opened", so there was nothing to do here.');
}
<commit_msg>new api<commit_after>module.exports = function (data, process) {
    var PAYLOAD      = data.payload,
        ACCESS_TOKEN = data.access_token,
        GET          = data.parameters;

    if (PAYLOAD.action === 'opened') {

        request.get(GET.template, function templateReceived(err, httpResponse, body) {

            var options = {
                url:      PAYLOAD.pull_request.url,
                headers: {
                    'Content-Type':  'application/json',
                    'User-Agent':    'pr-editor',
                    'Authorization': 'token ' + ACCESS_TOKEN
                },
                json: {
                    "body": PAYLOAD.pull_request.body + "\n" + body
                }
            };

            console.log(options);

            request.post(options, function templatePosted(err, httpResponse, body) {
                if (err) {
                    process.fail('Could not send POST request: ' + err);
                }
                else {
                    process.succeed('Template POST message successful. Response:' + body);
                }
            });

        });
    }
    else {
        process.succeed(PAYLOAD.action + ' (payload action) was not "opened", so there was nothing to do here.');
    }
};
<|endoftext|>


<commit_before>(function($) {
$(document).ready(function(){

  // putting lines by the pre blocks
  $("pre").each(function(){
    var pre = $(this).text().split("\n");
    var lines = new Array(pre.length+1);
    for(var i = 0; i < pre.length; i++) {
      var wrap = Math.floor(pre[i].split("").length / 70)
      if (pre[i]==""&&i==pre.length-1) {
        lines.splice(i, 1);
      } else {
        lines[i] = i+1;
        for(var j = 0; j < wrap; j++) {
          lines[i] += "\n";
        }
      }
    }
    $(this).before("
" + lines.join("\n") + "
");
  });

  var headings = [];

  var collectHeaders = function(){
    headings.push({"top":$(this).offset().top - 15,"text":$(this).text()});
  }

  if($(".markdown-body h1").length > 1) $(".markdown-body h1").each(collectHeaders)
  else if($(".markdown-body h2").length > 1) $(".markdown-body h2").each(collectHeaders)
  else if($(".markdown-body h3").length > 1) $(".markdown-body h3").each(collectHeaders)

  $(window).scroll(function(){
    if(headings.length==0) return true;
    var scrolltop = $(window).scrollTop() || 0;
    if(headings[0] && scrolltop < headings[0].top) {
      $(".current-section").css({"opacity":0,"visibility":"hidden"});
      return false;
    }
    $(".current-section").css({"opacity":1,"visibility":"visible"});
    for(var i in headings) {
      if(scrolltop >= headings[i].top) {
        $(".current-section .name").text(headings[i].text);
      }
    }
  });

  $(".current-section a").click(function(){
    $(window).scrollTop(0);
    return false;
  })
});
})(jQuery)<commit_msg>delete script.js<commit_after><|endoftext|>


<commit_before>/**
 * Notice: Some code was adapted from Material-UI's text field.
 *         Copyright (c) 2014 Call-Em-All (https://github.com/callemall/material-ui)
 */
import React, { PropTypes } from 'react'
import TextFieldUnderline from 'material-ui/TextField/TextFieldUnderline'
import TextFieldHint from 'material-ui/TextField/TextFieldHint'
import TextFieldLabel from 'material-ui/TextField/TextFieldLabel'
import AutoComplete from 'material-ui/AutoComplete/AutoComplete'
import transitions from 'material-ui/styles/transitions'
import Chip from 'material-ui/Chip'
import {blue300} from 'material-ui/styles/colors'
import {fade} from 'material-ui/utils/colorManipulator';

const getStyles = (props, context, state) => {
  const {
    baseTheme,
    textField: {
      floatingLabelColor,
      focusColor,
      textColor,
      disabledTextColor,
      backgroundColor,
      hintColor,
      errorColor,
    },
  } = context.muiTheme;

  const styles = {
    root: {
      fontSize: 16,
      lineHeight: '24px',
      width: props.fullWidth ? '100%' : 256,
      display: 'inline-block',
      position: 'relative',
      backgroundColor: backgroundColor,
      fontFamily: baseTheme.fontFamily,
      transition: transitions.easeOut('200ms', 'height'),
      cursor: 'text'
    },
    input: {
      padding: 0,
      marginTop: 0,
      marginBottom: 24,
      lineHeight: '32px',
      height: 32,
      position: 'relative',
      display: 'inline-block',
      border: 'none',
      outline: 'none',
      backgroundColor: 'rgba(0,0,0,0)',
      color: props.disabled ? disabledTextColor : textColor,
      cursor: props.disabled ? 'not-allowed' : 'initial',
      font: 'inherit',
      appearance: 'textfield', // Improve type search style.
      WebkitTapHighlightColor: 'rgba(0,0,0,0)', // Remove mobile color flashing (deprecated style).
      float: 'left',
    },
    floatingLabel: {
      color: hintColor,
      pointerEvents: 'none',
      top: 28
    },
    floatingLabelFocusStyle: {
      transform: 'scale(0.75) translate(0, -36px)'
    }
  };

  const hasValue = (props.value || state.chips).length > 0 || state.inputValue.length > 0
  if (hasValue) {
    styles.floatingLabel.color = fade(props.disabled ? disabledTextColor : floatingLabelColor, 0.5);
  }

  if (state.isFocused) {
    styles.floatingLabel.color = focusColor;
  }

  if (props.floatingLabelText) {
    styles.input.boxSizing = 'border-box';

    if (state.errorText) {
      styles.error.bottom = !props.multiLine ? styles.error.fontSize + 3 : 3;
    }
  }

  if (state.errorText) {
    if (state.isFocused) {
      styles.floatingLabel.color = styles.error.color;
    }
  }

  return styles;
};

class ChipInput extends React.Component {
  static contextTypes = {
    muiTheme: React.PropTypes.object.isRequired,
  };

  state = {
    isFocused: false,
    errorText: undefined,
    isClean: true,
    chips: [],
    focusedChip: null,
    inputValue: ''
  }

  constructor (props) {
    super(props)
    if (props.defaultValue) {
      this.state.chips = props.defaultValue
    }
  }

  componentWillMount() {
    const {
      name,
      hintText,
      floatingLabelText
    } = this.props;

    const uniqueId = `${name}-${hintText}-${floatingLabelText}-${
      Math.floor(Math.random() * 0xFFFF)}`;
    this.uniqueId = uniqueId.replace(/[^A-Za-z0-9-]/gi, '');
  }

  componentWillReceiveProps (nextProps) {
    if (nextProps.disabled) {
      this.setState({ focusedChip: null })
    }
  }

  blur() {
    if (this.input) this.getInputNode().blur();
  }

  focus() {
    if (this.input) this.getInputNode().focus();
    if (this.state.focusedChip) {
      this.setState({ focusedChip: null })
    }
  }

  select() {
    if (this.input) this.getInputNode().select();
  }

  getValue() {
    return this.input ? this.getInputNode().value : undefined;
  }

  getInputNode() {
    return this.input;
  }

  handleInputBlur = (event) => {
    this.setState({isFocused: false});
    if (this.props.onBlur) this.props.onBlur(event);
  }

  handleInputFocus = (event) => {
    if (this.props.disabled) {
      return;
    }
    this.setState({isFocused: true});
    if (this.props.onFocus) {
      this.props.onFocus(event);
    }
  }

  handleKeyDown = (event) => {
    if (event.keyCode === 13) { // enter
      this.handleAddChip(event.target.value)
    } else if (event.keyCode === 8 || event.keyCode === 46) {
      if (event.target.value === '') {
        const chips = this.props.value || this.state.chips
        if (this.state.focusedChip == null && event.keyCode === 8) {
          this.setState({ focusedChip: chips[chips.length - 1] })
        } else if (this.state.focusedChip) {
          const index = chips.indexOf(this.state.focusedChip)
          this.handleDeleteChip(this.state.focusedChip)
          if (event.keyCode === 8 && index > 0) {
            this.setState({ focusedChip: chips[index - 1] })
          } else if (event.keyCode === 46 && index < chips.length - 1) {
            this.setState({ focusedChip: chips[index + 1] })
          }
        }
      }
    } else if (event.keyCode === 37) {
      const chips = this.props.value || this.state.chips
      const index = chips.indexOf(this.state.focusedChip)
      if (index > 0) {
        this.setState({ focusedChip: chips[index - 1] })
      }
    } else if (event.keyCode === 39) {
      const chips = this.props.value || this.state.chips
      const index = chips.indexOf(this.state.focusedChip)
      if (index >= 0 && index < chips.length - 1) {
        this.setState({ focusedChip: chips[index + 1] })
      } else {
        this.setState({ focusedChip: null })
      }
    } else {
      this.setState({ focusedChip: null })
    }
  }

  handleAddChip (chip) {
    const chips = this.props.value || this.state.chips

    if (chip.trim().length > 0 && chips.indexOf(chip) === -1) {
      if (this.props.value) {
        if (this.props.onRequestAdd) {
          this.props.onRequestAdd(chip)
        }
      } else {
        this.setState({ chips: [ ...this.state.chips, chip ] })
        if (this.props.onChange) {
          this.props.onChange([ ...this.state.chips, chip ])
        }
      }

      this.setState({ inputValue: '' })
    }
  }

  handleDeleteChip (chip) {
    if (this.props.value) {
      if (this.props.onRequestDelete) {
        this.props.onRequestDelete(chip)
      }
    } else {
      const chips = this.state.chips.filter((c) => c !== chip)
      if (chips.length !== this.state.chips.length) {
        this.setState({
          chips,
          focusedChip: this.state.focusedChip === chip ? null : this.state.focusedChip
        })
        if (this.props.onChange) {
          this.props.onChange(chips)
        }
      }
    }
  }

  render () {
    const {
      children,
      className,
      disabled,
      errorStyle,
      errorText, // eslint-disable-line no-unused-vars
      fullWidth, // eslint-disable-line no-unused-vars
      hintText,
      hintStyle,
      inputStyle,
      onBlur, // eslint-disable-line no-unused-vars
      onChange, // eslint-disable-line no-unused-vars
      onFocus, // eslint-disable-line no-unused-vars
      style,
      underlineDisabledStyle,
      underlineFocusStyle,
      underlineShow,
      underlineStyle,
      defaultValue = [],
      value,
      dataSource,
      floatingLabelFixed,
      floatingLabelFocusStyle, // eslint-disable-line no-unused-vars
      floatingLabelStyle, // eslint-disable-line no-unused-vars
      floatingLabelText,
      onRequestAdd, // eslint-disable-line no-unused-vars
      onRequestDelete, // eslint-disable-line no-unused-vars
      ...other,
    } = this.props;

    const {prepareStyles} = this.context.muiTheme;
    const styles = getStyles(this.props, this.context, this.state);
    const inputId = this.uniqueId;

    const inputProps = {
      id: inputId,
      ref: (elem) => this.input = elem,
      disabled: this.props.disabled,
      onBlur: this.handleInputBlur,
      onFocus: this.handleInputFocus,
      onKeyDown: this.handleKeyDown
    }

    const inputStyleMerged = Object.assign(styles.input, inputStyle);

    const hasInput = (this.props.value || this.state.chips).length > 0 || this.state.inputValue.length > 0
    const showHintText = hintText && !hasInput
    const shrinkFloatingLabel = floatingLabelText && (hasInput || this.state.isFocused)

    const floatingLabelTextElement = floatingLabelText && (
      <TextFieldLabel
        muiTheme={this.context.muiTheme}
        style={Object.assign(styles.floatingLabel, this.props.floatingLabelStyle)}
        shrinkStyle={Object.assign(styles.floatingLabelFocusStyle, this.props.floatingLabelFocusStyle)}
        htmlFor={inputId}
        shrink={shrinkFloatingLabel}
        disabled={disabled}
      >
        {floatingLabelText}
      </TextFieldLabel>
    )

    const overrideRootStyles = {}
    if (floatingLabelText) {
      overrideRootStyles.marginTop = 14
    }
    if (fullWidth) {
      overrideRootStyles.width = '100%'
    }
    if (disabled) {
      overrideRootStyles.cursor = 'not-allowed'
    }

    return (

 this.focus()}
      >

          {floatingLabelTextElement}

            {(this.props.value || this.state.chips).map((tag) => (
              <Chip
                key={tag}
                style={{ margin: '8px 8px 0 0', float: 'left', pointerEvents: disabled ? 'none' : undefined }}
                backgroundColor={this.state.focusedChip === tag ? blue300 : null}
                onTouchTap={() => { this.setState({ focusedChip: tag }) }}
                onRequestDelete={() => this.handleDeleteChip(tag)}
              >
                {tag}
              </Chip>
            ))}

        {hintText ?
          <TextFieldHint
            muiTheme={this.context.muiTheme}
            show={showHintText && !(floatingLabelText && !this.state.isFocused)}
            style={Object.assign({ bottom: 20, pointerEvents: 'none' }, hintStyle)}
            text={hintText}
          /> :
          null
        }
        <AutoComplete
          {...other}
          {...inputProps}
          style={inputStyleMerged}
          dataSource={dataSource || []}
          menuProps={{
            onChange: (event, input) => {
              setTimeout(() => this.focus())
              setTimeout(() => {
                this.handleAddChip(input)
                this.setState({ inputValue: '' })
              }, (other.menuCloseDelay || 300) + 10) // menuCloseDelay + 10
            }
          }}
          searchText={this.state.inputValue}
          underlineShow={false}
          onKeyUp={(event) => this.setState({ inputValue: event.target.value })}
        />
        <TextFieldUnderline
          disabled={disabled}
          disabledStyle={underlineDisabledStyle}
          error={!!this.state.errorText}
          errorStyle={errorStyle}
          focus={this.state.isFocused}
          focusStyle={underlineFocusStyle}
          muiTheme={this.context.muiTheme}
          style={underlineStyle}
        />

    )
  }
}

ChipInput.propTypes = {
  style: PropTypes.object,
  floatingLabelText: PropTypes.node,
  hintText: PropTypes.node,
  disabled: PropTypes.bool,
  defaultValue: PropTypes.arrayOf(PropTypes.string),
  onChange: PropTypes.func,
  value: PropTypes.arrayOf(PropTypes.string),
  onRequestAdd: PropTypes.func,
  onRequestDelete: PropTypes.func,
  dataSource: PropTypes.arrayOf(PropTypes.string),
  onUpdateInput: PropTypes.func,
}

export default ChipInput
<commit_msg>Remove chips from autocomplete that are already selected. #8<commit_after>/**
 * Notice: Some code was adapted from Material-UI's text field.
 *         Copyright (c) 2014 Call-Em-All (https://github.com/callemall/material-ui)
 */
import React, { PropTypes } from 'react'
import TextFieldUnderline from 'material-ui/TextField/TextFieldUnderline'
import TextFieldHint from 'material-ui/TextField/TextFieldHint'
import TextFieldLabel from 'material-ui/TextField/TextFieldLabel'
import AutoComplete from 'material-ui/AutoComplete/AutoComplete'
import transitions from 'material-ui/styles/transitions'
import Chip from 'material-ui/Chip'
import {blue300} from 'material-ui/styles/colors'
import {fade} from 'material-ui/utils/colorManipulator';

const getStyles = (props, context, state) => {
  const {
    baseTheme,
    textField: {
      floatingLabelColor,
      focusColor,
      textColor,
      disabledTextColor,
      backgroundColor,
      hintColor,
      errorColor,
    },
  } = context.muiTheme;

  const styles = {
    root: {
      fontSize: 16,
      lineHeight: '24px',
      width: props.fullWidth ? '100%' : 256,
      display: 'inline-block',
      position: 'relative',
      backgroundColor: backgroundColor,
      fontFamily: baseTheme.fontFamily,
      transition: transitions.easeOut('200ms', 'height'),
      cursor: 'text'
    },
    input: {
      padding: 0,
      marginTop: 0,
      marginBottom: 24,
      lineHeight: '32px',
      height: 32,
      position: 'relative',
      display: 'inline-block',
      border: 'none',
      outline: 'none',
      backgroundColor: 'rgba(0,0,0,0)',
      color: props.disabled ? disabledTextColor : textColor,
      cursor: props.disabled ? 'not-allowed' : 'initial',
      font: 'inherit',
      appearance: 'textfield', // Improve type search style.
      WebkitTapHighlightColor: 'rgba(0,0,0,0)', // Remove mobile color flashing (deprecated style).
      float: 'left',
    },
    floatingLabel: {
      color: hintColor,
      pointerEvents: 'none',
      top: 28
    },
    floatingLabelFocusStyle: {
      transform: 'scale(0.75) translate(0, -36px)'
    }
  };

  const hasValue = (props.value || state.chips).length > 0 || state.inputValue.length > 0
  if (hasValue) {
    styles.floatingLabel.color = fade(props.disabled ? disabledTextColor : floatingLabelColor, 0.5);
  }

  if (state.isFocused) {
    styles.floatingLabel.color = focusColor;
  }

  if (props.floatingLabelText) {
    styles.input.boxSizing = 'border-box';

    if (state.errorText) {
      styles.error.bottom = !props.multiLine ? styles.error.fontSize + 3 : 3;
    }
  }

  if (state.errorText) {
    if (state.isFocused) {
      styles.floatingLabel.color = styles.error.color;
    }
  }

  return styles;
};

class ChipInput extends React.Component {
  static contextTypes = {
    muiTheme: React.PropTypes.object.isRequired,
  };

  state = {
    isFocused: false,
    errorText: undefined,
    isClean: true,
    chips: [],
    focusedChip: null,
    inputValue: ''
  }

  constructor (props) {
    super(props)
    if (props.defaultValue) {
      this.state.chips = props.defaultValue
    }
  }

  componentWillMount() {
    const {
      name,
      hintText,
      floatingLabelText
    } = this.props;

    const uniqueId = `${name}-${hintText}-${floatingLabelText}-${
      Math.floor(Math.random() * 0xFFFF)}`;
    this.uniqueId = uniqueId.replace(/[^A-Za-z0-9-]/gi, '');
  }

  componentWillReceiveProps (nextProps) {
    if (nextProps.disabled) {
      this.setState({ focusedChip: null })
    }
  }

  blur() {
    if (this.input) this.getInputNode().blur();
  }

  focus() {
    if (this.input) this.getInputNode().focus();
    if (this.state.focusedChip) {
      this.setState({ focusedChip: null })
    }
  }

  select() {
    if (this.input) this.getInputNode().select();
  }

  getValue() {
    return this.input ? this.getInputNode().value : undefined;
  }

  getInputNode() {
    return this.input;
  }

  handleInputBlur = (event) => {
    this.setState({isFocused: false});
    if (this.props.onBlur) this.props.onBlur(event);
  }

  handleInputFocus = (event) => {
    if (this.props.disabled) {
      return;
    }
    this.setState({isFocused: true});
    if (this.props.onFocus) {
      this.props.onFocus(event);
    }
  }

  handleKeyDown = (event) => {
    if (event.keyCode === 13) { // enter
      this.handleAddChip(event.target.value)
    } else if (event.keyCode === 8 || event.keyCode === 46) {
      if (event.target.value === '') {
        const chips = this.props.value || this.state.chips
        if (this.state.focusedChip == null && event.keyCode === 8) {
          this.setState({ focusedChip: chips[chips.length - 1] })
        } else if (this.state.focusedChip) {
          const index = chips.indexOf(this.state.focusedChip)
          this.handleDeleteChip(this.state.focusedChip)
          if (event.keyCode === 8 && index > 0) {
            this.setState({ focusedChip: chips[index - 1] })
          } else if (event.keyCode === 46 && index < chips.length - 1) {
            this.setState({ focusedChip: chips[index + 1] })
          }
        }
      }
    } else if (event.keyCode === 37) {
      const chips = this.props.value || this.state.chips
      const index = chips.indexOf(this.state.focusedChip)
      if (index > 0) {
        this.setState({ focusedChip: chips[index - 1] })
      }
    } else if (event.keyCode === 39) {
      const chips = this.props.value || this.state.chips
      const index = chips.indexOf(this.state.focusedChip)
      if (index >= 0 && index < chips.length - 1) {
        this.setState({ focusedChip: chips[index + 1] })
      } else {
        this.setState({ focusedChip: null })
      }
    } else {
      this.setState({ focusedChip: null })
    }
  }

  handleAddChip (chip) {
    const chips = this.props.value || this.state.chips

    if (chip.trim().length > 0 && chips.indexOf(chip) === -1) {
      if (this.props.value) {
        if (this.props.onRequestAdd) {
          this.props.onRequestAdd(chip)
        }
      } else {
        this.setState({ chips: [ ...this.state.chips, chip ] })
        if (this.props.onChange) {
          this.props.onChange([ ...this.state.chips, chip ])
        }
      }

      this.setState({ inputValue: '' })
    }
  }

  handleDeleteChip (chip) {
    if (this.props.value) {
      if (this.props.onRequestDelete) {
        this.props.onRequestDelete(chip)
      }
    } else {
      const chips = this.state.chips.filter((c) => c !== chip)
      if (chips.length !== this.state.chips.length) {
        this.setState({
          chips,
          focusedChip: this.state.focusedChip === chip ? null : this.state.focusedChip
        })
        if (this.props.onChange) {
          this.props.onChange(chips)
        }
      }
    }
  }

  render () {
    const {
      children,
      className,
      disabled,
      errorStyle,
      errorText, // eslint-disable-line no-unused-vars
      fullWidth, // eslint-disable-line no-unused-vars
      hintText,
      hintStyle,
      inputStyle,
      onBlur, // eslint-disable-line no-unused-vars
      onChange, // eslint-disable-line no-unused-vars
      onFocus, // eslint-disable-line no-unused-vars
      style,
      underlineDisabledStyle,
      underlineFocusStyle,
      underlineShow,
      underlineStyle,
      defaultValue = [],
      value,
      dataSource,
      floatingLabelFixed,
      floatingLabelFocusStyle, // eslint-disable-line no-unused-vars
      floatingLabelStyle, // eslint-disable-line no-unused-vars
      floatingLabelText,
      onRequestAdd, // eslint-disable-line no-unused-vars
      onRequestDelete, // eslint-disable-line no-unused-vars
      ...other,
    } = this.props;

    const {prepareStyles} = this.context.muiTheme;
    const styles = getStyles(this.props, this.context, this.state);
    const inputId = this.uniqueId;

    const inputProps = {
      id: inputId,
      ref: (elem) => this.input = elem,
      disabled: this.props.disabled,
      onBlur: this.handleInputBlur,
      onFocus: this.handleInputFocus,
      onKeyDown: this.handleKeyDown
    }

    const inputStyleMerged = Object.assign(styles.input, inputStyle);

    const hasInput = (this.props.value || this.state.chips).length > 0 || this.state.inputValue.length > 0
    const showHintText = hintText && !hasInput
    const shrinkFloatingLabel = floatingLabelText && (hasInput || this.state.isFocused)

    const floatingLabelTextElement = floatingLabelText && (
      <TextFieldLabel
        muiTheme={this.context.muiTheme}
        style={Object.assign(styles.floatingLabel, this.props.floatingLabelStyle)}
        shrinkStyle={Object.assign(styles.floatingLabelFocusStyle, this.props.floatingLabelFocusStyle)}
        htmlFor={inputId}
        shrink={shrinkFloatingLabel}
        disabled={disabled}
      >
        {floatingLabelText}
      </TextFieldLabel>
    )

    const overrideRootStyles = {}
    if (floatingLabelText) {
      overrideRootStyles.marginTop = 14
    }
    if (fullWidth) {
      overrideRootStyles.width = '100%'
    }
    if (disabled) {
      overrideRootStyles.cursor = 'not-allowed'
    }

    const chips = this.props.value || this.state.chips
    const autoCompleteData = (dataSource || []).filter((value) => chips.indexOf(value) < 0)

    return (

 this.focus()}
      >

          {floatingLabelTextElement}

            {chips.map((tag) => (
              <Chip
                key={tag}
                style={{ margin: '8px 8px 0 0', float: 'left', pointerEvents: disabled ? 'none' : undefined }}
                backgroundColor={this.state.focusedChip === tag ? blue300 : null}
                onTouchTap={() => { this.setState({ focusedChip: tag }) }}
                onRequestDelete={() => this.handleDeleteChip(tag)}
              >
                {tag}
              </Chip>
            ))}

        {hintText ?
          <TextFieldHint
            muiTheme={this.context.muiTheme}
            show={showHintText && !(floatingLabelText && !this.state.isFocused)}
            style={Object.assign({ bottom: 20, pointerEvents: 'none' }, hintStyle)}
            text={hintText}
          /> :
          null
        }
        <AutoComplete
          {...other}
          {...inputProps}
          style={inputStyleMerged}
          dataSource={autoCompleteData}
          menuProps={{
            onChange: (event, input) => {
              setTimeout(() => this.focus())
              setTimeout(() => {
                this.handleAddChip(input)
                this.setState({ inputValue: '' })
              }, (other.menuCloseDelay || 300) + 10) // menuCloseDelay + 10
            }
          }}
          searchText={this.state.inputValue}
          underlineShow={false}
          onKeyUp={(event) => this.setState({ inputValue: event.target.value })}
        />
        <TextFieldUnderline
          disabled={disabled}
          disabledStyle={underlineDisabledStyle}
          error={!!this.state.errorText}
          errorStyle={errorStyle}
          focus={this.state.isFocused}
          focusStyle={underlineFocusStyle}
          muiTheme={this.context.muiTheme}
          style={underlineStyle}
        />

    )
  }
}

ChipInput.propTypes = {
  style: PropTypes.object,
  floatingLabelText: PropTypes.node,
  hintText: PropTypes.node,
  disabled: PropTypes.bool,
  defaultValue: PropTypes.arrayOf(PropTypes.string),
  onChange: PropTypes.func,
  value: PropTypes.arrayOf(PropTypes.string),
  onRequestAdd: PropTypes.func,
  onRequestDelete: PropTypes.func,
  dataSource: PropTypes.arrayOf(PropTypes.string),
  onUpdateInput: PropTypes.func,
}

export default ChipInput
<|endoftext|>


<commit_before>(function() {
  'use strict';
  var module = angular.module('sourceSelection', [
    'regionSelection',
    'geolocator',
    'cookies',
  ]);

  module.directive('offerSourceSelection', ['$window', 'cookies',
    function($window, cookies) {
      return {
        scope: {
          onRegionSelected: '&',
          onLocationSelected: '&',
          isLocationSelectionEnabled: '=',
        },
        link: function($scope, $element, $attrs) {
          $scope.canSelectProximal = function() {
            return !$window.navigator.geolocation;
          };
          $scope.regionSelected = function(region) {
            cookies.setOfferSource({
              region: region,
            });
            $scope.onRegionSelected({
              $region: region,
            });
          };
          $scope.locationSelected = function(lat, lng) {
            cookies.setOfferSource({
              location: true,
            });
            $scope.onLocationSelected({
              $lat: lat,
              $lng: lng,
            });
          };
        },
        restrict: 'E',
        templateUrl: 'src/mainView/offerList/sourceSelection/offerSourceSelection.template.html',
      };
    }
  ]);
})();
<commit_msg>fix being unable to not bind to location selection attr<commit_after>(function() {
  'use strict';
  var module = angular.module('sourceSelection', [
    'regionSelection',
    'geolocator',
    'cookies',
  ]);

  module.directive('offerSourceSelection', ['$window', 'cookies',
    function($window, cookies) {
      return {
        scope: {
          onRegionSelected: '&',
          onLocationSelected: '&',
          isLocationSelectionEnabled: '=?',
        },
        link: function($scope, $element, $attrs) {
          $scope.canSelectProximal = function() {
            return !$window.navigator.geolocation;
          };
          $scope.regionSelected = function(region) {
            cookies.setOfferSource({
              region: region,
            });
            $scope.onRegionSelected({
              $region: region,
            });
          };
          $scope.locationSelected = function(lat, lng) {
            cookies.setOfferSource({
              location: true,
            });
            $scope.onLocationSelected({
              $lat: lat,
              $lng: lng,
            });
          };
        },
        restrict: 'E',
        templateUrl: 'src/mainView/offerList/sourceSelection/offerSourceSelection.template.html',
      };
    }
  ]);
})();
<|endoftext|>