<commit_before>/*global document, location, io, XMLHttpRequest, setTimeout, setInterval, clearInterval, StyleFix, less, ActiveXObject*/
(function () {
    'use strict';

    var liveStyleOptions = {}; // The options will be injected by the server

    function log(msg) {
        if (liveStyleOptions.debug && window.console) {
            console.log(msg);
        }
    }

    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function (o, from) {
            var i;
            for (i = from || 0; i < this.length; i += 1) {
                if (this[i] === o) {
                    return i;
                }
            }
            return -1;
        };
    }

    var pollTimeout = 2000,
        changedHrefsQueue = [], // Queue of incoming change events
        isBusyByHref = {},
        escapeRegExp = function (str) {
            return str.replace(/[\.\+\*\{\}\[\]\(\)\?\^\$]/g, '\\$&');
        },
        cleanHref = function (href) {
            var local = new RegExp(
                '^' + escapeRegExp(document.location.protocol + '//' + document.location.host + (document.location.port ? ':' + document.location.port : '')) + '/',
                'i'),
                proxy,
                remote = /:\/\/|^\/\//;

            if (liveStyleOptions.proxy) {
                proxy = new RegExp('^' + escapeRegExp(liveStyleOptions.proxy), 'i');
                if (proxy.test(href)) {
                    return '/' + href.replace(proxy, '');
                }
            }

            if (!local.test(href) && (/^\/\//.test(href) || /^[a-z0-9\+]+:\/\//i.test(href))) {
                return false;
            }

            if (/^data:/.test(href)) {
                // AdBlock for Chrome injects these
                return false;
            }

            // Normalize to be root relative:
            href = href.replace(local, '').replace(/\?.*$/, '');
            if (!/^\//.test(href)) {
                href = location.pathname.replace(/[^\/]+$/, '') + href;
            }

            // Normalize: /foo/../bar => /bar
            while (/\/[^\/\.][^\/]*\/\.\.\//.test(href)) {
                href = href.replace(/\/[^\/\.][^\/]*\/\.\.\//, '/');
            }

            return href;
        },
        findCssIncludes = function () {
            var cssIncludes = [],
                links = document.getElementsByTagName('link'),
                styles = document.getElementsByTagName('style'),
                style,
                cssRule,
                i,
                href;

            // Link tags with rel="stylesheet"
            for (i = 0; i < links.length; i += 1) {
                if (/\bstylesheet\b/i.test(links[i].getAttribute('rel'))) {
                    href = cleanHref(links[i].getAttribute('href'));
                    if (href) {
                        cssIncludes.push({type: 'link', href: href, node: links[i]});
                    }
                }
            }

            // Style tags: @includes and inline prefixfree blocks
            for (i = 0 ; i < styles.length ; i += 1) {
                style = styles[i];

                if (typeof StyleFix !== 'undefined') {
                    // Prefixfree support
                    href = style.href || style.getAttribute('data-href');

                    if (href) {
                        cssIncludes.push({type: 'prefixfree', href: cleanHref(href), node: style});
                    }
                }

                // @import
                style.innerHTML.replace(/@import\s+(?:'([^']+)'|"([^"]+)"|url\(([^\)]+)\))/g, function ($0, singleQuotedHref, doubleQuotedHref, urlParenthesesHref) {
                    if (urlParenthesesHref) {
                        urlParenthesesHref = urlParenthesesHref.replace(/^(['"])(.*)\1$/, '$2');
                    }
                    var href = singleQuotedHref || doubleQuotedHref || urlParenthesesHref;
                    cssIncludes.push({type: 'import', href: href, styleElement: style});
                });
            }

            return cssIncludes;
        },
        removeCacheBuster = function (href) {
            return href.replace(/[?&]livestyle=\d+/, '');
        },
        addCacheBuster = function (href) {
            return href + (href.indexOf('?') === -1 ? '?' : '&') + 'livestyle=' + new Date().getTime();
        },

        // Replaces a link tag with an updated version. Just replacing the href would cause FOUC.
        // We insert the new node before the old one and remove the old one after the new one has loaded.
        replaceLinkTag = function (node, href) {
            isBusyByHref[href] = (isBusyByHref[href] || 0) + 1;
            var parent = node.parentNode,
                newNode = node.cloneNode(true),
                monitor;

            // The node must be added to the document before the href is set, otherwise IE9 won't
            // apply the styles.
            if (node.nextSibling) {
                parent.insertBefore(newNode, node.nextSibling);
            } else {
                parent.appendChild(newNode);
            }

            newNode.href = href;
            newNode.onload = function () {
                isBusyByHref[href] -= 1;
                if (node.parentNode) {
                    parent.removeChild(node);

                    clearInterval(monitor);
                }
                // There may be additional occurrences of this href in changedHrefsQueue that can be processed
                // now that the busy counter was decremented:
                processNextChangedHref();
            };
            monitor = setInterval(function () {
                try {
                    if (newNode.sheet && newNode.sheet.cssRules.length > 0) { // Throws an error if the stylesheet hasn't loaded
                        newNode.onload();
                    }
                } catch (err) {}
            }, 20);
        },
        replaceStyleTag = function (node, oldHref, href) {
            var parent = node.parentNode,
                newNode = node.cloneNode(),
                replacerRegexp = new RegExp("@import\\s+url\\([\"']?" + oldHref.replace(/[\?\[\]\(\)\{\}]/g, "\\$&") + "[\"']?\\)");

            newNode.textContent = node.textContent.replace(replacerRegexp, '@import url(\'' + addCacheBuster(href) + '\')');
            parent.insertBefore(newNode, node);
            parent.removeChild(node);
        },
        processNextChangedHref = function () {
            var i,
                href;
            // Find the first non-busy href in changedHrefsQueue:
            for (i = 0 ; i < changedHrefsQueue.length ; i += 1) {
                if (isBusyByHref[changedHrefsQueue[i]]) {
                    if (liveStyleOptions.debug) {
                        log("Postponing 'change' notification on stylesheet that's already being refreshed: " + changedHrefsQueue[i]);
                    }
                } else {
                    href = changedHrefsQueue.splice(i, 1)[0];
                    break;
                }
            }
            if (!href) {
                return;
            }
            log('Refreshing ' + href);

            var cssIncludes = findCssIncludes(),
                cssInclude,
                cssIncludeHref,
                newHref,
                replacerRegExp;

            if (href === location.pathname) {
                location.reload(true);
            }

            for (i = 0; i < cssIncludes.length; i += 1) {
                cssInclude = cssIncludes[i];
                cssIncludeHref = removeCacheBuster(cssInclude.href);

                if (cssIncludeHref === href) {
                    if (cssInclude.type === 'link') {
                        // Less.js support (https://github.com/cloudhead/less.js)
                        if (/\bstylesheet\/less\b/i.test(cssInclude.node.getAttribute('rel')) && typeof less !== 'undefined') {
                            // Sadly this method isn't accessible
                            // less.loadStyleSheet(cssInclude.node, function () {}, false, 0);
                            // So instead we'll just have to brutally refresh ALL less includes
                            less.refresh();
                        } else {
                            replaceLinkTag(cssInclude.node, href);
                        }
                    }

                    if (cssInclude.type === 'import') {
                        replaceStyleTag(cssInclude.styleElement, cssInclude.href, addCacheBuster(href));
                    }

                    if (cssInclude.type === 'prefixfree') {
                        // The next two lines are hacks to make Prefixfree think this is a link and not a style block
                        cssInclude.node.setAttribute('href', href); // No cache buster needed
                        cssInclude.node.rel = 'stylesheet';
                        StyleFix.link(cssInclude.node);
                    }

                    // Replacing the first occurrence should be good enough. Besides, the @import replacement code invalidates
                    // the rest of the cssIncludes in the same stylesheet.
                    break;
                }
            }
            processNextChangedHref(); // We consumed an item from changedHrefsQueue, keep going
        },
        startListening = function () {
            var socket = io.connect();

            socket.on('connect', function () {
                var hrefs = [],
                    watchNewStylesheets = function () {
                        var cssIncludes = findCssIncludes(),
                            toWatch = [],
                            url,
                            i;
                        //cssIncludes.unshift({ href: location.pathname }); // See https://github.com/One-com/livestyle/issues/11

                        for (i = 0; i < cssIncludes.length; i += 1) {
                            url = removeCacheBuster(cssIncludes[i].href);
                            if (hrefs.indexOf(url) === -1) {
                                hrefs.push(url);
                                toWatch.push(url);
                            }
                        }

                        if (toWatch.length !== 0) {
                            log('Subscribing to ' + toWatch.length + ' files:\n  ' + toWatch.join('\n  '));
                            socket.emit('watch', toWatch);
                        }
                    };

                watchNewStylesheets();
                setInterval(watchNewStylesheets, pollTimeout);
            }).on('change', function (href) {
                if (changedHrefsQueue.indexOf(href) === -1) {
                    changedHrefsQueue.push(href);
                    log('Received change notification for ' + href + ', queued');
                    processNextChangedHref();
                } else {
                    log('Received change notification for ' + href + ', skipped (already in queue)');
                }
            });
        },
        state = {},
        startPolling = function () {
            var getXHR = function () {
                    try {
                        return new XMLHttpRequest();
                    } catch (e1) {
                        try {
                            return new ActiveXObject("Msxml2.XMLHTTP.6.0");
                        } catch (e2) {
                            try {
                                return new ActiveXObject("Msxml2.XMLHTTP.3.0");
                            } catch (e3) {
                                try {
                                    return new ActiveXObject("Msxml2.XMLHTTP");
                                } catch (e4) {
                                    try {
                                        return new ActiveXObject("Microsoft.XMLHTTP");
                                    } catch (e5) {}
                                }
                            }
                        }
                    }

                    return null; // no XHR support
                },
                cssIncludes = findCssIncludes(),
                proceed = function () {
                    var cssInclude,
                        url,
                        xhr;

                    if (cssIncludes.length > 0) {
                        cssInclude = cssIncludes.shift();
                        url = removeCacheBuster(cssInclude.href);
                        xhr = getXHR();

                        xhr.onreadystatechange = function () {
                            var lastModified,
                                etag;

                            if (xhr.readyState === 4) {
                                if (xhr.status === 200) {
                                    lastModified = Date.parse(xhr.getResponseHeader("Last-Modified"));
                                    etag = xhr.getResponseHeader("ETag");

                                    if (!state[url] || state[url].lastModified < lastModified || state[url].etag !== etag) {
                                        state[url] = {
                                            lastModified: lastModified,
                                            etag: etag
                                        };
                                        refresh(url);
                                    }
                                }

                                proceed();
                            }
                        };
                        xhr.open('HEAD', addCacheBuster(url), true);
                        xhr.send(null);
                    } else {
                        setTimeout(startPolling, pollTimeout);
                    }
                };
            //cssIncludes.unshift({ href: location.pathname }); // See https://github.com/One-com/livestyle/issues/11
            proceed();
        };

    if (typeof io !== 'undefined') {
        log('socket.io present, connecting');
        startListening();
    } else {
        log('socket.io not present, falling back to polling mode');
        startPolling();
    }
}());
<commit_msg>livestyle-client.js, cleanHref: If an href has a protocol, require it to be http or https, otherwise skip it.<commit_after>/*global document, location, io, XMLHttpRequest, setTimeout, setInterval, clearInterval, StyleFix, less, ActiveXObject*/
(function () {
    'use strict';

    var liveStyleOptions = {}; // The options will be injected by the server

    function log(msg) {
        if (liveStyleOptions.debug && window.console) {
            console.log(msg);
        }
    }

    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function (o, from) {
            var i;
            for (i = from || 0; i < this.length; i += 1) {
                if (this[i] === o) {
                    return i;
                }
            }
            return -1;
        };
    }

    var pollTimeout = 2000,
        changedHrefsQueue = [], // Queue of incoming change events
        isBusyByHref = {},
        escapeRegExp = function (str) {
            return str.replace(/[\.\+\*\{\}\[\]\(\)\?\^\$]/g, '\\$&');
        },
        cleanHref = function (href) {
            var local = new RegExp(
                '^' + escapeRegExp(document.location.protocol + '//' + document.location.host + (document.location.port ? ':' + document.location.port : '')) + '/',
                'i'),
                proxy,
                remote = /:\/\/|^\/\//;

            // Skip things like chrome-extension://hmdcmlfkchdmnmnmheododdhjedfccka/inject/anchor-cursor-default.css?0.2.6
            if (/^[\w\-]+:/.test(href) && !/^https?:/.test(href)) {
                return false;
            }

            if (liveStyleOptions.proxy) {
                proxy = new RegExp('^' + escapeRegExp(liveStyleOptions.proxy), 'i');
                if (proxy.test(href)) {
                    return '/' + href.replace(proxy, '');
                }
            }

            if (!local.test(href) && (/^\/\//.test(href) || /^[a-z0-9\+]+:\/\//i.test(href))) {
                return false;
            }

            if (/^data:/.test(href)) {
                // AdBlock for Chrome injects these
                return false;
            }

            // Normalize to be root relative:
            href = href.replace(local, '').replace(/\?.*$/, '');
            if (!/^\//.test(href)) {
                href = location.pathname.replace(/[^\/]+$/, '') + href;
            }

            // Normalize: /foo/../bar => /bar
            while (/\/[^\/\.][^\/]*\/\.\.\//.test(href)) {
                href = href.replace(/\/[^\/\.][^\/]*\/\.\.\//, '/');
            }

            return href;
        },
        findCssIncludes = function () {
            var cssIncludes = [],
                links = document.getElementsByTagName('link'),
                styles = document.getElementsByTagName('style'),
                style,
                cssRule,
                i,
                href;

            // Link tags with rel="stylesheet"
            for (i = 0; i < links.length; i += 1) {
                if (/\bstylesheet\b/i.test(links[i].getAttribute('rel'))) {
                    href = cleanHref(links[i].getAttribute('href'));
                    if (href) {
                        cssIncludes.push({type: 'link', href: href, node: links[i]});
                    }
                }
            }

            // Style tags: @includes and inline prefixfree blocks
            for (i = 0 ; i < styles.length ; i += 1) {
                style = styles[i];

                if (typeof StyleFix !== 'undefined') {
                    // Prefixfree support
                    href = style.href || style.getAttribute('data-href');

                    if (href) {
                        cssIncludes.push({type: 'prefixfree', href: cleanHref(href), node: style});
                    }
                }

                // @import
                style.innerHTML.replace(/@import\s+(?:'([^']+)'|"([^"]+)"|url\(([^\)]+)\))/g, function ($0, singleQuotedHref, doubleQuotedHref, urlParenthesesHref) {
                    if (urlParenthesesHref) {
                        urlParenthesesHref = urlParenthesesHref.replace(/^(['"])(.*)\1$/, '$2');
                    }
                    var href = singleQuotedHref || doubleQuotedHref || urlParenthesesHref;
                    cssIncludes.push({type: 'import', href: href, styleElement: style});
                });
            }

            return cssIncludes;
        },
        removeCacheBuster = function (href) {
            return href.replace(/[?&]livestyle=\d+/, '');
        },
        addCacheBuster = function (href) {
            return href + (href.indexOf('?') === -1 ? '?' : '&') + 'livestyle=' + new Date().getTime();
        },

        // Replaces a link tag with an updated version. Just replacing the href would cause FOUC.
        // We insert the new node before the old one and remove the old one after the new one has loaded.
        replaceLinkTag = function (node, href) {
            isBusyByHref[href] = (isBusyByHref[href] || 0) + 1;
            var parent = node.parentNode,
                newNode = node.cloneNode(true),
                monitor;

            // The node must be added to the document before the href is set, otherwise IE9 won't
            // apply the styles.
            if (node.nextSibling) {
                parent.insertBefore(newNode, node.nextSibling);
            } else {
                parent.appendChild(newNode);
            }

            newNode.href = href;
            newNode.onload = function () {
                isBusyByHref[href] -= 1;
                if (node.parentNode) {
                    parent.removeChild(node);

                    clearInterval(monitor);
                }
                // There may be additional occurrences of this href in changedHrefsQueue that can be processed
                // now that the busy counter was decremented:
                processNextChangedHref();
            };
            monitor = setInterval(function () {
                try {
                    if (newNode.sheet && newNode.sheet.cssRules.length > 0) { // Throws an error if the stylesheet hasn't loaded
                        newNode.onload();
                    }
                } catch (err) {}
            }, 20);
        },
        replaceStyleTag = function (node, oldHref, href) {
            var parent = node.parentNode,
                newNode = node.cloneNode(),
                replacerRegexp = new RegExp("@import\\s+url\\([\"']?" + oldHref.replace(/[\?\[\]\(\)\{\}]/g, "\\$&") + "[\"']?\\)");

            newNode.textContent = node.textContent.replace(replacerRegexp, '@import url(\'' + addCacheBuster(href) + '\')');
            parent.insertBefore(newNode, node);
            parent.removeChild(node);
        },
        processNextChangedHref = function () {
            var i,
                href;
            // Find the first non-busy href in changedHrefsQueue:
            for (i = 0 ; i < changedHrefsQueue.length ; i += 1) {
                if (isBusyByHref[changedHrefsQueue[i]]) {
                    if (liveStyleOptions.debug) {
                        log("Postponing 'change' notification on stylesheet that's already being refreshed: " + changedHrefsQueue[i]);
                    }
                } else {
                    href = changedHrefsQueue.splice(i, 1)[0];
                    break;
                }
            }
            if (!href) {
                return;
            }
            log('Refreshing ' + href);

            var cssIncludes = findCssIncludes(),
                cssInclude,
                cssIncludeHref,
                newHref,
                replacerRegExp;

            if (href === location.pathname) {
                location.reload(true);
            }

            for (i = 0; i < cssIncludes.length; i += 1) {
                cssInclude = cssIncludes[i];
                cssIncludeHref = removeCacheBuster(cssInclude.href);

                if (cssIncludeHref === href) {
                    if (cssInclude.type === 'link') {
                        // Less.js support (https://github.com/cloudhead/less.js)
                        if (/\bstylesheet\/less\b/i.test(cssInclude.node.getAttribute('rel')) && typeof less !== 'undefined') {
                            // Sadly this method isn't accessible
                            // less.loadStyleSheet(cssInclude.node, function () {}, false, 0);
                            // So instead we'll just have to brutally refresh ALL less includes
                            less.refresh();
                        } else {
                            replaceLinkTag(cssInclude.node, href);
                        }
                    }

                    if (cssInclude.type === 'import') {
                        replaceStyleTag(cssInclude.styleElement, cssInclude.href, addCacheBuster(href));
                    }

                    if (cssInclude.type === 'prefixfree') {
                        // The next two lines are hacks to make Prefixfree think this is a link and not a style block
                        cssInclude.node.setAttribute('href', href); // No cache buster needed
                        cssInclude.node.rel = 'stylesheet';
                        StyleFix.link(cssInclude.node);
                    }

                    // Replacing the first occurrence should be good enough. Besides, the @import replacement code invalidates
                    // the rest of the cssIncludes in the same stylesheet.
                    break;
                }
            }
            processNextChangedHref(); // We consumed an item from changedHrefsQueue, keep going
        },
        startListening = function () {
            var socket = io.connect();

            socket.on('connect', function () {
                var hrefs = [],
                    watchNewStylesheets = function () {
                        var cssIncludes = findCssIncludes(),
                            toWatch = [],
                            url,
                            i;
                        //cssIncludes.unshift({ href: location.pathname }); // See https://github.com/One-com/livestyle/issues/11

                        for (i = 0; i < cssIncludes.length; i += 1) {
                            url = removeCacheBuster(cssIncludes[i].href);
                            if (hrefs.indexOf(url) === -1) {
                                hrefs.push(url);
                                toWatch.push(url);
                            }
                        }

                        if (toWatch.length !== 0) {
                            log('Subscribing to ' + toWatch.length + ' files:\n  ' + toWatch.join('\n  '));
                            socket.emit('watch', toWatch);
                        }
                    };

                watchNewStylesheets();
                setInterval(watchNewStylesheets, pollTimeout);
            }).on('change', function (href) {
                if (changedHrefsQueue.indexOf(href) === -1) {
                    changedHrefsQueue.push(href);
                    log('Received change notification for ' + href + ', queued');
                    processNextChangedHref();
                } else {
                    log('Received change notification for ' + href + ', skipped (already in queue)');
                }
            });
        },
        state = {},
        startPolling = function () {
            var getXHR = function () {
                    try {
                        return new XMLHttpRequest();
                    } catch (e1) {
                        try {
                            return new ActiveXObject("Msxml2.XMLHTTP.6.0");
                        } catch (e2) {
                            try {
                                return new ActiveXObject("Msxml2.XMLHTTP.3.0");
                            } catch (e3) {
                                try {
                                    return new ActiveXObject("Msxml2.XMLHTTP");
                                } catch (e4) {
                                    try {
                                        return new ActiveXObject("Microsoft.XMLHTTP");
                                    } catch (e5) {}
                                }
                            }
                        }
                    }

                    return null; // no XHR support
                },
                cssIncludes = findCssIncludes(),
                proceed = function () {
                    var cssInclude,
                        url,
                        xhr;

                    if (cssIncludes.length > 0) {
                        cssInclude = cssIncludes.shift();
                        url = removeCacheBuster(cssInclude.href);
                        xhr = getXHR();

                        xhr.onreadystatechange = function () {
                            var lastModified,
                                etag;

                            if (xhr.readyState === 4) {
                                if (xhr.status === 200) {
                                    lastModified = Date.parse(xhr.getResponseHeader("Last-Modified"));
                                    etag = xhr.getResponseHeader("ETag");

                                    if (!state[url] || state[url].lastModified < lastModified || state[url].etag !== etag) {
                                        state[url] = {
                                            lastModified: lastModified,
                                            etag: etag
                                        };
                                        refresh(url);
                                    }
                                }

                                proceed();
                            }
                        };
                        xhr.open('HEAD', addCacheBuster(url), true);
                        xhr.send(null);
                    } else {
                        setTimeout(startPolling, pollTimeout);
                    }
                };
            //cssIncludes.unshift({ href: location.pathname }); // See https://github.com/One-com/livestyle/issues/11
            proceed();
        };

    if (typeof io !== 'undefined') {
        log('socket.io present, connecting');
        startListening();
    } else {
        log('socket.io not present, falling back to polling mode');
        startPolling();
    }
}());
<|endoftext|>


<commit_before>Ensembl.Panel.VEPForm = Ensembl.Panel.Content.extend({
  constructor: function () {
    this.base.apply(this, arguments);
    Ensembl.EventManager.register('indicateInputError', this, this.indicateInputError);
  },

  init: function () {
    this.base();
    var panel = this;
    this.elLk.vepForm = this.el.find('form.blast');

    this.elLk.vepForm.on('submit', function () {
      panel.elLk.vepForm.addClass('overlay_blast');
      $('input.submit_vep', panel.elLk.vepForm).addClass('disabled').prop('value', 'Processing');
      $('.vep_input', panel.elLk.vepForm).attr('disabled', 'disabled');

      // make FormData to allow file upload to go through AJAX
      var formData = new FormData(this);

      $.ajax({
        url: this.action,
        data: formData,
        dataType: 'json',
        type: this.method,
        cache: false,
        processData: false,
        contentType: false,
        success: function (json) {

          Ensembl.EventManager.trigger(json.functionName, json.functionData);

          if (json.functionName === 'updateJobsList') {
            window.scrollTo(0, 0);
            panel.elLk.vepForm[0].reset();
          }
          panel.elLk.vepForm.removeClass('overlay_blast');
          $('input.submit_vep', panel.elLk.vepForm).removeClass('disabled').prop('value', 'Run');
          $('.vep_input', panel.elLk.blastform).removeAttr('disabled');
          Ensembl.replaceTimestamp(window.location.href);
        }
      });
      return false;
    });

    $('.select_on_focus').on('click', function() { $(this).select(); });
  },

  indicateInputError: function (errors) {
    var panel = this;
    panel.elLk.vepForm.addClass('check');

    var display_errors = { rules: {}, message: {} };

    var failed = $.map(errors, function (message, error_class) {
      var tmp_errors = { rules: {}, messages: {} };
      tmp_errors.rules[error_class] = function (val) {
        return !this.inputs.filter('._' + error_class).hasClass('failed');
      };
      tmp_errors.messages[error_class] = message;
      $.extend(true, display_errors, tmp_errors);
      $("." + error_class +":last", panel.elLk.vepForm).prop('title', message).addClass('_' + error_class + ' failed');
      return;
    });

    panel.elLk.vepForm.validate( display_errors, 'showError');
    $.each(failed, function () { this.removeClass('failed valid'); });
    failed = null;
  }
});
<commit_msg>minor fixes for error handling<commit_after>Ensembl.Panel.VEPForm = Ensembl.Panel.Content.extend({
  constructor: function () {
    this.base.apply(this, arguments);
    Ensembl.EventManager.register('indicateInputError', this, this.indicateInputError);
  },

  init: function () {
    this.base();
    var panel = this;
    this.elLk.vepForm = this.el.find('form.blast');

    this.elLk.vepForm.on('submit', function () {
      panel.elLk.vepForm.addClass('overlay_blast');
      $('input.submit_vep', panel.elLk.vepForm).addClass('disabled').prop('value', 'Processing');
      $('.vep_input', panel.elLk.vepForm).attr('disabled', 'disabled');

      // make FormData to allow file upload to go through AJAX
      var formData = new FormData(this);

      $.ajax({
        url: this.action,
        data: formData,
        dataType: 'json',
        type: this.method,
        cache: false,
        processData: false,
        contentType: false,
        success: function (json) {

          Ensembl.EventManager.trigger(json.functionName, json.functionData);

          if (json.functionName === 'updateJobsList') {
            window.scrollTo(0, 0);
            $('.failed').removeClass('failed');
            panel.elLk.vepForm[0].reset();
          }
          panel.elLk.vepForm.removeClass('overlay_blast');
          $('input.submit_vep', panel.elLk.vepForm).removeClass('disabled').prop('value', 'Run');
          $('.vep_input', panel.elLk.blastform).removeAttr('disabled');
          Ensembl.replaceTimestamp(window.location.href);
        }
      });
      return false;
    });

    $('.select_on_focus').on('click', function() { $(this).select(); });
  },

  indicateInputError: function (errors) {
    var panel = this;
    panel.elLk.vepForm.addClass('check');

    var display_errors = { rules: {}, message: {} };

    $('.failed').removeClass('failed valid');

    var failed = $.map(errors, function (message, error_class) {
      var tmp_errors = { rules: {}, messages: {} };
      tmp_errors.rules[error_class] = function (val) {
        return !this.inputs.filter('._' + error_class).hasClass('failed');
      };
      tmp_errors.messages[error_class] = message;
      $.extend(true, display_errors, tmp_errors);
      $("." + error_class +":last", panel.elLk.vepForm).parent().parent().prop('title', '<span style="color: red; font-weight: bold;">ERROR: </span>' + message).addClass('_' + error_class + ' failed _ht').helptip();
      return;
    });

    panel.elLk.vepForm.validate( display_errors, 'showError');
    $.each(failed, function () { this.removeClass('failed valid'); });
    failed = null;
  }
});
<|endoftext|>


<commit_before>udefine(['../graphics'], function(Graphics) {

  var pixelize = function(num) {
    return num + 'px';
  };

  var unpixelize = function(str) {
    return parseFloat(str) || 0;
  };

  Graphics.renderer = 'DOM';
  var rootElement = null;

  Graphics.on('initialize', function(Game) {
  	var containerName = (function() {
	  	if (Game.container == null) {
	  		return Game.container = Game.id;
	  	} else {
		  	if (Game.container.indexOf('#') === 0) {
		      return Game.container.slice(1);
		    }
	  	}
  	})();

    Game.width = Game.width || window.innerWidth;
    Game.height = Game.height || window.innerHeight;

    rootElement = document.getElementById(containerName);

    if (rootElement == null) {
      var element = document.createElement('div');
      element.id = containerName.toLowerCase();
      document.body.appendChild(element);

      rootElement = element;
    }

   	rootElement.className = [Game.type.toLowerCase(), Game.name.toLowerCase()].join(' ');

		rootElement.style.position = 'absolute';
    rootElement.style.width = pixelize(Game.width);
    rootElement.style.height = pixelize(Game.height);
    rootElement.style.backgroundColor = Game.color;
    rootElement.style.overflow = 'hidden';

    if (Game.width < window.innerWidth) {
    	rootElement.style.left = '50%';
    	rootElement.style.marginLeft = (Game.width * (-0.5)) + 'px';
    }

    if (Game.height < window.innerHeight) {
    	rootElement.style.top = '50%';
    	rootElement.style.marginTop = (Game.width * (-0.5)) + 'px';
    }
  });

  Graphics.on('add', function(obj) {
  	var elementId = obj.id.toLowerCase();

    // Remove previous elements of the same id
    if (document.getElementById(elementId) != null) {
    	(function() {
				var parentId = obj.parent.id.toLowerCase();

				var parentElem = document.getElementById(parentId);
				parentElem.removeChild(document.getElementId(elementId));
    	})();
    }

    var parent = obj.parent;

    var parentElem = (function() {
      if ((parent && parent.isRoot) || parent == null) {
        return rootElement;
      } else {
        var parentId = obj.parent.id.toLowerCase();
        var element = document.getElementById(parentId);
        if (element == null) {
          return rootElement;
        } else {
          return element;
        }
      }
    })();

    var element = document.createElement('div');
    element.id = elementId;
    element.className = [obj.type.toLowerCase(), obj.name.toLowerCase()].join(' ');
    element.style.position = 'absolute';

    switch (obj.type) {
    case 'Scene':
    	element.style.width = pixelize(obj.parent.width);
    	element.style.height = pixelize(obj.parent.height);
      break;
    case 'GameObject':
      element.style.left = pixelize(obj.x);
      element.style.top = pixelize(obj.y);
      element.style.width = pixelize(obj.width);
      element.style.height = pixelize(obj.height);
      break;
    default:
      break;
    }

    parentElem.appendChild(element);
  });

  Graphics.on('texture-loaded', function(obj, texture) {
    var element = document.getElementById(obj.id.toLowerCase());

    if (element != null) {
      element.style.backgroundImage = 'url(' + texture.filename + ')';
      element.style.width = pixelize(obj.width);
      element.style.height = pixelize(obj.height);
    }
  });

  Graphics.on('render', function(obj) {
    // Update element attributes
    var element = document.getElementById(obj.id.toLowerCase());

    if (element != null) {
      switch (obj.type) {
      case 'GameObject':
      	var elemVisible = element.style.display === 'block';

      	if (elemVisible !== obj.visible) {
      		element.style.display = (obj.visible) ? 'block' : 'hidden';
      	}

      	if (!elemVisible) {
      		return;
      	}

        var elemX = unpixelize(element.style.left);
        var elemY = unpixelize(element.style.top);
        var elemWidth = unpixelize(element.style.width);
        var elemHeight = unpixelize(element.style.height);

        if (elemX !== obj.x) {
          element.style.left = pixelize(obj.x);
        }

        if (elemY !== obj.y) {
          element.style.top = pixelize(obj.y);
        }

        if (elemWidth !== obj.width) {
          element.style.width = pixelize(obj.width);
        }

        if (elemHeight !== obj.height) {
          element.style.height = pixelize(obj.height);
        }

        if (obj.angle) {
        	element.style.transform = 'rotate(' + obj.angle + 'deg)';
        }

        // Set background color
        if (!obj.texture.filename) {
        	element.style.backgroundColor = obj.texture.color;
        }
        break;
      case 'Game':
      	break;
      default:
      	break;
      }

    }

  });

  return Graphics;

});
<commit_msg>DOM renderer can now handle scene switches<commit_after>udefine(['../graphics'], function(Graphics) {

  var pixelize = function(num) {
    return num + 'px';
  };

  var unpixelize = function(str) {
    return parseFloat(str) || 0;
  };

  Graphics.renderer = 'DOM';
  var rootElement = null;

  Graphics.on('initialize', function(Game) {
  	var containerName = (function() {
	  	if (Game.container == null) {
	  		return Game.container = Game.id;
	  	} else {
		  	if (Game.container.indexOf('#') === 0) {
		      return Game.container.slice(1);
		    }
	  	}
  	})();

    Game.width = Game.width || window.innerWidth;
    Game.height = Game.height || window.innerHeight;

    rootElement = document.getElementById(containerName);

    if (rootElement == null) {
      var element = document.createElement('div');
      element.id = containerName.toLowerCase();
      document.body.appendChild(element);

      rootElement = element;
    }

   	rootElement.className = [Game.type.toLowerCase(), Game.name.toLowerCase()].join(' ');

		rootElement.style.position = 'absolute';
    rootElement.style.width = pixelize(Game.width);
    rootElement.style.height = pixelize(Game.height);
    rootElement.style.backgroundColor = Game.color;
    rootElement.style.overflow = 'hidden';

    if (Game.width < window.innerWidth) {
    	rootElement.style.left = '50%';
    	rootElement.style.marginLeft = (Game.width * (-0.5)) + 'px';
    }

    if (Game.height < window.innerHeight) {
    	rootElement.style.top = '50%';
    	rootElement.style.marginTop = (Game.width * (-0.5)) + 'px';
    }
  });

  Graphics.on('add', function(obj) {
  	var elementId = obj.id.toLowerCase();

    // Remove previous elements of the same id
    if (document.getElementById(elementId) != null) {
    	(function() {
				var parentId = obj.parent.id.toLowerCase();

				var parentElem = document.getElementById(parentId);
				parentElem.removeChild(document.getElementId(elementId));
    	})();
    }

    var parent = obj.parent;

    var parentElem = (function() {
      if ((parent && parent.isRoot) || parent == null) {
        return rootElement;
      } else {
        var parentId = obj.parent.id.toLowerCase();
        var element = document.getElementById(parentId);
        if (element == null) {
          return rootElement;
        } else {
          return element;
        }
      }
    })();

    var element = document.createElement('div');
    element.id = elementId;
    element.className = [obj.type.toLowerCase(), obj.name.toLowerCase()].join(' ');
    element.style.position = 'absolute';

    switch (obj.type) {
    case 'Scene':
    	element.style.width = pixelize(obj.parent.width);
    	element.style.height = pixelize(obj.parent.height);
      break;
    case 'GameObject':
      element.style.left = pixelize(obj.x);
      element.style.top = pixelize(obj.y);
      element.style.width = pixelize(obj.width);
      element.style.height = pixelize(obj.height);
      break;
    default:
      break;
    }

    parentElem.appendChild(element);
  });

  Graphics.on('texture-loaded', function(obj, texture) {
    var element = document.getElementById(obj.id.toLowerCase());

    if (element != null) {
      element.style.backgroundImage = 'url(' + texture.filename + ')';
      element.style.width = pixelize(obj.width);
      element.style.height = pixelize(obj.height);
    }
  });

  Graphics.on('render', function(obj) {
    // Update element attributes
    var element = document.getElementById(obj.id.toLowerCase());

    if (element != null) {
      switch (obj.type) {
      case 'GameObject':
      	var elemVisible = element.style.display === 'block';

      	if (elemVisible !== obj.visible) {
      		element.style.display = (obj.visible) ? 'block' : 'hidden';
      	}

      	if (!elemVisible) {
      		return;
      	}

        var elemX = unpixelize(element.style.left);
        var elemY = unpixelize(element.style.top);
        var elemWidth = unpixelize(element.style.width);
        var elemHeight = unpixelize(element.style.height);

        if (elemX !== obj.x) {
          element.style.left = pixelize(obj.x);
        }

        if (elemY !== obj.y) {
          element.style.top = pixelize(obj.y);
        }

        if (elemWidth !== obj.width) {
          element.style.width = pixelize(obj.width);
        }

        if (elemHeight !== obj.height) {
          element.style.height = pixelize(obj.height);
        }

        if (obj.angle) {
        	element.style.transform = 'rotate(' + obj.angle + 'deg)';
        }

        if (obj.alpha !== 1) {
        	element.style.opacity = obj.alpha;
        }

        // Set background color
        if (!obj.texture.filename) {
        	element.style.backgroundColor = obj.texture.color;
        }
        break;
      case 'Scene':
      	var elemVisibleStyle = element.style.display;

      	if (obj.parent.activeScene !== obj.name) {
      		if (elemVisibleStyle !== 'hidden') {
      			element.style.display = 'hidden';
      		}
      	} else {
      		if (elemVisibleStyle !== 'block') {
      			element.style.display = 'block';
      		}
      	}
      	break;
      default:
      	break;
      }

    }

  });

  return Graphics;

});
<|endoftext|>


<commit_before>#!/usr/bin/env node

var express = require('express');
var bodyParser = require('body-parser');
var exec = require('child_process').exec;

var app = express();

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: false}));

// parse application/json
app.use(bodyParser.json());

// parse application/vnd.api+json as json
app.use(bodyParser.json({type: 'application/vnd.api+json'}));

app.use(function (req, res, next) {
  console.log('\n\n');
  console.log(req.url);
  console.log(req.body); // populated!

  doAfter(req.body);

  next();
});

app.get('/', function (req, res, next) {
  console.log('REQ', new Date());
  res.end('Hello world.\n');
});

var server = app.listen(1394, function () {
  console.log('Listening...');
});

function doAfter(data) {
  var repo = data.repository;
  var commits = data.commits;

  if (!repo || !commits) {
    return;
  }

  if (repo === 'youdar.net' && commits.length > 0) {
    updateYoudarNet();
  }
}

function updateYoudarNet() {
  var cmd = 'cd /usr/share/nginx/html/next.youdar.net/youdar && git pull origin master';

  exec(cmd, function (error, stdout, stderr) {
    console.log(cmd, stdout, stderr);
  });
}<commit_msg>UPDATE: add a command after youdar.net commit<commit_after>#!/usr/bin/env node

var express = require('express');
var bodyParser = require('body-parser');
var exec = require('child_process').exec;

var app = express();

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: false}));

// parse application/json
app.use(bodyParser.json());

// parse application/vnd.api+json as json
app.use(bodyParser.json({type: 'application/vnd.api+json'}));

app.use(function (req, res, next) {
  console.log('\n\n');
  console.log(req.url);
  console.log(req.body); // populated!

  doAfter(req.body);

  next();
});

app.get('/', function (req, res, next) {
  console.log('REQ', new Date());
  res.end('Hello world.\n');
});

var server = app.listen(1394, function () {
  console.log('Listening...');
});

function doAfter(data) {
  console.log('doAfter data');
  var repo = data.repository;
  var commits = data.commits;

  if (!repo || !commits) {
    return;
  }

  console.log('repo === youdar.net?');
  if (repo === 'youdar.net' && commits.length > 0) {
    updateYoudarNet();
  }
}

function updateYoudarNet() {
  var cmd = 'cd /usr/share/nginx/html/next.youdar.net/youdar && git pull origin master';

  console.log('execute cmd:', cmd);
  exec(cmd, function (error, stdout, stderr) {
    console.log(cmd, stdout, stderr);
  });
}<|endoftext|>


<commit_before>"use strict";

var filters = require('./filters'),
    uniq = require('uniq');

var doNgram = function doNgram (string, resultData, config) {
    var ngramCount = string.length - config.n + 1,
        ngram,
        previousNgram = null,
        ngramData,
        i;

    for (i = 0; i < ngramCount; i++) {
        ngram = string.substr(i, config.n);

        if (!resultData.elements[ngram]) {
            ngramData = resultData.elements[ngram] = {
                probabilityAsFirst: 0,
                children: {},
                lastChildren: {}
            };
        } else {
            ngramData = resultData.elements[ngram];
        }

        if (i === 0) {
            ngramData.probabilityAsFirst++;
        }

        if (previousNgram !== null) {
            if (i === ngramCount - 1) {
                if (!previousNgram.lastChildren[ngram]) {
                    previousNgram.lastChildren[ngram] = 1;
                } else {
                    previousNgram.lastChildren[ngram]++;
                }
            } else {
                if (!previousNgram.children[ngram]) {
                    previousNgram.children[ngram] = 1;
                } else {
                    previousNgram.children[ngram]++;
                }
            }
        }

        previousNgram = ngramData;
    }
};

var postProcessData = function postProcessData (resultData, compressFloat) {
    var keys = Object.keys(resultData.elements),
        childrenKeys,
        validFirst = {},
        sumFirst = 0,
        sumChildren = 0,
        key,
        data,
        i,
        k;

    for (i = 0; i < keys.length; i++) {
        key = keys[i];
        data = resultData.elements[key];

        if (data.probabilityAsFirst > 0) {
            if (!validFirst[key]) {
                validFirst[key] = data.probabilityAsFirst;
                sumFirst += data.probabilityAsFirst;
            } else {
                validFirst[key] += data.probabilityAsFirst;
                sumFirst += data.probabilityAsFirst;
            }
        }

        delete data.probabilityAsFirst;

        childrenKeys = Object.keys(data.children);
        sumChildren = 0;

        for (k = 0; k < childrenKeys.length; k++) {
            sumChildren += data.children[childrenKeys[k]];
        }

        for (k = 0; k < childrenKeys.length; k++) {
            data.children[childrenKeys[k]] /= sumChildren;
            data.children[childrenKeys[k]] = compressFloat(data.children[childrenKeys[k]]);
        }

        data.hasChildren = childrenKeys.length > 0;

        childrenKeys = Object.keys(data.lastChildren);
        sumChildren = 0;

        for (k = 0; k < childrenKeys.length; k++) {
            sumChildren += data.lastChildren[childrenKeys[k]];
        }

        for (k = 0; k < childrenKeys.length; k++) {
            data.lastChildren[childrenKeys[k]] /= sumChildren;
            data.lastChildren[childrenKeys[k]] = compressFloat(data.lastChildren[childrenKeys[k]]);
        }

        data.hasLastChildren = childrenKeys.length > 0;
    }

    keys = Object.keys(validFirst);

    for (i = 0; i < keys.length; i++) {
        key = keys[i];
        validFirst[key] /= sumFirst;
        validFirst[key] = compressFloat(validFirst[key]);
    }

    resultData.firstElements = validFirst;

    return resultData;
};

var compact = function compact (resultData) {
    var keys = Object.keys(resultData.elements),
        ngramData,
        ngramDesc,
        i;

    for (i = 0; i < keys.length; i++) {
        ngramData = resultData.elements[keys[i]];
        ngramDesc = [
            ngramData.hasChildren ? ngramData.children : 0,
            ngramData.hasLastChildren ? ngramData.lastChildren : 0
        ];

        resultData.elements[keys[i]] = ngramDesc;
    }

    resultData.e = resultData.elements;
    resultData.fe = resultData.firstElements;

    delete resultData.elements;
    delete resultData.firstElements;
};

var preProcessString = function preProcessString (string, config) {
    if (config.filter && filters.hasOwnProperty(config.filter)) {
        string = string.replace(filters[config.filter], ' ');
    }

    var strings = string.split(/\s+/).filter(function (v) {
        return v.length > 0;
    });

    if (config.minLength) {
        strings = strings.filter(function (v) {
            return v.length > config.minLength;
        });
    }

    if (config.unique) {
        uniq(strings);
    }

    return strings;
};

module.exports  = function process (data, config) {
    config.name = config.name || null;
    config.filter = config.filter || 'extended';
    config.n = parseInt(config.n, 10) || 3;
    config.minLength = parseInt(config.minLength, 10) || 0;
    config.unique = !!config.unique;
    config.excludeOriginal = !!config.excludeOriginal;
    config.compress = !!config.compress;

    var resultConfig = {
        name: config.name,
        type: config.type,
        n: config.n,
        minLength: config.minLength,
        unique: config.unique ? 1 : 0,
        excludeOriginal: config.excludeOriginal ? 1 : 0
    };

    var resultData = {
        elements: {}
    };

    var excludeData = [];

    var strings = preProcessString(data, config);

    for (var i = 0; i < strings.length; i++) {
        doNgram(strings[i], resultData, config);

        if (config.excludeOriginal && excludeData.indexOf(strings[i]) === -1) {
            excludeData.push(strings[i]);
        }
    }

    var formatFloat = config.compress ? function compressFloat (float, precision) {
        return parseFloat(float.toFixed(precision || 7), 10);
    } : function (v) { return v; };

    compact(postProcessData(resultData, formatFloat));

    return {
        config: resultConfig,
        data: resultData,
        exclude: excludeData.length ? excludeData : 0
    };
};
<commit_msg>allow regex as filter options for the cli utility<commit_after>"use strict";

var filters = require('./filters'),
    uniq = require('uniq');

var doNgram = function doNgram (string, resultData, config) {
    var ngramCount = string.length - config.n + 1,
        ngram,
        previousNgram = null,
        ngramData,
        i;

    for (i = 0; i < ngramCount; i++) {
        ngram = string.substr(i, config.n);

        if (!resultData.elements[ngram]) {
            ngramData = resultData.elements[ngram] = {
                probabilityAsFirst: 0,
                children: {},
                lastChildren: {}
            };
        } else {
            ngramData = resultData.elements[ngram];
        }

        if (i === 0) {
            ngramData.probabilityAsFirst++;
        }

        if (previousNgram !== null) {
            if (i === ngramCount - 1) {
                if (!previousNgram.lastChildren[ngram]) {
                    previousNgram.lastChildren[ngram] = 1;
                } else {
                    previousNgram.lastChildren[ngram]++;
                }
            } else {
                if (!previousNgram.children[ngram]) {
                    previousNgram.children[ngram] = 1;
                } else {
                    previousNgram.children[ngram]++;
                }
            }
        }

        previousNgram = ngramData;
    }
};

var postProcessData = function postProcessData (resultData, compressFloat) {
    var keys = Object.keys(resultData.elements),
        childrenKeys,
        validFirst = {},
        sumFirst = 0,
        sumChildren = 0,
        key,
        data,
        i,
        k;

    for (i = 0; i < keys.length; i++) {
        key = keys[i];
        data = resultData.elements[key];

        if (data.probabilityAsFirst > 0) {
            if (!validFirst[key]) {
                validFirst[key] = data.probabilityAsFirst;
                sumFirst += data.probabilityAsFirst;
            } else {
                validFirst[key] += data.probabilityAsFirst;
                sumFirst += data.probabilityAsFirst;
            }
        }

        delete data.probabilityAsFirst;

        childrenKeys = Object.keys(data.children);
        sumChildren = 0;

        for (k = 0; k < childrenKeys.length; k++) {
            sumChildren += data.children[childrenKeys[k]];
        }

        for (k = 0; k < childrenKeys.length; k++) {
            data.children[childrenKeys[k]] /= sumChildren;
            data.children[childrenKeys[k]] = compressFloat(data.children[childrenKeys[k]]);
        }

        data.hasChildren = childrenKeys.length > 0;

        childrenKeys = Object.keys(data.lastChildren);
        sumChildren = 0;

        for (k = 0; k < childrenKeys.length; k++) {
            sumChildren += data.lastChildren[childrenKeys[k]];
        }

        for (k = 0; k < childrenKeys.length; k++) {
            data.lastChildren[childrenKeys[k]] /= sumChildren;
            data.lastChildren[childrenKeys[k]] = compressFloat(data.lastChildren[childrenKeys[k]]);
        }

        data.hasLastChildren = childrenKeys.length > 0;
    }

    keys = Object.keys(validFirst);

    for (i = 0; i < keys.length; i++) {
        key = keys[i];
        validFirst[key] /= sumFirst;
        validFirst[key] = compressFloat(validFirst[key]);
    }

    resultData.firstElements = validFirst;

    return resultData;
};

var compact = function compact (resultData) {
    var keys = Object.keys(resultData.elements),
        ngramData,
        ngramDesc,
        i;

    for (i = 0; i < keys.length; i++) {
        ngramData = resultData.elements[keys[i]];
        ngramDesc = [
            ngramData.hasChildren ? ngramData.children : 0,
            ngramData.hasLastChildren ? ngramData.lastChildren : 0
        ];

        resultData.elements[keys[i]] = ngramDesc;
    }

    resultData.e = resultData.elements;
    resultData.fe = resultData.firstElements;

    delete resultData.elements;
    delete resultData.firstElements;
};

var stringToRegExp = function stringToRegExp (string) {
    var match = string.match(/^\/(.+)\/([igmuy]+)$/),
        regex = null;

    if (match !== null) {
        regex = new RegExp(match[1], match[2]);
    }

    return regex;
};

var preProcessString = function preProcessString (string, config) {
    if (config.filter) {
        var filterRegex = null;

        if (config.filter instanceof RegExp) {
            filterRegex = config.filter
        } else if (filters.hasOwnProperty(config.filter)) {
            filterRegex = filters[config.filter];
        } else {
            filterRegex = stringToRegExp(config.filter);
        }

        if (filterRegex) {
            string = string.replace(filterRegex, ' ');
        }
    }

    var strings = string.split(/\s+/).filter(function (v) {
        return v.length > 0;
    });

    if (config.minLength) {
        strings = strings.filter(function (v) {
            return v.length > config.minLength;
        });
    }

    if (config.unique) {
        uniq(strings);
    }

    return strings;
};

module.exports  = function process (data, config) {
    config.name = config.name || null;
    config.filter = config.filter || 'extended';
    config.n = parseInt(config.n, 10) || 3;
    config.minLength = parseInt(config.minLength, 10) || 0;
    config.unique = !!config.unique;
    config.excludeOriginal = !!config.excludeOriginal;
    config.compress = !!config.compress;

    var resultConfig = {
        name: config.name,
        type: config.type,
        n: config.n,
        minLength: config.minLength,
        unique: config.unique ? 1 : 0,
        excludeOriginal: config.excludeOriginal ? 1 : 0
    };

    var resultData = {
        elements: {}
    };

    var excludeData = [];

    var strings = preProcessString(data, config);

    for (var i = 0; i < strings.length; i++) {
        doNgram(strings[i], resultData, config);

        if (config.excludeOriginal && excludeData.indexOf(strings[i]) === -1) {
            excludeData.push(strings[i]);
        }
    }

    var formatFloat = config.compress ? function compressFloat (float, precision) {
        return parseFloat(float.toFixed(precision || 7), 10);
    } : function (v) { return v; };

    compact(postProcessData(resultData, formatFloat));

    return {
        config: resultConfig,
        data: resultData,
        exclude: excludeData.length ? excludeData : 0
    };
};
<|endoftext|>


<commit_before>/*
Copyright (C) 2011-2013 by Gregory Burlet, Alastair Porter

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * Creates a new neume view
 *
 * @class View for the neume
 * @param {Toe.View.RenderEngine} renderEngine The rendering engine
 */
Toe.View.NeumeView = function(renderEngine, documentType) {
    this.rendEng = renderEngine;

    // dynamically call the drawing function for the right manuscript
    switch (documentType) {
        case "liber":
            Toe.View.NeumeView.prototype.drawNeume = drawLiberNeume;
            break;
        case "salzinnes":
            Toe.View.NeumeView.prototype.drawNeume = drawSalzinnesNeume;
            break;
        case "stgallen":
            Toe.View.NeumeView.prototype.drawNeume = drawHartkerNeume;
            break;
        default:
            throw "Invalid Drawing Library";
    }

    this.drawing = null;
    this.ledgerLines = null;
};

Toe.View.NeumeView.prototype = new Toe.View.View();
Toe.View.NeumeView.prototype.constructor = Toe.View.NeumeView;

/*********************************
 *      HELPER FUNCTIONS         *
 *********************************/
Toe.View.NeumeView.prototype.calcNoteYPos = function(neume) {
    var system = neume.system;

    // derive positions of neume components
    var nc_y = new Array();

    // set root note y pos
    nc_y.push(system.zone.uly - neume.rootSystemPos*system.delta_y/2);
    for (var i = 1; i < neume.components.length; i++) {
        nc_y.push(nc_y[0] + (-neume.components[i].pitchDiff * system.delta_y/2));
    }

    return nc_y;
}

Toe.View.NeumeView.prototype.bestDotPlacements = function(aSystem, nc_y, yposInd) {
    // corresponding to whether or not it is good to put a dot
    // at the middle, top, or bottom of the neume component
    var bestDots = [false, false, false];
    var dotsy = new Array();

    var firstSpace = aSystem.zone.uly + aSystem.delta_y/2;

    ypos = nc_y[yposInd];

    // try middle first
    var midPos = ypos;
    k = Math.round(2*(midPos - firstSpace) / aSystem.delta_y);
    if (k % 2 == 0) {
        dotsy.push(midPos);
    }

    // try top next
    var topPos = ypos - aSystem.delta_y/2;
    var k = Math.round(2*(topPos - firstSpace) / aSystem.delta_y);

    // check there isn't a note here
    // must also check note after (eg., podatus)
    var isOccNote = false;
    if ((yposInd-1 >= 0 && ypos - aSystem.delta_y/2 == nc_y[yposInd-1]) || (yposInd+1 < nc_y.length && ypos - aSystem.delta_y/2 == nc_y[yposInd+1])) {
        isOccNote = true;
    }

    if (k % 2 == 0 && !isOccNote) {
        dotsy.push(topPos);
    }

    // try bottom
    var botPos = ypos + aSystem.delta_y/2;
    k = Math.round(2*(botPos - firstSpace) / aSystem.delta_y);

    // check there isn't a note here
    isOccNote = false;
    if ((yposInd+1 < nc_y.length && ypos + aSystem.delta_y/2 == nc_y[yposInd+1]) || (yposInd-1 >= 0 && ypos + aSystem.delta_y/2 == nc_y[yposInd-1])) {
        isOccNote = true;
    }

    if (k % 2 == 0 && !isOccNote) {
        dotsy.push(botPos);
    }

    return dotsy;
}

Toe.View.NeumeView.prototype.bestHorizEpisemaPlacements = function(aSystem, nc_y, yposInd) {
    // calculate where to put the horizontal episema above the neume.
    var bestHorizEpisemas = [false, false, false];
    var hEpsy = new Array();

    var firstSpace = aSystem.zone.uly + aSystem.delta_y/2;

    ypos = nc_y[yposInd];

    // try middle first
    var midPos = ypos - 10;
    k = Math.round(2*(midPos - firstSpace) / aSystem.delta_y);

    if (k % 2 != 0) {
        hEpsy.push(midPos);
    }

    // try top next
    var topPos = ypos - aSystem.delta_y/2;
    var k = Math.round(2*(topPos - firstSpace) / aSystem.delta_y);

    // check there isn't a note here
    // must also check note after (eg., podatus)
    var isOccNote = false;
    if ((yposInd-1 >= 0 && ypos - aSystem.delta_y/2 == nc_y[yposInd-1]) || (yposInd+1 < nc_y.length && ypos - aSystem.delta_y/2 == nc_y[yposInd+1])) {
        isOccNote = true;
    }

    if (k % 2 != 0 && !isOccNote) {
        hEpsy.push(topPos);
    }

    // try bottom
    var botPos = ypos + aSystem.delta_y/2;
    k = Math.round(2*(botPos - firstSpace) / aSystem.delta_y);

    // check there isn't a note here
    isOccNote = false;
    if ((yposInd+1 < nc_y.length && ypos + aSystem.delta_y/2 == nc_y[yposInd+1]) || (yposInd-1 >= 0 && ypos + aSystem.delta_y/2 == nc_y[yposInd-1])) {
        isOccNote = true;
    }

    if (k % 2 != 0 && !isOccNote) {
        hEpsy.push(botPos);
    }

    return hEpsy;
}

Toe.View.NeumeView.prototype.drawLedgerLines = function(ncSystemPos, centre, width, aSystem) {
    width *= 0.75;

    var nv = this;
    var ledgers = new Array();
    var bottomSystemPos = 2*(1-aSystem.props.numLines);
    $.each(ncSystemPos, function(ncInd, systemPos) {
        if (systemPos > 0) {
            for (var i = 0; i <= systemPos; i += 2) {
                var line_y = aSystem.zone.uly - (i*aSystem.delta_y/2);
                ledgers.push(nv.rendEng.createLine([centre[ncInd]-width, line_y, centre[ncInd]+width, line_y]));
            }
        }
        else if (systemPos < bottomSystemPos) {
            for (var i = bottomSystemPos; i >= systemPos; i -= 2) {
                var line_y = aSystem.zone.uly - (i*aSystem.delta_y/2);
                ledgers.push(nv.rendEng.createLine([centre[ncInd]-width, line_y, centre[ncInd]+width, line_y]));
            }
        }
    });

    this.ledgerLines = this.rendEng.draw({fixed: ledgers, modify: []}, {group: true, selectable: false})[0];
}

/*********************************
 *      VIEW HANDLERS            *
 *********************************/
/**
 * Renders the neume on the canvas
 *
 * @methodOf Toe.View.NeumeView
 * @param {Toe.Model.Neume} neume Neume to render
 */
Toe.View.NeumeView.prototype.render = function(neume) {
    this.drawNeume(neume);
}

/**
 * Renders the bounding box of the neume
 *
 * @methodOf Toe.View.NeumeView
 * @param {Toe.Model.Neume} neume Neume to render the bounding box
 */
Toe.View.NeumeView.prototype.renderBoundingBox = function(neume) {
    var n_bb = [neume.zone.ulx, neume.zone.uly, neume.zone.lrx, neume.zone.lry];
    this.rendEng.outlineBoundingBox(n_bb, {fill: "green"});
}

Toe.View.NeumeView.prototype.updateDrawing = function(neume) {
    // if a drawing exists for this neume, update it
    // by removing and drawing again.
    if (this.drawing) {
        this.rendEng.canvas.remove(this.drawing);
    }
    if (this.ledgerLines) {
        this.rendEng.canvas.remove(this.ledgerLines);
        this.ledgerLines = null;
    }

    this.drawNeume(neume);

    // select the new drawing
    this.selectDrawing();

    this.rendEng.repaint();
}

Toe.View.NeumeView.prototype.eraseDrawing = function() {
    if (this.drawing) {
        this.rendEng.canvas.remove(this.drawing);
    }
    if (this.ledgerLines) {
        this.rendEng.canvas.remove(this.ledgerLines);
        this.ledgerLines = null;
    }

    this.rendEng.repaint();
}

Toe.View.NeumeView.prototype.selectDrawing = function() {
    this.rendEng.canvas.setActiveObject(this.drawing);
}
<commit_msg>Fixed #166: Horizontal episemas insert properly<commit_after>/*
Copyright (C) 2011-2013 by Gregory Burlet, Alastair Porter

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/**
 * Creates a new neume view
 *
 * @class View for the neume
 * @param {Toe.View.RenderEngine} renderEngine The rendering engine
 */
Toe.View.NeumeView = function(renderEngine, documentType) {
    this.rendEng = renderEngine;

    // dynamically call the drawing function for the right manuscript
    switch (documentType) {
        case "liber":
            Toe.View.NeumeView.prototype.drawNeume = drawLiberNeume;
            break;
        case "salzinnes":
            Toe.View.NeumeView.prototype.drawNeume = drawSalzinnesNeume;
            break;
        case "stgallen":
            Toe.View.NeumeView.prototype.drawNeume = drawHartkerNeume;
            break;
        default:
            throw "Invalid Drawing Library";
    }

    this.drawing = null;
    this.ledgerLines = null;
};

Toe.View.NeumeView.prototype = new Toe.View.View();
Toe.View.NeumeView.prototype.constructor = Toe.View.NeumeView;

/*********************************
 *      HELPER FUNCTIONS         *
 *********************************/
Toe.View.NeumeView.prototype.calcNoteYPos = function(neume) {
    var system = neume.system;

    // derive positions of neume components
    var nc_y = new Array();

    // set root note y pos
    nc_y.push(system.zone.uly - neume.rootSystemPos*system.delta_y/2);
    for (var i = 1; i < neume.components.length; i++) {
        nc_y.push(nc_y[0] + (-neume.components[i].pitchDiff * system.delta_y/2));
    }

    return nc_y;
}

Toe.View.NeumeView.prototype.bestDotPlacements = function(aSystem, nc_y, yposInd) {
    // corresponding to whether or not it is good to put a dot
    // at the middle, top, or bottom of the neume component
    var bestDots = [false, false, false];
    var dotsy = new Array();

    var firstSpace = aSystem.zone.uly + aSystem.delta_y/2;

    ypos = nc_y[yposInd];

    // try middle first
    var midPos = ypos;
    k = Math.round(2*(midPos - firstSpace) / aSystem.delta_y);
    if (k % 2 == 0) {
        dotsy.push(midPos);
    }

    // try top next
    var topPos = ypos - aSystem.delta_y/2;
    var k = Math.round(2*(topPos - firstSpace) / aSystem.delta_y);

    // check there isn't a note here
    // must also check note after (eg., podatus)
    var isOccNote = false;
    if ((yposInd-1 >= 0 && ypos - aSystem.delta_y/2 == nc_y[yposInd-1]) || (yposInd+1 < nc_y.length && ypos - aSystem.delta_y/2 == nc_y[yposInd+1])) {
        isOccNote = true;
    }

    if (k % 2 == 0 && !isOccNote) {
        dotsy.push(topPos);
    }

    // try bottom
    var botPos = ypos + aSystem.delta_y/2;
    k = Math.round(2*(botPos - firstSpace) / aSystem.delta_y);

    // check there isn't a note here
    isOccNote = false;
    if ((yposInd+1 < nc_y.length && ypos + aSystem.delta_y/2 == nc_y[yposInd+1]) || (yposInd-1 >= 0 && ypos + aSystem.delta_y/2 == nc_y[yposInd-1])) {
        isOccNote = true;
    }

    if (k % 2 == 0 && !isOccNote) {
        dotsy.push(botPos);
    }

    return dotsy;
}

Toe.View.NeumeView.prototype.bestHorizEpisemaPlacements = function(aSystem, nc_y, yposInd) {
    // calculate where to put the horizontal episema above the neume.
    var bestHorizEpisemas = [false, false, false];
    var hEpsy = new Array();

    var firstSpace = aSystem.zone.uly + aSystem.delta_y/2;

    ypos = nc_y[yposInd];

    // // try middle first
    var midPos = ypos - aSystem.delta_y/2;
    k = Math.round(2*(midPos - firstSpace) / aSystem.delta_y);

    if (k % 2 != 0) {
        hEpsy.push(midPos);
    }

    // try top next
    var topPos = ypos - aSystem.delta_y/4;
    var k = Math.round(2*(topPos - firstSpace) / aSystem.delta_y);

    // check there isn't a note here
    // must also check note after (eg., podatus)
    var isOccNote = false;
    if ((yposInd-1 >= 0 && ypos - aSystem.delta_y/2 == nc_y[yposInd-1]) || (yposInd+1 < nc_y.length && ypos - aSystem.delta_y/2 == nc_y[yposInd+1])) {
        isOccNote = true;
    }

    if (k % 2 != 0 && !isOccNote) {
        hEpsy.push(topPos);
    }

    return hEpsy;
}

Toe.View.NeumeView.prototype.drawLedgerLines = function(ncSystemPos, centre, width, aSystem) {
    width *= 0.75;

    var nv = this;
    var ledgers = new Array();
    var bottomSystemPos = 2*(1-aSystem.props.numLines);
    $.each(ncSystemPos, function(ncInd, systemPos) {
        if (systemPos > 0) {
            for (var i = 0; i <= systemPos; i += 2) {
                var line_y = aSystem.zone.uly - (i*aSystem.delta_y/2);
                ledgers.push(nv.rendEng.createLine([centre[ncInd]-width, line_y, centre[ncInd]+width, line_y]));
            }
        }
        else if (systemPos < bottomSystemPos) {
            for (var i = bottomSystemPos; i >= systemPos; i -= 2) {
                var line_y = aSystem.zone.uly - (i*aSystem.delta_y/2);
                ledgers.push(nv.rendEng.createLine([centre[ncInd]-width, line_y, centre[ncInd]+width, line_y]));
            }
        }
    });

    this.ledgerLines = this.rendEng.draw({fixed: ledgers, modify: []}, {group: true, selectable: false})[0];
}

/*********************************
 *      VIEW HANDLERS            *
 *********************************/
/**
 * Renders the neume on the canvas
 *
 * @methodOf Toe.View.NeumeView
 * @param {Toe.Model.Neume} neume Neume to render
 */
Toe.View.NeumeView.prototype.render = function(neume) {
    this.drawNeume(neume);
}

/**
 * Renders the bounding box of the neume
 *
 * @methodOf Toe.View.NeumeView
 * @param {Toe.Model.Neume} neume Neume to render the bounding box
 */
Toe.View.NeumeView.prototype.renderBoundingBox = function(neume) {
    var n_bb = [neume.zone.ulx, neume.zone.uly, neume.zone.lrx, neume.zone.lry];
    this.rendEng.outlineBoundingBox(n_bb, {fill: "green"});
}

Toe.View.NeumeView.prototype.updateDrawing = function(neume) {
    // if a drawing exists for this neume, update it
    // by removing and drawing again.
    if (this.drawing) {
        this.rendEng.canvas.remove(this.drawing);
    }
    if (this.ledgerLines) {
        this.rendEng.canvas.remove(this.ledgerLines);
        this.ledgerLines = null;
    }

    this.drawNeume(neume);

    // select the new drawing
    this.selectDrawing();

    this.rendEng.repaint();
}

Toe.View.NeumeView.prototype.eraseDrawing = function() {
    if (this.drawing) {
        this.rendEng.canvas.remove(this.drawing);
    }
    if (this.ledgerLines) {
        this.rendEng.canvas.remove(this.ledgerLines);
        this.ledgerLines = null;
    }

    this.rendEng.repaint();
}

Toe.View.NeumeView.prototype.selectDrawing = function() {
    this.rendEng.canvas.setActiveObject(this.drawing);
}
<|endoftext|>


<commit_before>import Vector2 from "../math/Vector2.js";

import Signal from "dlib/utils/Signal";

let pointers = new Map();

export default class Pointer extends Vector2 {
  static get TOUCH_TYPE() {
    return "touchtype";
  }
  static get MOUSE_TYPE() {
    return "mousetype";
  }
  static get(domElement) {
    let pointer = pointers.get(domElement);
    if (!pointer) {
      pointer = new Pointer(domElement);
    }
    return pointer;
  }
  get downed() {
    return this._downed;
  }
  constructor(domElement = document.body) {
    super();

    this.domElement = domElement;

    this.type = Pointer.TOUCH_TYPE;

    this._position = new Vector2();

    this.velocity = new Vector2();
    this.dragOffset = new Vector2();

    this.centered = new Vector2();
    this.centeredFlippedY = new Vector2();
    this.normalized = new Vector2();
    this.normalizedFlippedY = new Vector2();
    this.normalizedCentered = new Vector2();
    this.normalizedCenteredFlippedY = new Vector2();

    this._downed = false;

    pointers.set(this.domElement, this);

    this.onDown = new Signal();
    this.onMove = new Signal();
    this.onUp = new Signal();
    this.onClick = new Signal();
    this.onTypeChange = new Signal();

    this._preventMouseTypeChange = false;

    this._onPointerMoveBinded = this._onPointerMove.bind(this);
    this._onPointerDownBinded = this._onPointerDown.bind(this);
    this._onPointerUpBinded = this._onPointerUp.bind(this);

    this._updateBinded = this._update.bind(this);
    this._resizeBinded = this.resize.bind(this);

    this.resize();
    this.enable();
  }
  resize() {
    this._domElementBoundingRect = this.domElement.getBoundingClientRect();
  }
  _onPointerDown(e) {
    if(e.type === "touchstart") {
      this._preventMouseTypeChange = true;
      this._changeType(Pointer.TOUCH_TYPE);
    }
    this.dragOffset.set(0, 0);
    this._downed = true;
    this._updatePosition(e);
    this.copy(this._position);
    this.onDown.dispatch();
  }
  _onPointerMove(e) {
    if(e.type === "mousemove") {
      if(this._preventMouseTypeChange) {
        return;
      } else {
        this._changeType(Pointer.MOUSE_TYPE);
      }
    }
    this._updatePosition(e);
    this.onMove.dispatch();
  }
  _onPointerUp(e) {
    this._downed = false;
    this._updatePosition(e);
    this.onUp.dispatch();
    if(this.dragOffset.length < 4) {
      this.onClick.dispatch();
    }
    setTimeout(() => {
      this._preventMouseTypeChange = false;
    }, 100);
  }
  _updatePosition(e) {
    if (!!window.TouchEvent && e instanceof window.TouchEvent) {
      if(e.type === "touchend") {
        e = e.changedTouches[0];
      } else {
        e = e.touches[0];
      }
    }
    this._position.x = e.clientX - this._domElementBoundingRect.left;
    this._position.y = e.clientY - this._domElementBoundingRect.top;
  }
  _changeType(type) {
    if(this.type === type) {
      return;
    }
    this.type = type;
    this.disable();
    this.enable();
    this.onTypeChange.dispatch(this.type);
  }
  _update() {
    this._requestAnimationFrameId = requestAnimationFrame(this._updateBinded);

    if(this.x || this.y) {
      this.velocity.x = this._position.x - this.x;
      this.velocity.y = this._position.y - this.y;
      if(this.downed) {
        this.dragOffset.add(this.velocity);
      }
    }
    this.x = this._position.x;
    this.y = this._position.y;

    this.centered.x = this.centeredFlippedY.x = this.x - this._domElementBoundingRect.width * .5;
    this.centered.y = this.centeredFlippedY.y = this.y - this._domElementBoundingRect.height * .5;
    this.centeredFlippedY.y *= -1;

    this.normalized.x = this.normalizedFlippedY.x = this.x / this._domElementBoundingRect.width;
    this.normalized.y = this.normalizedFlippedY.y = this.y / this._domElementBoundingRect.height;
    this.normalizedFlippedY.y = 1 - this.normalizedFlippedY.y;

    this.normalizedCentered.x = this.normalizedCenteredFlippedY.x = this.normalized.x * 2 - 1;
    this.normalizedCentered.y = this.normalizedCenteredFlippedY.y = this.normalized.y * 2 - 1;
    this.normalizedCenteredFlippedY.y *= -1;
  }
  enable() {
    this.disable();
    this.resize();
    if(this.type === Pointer.TOUCH_TYPE) {
      this.domElement.addEventListener("touchmove", this._onPointerMoveBinded);
      window.addEventListener("touchend", this._onPointerUpBinded);
    }
    else {
      this.domElement.addEventListener("mousedown", this._onPointerDownBinded);
      window.addEventListener("mouseup", this._onPointerUpBinded);
    }
    this.domElement.addEventListener("touchstart", this._onPointerDownBinded);
    this.domElement.addEventListener("mousemove", this._onPointerMoveBinded);
    window.addEventListener("resize", this._resizeBinded);
    this._update();
  }
  disable() {
    cancelAnimationFrame(this._requestAnimationFrameId);
    this.domElement.removeEventListener("touchdown", this._onPointerDownBinded);
    this.domElement.removeEventListener("mousedown", this._onPointerDownBinded);
    this.domElement.removeEventListener("touchmove", this._onPointerMoveBinded);
    this.domElement.removeEventListener("mousemove", this._onPointerMoveBinded);
    window.removeEventListener("touchend", this._onPointerUpBinded);
    window.removeEventListener("mouseup", this._onPointerUpBinded);
    window.removeEventListener("resize", this._resizeBinded);
  }
}
<commit_msg>fix positions on mobile in pointer<commit_after>import Vector2 from "../math/Vector2.js";

import Signal from "dlib/utils/Signal";

let pointers = new Map();

export default class Pointer extends Vector2 {
  static get TOUCH_TYPE() {
    return "touchtype";
  }
  static get MOUSE_TYPE() {
    return "mousetype";
  }
  static get(domElement) {
    let pointer = pointers.get(domElement);
    if (!pointer) {
      pointer = new Pointer(domElement);
    }
    return pointer;
  }
  get downed() {
    return this._downed;
  }
  constructor(domElement = document.body) {
    super();

    this.domElement = domElement;

    this.type = Pointer.TOUCH_TYPE;

    this._position = new Vector2();

    this.velocity = new Vector2();
    this.dragOffset = new Vector2();

    this.centered = new Vector2();
    this.centeredFlippedY = new Vector2();
    this.normalized = new Vector2();
    this.normalizedFlippedY = new Vector2();
    this.normalizedCentered = new Vector2();
    this.normalizedCenteredFlippedY = new Vector2();

    this._downed = false;

    pointers.set(this.domElement, this);

    this.onDown = new Signal();
    this.onMove = new Signal();
    this.onUp = new Signal();
    this.onClick = new Signal();
    this.onTypeChange = new Signal();

    this._preventMouseTypeChange = false;

    this._onPointerMoveBinded = this._onPointerMove.bind(this);
    this._onPointerDownBinded = this._onPointerDown.bind(this);
    this._onPointerUpBinded = this._onPointerUp.bind(this);

    this._updateBinded = this._update.bind(this);
    this._resizeBinded = this.resize.bind(this);

    this.resize();
    this.enable();
  }
  resize() {
    this._domElementBoundingRect = this.domElement.getBoundingClientRect();
  }
  _onPointerDown(e) {
    if(e.type === "touchstart") {
      this._preventMouseTypeChange = true;
      this._changeType(Pointer.TOUCH_TYPE);
    }
    this._downed = true;
    this.dragOffset.set(0, 0);
    this.copy(this._position);
    this._onPointerEvent(e);
    this._updatePositions();
    this.onDown.dispatch();
  }
  _onPointerMove(e) {
    if(e.type === "mousemove") {
      if(this._preventMouseTypeChange) {
        return;
      } else {
        this._changeType(Pointer.MOUSE_TYPE);
      }
    }
    this._onPointerEvent(e);
    this.onMove.dispatch();
  }
  _onPointerUp(e) {
    this._downed = false;
    this._onPointerEvent(e);
    this._updatePositions();
    this.onUp.dispatch();
    if(this.dragOffset.length < 4) {
      this.onClick.dispatch();
    }
    setTimeout(() => {
      this._preventMouseTypeChange = false;
    }, 100);
  }
  _onPointerEvent(e) {
    if (!!window.TouchEvent && e instanceof window.TouchEvent) {
      if(e.type === "touchend") {
        e = e.changedTouches[0];
      } else {
        e = e.touches[0];
      }
    }
    this._position.x = e.clientX - this._domElementBoundingRect.left;
    this._position.y = e.clientY - this._domElementBoundingRect.top;
  }
  _changeType(type) {
    if(this.type === type) {
      return;
    }
    this.type = type;
    this.disable();
    this.enable();
    this.onTypeChange.dispatch(this.type);
  }
  _update() {
    this._requestAnimationFrameId = requestAnimationFrame(this._updateBinded);

    if(this.x || this.y) {
      this.velocity.x = this._position.x - this.x;
      this.velocity.y = this._position.y - this.y;
      if(this.downed) {
        this.dragOffset.add(this.velocity);
      }
    }

    this._updatePositions();
  }
  _updatePositions() {
    this.x = this._position.x;
    this.y = this._position.y;

    this.centered.x = this.centeredFlippedY.x = this.x - this._domElementBoundingRect.width * .5;
    this.centered.y = this.centeredFlippedY.y = this.y - this._domElementBoundingRect.height * .5;
    this.centeredFlippedY.y *= -1;

    this.normalized.x = this.normalizedFlippedY.x = this.x / this._domElementBoundingRect.width;
    this.normalized.y = this.normalizedFlippedY.y = this.y / this._domElementBoundingRect.height;
    this.normalizedFlippedY.y = 1 - this.normalizedFlippedY.y;

    this.normalizedCentered.x = this.normalizedCenteredFlippedY.x = this.normalized.x * 2 - 1;
    this.normalizedCentered.y = this.normalizedCenteredFlippedY.y = this.normalized.y * 2 - 1;
    this.normalizedCenteredFlippedY.y *= -1;
  }
  enable() {
    this.disable();
    this.resize();
    if(this.type === Pointer.TOUCH_TYPE) {
      this.domElement.addEventListener("touchmove", this._onPointerMoveBinded);
      window.addEventListener("touchend", this._onPointerUpBinded);
    }
    else {
      this.domElement.addEventListener("mousedown", this._onPointerDownBinded);
      window.addEventListener("mouseup", this._onPointerUpBinded);
    }
    this.domElement.addEventListener("touchstart", this._onPointerDownBinded);
    this.domElement.addEventListener("mousemove", this._onPointerMoveBinded);
    window.addEventListener("resize", this._resizeBinded);
    this._update();
  }
  disable() {
    cancelAnimationFrame(this._requestAnimationFrameId);
    this.domElement.removeEventListener("touchdown", this._onPointerDownBinded);
    this.domElement.removeEventListener("mousedown", this._onPointerDownBinded);
    this.domElement.removeEventListener("touchmove", this._onPointerMoveBinded);
    this.domElement.removeEventListener("mousemove", this._onPointerMoveBinded);
    window.removeEventListener("touchend", this._onPointerUpBinded);
    window.removeEventListener("mouseup", this._onPointerUpBinded);
    window.removeEventListener("resize", this._resizeBinded);
  }
}
<|endoftext|>


<commit_before>var _ = require('lodash');
var dd = require('react-dd');

var placeholder_value = '__some$random$uuid__';

var component = dd.createClass({
  __onChange: function(e){
    var field = this.props.field;
    var new_value = e.target.value;
    this.props.onChange(_.has(field.options, new_value) ? new_value : null);
  },
  render: function(){
    var field = this.props.field;
    var value = _.has(field.options, this.props.value) ? this.props.value : (field.placeholder ? placeholder_value : '');

    if(field.read_only){
      return dd.p({className: 'form-control-static'},
        _.has(field.options, value) ? field.options[value] : value
      );
    }

    var options = _.pairs(field.options);
    if(!field.dont_sort_options){
      options = _.sortBy(options, function(option){
        return _.isString(option[1]) ? option[1].toUpperCase() : 0;
      });
    }

    return dd.select({
        name: field.name,
        value: value,
        onChange: this.__onChange,
        disabled: field.disabled ? 'disabled' : null,
        className: 'form-control' + (field.disabled ? ' disabled' : '')
      },
      dd.option({value: placeholder_value}, field.placeholder ? field.placeholder : ''),
      _.map(options, function(option){
        return dd.option({value: option[0], key: option[0]}, option[1]);
      })
    );
  }
});

module.exports = {
  component: component,
  validate: function(value, field){
    if(!_.has(field.options, value)){
      return 'Please make a selection';
    }
    return true;
  }
};
<commit_msg>fixing bug with Select input displaying the placeholder_value in read_only mode<commit_after>var _ = require('lodash');
var dd = require('react-dd');

var placeholder_value = '__some$random$uuid__';

var component = dd.createClass({
  __onChange: function(e){
    var field = this.props.field;
    var new_value = e.target.value;
    this.props.onChange(_.has(field.options, new_value) ? new_value : null);
  },
  render: function(){
    var field = this.props.field;
    var value = _.has(field.options, this.props.value) ? this.props.value : (field.placeholder ? placeholder_value : '');

    if(field.read_only){
      return dd.p({className: 'form-control-static'},
        _.has(field.options, value) ? field.options[value] : (value === placeholder_value ? null : value)
      );
    }

    var options = _.pairs(field.options);
    if(!field.dont_sort_options){
      options = _.sortBy(options, function(option){
        return _.isString(option[1]) ? option[1].toUpperCase() : 0;
      });
    }

    return dd.select({
        name: field.name,
        value: value,
        onChange: this.__onChange,
        disabled: field.disabled ? 'disabled' : null,
        className: 'form-control' + (field.disabled ? ' disabled' : '')
      },
      dd.option({value: placeholder_value}, field.placeholder ? field.placeholder : ''),
      _.map(options, function(option){
        return dd.option({value: option[0], key: option[0]}, option[1]);
      })
    );
  }
});

module.exports = {
  component: component,
  validate: function(value, field){
    if(!_.has(field.options, value)){
      return 'Please make a selection';
    }
    return true;
  }
};
<|endoftext|>


<commit_before>var React = require('react');
var objectAssign = require('object-assign');

var Notification = React.createClass({

  getBarStyles: function () {

    var styles = {};

    /**
     * If styles is set to false,
     * then return nothing.
     */
    if (this.props.styles === false) {
      return styles;
    }

    styles.active = {
      left: '1rem'
    };

    styles.default = {
      padding: '1rem',
      background: '#212121',
      color: '#FAFAFA',
      width: 'auto',
      position: 'fixed',
      left: '-100%',
      bottom: '1rem',
      boxShadow: '0 0 1px 1px rgba(10,10,11,0.125)',
      borderRadius: '5px',
      cursor: 'default',
      font: '1rem normal Roboto, sans-serif',
      transition: '.5s ease'
    };

    styles = !this.state.active ? styles.default : objectAssign(styles.default, styles.active);

    if (this.props.styles && this.props.styles.bar) {
      styles = objectAssign(styles, this.props.styles.bar);
    }

    return styles;

  },

  getActionStyles: function () {

    var styles = {};

    /**
     * If styles is set to false,
     * then return nothing.
     */
    if (this.props.styles === false) {
      return styles;
    }

    styles = {
      padding: '0.125rem',
      marginLeft: '1rem',
      color: '#f44336',
      textTransform: 'uppercase',
      letterSpacing: '.125ex',
      borderRadius: '5px',
      cursor: 'pointer',
      lineHeight: '1rem',
      font: '.75rem normal Roboto, sans-serif',
    };

    if (this.props.styles && this.props.styles.action) {
      styles = objectAssign(styles, this.props.styles.action);
    }

    return styles;

  },

  /**
   * @function show
   * @description Show the notification message.
   */
  show: function () {
    this.setState({
      active: true
    });
  },

  /**
   * @function hide
   * @description Hide the notification message.
   */
  hide: function () {
    this.setState({
      active: false
    });
  },

  handleClick: function (event) {
    event.preventDefault();
    this.props.onClick();
    this.hide();
  },

  propTypes: {
    message: React.PropTypes.string.isRequired,
    action: React.PropTypes.string,
    onClick: React.PropTypes.func
  },

  getInitialState: function () {
    return {
      active: false
    };
  },

  getDefaultProps: function () {
    return {
      action: 'Dismiss',
      onClick: function () {
        return;
      }
    };
  },

  componentWillReceiveProps: function (nextProps) {
    if (!nextProps.dismissAfter) return;

    if (this.state.timeoutId) clearTimeout( this.state.timeoutId );
    this.state.timeoutId = setTimeout( this.hide(), nextProps.dismissAfter );

    this.setState(this.state);
  },

  render: function () {
    return (

          {this.props.message}
          {this.props.action}

    );
  }

});

module.exports = Notification;
<commit_msg>Dismiss timeout passes correct function. Fixes #14<commit_after>var React = require('react');
var objectAssign = require('object-assign');

var Notification = React.createClass({

  getBarStyles: function () {

    var styles = {};

    /**
     * If styles is set to false,
     * then return nothing.
     */
    if (this.props.styles === false) {
      return styles;
    }

    styles.active = {
      left: '1rem'
    };

    styles.default = {
      padding: '1rem',
      background: '#212121',
      color: '#FAFAFA',
      width: 'auto',
      position: 'fixed',
      left: '-100%',
      bottom: '1rem',
      boxShadow: '0 0 1px 1px rgba(10,10,11,0.125)',
      borderRadius: '5px',
      cursor: 'default',
      font: '1rem normal Roboto, sans-serif',
      transition: '.5s ease'
    };

    styles = !this.state.active ? styles.default : objectAssign(styles.default, styles.active);

    if (this.props.styles && this.props.styles.bar) {
      styles = objectAssign(styles, this.props.styles.bar);
    }

    return styles;

  },

  getActionStyles: function () {

    var styles = {};

    /**
     * If styles is set to false,
     * then return nothing.
     */
    if (this.props.styles === false) {
      return styles;
    }

    styles = {
      padding: '0.125rem',
      marginLeft: '1rem',
      color: '#f44336',
      textTransform: 'uppercase',
      letterSpacing: '.125ex',
      borderRadius: '5px',
      cursor: 'pointer',
      lineHeight: '1rem',
      font: '.75rem normal Roboto, sans-serif',
    };

    if (this.props.styles && this.props.styles.action) {
      styles = objectAssign(styles, this.props.styles.action);
    }

    return styles;

  },

  /**
   * @function show
   * @description Show the notification message.
   */
  show: function () {
    this.setState({
      active: true
    });
  },

  /**
   * @function hide
   * @description Hide the notification message.
   */
  hide: function () {
    this.setState({
      active: false
    });
  },

  handleClick: function (event) {
    event.preventDefault();
    this.props.onClick();
    this.hide();
  },

  propTypes: {
    message: React.PropTypes.string.isRequired,
    action: React.PropTypes.string,
    onClick: React.PropTypes.func
  },

  getInitialState: function () {
    return {
      active: false
    };
  },

  getDefaultProps: function () {
    return {
      action: 'Dismiss',
      onClick: function () {
        return;
      }
    };
  },

  componentWillReceiveProps: function (nextProps) {
    if (!nextProps.dismissAfter) return;

    if (this.state.timeoutId) clearTimeout( this.state.timeoutId );
    this.state.timeoutId = setTimeout( this.hide, nextProps.dismissAfter );

    this.setState(this.state);
  },

  render: function () {
    return (

          {this.props.message}
          {this.props.action}

    );
  }

});

module.exports = Notification;
<|endoftext|>