<commit_before>import findCountryCode from './findCountryCode.js';

export default function createHitFormatter({formatAutocompleteSuggestion, formatInputValue}) {
  return hit => {
    let formatted = {
      administrative: hit.administrative && hit.administrative[0],
      city: hit.city && hit.city.default[0],
      country: hit.country.default,
      countryCode: findCountryCode(hit._tags),
      isCity: hit.is_city,
      name: hit.locale_names.default[0]
    };

    // this is the value to put inside the input.value
    // autocomplete.js automatically takes hit.value as the underlying
    // input value when a suggestion is validated with enter or selected with the mouse
    formatted.value = formatInputValue(formatted);

    // this is the value shown in suggestions, we highlight the name
    formatted.suggestion = formatAutocompleteSuggestion({
      ...formatted,
      name: hit._highlightResult.locale_names.default[0].value
    });

    return formatted;
  };
}
<commit_msg>fix(dropdown): trim whitespace in locale name<commit_after>import findCountryCode from './findCountryCode.js';

export default function createHitFormatter({formatAutocompleteSuggestion, formatInputValue}) {
  return hit => {
    let formatted = {
      administrative: hit.administrative && hit.administrative[0],
      city: hit.city && hit.city.default[0],
      country: hit.country.default,
      countryCode: findCountryCode(hit._tags),
      isCity: hit.is_city,
      name: hit.locale_names.default[0].trim() // trim should be done in data, waiting for a fix in Places API
    };

    // this is the value to put inside the input.value
    // autocomplete.js automatically takes hit.value as the underlying
    // input value when a suggestion is validated with enter or selected with the mouse
    formatted.value = formatInputValue(formatted);

    // this is the value shown in suggestions, we highlight the name
    formatted.suggestion = formatAutocompleteSuggestion({
      ...formatted,
      name: hit._highlightResult.locale_names.default[0].value.trim()
    });

    return formatted;
  };
}
<|endoftext|>


<commit_before>class SongDetail {
    constructor(song, contentPane) {
        this.song = song;
        this.contentPane = contentPane;
        this.onClickStart = this.onClickStart.bind(this);
        this.onClickPause = this.onClickPause.bind(this);
        this.onClickRestart = this.onClickRestart.bind(this);
        this.totalBars = 0;
        this.totalBeats = 0;
        this.bpm = 0;
    }

    render () {
        var _this = this;
        this.reset();
        var xhr = new XMLHttpRequest();
        xhr.open("GET", this.song.href);
        xhr.responseType = "json";
        xhr.onload = function(){_this.renderDetail(xhr.response)};
        xhr.send();
    }

    renderDetail(detail){
        this.songDetail = detail;
        var songDetail = document.createElement("div");
        songDetail.setAttribute("id","songDetail");
        this.renderSong(detail, songDetail);
        this.contentPane.appendChild(songDetail);

        var controlsContainer = document.createElement("div");
        controlsContainer.setAttribute("id", "controlsContainer");

        var startButton = document.createElement("button");
        startButton.innerHTML = "Start";
        startButton.classList.add("material");
        startButton.addEventListener("click", this.onClickStart);
        startButton.setAttribute("id","startButton");
        startButton.classList.add("runControlButton");
        controlsContainer.appendChild(startButton);

        var pauseButton = document.createElement("button");
        pauseButton.innerHTML = "Pause";
        pauseButton.classList.add("material");
        pauseButton.addEventListener("click", this.onClickPause);
        pauseButton.setAttribute("id","pauseButton");
        pauseButton.classList.add("runControlButton");
        pauseButton.classList.add("hidden");
        controlsContainer.appendChild(pauseButton);

        var restartButton = document.createElement("button");
        restartButton.innerHTML = "Restart";
        restartButton.classList.add("material");
        restartButton.addEventListener("click", this.onClickRestart);
        restartButton.setAttribute("id","restartButton");
        restartButton.classList.add("runControlButton");
        controlsContainer.appendChild(restartButton);

        var checkboxContainer = document.createElement("span");
        checkboxContainer.setAttribute("id","metronomeContainer");

        var checkbox = document.createElement("input");
        checkbox.setAttribute("type", "checkbox");
        checkbox.setAttribute("id", "metronomeCheckbox");
        checkboxContainer.appendChild(checkbox);

        var label = document.createElement("label");
        label.setAttribute("for", "metronomeCheckbox");
        label.innerHTML = "Metronome";
        checkboxContainer.appendChild(label);
        controlsContainer.appendChild(checkboxContainer);

        this.contentPane.appendChild(controlsContainer);
    }

    onClickStart() {
        this.play();
        this.startMetronome();
        document.getElementById("startButton").innerHTML="Resume"
    }

    onClickPause() {
        this.pause();
        this.pauseMetronome();
    }

    onClickRestart() {
        this.restart();
    }

    play() {
        var songDetail = document.getElementById("songDetail");
        songDetail.style.transitionDuration = this.songDetail.duration + "s";
        songDetail.style.left = -songDetail.offsetWidth + "px";
        songDetail.classList.add("slider");
        var pauseButton = document.getElementById("pauseButton");
        pauseButton.classList.remove("hidden");
        var startButton = document.getElementById("startButton");
        startButton.classList.add("hidden");

    }

    restart() {
        var songDetail = document.getElementById("songDetail");
        songDetail.style.transitionDuration = 0 + "s";
        songDetail.classList.remove("slider");
        songDetail.style.left = 0 + "px";
        this.stopMetronome();
        var startButton = document.getElementById("startButton");
        startButton.innerHTML = "Start";
        var pauseButton = document.getElementById("pauseButton");
        pauseButton.classList.add("hidden")
        startButton.classList.remove("hidden");

    }

    startMetronome() {
        var metronomeCheckbox = document.getElementById("metronomeCheckbox");
        if(document.querySelector("#metronomeCheckbox").checked) {
            var metronome = document.getElementById("metronome");
            metronome.playbackRate = this.bpm;
            metronome.play();
            this.metronomeAutoStopIntervalId = setTimeout(function() {
                metronome.pause();
            }, this.calculateRemainingDuration() * 1000);
        }
    }
    calculateRemainingDuration() {
        var duration = this.song.duration;
        var computedStyle = window.getComputedStyle(songDetail);
        var left = Math.abs(parseInt(computedStyle.getPropertyValue("left")));
        var width = parseInt(computedStyle.getPropertyValue("width").replace("px",""));
        var pct = left/width;
        return duration * 1-pct;
    }
    pause() {
        var songDetail = document.getElementById("songDetail");
        var computedStyle = window.getComputedStyle(songDetail);
        songDetail.classList.remove("slider");
        songDetail.style.left = computedStyle.getPropertyValue("left");
        var startButton = document.getElementById("startButton");
        startButton.classList.remove("hidden");
        var pauseButton = document.getElementById("pauseButton");
        pauseButton.classList.add("hidden");

    }

    pauseMetronome() {
        var metronome = document.getElementById("metronome");
        metronome.pause();
        clearInterval(this.metronomeAutoStopIntervalId);
    }

    stopMetronome() {
        this.pauseMetronome();
        document.getElementById("metronome").currentTime=0;
    }

    reset() {
        var range = new Range();
        range.selectNodeContents(this.contentPane);
        range.deleteContents();
    }

    renderSong(song, container) {
        for(var i=0;i<song.phrases.length;i++) {
            var phrase = song.phrases[i];
            this.totalBars += parseInt(phrase.bars);
            var phraseView = new Phrase(phrase, container);
            phraseView.render();
            if(phrase.repeat) {
                this.totalBars += parseInt(phrase.bars);
                //We start at 1 instead of 0 because we've already rendered 1 phrase already before the if statement
                for(var j=1;j<phrase.repeat;j++) {
                    phraseView.render();
                }
            }
        }
        var beatsPerBar = song.timing.lower;
        this.totalBeats = beatsPerBar * this.totalBars;
        this.bpm = this.totalBeats / song.duration;
    }
}

class Phrase {
    constructor(phrase, container) {
        this.phrase = phrase;
        this.container = container;
        this.baseWidth = 430;
    }
    render() {
        var view = document.createElement("div");
        view.setAttribute("class","phraseContainer");
        view.style.width = this.baseWidth * this.phrase.bars + "px";

        if(this.phrase.note) {
            var noteView = document.createElement("div");
            noteView.innerHTML = this.phrase.note;
            noteView.setAttribute("class","note");
            view.appendChild(noteView);
        }

        var phraseView = document.createElement("div");
        phraseView.setAttribute("class","phrase");
        if(this.phrase.lyric) {
            phraseView.innerHTML = this.phrase.lyric;
        }
        view.appendChild(phraseView);
        this.container.appendChild(view);
    }
}<commit_msg>Fixed playback rate on metronome<commit_after>class SongDetail {
    constructor(song, contentPane) {
        this.song = song;
        this.contentPane = contentPane;
        this.onClickStart = this.onClickStart.bind(this);
        this.onClickPause = this.onClickPause.bind(this);
        this.onClickRestart = this.onClickRestart.bind(this);
        this.totalBars = 0;
        this.totalBeats = 0;
        this.bpm = 0;
    }

    render () {
        var _this = this;
        this.reset();
        var xhr = new XMLHttpRequest();
        xhr.open("GET", this.song.href);
        xhr.responseType = "json";
        xhr.onload = function(){_this.renderDetail(xhr.response)};
        xhr.send();
    }

    renderDetail(detail){
        this.songDetail = detail;
        var songDetail = document.createElement("div");
        songDetail.setAttribute("id","songDetail");
        this.renderSong(detail, songDetail);
        this.contentPane.appendChild(songDetail);

        var controlsContainer = document.createElement("div");
        controlsContainer.setAttribute("id", "controlsContainer");

        var startButton = document.createElement("button");
        startButton.innerHTML = "Start";
        startButton.classList.add("material");
        startButton.addEventListener("click", this.onClickStart);
        startButton.setAttribute("id","startButton");
        startButton.classList.add("runControlButton");
        controlsContainer.appendChild(startButton);

        var pauseButton = document.createElement("button");
        pauseButton.innerHTML = "Pause";
        pauseButton.classList.add("material");
        pauseButton.addEventListener("click", this.onClickPause);
        pauseButton.setAttribute("id","pauseButton");
        pauseButton.classList.add("runControlButton");
        pauseButton.classList.add("hidden");
        controlsContainer.appendChild(pauseButton);

        var restartButton = document.createElement("button");
        restartButton.innerHTML = "Restart";
        restartButton.classList.add("material");
        restartButton.addEventListener("click", this.onClickRestart);
        restartButton.setAttribute("id","restartButton");
        restartButton.classList.add("runControlButton");
        controlsContainer.appendChild(restartButton);

        var checkboxContainer = document.createElement("span");
        checkboxContainer.setAttribute("id","metronomeContainer");

        var checkbox = document.createElement("input");
        checkbox.setAttribute("type", "checkbox");
        checkbox.setAttribute("id", "metronomeCheckbox");
        checkboxContainer.appendChild(checkbox);

        var label = document.createElement("label");
        label.setAttribute("for", "metronomeCheckbox");
        label.innerHTML = "Metronome";
        checkboxContainer.appendChild(label);
        controlsContainer.appendChild(checkboxContainer);

        this.contentPane.appendChild(controlsContainer);
    }

    onClickStart() {
        this.play();
        this.startMetronome();
        document.getElementById("startButton").innerHTML="Resume"
    }

    onClickPause() {
        this.pause();
        this.pauseMetronome();
    }

    onClickRestart() {
        this.restart();
    }

    play() {
        var songDetail = document.getElementById("songDetail");
        songDetail.style.transitionDuration = this.songDetail.duration + "s";
        songDetail.style.left = -songDetail.offsetWidth + "px";
        songDetail.classList.add("slider");
        var pauseButton = document.getElementById("pauseButton");
        pauseButton.classList.remove("hidden");
        var startButton = document.getElementById("startButton");
        startButton.classList.add("hidden");

    }

    restart() {
        var songDetail = document.getElementById("songDetail");
        songDetail.style.transitionDuration = 0 + "s";
        songDetail.classList.remove("slider");
        songDetail.style.left = 0 + "px";
        this.stopMetronome();
        var startButton = document.getElementById("startButton");
        startButton.innerHTML = "Start";
        var pauseButton = document.getElementById("pauseButton");
        pauseButton.classList.add("hidden")
        startButton.classList.remove("hidden");

    }

    startMetronome() {
        var metronomeCheckbox = document.getElementById("metronomeCheckbox");
        if(document.querySelector("#metronomeCheckbox").checked) {
            var metronome = document.getElementById("metronome");
            metronome.playbackRate = this.bpm / 100;
            metronome.play();
            this.metronomeAutoStopIntervalId = setTimeout(function() {
                metronome.pause();
            }, this.calculateRemainingDuration() * 1000);
        }
    }
    calculateRemainingDuration() {
        var duration = this.songDetail.duration;
        var computedStyle = window.getComputedStyle(songDetail);
        var left = Math.abs(parseInt(computedStyle.getPropertyValue("left")));
        var width = parseInt(computedStyle.getPropertyValue("width").replace("px",""));
        var pct = left/width;
        return duration * 1-pct;
    }
    pause() {
        var songDetail = document.getElementById("songDetail");
        var computedStyle = window.getComputedStyle(songDetail);
        songDetail.classList.remove("slider");
        songDetail.style.left = computedStyle.getPropertyValue("left");
        var startButton = document.getElementById("startButton");
        startButton.classList.remove("hidden");
        var pauseButton = document.getElementById("pauseButton");
        pauseButton.classList.add("hidden");

    }

    pauseMetronome() {
        var metronome = document.getElementById("metronome");
        metronome.pause();
        clearInterval(this.metronomeAutoStopIntervalId);
    }

    stopMetronome() {
        this.pauseMetronome();
        document.getElementById("metronome").currentTime=0;
    }

    reset() {
        var range = new Range();
        range.selectNodeContents(this.contentPane);
        range.deleteContents();
    }

    renderSong(song, container) {
        for(var i=0;i<song.phrases.length;i++) {
            var phrase = song.phrases[i];
            this.totalBars += parseInt(phrase.bars);
            var phraseView = new Phrase(phrase, container);
            phraseView.render();
            if(phrase.repeat) {
                //We start at 1 instead of 0 because we've already rendered 1 phrase already before the if statement
                for(var j=1;j<phrase.repeat;j++) {
                    this.totalBars += parseInt(phrase.bars);
                    phraseView.render();
                }
            }
        }
        var beatsPerBar = song.timing.lower;
        this.totalBeats = beatsPerBar * this.totalBars;
        this.bpm = this.totalBeats / (song.duration / 60);
    }
}

class Phrase {
    constructor(phrase, container) {
        this.phrase = phrase;
        this.container = container;
        this.baseWidth = 430;
    }
    render() {
        var view = document.createElement("div");
        view.setAttribute("class","phraseContainer");
        view.style.width = this.baseWidth * this.phrase.bars + "px";

        if(this.phrase.note) {
            var noteView = document.createElement("div");
            noteView.innerHTML = this.phrase.note;
            noteView.setAttribute("class","note");
            view.appendChild(noteView);
        }

        var phraseView = document.createElement("div");
        phraseView.setAttribute("class","phrase");
        if(this.phrase.lyric) {
            phraseView.innerHTML = this.phrase.lyric;
        }
        view.appendChild(phraseView);
        this.container.appendChild(view);
    }
}<|endoftext|>


<commit_before>(function() {

    var inp   = document.getElementById('pastek-input'),
        out   = document.getElementById('html-output'),
        tools = document.getElementById('input-tools'),

        body  = document.getElementsByTagName('body')[0],

        // saving tools
        rawbutton,
        savebutton,
        last_filename = 'pastek.txt',

        // cache string used to check if the text in the box has changed or not
        cache = '',

        // helpers
        noop = function() {},
        warn = window.console && console.warn ? console.warn.bind(console) : noop,

        createElement = function( name, opts, klass ) {
            var e = document.createElement( name ), o;
            for (o in opts) {
                if (opts.hasOwnProperty(o)) {
                    e.setAttribute( o, opts[o] );
                }
            }
            if (klass) {
                e.className = klass;
            }
            return e;
        },

        // regexes
        empty_re = /^\s*$/,

        help_text = document.getElementById('intro-text').innerHTML,

        s;

    function addEventListener( el, name, fn, useCapture ) {
        if  (el.addEventListener) { // Modern browsers
            el.addEventListener(name, fn, !!useCapture);
        } else if (inp.attachEvent) { // IE
            inp.attachEvent('on' + name, fn);
        } else { // others
            inp['on' + name] = fn;
        }
    }

    /**
     * Main rendering function. It reads the Pastek input,
     * and update the HTML one.
     **/
    function updateHTML() {
        var text = inp.value.replace(/\n+$/g, '');

        if (text == cache) { return; }

        cache = text;

        if (empty_re.test(text)) {
            out.innerHTML = '';
            return;
        }

        try {
            out.innerHTML = pastek_core.mk_html(text + "\n");
        } catch(e) {
            warn('' + e + ', text=<'+text.replace(/\n/g, '\\n')+'>');
        }
    }

    addEventListener(inp, 'keyup', updateHTML);

    /**
     * Save text across sessions
     **/

    if (window.localStorage && typeof localStorage.getItem == 'function') {
        s = localStorage.getItem('pastek.text');

        if (s && inp.value.length == 0) {
            inp.value = s;
            updateHTML();
        }

        addEventListener(window, 'unload', function() {
            localStorage.setItem('pastek.text',
                                 inp.value != help_text ? inp.value : "");
        });
    }

    /**
     * On startup include the help text if the input is empty
     **/

    if (inp.value.length == 0) {

        inp.value = help_text;
        updateHTML();
    }

    /**
     * Save Pastek input as a file using a Blob, if it's supported
     * by the browser.
     **/

    function createSourceURL() {
        var b = new Blob([inp.value], {type: "text/plain"});
        return URL.createObjectURL(b);
    }

    if (window.Blob && window.URL && typeof URL.createObjectURL == 'function') {

        rawbutton = createElement('a', {
            href: '#',
            target: '_blank',
            title: 'Right-click → "Save as…"'
        }, 'button');
        rawbutton.textContent = rawbutton.innerText = 'View raw…';

        savebutton = rawbutton.cloneNode(true);
        savebutton.textContent = savebutton.innerText = 'Save as…';
        savebutton.setAttribute('download', last_filename);

        addEventListener(rawbutton, 'click', function() {
            rawbutton.setAttribute('href', createSourceURL());
        });

        addEventListener(savebutton, 'click', function(e) {
            var name = prompt('Select a filename:', last_filename);

            if (name == null) { e.preventDefault(); return false; }

            savebutton.setAttribute('href', createSourceURL());
            savebutton.setAttribute('download', last_filename = name);
        });

        tools.appendChild(rawbutton);
        tools.appendChild(savebutton);

    }

    // Editing a local file (#2)
    if (window.File && window.FileReader) (function(){
        var fileinput, button,
            ref = '_local_file';

        button = createElement('label', {
            href: '#',
           'for': ref
        }, 'button');
        button.innerText = button.textContent = 'Edit a local file';

        fileinput = createElement('input', {
            type: 'file',
            accept: 'text/*'
        }, 'hidden');
        fileinput.id = ref;

        addEventListener( fileinput, 'change', function() {
            var f = fileinput.files[0],
                reader;
            if (!f) { return; }

            reader = new FileReader();
            reader.onload = function() {
                inp.value = reader.result.slice(0, 0xFFFFF);
                updateHTML();
            };
            reader.readAsText(f);
        });

        body.appendChild(fileinput);
        tools.appendChild(button);

    })();

})();
<commit_msg>Formatting.<commit_after>(function() {

    var inp   = document.getElementById('pastek-input'),
        out   = document.getElementById('html-output'),
        tools = document.getElementById('input-tools'),

        body  = document.getElementsByTagName('body')[0],

        // saving tools
        rawbutton,
        savebutton,
        last_filename = 'pastek.txt',

        // cache string used to check if the text in the box has changed or not
        cache = '',

        // helpers
        noop = function() {},
        warn = window.console && console.warn ? console.warn.bind(console) : noop,

        createElement = function( name, opts, klass ) {
            var e = document.createElement( name ), o;
            for (o in opts) {
                if (opts.hasOwnProperty(o)) {
                    e.setAttribute( o, opts[o] );
                }
            }
            if (klass) {
                e.className = klass;
            }
            return e;
        },

        // regexes
        empty_re = /^\s*$/,

        help_text = document.getElementById('intro-text').innerHTML,

        s;

    function addEventListener( el, name, fn, useCapture ) {
        if  (el.addEventListener) { // Modern browsers
            el.addEventListener(name, fn, !!useCapture);
        } else if (inp.attachEvent) { // IE
            inp.attachEvent('on' + name, fn);
        } else { // others
            inp['on' + name] = fn;
        }
    }

    /**
     * Main rendering function. It reads the Pastek input,
     * and update the HTML one.
     **/
    function updateHTML() {
        var text = inp.value.replace(/\n+$/g, '');

        if (text == cache) { return; }

        cache = text;

        if (empty_re.test(text)) {
            out.innerHTML = '';
            return;
        }

        try {
            out.innerHTML = pastek_core.mk_html(text + "\n");
        } catch(e) {
            warn('' + e + ', text=<'+text.replace(/\n/g, '\\n')+'>');
        }
    }

    addEventListener(inp, 'keyup', updateHTML);

    /**
     * Save text across sessions
     **/

    if (window.localStorage && typeof localStorage.getItem == 'function') {
        s = localStorage.getItem('pastek.text');

        if (s && inp.value.length == 0) {
            inp.value = s;
            updateHTML();
        }

        addEventListener(window, 'unload', function() {
            localStorage.setItem('pastek.text',
                                 inp.value != help_text ? inp.value : "");
        });
    }

    /**
     * On startup, include the help text if the input is empty
     **/
    if (inp.value.length == 0) {

        inp.value = help_text;
        updateHTML();
    }

    /**
     * Save Pastek input as a file using a Blob, if it's supported
     * by the browser.
     **/
    function createSourceURL() {
        var b = new Blob([inp.value], {type: "text/plain"});
        return URL.createObjectURL(b);
    }

    if (window.Blob && window.URL && typeof URL.createObjectURL == 'function') {

        rawbutton = createElement('a', {
            href: '#',
            target: '_blank',
            title: 'Right-click → "Save as…"'
        }, 'button');
        rawbutton.textContent = rawbutton.innerText = 'View raw…';

        savebutton = rawbutton.cloneNode(true);
        savebutton.textContent = savebutton.innerText = 'Save as…';
        savebutton.setAttribute('download', last_filename);

        addEventListener(rawbutton, 'click', function() {
            rawbutton.setAttribute('href', createSourceURL());
        });

        addEventListener(savebutton, 'click', function(e) {
            var name = prompt('Select a filename:', last_filename);

            if (name == null) { e.preventDefault(); return false; }

            savebutton.setAttribute('href', createSourceURL());
            savebutton.setAttribute('download', last_filename = name);
        });

        tools.appendChild(rawbutton);
        tools.appendChild(savebutton);

    }

    /**
     * Edit a file from your local storage (#2)
     **/
    if (window.File && window.FileReader) (function(){
        var fileinput, button,
            ref = '_local_file';

        button = createElement('label', {
            href: '#',
           'for': ref
        }, 'button');
        button.innerText = button.textContent = 'Edit a local file…';

        fileinput = createElement('input', {
            type: 'file',
            accept: 'text/*'
        }, 'hidden');
        fileinput.id = ref;

        addEventListener( fileinput, 'change', function() {
            var f = fileinput.files[0],
                reader;
            if (!f) { return; }

            reader = new FileReader();
            reader.onload = function() {
                inp.value = reader.result.slice(0, 0xFFFFF);
                updateHTML();
            };
            reader.readAsText(f);
        });

        body.appendChild(fileinput);
        tools.appendChild(button);

    })();

    /**
     * Auto-expand the textarea when you type in it
     **/

})();
<|endoftext|>


<commit_before>(function() {
    'use strict';

    var main        = global.cloudcmd.main,
        path        = require('path'),
        fs          = require('fs'),
        diff        = main.diff,
        CloudFunc   = main.cloudfunc,
        DIR         = '../../../',
        DIR_SERVER  = DIR + 'server/',

        Util        = require(DIR + 'util'),

        flop        = require(DIR_SERVER + 'flop'),
        pack        = require(DIR_SERVER + 'pack'),
        pipe        = require(DIR_SERVER + 'pipe');

    exports.onPut = onPut;

    function onPut(name, query, readStream, callback) {
        var func        = Util.exec.ret(callback),
            baseName    = path.basename(name);

        switch(query) {
        case 'dir':
            flop.create(name, 'dir', function(error) {
                var msg;

                if (!error)
                    msg = CloudFunc.formatMsg('make dir', name);

                func(error, msg);
            });

            break;

        case 'file':
            fs.writeFile(name, '', callback);
            break;

        default:
            pack.gunzip(readStream, path, function(error) {
                var msg;

                if (!error)
                    msg     = CloudFunc.formatMsg('save', baseName);

                func(error, msg);
            });
            break;

        case 'patch':
            flop.read(name, 'size', function(error, size) {
                var MAX_SIZE = CloudFunc.MAX_FILE_SIZE;

                if (!error)
                    if (size < MAX_SIZE)
                        pipe.getBody(readStream, function(error, patch) {
                            if (error)
                                func(error);
                            else
                                patchFile(name, patch, func);
                        });
                    else
                        error = 'File is to big. '          +
                                'Could not patch files '    +
                                'bigger then' + MAX_SIZE;

                if (error)
                    func(error);
            });
            break;
        }
    }

    function patchFile(name, patch, func) {
        var msg,
            baseName = path.basename(name);

        fs.readFile(name, 'utf8', read);

        function read(error, data) {
            var diffResult;

            if (error)
                func(error);
            else {
                error         = Util.exec.tryLog(function() {
                    diffResult = diff.applyPatch(data, patch);
                });

                if (diffResult && !error)
                    fs.writeFile(name, diffResult, onWrite);
                else {
                    msg     = CloudFunc.formatMsg('patch', baseName, 'fail');
                    func(null, msg);
                }
            }
        }

        function onWrite(error) {
            var msg,
                baseName = path.basename(name);

            if (!error)
                msg = CloudFunc.formatMsg('patch', baseName);

            func(error, msg);
        }
    }
})();
<commit_msg>fix(put) path -> name<commit_after>(function() {
    'use strict';

    var main        = global.cloudcmd.main,
        path        = require('path'),
        fs          = require('fs'),
        diff        = main.diff,
        CloudFunc   = main.cloudfunc,
        DIR         = '../../../',
        DIR_SERVER  = DIR + 'server/',

        Util        = require(DIR + 'util'),

        flop        = require(DIR_SERVER + 'flop'),
        pack        = require(DIR_SERVER + 'pack'),
        pipe        = require(DIR_SERVER + 'pipe');

    exports.onPut = onPut;

    function onPut(name, query, readStream, callback) {
        var func        = Util.exec.ret(callback),
            baseName    = path.basename(name);

        switch(query) {
        case 'dir':
            flop.create(name, 'dir', function(error) {
                var msg;

                if (!error)
                    msg = CloudFunc.formatMsg('make dir', name);

                func(error, msg);
            });

            break;

        case 'file':
            fs.writeFile(name, '', callback);
            break;

        default:
            pack.gunzip(readStream, name, function(error) {
                var msg;

                if (!error)
                    msg     = CloudFunc.formatMsg('save', baseName);

                func(error, msg);
            });
            break;

        case 'patch':
            flop.read(name, 'size', function(error, size) {
                var MAX_SIZE = CloudFunc.MAX_FILE_SIZE;

                if (!error)
                    if (size < MAX_SIZE)
                        pipe.getBody(readStream, function(error, patch) {
                            if (error)
                                func(error);
                            else
                                patchFile(name, patch, func);
                        });
                    else
                        error = 'File is to big. '          +
                                'Could not patch files '    +
                                'bigger then' + MAX_SIZE;

                if (error)
                    func(error);
            });
            break;
        }
    }

    function patchFile(name, patch, func) {
        var msg,
            baseName = path.basename(name);

        fs.readFile(name, 'utf8', read);

        function read(error, data) {
            var diffResult;

            if (error)
                func(error);
            else {
                error         = Util.exec.tryLog(function() {
                    diffResult = diff.applyPatch(data, patch);
                });

                if (diffResult && !error)
                    fs.writeFile(name, diffResult, onWrite);
                else {
                    msg     = CloudFunc.formatMsg('patch', baseName, 'fail');
                    func(null, msg);
                }
            }
        }

        function onWrite(error) {
            var msg,
                baseName = path.basename(name);

            if (!error)
                msg = CloudFunc.formatMsg('patch', baseName);

            func(error, msg);
        }
    }
})();
<|endoftext|>


<commit_before>import ojsama from 'ojsama'

function calculateDTAR(ms) {
  if (ms < 300) {
    return 11 // with DT, the AR is capped at 11
  }
  if (ms < 1200) {
    return 11 - (ms - 300) / 150
  }
  return 5 - (ms - 1200) / 120
}

export function calculateApproachRate(modifiers, ar) {
  let ms
  switch (
    modifiers &
    (ojsama.modbits.ht |
      ojsama.modbits.dt |
      ojsama.modbits.ez |
      ojsama.modbits.hr)
  ) {
    case ojsama.modbits.hr:
      return Math.min(10, ar * 1.4)
    case ojsama.modbits.ez:
      return ar / 2

    case ojsama.modbits.dt & ojsama.modbits.hr: {
      if (ar < 4) {
        ms = 1200 - 112 * ar
      } else if (ar > 4) {
        ms = 740 - 140 * (ar - 4)
      } else {
        ms = 864 - 124 * (ar - 3)
      }
      return calculateDTAR(ms)
    }
    case ojsama.modbits.dt & ojsama.modbits.ez:
      return calculateDTAR(1200 - 40 * ar)

    case ojsama.modbits.dt:
      return calculateDTAR(ar > 5 ? 200 + (11 - ar) * 100 : 800 + (5 - ar) * 80)
    case ojsama.modbits.ht: {
      if (ar === 5) return 0
      if (ar < 5) return -1.5 * (5 - ar)
      if (ar < 8) return 1.875 * ar
      return 4 + 1.5 * (ar - 7)
    }

    case ojsama.modbits.ht & ojsama.modbits.hr: {
      if (ar > 7) return 8.5
      if (ar < 4) {
        ms = 2700 - 252 * ar
      } else if (ar < 5) {
        ms = 1944 - 279 * (ar - 3)
      } else {
        ms = 1665 - 315 * (ar - 4)
      }
      if (ar < 6) {
        return 15 - ms / 120
      }
      if (ar > 7) {
        return 13 - ms / 150
      }
      return 15 - ms / 120
    }
    case ojsama.modbits.ht & ojsama.modbits.ez:
      return -0.75 * (10 - ar)

    default:
      return ar
  }
}

export function calculatePerformance(map, mods, combo, misses, accuracy) {
  const stars = new ojsama.diff().calc({ map, mods })

  const pp = ojsama.ppv2({
    stars,
    combo,
    nmiss: misses,
    acc_percent: accuracy,
  })

  return { pp, stars }
}
<commit_msg>Fix AR calculation<commit_after>import ojsama from 'ojsama'

function calculateDTAR(ms) {
  if (ms < 300) {
    return 11 // with DT, the AR is capped at 11
  }
  if (ms < 1200) {
    return 11 - (ms - 300) / 150
  }
  return 5 - (ms - 1200) / 120
}

export function calculateApproachRate(modifiers, ar) {
  let ms
  switch (
    modifiers &
    (ojsama.modbits.ht |
      ojsama.modbits.dt |
      ojsama.modbits.ez |
      ojsama.modbits.hr)
  ) {
    case ojsama.modbits.hr:
      return Math.min(10, ar * 1.4)
    case ojsama.modbits.ez:
      return ar / 2

    case ojsama.modbits.dt + ojsama.modbits.hr: {
      if (ar < 4) {
        ms = 1200 - 112 * ar
      } else if (ar > 4) {
        ms = 740 - 140 * (ar - 4)
      } else {
        ms = 864 - 124 * (ar - 3)
      }
      return calculateDTAR(ms)
    }
    case ojsama.modbits.dt + ojsama.modbits.ez:
      return calculateDTAR(1200 - 40 * ar)

    case ojsama.modbits.dt:
      return calculateDTAR(ar > 5 ? 200 + (11 - ar) * 100 : 800 + (5 - ar) * 80)
    case ojsama.modbits.ht: {
      if (ar <= 5) return (1600 - (600 + 160 * (10 - ar))) / 120
      ms = 600 + (10 - ar) * 200
      if (ms >= 1200) return 15 - ms / 120
      return 13 - ms / 150
    }

    case ojsama.modbits.ht + ojsama.modbits.hr: {
      if (ar > 7) return 8.5
      if (ar < 4) {
        ms = 2700 - 252 * ar
      } else if (ar < 5) {
        ms = 1944 - 279 * (ar - 3)
      } else {
        ms = 1665 - 315 * (ar - 4)
      }
      if (ar < 6) {
        return 15 - ms / 120
      }
      if (ar > 7) {
        return 13 - ms / 150
      }
      return 15 - ms / 120
    }
    case ojsama.modbits.ht + ojsama.modbits.ez:
      return (1800 - (1600 + 80 * (10 - ar))) / 120

    default:
      return ar
  }
}

export function calculatePerformance(map, mods, combo, misses, accuracy) {
  const stars = new ojsama.diff().calc({ map, mods })

  const pp = ojsama.ppv2({
    stars,
    combo,
    nmiss: misses,
    acc_percent: accuracy,
  })

  return { pp, stars }
}
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import Papa from 'papaparse';
import { connect } from 'react-redux';
import { browserHistory } from 'react-router';
import { saveChartDataRequest} from '../../HomeActions';
import { homeData } from '../../HomeReducer';
import FontAwesome from 'react-fontawesome';
import styles from './HomePage.css';
import  {ToastContainer, ToastMessage} from '../../../../lib';
const ToastMessageFactory = React.createFactory(ToastMessage.animation);
var _ = require('lodash');

class HomePage extends Component {

	constructor(props) {
		super(props)
		this.state = {
			error: false
		}
	}

	handleUploadCSV = (e) => {
		var file = e.target.files[0];
		var self = this;
		Papa.parse(file, {
			skipEmptyLines: true,
			complete: function(results, file) {
				if(results != undefined) {
					var finalArr = []
  				var uniqueSeriesName = ''
  				var uniqueSeriesData = ''
				  for(var i=0; i< results.data.length; i++) {
				    var dataArr = []
				    // console.log((new Set(results.data[i])).size !== results.data[i].length ) // For unique data within one series
				    var dataWithoutSeriesName = _.without(results.data[i], results.data[i][0])
						if(_.isEqual(uniqueSeriesData, dataWithoutSeriesName)) {
						  self.refs.home_container.error('Each series should be unique');
						  self.setState({
		      			error: true
		      		})
						} else {
							uniqueSeriesData = dataWithoutSeriesName
					    for(var j=0; j< results.data[i].length; j++) {
					      if(results.data[i][j].indexOf("|") > -1) {
					        var score = results.data[i][j].substring(results.data[i][j].indexOf("|") + 1)
					        var year = results.data[i][j].substring(0, results.data[i][j].indexOf("|"))
					        dataArr.push({
					          y: score,
					          x: year
					        })
					      } else {
					      	if(uniqueSeriesName == results.data[i][j]) {
					      		self.refs.home_container.error("Series name should be unique");
					      		self.setState({
					      			error: true
					      		})
					      	} else {
						        finalArr.push({
						          name: results.data[i][j],
						          data: dataArr
						        })
						        uniqueSeriesName = results.data[i][j]
					        }
					      }
					    }
					  }
				  }
				  if(self.state.error == false) {
						self.props.dispatch(saveChartDataRequest(finalArr)).then(res => self.uploadData(res));
					}
				}
			}
		})
  }

  uploadData(res) {
  	if(res.status) {
  		this.refs.home_container.success(res.message);
  	}
  }

  handleChart() {
  	browserHistory.push('/chart')
  }

  render() {
  	let uploadIcon = {
			marginTop: '8px'
		}
		let uploadText = {
			padding: '0 0 8px 0',
    	margin: '0'
		}
    return (

				<ToastContainer
	        toastMessageFactory={ToastMessageFactory}
	        ref="home_container"
	        className="toast-top-right"
	       />

		        <input type="file" accept=".csv" onChange={this.handleUploadCSV.bind(this)} value={''}/>
		        <FontAwesome name="upload" style={uploadIcon}></FontAwesome>

Upload CSV

		      <button onClick={this.handleChart.bind(this)} value={''}> View Chart </button>

    );
  }
}

// Retrieve data from store as props
function mapStateToProps(state) {
  return {
    homeData: homeData(state),
  };
}

export default connect(mapStateToProps)(HomePage);<commit_msg>Error state changes<commit_after>import React, { Component, PropTypes } from 'react';
import ReactDOM from 'react-dom';
import Papa from 'papaparse';
import { connect } from 'react-redux';
import { browserHistory } from 'react-router';
import { saveChartDataRequest} from '../../HomeActions';
import { homeData } from '../../HomeReducer';
import FontAwesome from 'react-fontawesome';
import styles from './HomePage.css';
import  {ToastContainer, ToastMessage} from '../../../../lib';
const ToastMessageFactory = React.createFactory(ToastMessage.animation);
var _ = require('lodash');

class HomePage extends Component {

	constructor(props) {
		super(props)
		this.state = {
			error: false
		}
	}

	handleUploadCSV = (e) => {
		console.log("in")
		var file = e.target.files[0];
		var self = this;
		Papa.parse(file, {
			skipEmptyLines: true,
			complete: function(results, file) {
				if(results != undefined) {
					var finalArr = []
  				var uniqueSeriesName = ''
  				var uniqueSeriesData = ''
				  for(var i=0; i< results.data.length; i++) {
				    var dataArr = []
				    // console.log((new Set(results.data[i])).size !== results.data[i].length ) // For unique data within one series
				    var dataWithoutSeriesName = _.without(results.data[i], results.data[i][0])
						if(_.isEqual(uniqueSeriesData, dataWithoutSeriesName)) {
						  self.refs.home_container.error('Each series should be unique');
						  self.setState({
		      			error: true
		      		})
						} else {
							uniqueSeriesData = dataWithoutSeriesName
					    for(var j=0; j< results.data[i].length; j++) {
					      if(results.data[i][j].indexOf("|") > -1) {
					        var score = results.data[i][j].substring(results.data[i][j].indexOf("|") + 1)
					        var year = results.data[i][j].substring(0, results.data[i][j].indexOf("|"))
					        dataArr.push({
					          y: score,
					          x: year
					        })
					      } else {
					      	if(uniqueSeriesName == results.data[i][j]) {
					      		self.refs.home_container.error("Series name should be unique");
					      		self.setState({
					      			error: true
					      		})
					      	} else {
						        finalArr.push({
						          name: results.data[i][j],
						          data: dataArr
						        })
						        uniqueSeriesName = results.data[i][j]
					        }
					      }
					    }
					  }
				  }
				  if(self.state.error == false) {
						self.props.dispatch(saveChartDataRequest(finalArr)).then(res => self.uploadData(res));
					}
				}
			}
		})
		self.setState({
			error: false
		})
  }

  uploadData(res) {
  	if(res.status) {
  		this.refs.home_container.success(res.message);
  	}
  }

  handleChart() {
  	browserHistory.push('/chart')
  }

  render() {
  	let uploadIcon = {
			marginTop: '8px'
		}
		let uploadText = {
			padding: '0 0 8px 0',
    	margin: '0'
		}
    return (

				<ToastContainer
	        toastMessageFactory={ToastMessageFactory}
	        ref="home_container"
	        className="toast-top-right"
	       />

		        <input type="file" accept=".csv" onChange={this.handleUploadCSV.bind(this)} value={''}/>
		        <FontAwesome name="upload" style={uploadIcon}></FontAwesome>

Upload CSV

		      <button onClick={this.handleChart.bind(this)} value={''}> View Chart </button>

    );
  }
}

// Retrieve data from store as props
function mapStateToProps(state) {
  return {
    homeData: homeData(state),
  };
}

export default connect(mapStateToProps)(HomePage);<|endoftext|>


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

(function() {
  'use strict';

  var app = {
    isLoading: true,
    visibleCards: {},
    selectedCities: [],
    spinner: document.querySelector('.loader'),
    cardTemplate: document.querySelector('.cardTemplate'),
    container: document.querySelector('.main'),
    addDialog: document.querySelector('.dialog-container'),
    daysOfWeek: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  };

  /*****************************************************************************
   *
   * localforage config
   *
   ****************************************************************************/
   localforage.config({
      // driver      : localforage.WEBSQL, // Force WebSQL; same as using setDriver()
       driver      : localforage.INDEXEDDB,
       name        : 'weatherPWA',
       version     : 1.0,
       // size        : 4980736, // Size of database, in bytes. WebSQL-only for now.
       storeName   : 'keyvalpairs', // Should be alphanumeric, with underscores.
       description : 'for saving cities we want weather forecasts for'
   });

  /*****************************************************************************
   *
   * Event listeners for UI elements
   *
   ****************************************************************************/

  document.getElementById('butRefresh').addEventListener('click', function() {
    // Refresh all of the forecasts
    app.updateForecasts();
  });

  document.getElementById('butAdd').addEventListener('click', function() {
    // Open/show the add new city dialog
    app.toggleAddDialog(true);
  });

  document.getElementById('butAddCity').addEventListener('click', function() {
    // Add the newly selected city
    var select = document.getElementById('selectCityToAdd');
    var selected = select.options[select.selectedIndex];
    var key = selected.value;
    var label = selected.textContent;

    if(!app.selectedCities) { app.selectedCities = []; }
    app.getForecast(key, label);

    app.selectedCities.push({ key: key, label: label});
    app.saveSelectedCities();

    app.toggleAddDialog(false);
  });

  document.getElementById('butAddCancel').addEventListener('click', function() {
    // Close the add new city dialog
    app.toggleAddDialog(false);
  });

  /*****************************************************************************
   *
   * Methods to update/refresh the UI
   *
   ****************************************************************************/

  // Toggles the visibility of the add new city dialog.
  app.toggleAddDialog = function(visible) {
    if (visible) {
      app.addDialog.classList.add('dialog-container--visible');
    } else {
      app.addDialog.classList.remove('dialog-container--visible');
    }
  };

  // Updates a weather card with the latest weather forecast. If the card
  // doesn't already exist, it's cloned from the template.
  app.updateForecastCard = function(data) {
    var dataLastUpdated = new Date(data.created);
    var sunrise = data.channel.astronomy.sunrise;
    var sunset = data.channel.astronomy.sunset;
    var current = data.channel.item.condition;
    var humidity = data.channel.atmosphere.humidity;
    var wind = data.channel.wind;

    var card = app.visibleCards[data.key];
    if (!card) {
      card = app.cardTemplate.cloneNode(true);
      card.classList.remove('cardTemplate');
      card.querySelector('.location').textContent = data.label;
      card.removeAttribute('hidden');
      app.container.appendChild(card);
      app.visibleCards[data.key] = card;
    }

    // Verifies the data provide is newer than what's already visible
    // on the card, if it's not bail, if it is, continue and update the
    // time saved in the card
    var cardLastUpdatedElem = card.querySelector('.card-last-updated');
    var cardLastUpdated = cardLastUpdatedElem.textContent;
    if (cardLastUpdated) {
      cardLastUpdated = new Date(cardLastUpdated);
      // Bail if the card has more recent data then the data
      if (dataLastUpdated.getTime() < cardLastUpdated.getTime()) {
        return;
      }
    }
    cardLastUpdatedElem.textContent = data.created;

    card.querySelector('.description').textContent = current.text;
    card.querySelector('.date').textContent = current.date;
    card.querySelector('.current .icon').classList.add(app.getIconClass(current.code));
    card.querySelector('.current .temperature .value').textContent =
      Math.round(current.temp);
    card.querySelector('.current .sunrise').textContent = sunrise;
    card.querySelector('.current .sunset').textContent = sunset;
    card.querySelector('.current .humidity').textContent =
      Math.round(humidity) + '%';
    card.querySelector('.current .wind .value').textContent =
      Math.round(wind.speed);
    card.querySelector('.current .wind .direction').textContent = wind.direction;
    var nextDays = card.querySelectorAll('.future .oneday');
    var today = new Date();
    today = today.getDay();
    for (var i = 0; i < 7; i++) {
      var nextDay = nextDays[i];
      var daily = data.channel.item.forecast[i];
      if (daily && nextDay) {
        nextDay.querySelector('.date').textContent =
          app.daysOfWeek[(i + today) % 7];
        nextDay.querySelector('.icon').classList.add(app.getIconClass(daily.code));
        nextDay.querySelector('.temp-high .value').textContent =
          Math.round(daily.high);
        nextDay.querySelector('.temp-low .value').textContent =
          Math.round(daily.low);
      }
    }
    if (app.isLoading) {
      app.spinner.setAttribute('hidden', true);
      app.container.removeAttribute('hidden');
      app.isLoading = false;
    }
  };

  /*****************************************************************************
   *
   * Methods for dealing with the model
   *
   ****************************************************************************/

  /*
   * Gets a forecast for a specific city and updates the card with the data.
   * getForecast() first checks if the weather data is in the cache. If so,
   * then it gets that data and populates the card with the cached data.
   * Then, getForecast() goes to the network for fresh data. If the network
   * request goes through, then the card gets updated a second time with the
   * freshest data.
   */
  app.getForecast = function(key, label) {
    var statement = 'select * from weather.forecast where woeid=' + key;
    var url = 'https://query.yahooapis.com/v1/public/yql?format=json&q=' +
        statement;

    // TODO add cache logic here

    if ('caches' in window) {
      /*
       * Check if the service worker has already cached this city's weather
       * data. If the service worker has the data, then display the cached
       * data while the app fetches the latest data.
       */
      caches.match(url).then(function(response) {
        if (response) {
          response.json().then(function updateFromCache(json) {
            var results = json.query.results;
            results.key = key;
            results.label = label;
            results.created = json.query.created;
            app.updateForecastCard(results);
          });
        }
      });
    }

    // Fetch the latest data.
    var request = new XMLHttpRequest();
    request.onreadystatechange = function() {
      if (request.readyState === XMLHttpRequest.DONE) {
        if (request.status === 200) {
          var response = JSON.parse(request.response);
          var results = response.query.results;
          results.key = key;
          results.label = label;
          results.created = response.query.created;
          app.updateForecastCard(results);
        }
      } else {
        // Return the initial weather forecast since no data is available.
        app.updateForecastCard(initialWeatherForecast);
      }
    };
    request.open('GET', url);
    request.send();
  };

  // Iterate all of the cards and attempt to get the latest forecast data
  app.updateForecasts = function() {
    var keys = Object.keys(app.visibleCards);
    keys.forEach(function(key) {
      app.getForecast(key);
    });
  };

  // TODO add saveSelectedCities function here
  app.saveSelectedCities = function(){
    //var selectedCities = JSON.stringify(app.selectedCities);
    //localStorage.selectedCities = selectedCities;

    /* Extra Credit: Replace localStorage implementation with localForage
    *
    * future TODO: use idb-keyval (or just idb) instead because its
    * smaller for our simple purpose of just storing key value pairs
    *
        idbKeyval.set('selectedCities', app.selectedCities)
          .then(() => console.log('Saved selected cities'))
          .catch(err => console.log('Failed to save selected cities; ', err));
        };
    */

    localforage.setItem('selectedCities', app.selectedCities).then(function () {
      return localforage.getItem('selectedCities');
    }).then(function(value){
      console.log('cities saved');
    }).catch(function (err) {
      console.log(err);
    });

  };

  app.getIconClass = function(weatherCode) {
    // Weather codes: https://developer.yahoo.com/weather/documentation.html#codes
    weatherCode = parseInt(weatherCode);
    switch (weatherCode) {
      case 25: // cold
      case 32: // sunny
      case 33: // fair (night)
      case 34: // fair (day)
      case 36: // hot
      case 3200: // not available
        return 'clear-day';
      case 0: // tornado
      case 1: // tropical storm
      case 2: // hurricane
      case 6: // mixed rain and sleet
      case 8: // freezing drizzle
      case 9: // drizzle
      case 10: // freezing rain
      case 11: // showers
      case 12: // showers
      case 17: // hail
      case 35: // mixed rain and hail
      case 40: // scattered showers
        return 'rain';
      case 3: // severe thunderstorms
      case 4: // thunderstorms
      case 37: // isolated thunderstorms
      case 38: // scattered thunderstorms
      case 39: // scattered thunderstorms (not a typo)
      case 45: // thundershowers
      case 47: // isolated thundershowers
        return 'thunderstorms';
      case 5: // mixed rain and snow
      case 7: // mixed snow and sleet
      case 13: // snow flurries
      case 14: // light snow showers
      case 16: // snow
      case 18: // sleet
      case 41: // heavy snow
      case 42: // scattered snow showers
      case 43: // heavy snow
      case 46: // snow showers
        return 'snow';
      case 15: // blowing snow
      case 19: // dust
      case 20: // foggy
      case 21: // haze
      case 22: // smoky
        return 'fog';
      case 24: // windy
      case 23: // blustery
        return 'windy';
      case 26: // cloudy
      case 27: // mostly cloudy (night)
      case 28: // mostly cloudy (day)
      case 31: // clear (night)
        return 'cloudy';
      case 29: // partly cloudy (night)
      case 30: // partly cloudy (day)
      case 44: // partly cloudy
        return 'partly-cloudy-day';
    }
  };

  /*
   * Fake weather data that is presented when the user first uses the app,
   * or when the user has not saved any cities. See startup code for more
   * discussion.
   */
  var initialWeatherForecast = {
    key: '2487956',
    label: 'San Francisco, CA',
    created: '2017-04-28T07:39:59Z',
    channel: {
      astronomy: {
        sunrise: "6:18 am",
        sunset: "7:57 pm"
      },
      item: {
        condition: {
          text: "Clear",
          date: "Fri, 28 Apr 2017 12:00 AM PDT",
          temp: 52,
          code: 31
        },
        forecast: [
          {code: 34, high: 66, low: 52},
          {code: 32, high: 69, low: 56},
          {code: 32, high: 69, low: 54},
          {code: 32, high: 71, low: 54},
          {code: 30, high: 73, low: 57},
          {code: 34, high: 73, low: 60},
          {code: 30, high: 67, low: 58}
        ]
      },
      atmosphere: {
        humidity: 78
      },
      wind: {
        speed: 22,
        direction: 310
      }
    }
  };
  // TODO uncomment line below to test app with fake data
  // app.updateForecastCard(initialWeatherForecast);

  // TODO add startup code here

  /************************************************************************
     *
     * Code required to start the app
     *
     * NOTE: To simplify this codelab, we've used localStorage.
     *   localStorage is a synchronous API and has serious performance
     *   implications. It should not be used in production applications!
     *   Instead, check out IDB (https://www.npmjs.com/package/idb) or
     *   SimpleDB (https://gist.github.com/inexorabletash/c8069c042b734519680c)
     ************************************************************************/

     function locationSuccess(pos) {

       var statement = 'select * FROM geo.places WHERE text="('
       statement += pos.coords.latitude + ', ' + pos.coords.longitude + ')"';

       var url = 'https://query.yahooapis.com/v1/public/yql?format=json&q=' +
           statement;

      var request = new XMLHttpRequest();
      request.onreadystatechange = function() {
        if (request.readyState === XMLHttpRequest.DONE) {
          if (request.status === 200) {
            //console.log(request.response);
            var response = JSON.parse(request.response);
            var results = response.query.results;
            var key = results.place.locality1.woeid;
            var label = results.place.locality1.content + ', ';

            app.getForecast(key, label);
            app.selectedCities = [
              {key: key, label: label}
            ];
            app.saveSelectedCities();
            console.log('first');
            //app.updateForecastCard(results);
          }
        } else {
          // Return the initial weather forecast since no data is available.
          app.updateForecastCard(initialWeatherForecast);
        }
      };

       request.open('GET', url);
       request.send();
     }

     if ("geolocation" in navigator) {
       /* geolocation is available */
       console.log('geolocation was here!');
       navigator.geolocation.getCurrentPosition(locationSuccess);
     } else {
       /* geolocation IS NOT available */
       console.log('geolocation is not available');
     }

    //app.selectedCities = localStorage.selectedCities
    localforage.getItem('selectedCities').then(function (vals) {
      // we got our value
      app.selectedCities = vals;
      if (app.selectedCities) {
        //app.selectedCities = JSON.parse(app.selectedCities);
        app.selectedCities.forEach(function(city) {
          //console.log(city);
          app.getForecast(city.key, city.label);
        });
      } else {
        /* The user is using the app for the first time, or the user has not
         * saved any cities, so show the user some fake data. A real app in this
         * scenario could guess the user's location via IP lookup and then inject
         * that data into the page.
         */

        //app.updateForecastCard(initialWeatherForecast);
        // forget using fake data, lets just use the fake datas woeid (key)
        // and label to get an updated forecast instead.

        // TODO get the user's geolocation if they allow

        // if they don't, lets get lat and long using just ip

        // then once we have lat/long, we can query

        app.getForecast(initialWeatherForecast.key, initialWeatherForecast.label);
        app.selectedCities = [
          {key: initialWeatherForecast.key, label: initialWeatherForecast.label}
        ];
        app.saveSelectedCities();
        console.log('second');

      }

    }).catch(function (err) {
      // we got an error
      console.log(err);
    });

  // TODO add service worker code here

  if ('serviceWorker' in navigator) {
   navigator.serviceWorker
            .register('./service-worker.js')
            .then(function() { console.log('Service Worker Registered'); });
 }

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

(function() {
  'use strict';

  var app = {
    isLoading: true,
    visibleCards: {},
    selectedCities: [],
    spinner: document.querySelector('.loader'),
    cardTemplate: document.querySelector('.cardTemplate'),
    container: document.querySelector('.main'),
    addDialog: document.querySelector('.dialog-container'),
    daysOfWeek: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  };

  /*****************************************************************************
   *
   * localforage config
   *
   ****************************************************************************/
   localforage.config({
      // driver      : localforage.WEBSQL, // Force WebSQL; same as using setDriver()
       driver      : localforage.INDEXEDDB,
       name        : 'weatherPWA',
       version     : 1.0,
       // size        : 4980736, // Size of database, in bytes. WebSQL-only for now.
       storeName   : 'keyvalpairs', // Should be alphanumeric, with underscores.
       description : 'for saving cities we want weather forecasts for'
   });

  /*****************************************************************************
   *
   * Event listeners for UI elements
   *
   ****************************************************************************/

  document.getElementById('butRefresh').addEventListener('click', function() {
    // Refresh all of the forecasts
    app.updateForecasts();
  });

  document.getElementById('butAdd').addEventListener('click', function() {
    // Open/show the add new city dialog
    app.toggleAddDialog(true);
  });

  document.getElementById('butAddCity').addEventListener('click', function() {
    // Add the newly selected city
    var select = document.getElementById('selectCityToAdd');
    var selected = select.options[select.selectedIndex];
    var key = selected.value;
    var label = selected.textContent;

    if(!app.selectedCities) { app.selectedCities = []; }
    app.getForecast(key, label);

    app.selectedCities.push({ key: key, label: label});
    app.saveSelectedCities();

    app.toggleAddDialog(false);
  });

  document.getElementById('butAddCancel').addEventListener('click', function() {
    // Close the add new city dialog
    app.toggleAddDialog(false);
  });

  /*****************************************************************************
   *
   * Methods to update/refresh the UI
   *
   ****************************************************************************/

  // Toggles the visibility of the add new city dialog.
  app.toggleAddDialog = function(visible) {
    if (visible) {
      app.addDialog.classList.add('dialog-container--visible');
    } else {
      app.addDialog.classList.remove('dialog-container--visible');
    }
  };

  // Updates a weather card with the latest weather forecast. If the card
  // doesn't already exist, it's cloned from the template.
  app.updateForecastCard = function(data) {
    var dataLastUpdated = new Date(data.created);
    var sunrise = data.channel.astronomy.sunrise;
    var sunset = data.channel.astronomy.sunset;
    var current = data.channel.item.condition;
    var humidity = data.channel.atmosphere.humidity;
    var wind = data.channel.wind;

    var card = app.visibleCards[data.key];
    if (!card) {
      card = app.cardTemplate.cloneNode(true);
      card.classList.remove('cardTemplate');
      card.querySelector('.location').textContent = data.label;
      card.removeAttribute('hidden');
      app.container.appendChild(card);
      app.visibleCards[data.key] = card;
    }

    // Verifies the data provide is newer than what's already visible
    // on the card, if it's not bail, if it is, continue and update the
    // time saved in the card
    var cardLastUpdatedElem = card.querySelector('.card-last-updated');
    var cardLastUpdated = cardLastUpdatedElem.textContent;
    if (cardLastUpdated) {
      cardLastUpdated = new Date(cardLastUpdated);
      // Bail if the card has more recent data then the data
      if (dataLastUpdated.getTime() < cardLastUpdated.getTime()) {
        return;
      }
    }
    cardLastUpdatedElem.textContent = data.created;

    card.querySelector('.description').textContent = current.text;
    card.querySelector('.date').textContent = current.date;
    card.querySelector('.current .icon').classList.add(app.getIconClass(current.code));
    card.querySelector('.current .temperature .value').textContent =
      Math.round(current.temp);
    card.querySelector('.current .sunrise').textContent = sunrise;
    card.querySelector('.current .sunset').textContent = sunset;
    card.querySelector('.current .humidity').textContent =
      Math.round(humidity) + '%';
    card.querySelector('.current .wind .value').textContent =
      Math.round(wind.speed);
    card.querySelector('.current .wind .direction').textContent = wind.direction;
    var nextDays = card.querySelectorAll('.future .oneday');
    var today = new Date();
    today = today.getDay();
    for (var i = 0; i < 7; i++) {
      var nextDay = nextDays[i];
      var daily = data.channel.item.forecast[i];
      if (daily && nextDay) {
        nextDay.querySelector('.date').textContent =
          app.daysOfWeek[(i + today) % 7];
        nextDay.querySelector('.icon').classList.add(app.getIconClass(daily.code));
        nextDay.querySelector('.temp-high .value').textContent =
          Math.round(daily.high);
        nextDay.querySelector('.temp-low .value').textContent =
          Math.round(daily.low);
      }
    }
    if (app.isLoading) {
      app.spinner.setAttribute('hidden', true);
      app.container.removeAttribute('hidden');
      app.isLoading = false;
    }
  };

  /*****************************************************************************
   *
   * Methods for dealing with the model
   *
   ****************************************************************************/

  /*
   * Gets a forecast for a specific city and updates the card with the data.
   * getForecast() first checks if the weather data is in the cache. If so,
   * then it gets that data and populates the card with the cached data.
   * Then, getForecast() goes to the network for fresh data. If the network
   * request goes through, then the card gets updated a second time with the
   * freshest data.
   */
  app.getForecast = function(key, label) {
    var statement = 'select * from weather.forecast where woeid=' + key;
    var url = 'https://query.yahooapis.com/v1/public/yql?format=json&q=' +
        statement;

    // TODO add cache logic here

    if ('caches' in window) {
      /*
       * Check if the service worker has already cached this city's weather
       * data. If the service worker has the data, then display the cached
       * data while the app fetches the latest data.
       */
      caches.match(url).then(function(response) {
        if (response) {
          response.json().then(function updateFromCache(json) {
            var results = json.query.results;
            results.key = key;
            results.label = label;
            results.created = json.query.created;
            app.updateForecastCard(results);
          });
        }
      });
    }

    // Fetch the latest data.
    var request = new XMLHttpRequest();
    request.onreadystatechange = function() {
      if (request.readyState === XMLHttpRequest.DONE) {
        if (request.status === 200) {
          var response = JSON.parse(request.response);
          var results = response.query.results;
          results.key = key;
          results.label = label;
          results.created = response.query.created;
          app.updateForecastCard(results);
        }
      } else {
        // Return the initial weather forecast since no data is available.
        app.updateForecastCard(initialWeatherForecast);
      }
    };
    request.open('GET', url);
    request.send();
  };

  // Iterate all of the cards and attempt to get the latest forecast data
  app.updateForecasts = function() {
    var keys = Object.keys(app.visibleCards);
    keys.forEach(function(key) {
      app.getForecast(key);
    });
  };

  // TODO add saveSelectedCities function here
  app.saveSelectedCities = function(){
    //var selectedCities = JSON.stringify(app.selectedCities);
    //localStorage.selectedCities = selectedCities;

    /* Extra Credit: Replace localStorage implementation with localForage
    *
    * future TODO: use idb-keyval (or just idb) instead because its
    * smaller for our simple purpose of just storing key value pairs
    *
        idbKeyval.set('selectedCities', app.selectedCities)
          .then(() => console.log('Saved selected cities'))
          .catch(err => console.log('Failed to save selected cities; ', err));
        };
    */

    localforage.setItem('selectedCities', app.selectedCities).then(function () {
      return localforage.getItem('selectedCities');
    }).then(function(value){
      console.log('cities saved');
    }).catch(function (err) {
      console.log(err);
    });

  };

  app.getIconClass = function(weatherCode) {
    // Weather codes: https://developer.yahoo.com/weather/documentation.html#codes
    weatherCode = parseInt(weatherCode);
    switch (weatherCode) {
      case 25: // cold
      case 32: // sunny
      case 33: // fair (night)
      case 34: // fair (day)
      case 36: // hot
      case 3200: // not available
        return 'clear-day';
      case 0: // tornado
      case 1: // tropical storm
      case 2: // hurricane
      case 6: // mixed rain and sleet
      case 8: // freezing drizzle
      case 9: // drizzle
      case 10: // freezing rain
      case 11: // showers
      case 12: // showers
      case 17: // hail
      case 35: // mixed rain and hail
      case 40: // scattered showers
        return 'rain';
      case 3: // severe thunderstorms
      case 4: // thunderstorms
      case 37: // isolated thunderstorms
      case 38: // scattered thunderstorms
      case 39: // scattered thunderstorms (not a typo)
      case 45: // thundershowers
      case 47: // isolated thundershowers
        return 'thunderstorms';
      case 5: // mixed rain and snow
      case 7: // mixed snow and sleet
      case 13: // snow flurries
      case 14: // light snow showers
      case 16: // snow
      case 18: // sleet
      case 41: // heavy snow
      case 42: // scattered snow showers
      case 43: // heavy snow
      case 46: // snow showers
        return 'snow';
      case 15: // blowing snow
      case 19: // dust
      case 20: // foggy
      case 21: // haze
      case 22: // smoky
        return 'fog';
      case 24: // windy
      case 23: // blustery
        return 'windy';
      case 26: // cloudy
      case 27: // mostly cloudy (night)
      case 28: // mostly cloudy (day)
      case 31: // clear (night)
        return 'cloudy';
      case 29: // partly cloudy (night)
      case 30: // partly cloudy (day)
      case 44: // partly cloudy
        return 'partly-cloudy-day';
    }
  };

  /*
   * Fake weather data that is presented when the user first uses the app,
   * or when the user has not saved any cities. See startup code for more
   * discussion.
   */
  var initialWeatherForecast = {
    key: '2487956',
    label: 'San Francisco, CA',
    created: '2017-04-28T07:39:59Z',
    channel: {
      astronomy: {
        sunrise: "6:18 am",
        sunset: "7:57 pm"
      },
      item: {
        condition: {
          text: "Clear",
          date: "Fri, 28 Apr 2017 12:00 AM PDT",
          temp: 52,
          code: 31
        },
        forecast: [
          {code: 34, high: 66, low: 52},
          {code: 32, high: 69, low: 56},
          {code: 32, high: 69, low: 54},
          {code: 32, high: 71, low: 54},
          {code: 30, high: 73, low: 57},
          {code: 34, high: 73, low: 60},
          {code: 30, high: 67, low: 58}
        ]
      },
      atmosphere: {
        humidity: 78
      },
      wind: {
        speed: 22,
        direction: 310
      }
    }
  };
  // TODO uncomment line below to test app with fake data
  // app.updateForecastCard(initialWeatherForecast);

  // TODO add startup code here

  /************************************************************************
     *
     * Code required to start the app
     *
     * NOTE: To simplify this codelab, we've used localStorage.
     *   localStorage is a synchronous API and has serious performance
     *   implications. It should not be used in production applications!
     *   Instead, check out IDB (https://www.npmjs.com/package/idb) or
     *   SimpleDB (https://gist.github.com/inexorabletash/c8069c042b734519680c)
     ************************************************************************/

     function locationSuccess(pos) {

       var statement = 'select * FROM geo.places WHERE text="('
       statement += pos.coords.latitude + ', ' + pos.coords.longitude + ')"';

       var url = 'https://query.yahooapis.com/v1/public/yql?format=json&q=' +
           statement;

      var request = new XMLHttpRequest();
      request.onreadystatechange = function() {
        if (request.readyState === XMLHttpRequest.DONE) {
          if (request.status === 200) {
            //console.log(request.response);
            var response = JSON.parse(request.response);
            var results = response.query.results;
            var key = results.place.locality1.woeid;
            var label = results.place.locality1.content + ', ';

            app.getForecast(key, label);
            app.selectedCities = [
              {key: key, label: label}
            ];
            app.saveSelectedCities();
            console.log('first');
            checkForSavedCities();
            //app.updateForecastCard(results);
          }
        } else {
          // Return the initial weather forecast since no data is available.
          app.updateForecastCard(initialWeatherForecast);
        }
      };

       request.open('GET', url);
       request.send();
     }

     if ("geolocation" in navigator) {
       /* geolocation is available */
       console.log('geolocation was here!');
       navigator.geolocation.getCurrentPosition(locationSuccess);
     } else {
       /* geolocation IS NOT available */
       console.log('geolocation is not available');
     }

function checkForSavedCities(){
    //app.selectedCities = localStorage.selectedCities
    localforage.getItem('selectedCities').then(function (vals) {
      // we got our value
      app.selectedCities = vals;
      if (app.selectedCities) {
        //app.selectedCities = JSON.parse(app.selectedCities);
        app.selectedCities.forEach(function(city) {
          //console.log(city);
          app.getForecast(city.key, city.label);
        });
      } else {
        /* The user is using the app for the first time, or the user has not
         * saved any cities, so show the user some fake data. A real app in this
         * scenario could guess the user's location via IP lookup and then inject
         * that data into the page.
         */

        //app.updateForecastCard(initialWeatherForecast);
        // forget using fake data, lets just use the fake datas woeid (key)
        // and label to get an updated forecast instead.

        // TODO get the user's geolocation if they allow

        // if they don't, lets get lat and long using just ip

        // then once we have lat/long, we can query

        app.getForecast(initialWeatherForecast.key, initialWeatherForecast.label);
        app.selectedCities = [
          {key: initialWeatherForecast.key, label: initialWeatherForecast.label}
        ];
        app.saveSelectedCities();
        console.log('second');

      }

    }).catch(function (err) {
      // we got an error
      console.log(err);
    });
}

  // TODO add service worker code here

  if ('serviceWorker' in navigator) {
   navigator.serviceWorker
            .register('./service-worker.js')
            .then(function() { console.log('Service Worker Registered'); });
 }

})();
<|endoftext|>


<commit_before>var connect = require('connect');
var serveStatic = require('serve-static');

var app = connect();
app.use(serveStatic("C:/Users/Michael/Documents/TreeHouse/jQueryBasics/passwordConfirmationForm"));
app.listen(5100);
<commit_msg>Delete webserver.js<commit_after><|endoftext|>


<commit_before>var concat     = require('broccoli-sourcemap-concat');
var Funnel     = require('broccoli-funnel');
var mergeTrees = require('broccoli-merge-trees');
var compileES6Modules = require('broccoli-es6modules');
var transpileES6 = require('broccoli-babel-transpiler');
var jshintTree = require('broccoli-jshint');
var replace    = require('broccoli-string-replace');
var gitVersion = require('git-repo-version');
var browserify = require('broccoli-browserify');
var writeFile = require('broccoli-file-creator');
var jscs = require('broccoli-jscs');

// extract version from git
// note: remove leading `v` (since by default our tags use a `v` prefix)
var version = gitVersion().replace(/^v/, '');

var packages = [
  {
    name: 'orbit-rethinkdb',
    include: [/orbit-rethinkdb\/.*.js/]
  }
];

var loader = new Funnel('bower_components', {
  srcDir: 'loader',
  files: ['loader.js'],
  destDir: '/assets/'
});

var globalizedLoader = new Funnel('build-support', {
  srcDir: '/',
  files: ['globalized-loader.js'],
  destDir: '/assets/'
});

var generatedBowerConfig = new Funnel('build-support', {
  srcDir: '/',
  destDir: '/',
  files: ['bower.json']
});

generatedBowerConfig = replace(generatedBowerConfig, {
  files: ['bower.json'],
  pattern: {
    match: /VERSION_PLACEHOLDER/,
    replacement: function() {
      return version;
    }
  }
});

var tests = new Funnel('test', {
  srcDir: '/tests',
  include: [/.js$/],
  destDir: '/tests'
});

var buildExtras = new Funnel('build-support', {
  srcDir: '/',
  destDir: '/',
  files: ['README.md', 'LICENSE']
});

var lib = {};
var main = {};
var globalized = {};

packages.forEach(function(package) {
  lib[package.name] = new Funnel('lib', {
    srcDir: '/',
    include: package.include,
    exclude: package.exclude || [],
    destDir: '/'
  });

  main[package.name] = mergeTrees([ lib[package.name] ]);
  main[package.name] = jscs(main[package.name], {
    esnext: true,
    enabled: true
  });
  main[package.name] = new compileES6Modules(main[package.name]);
  main[package.name] = new transpileES6(main[package.name]);
  main[package.name] = concat(main[package.name], {
    inputFiles: ['**/*.js'],
    outputFile: '/' + package.name + '.amd.js'
  });

  var support = new Funnel('build-support', {
    srcDir: '/',
    files: ['iife-start.js', 'globalize-' + package.name + '.js', 'iife-stop.js'],
    destDir: '/'
  });

  var loaderTree = (package.name === 'orbit' ? loader : globalizedLoader);
  var loaderFile = (package.name === 'orbit' ? 'loader.js' : 'globalized-loader.js');

  globalized[package.name] = concat(mergeTrees([loaderTree, main[package.name], support]), {
    inputFiles: ['iife-start.js', 'assets/' + loaderFile, package.name + '.amd.js', 'globalize-' + package.name + '.js', 'iife-stop.js'],
    outputFile: '/' + package.name + '.js'
  });
});

var allLib = mergeTrees(Object.keys(lib).map(function(package) {
  return lib[package];
}));
var allMain = mergeTrees(Object.keys(main).map(function(package) {
  return main[package];
}));
var allGlobalized = mergeTrees(Object.keys(globalized).map(function(package) {
  return globalized[package];
}));

var jshintLib = jshintTree(allLib);
var jshintTest = jshintTree(tests);

var jscsLib = jscs(allLib, {esnext: true, enabled: true});
var jscsTest = jscs(tests, {esnext: true, enabled: true});

var mainWithTests = mergeTrees([allLib, tests, jshintLib, jshintTest, jscsLib, jscsTest]);

mainWithTests = new compileES6Modules(mainWithTests);
mainWithTests = new transpileES6(mainWithTests);

mainWithTests = concat(mainWithTests, {
  inputFiles: ['**/*.js'],
  outputFile: '/assets/tests.amd.js'
});

mainWithTests = replace(mainWithTests, {
  files: "/assets/tests.amd.js",
  patterns: []
});

var vendor = concat('bower_components', {
  inputFiles: [
    'jquery/dist/jquery.js',
    'rsvp/rsvp.js',
    'orbit.js/orbit.amd.js',
    'orbit.js/orbit-common.amd.js',
    'rxjs/dist/rx.all.js'],
  outputFile: '/assets/vendor.js'
});

var qunit = new Funnel('bower_components', {
  srcDir: '/qunit/qunit',
  files: ['qunit.js', 'qunit.css'],
  destDir: '/assets'
});

var testSupport = concat('test', {
  inputFiles: ['../test/test-support/sinon.js', '../test/test-support/test-shims.js', '../test/test-support/test-loader.js'],
  outputFile: '/assets/test-support.js'
});

var testIndex = new Funnel('test', {
  srcDir: '/',
  files: ['index.html'],
  destDir: '/tests'
});

function generateNpmStubs(moduleNames) {
  return moduleNames.map(function(moduleName){
    return "define('npm:" +
      moduleName +
      "', function(){ return { 'default': require('" +
      moduleName +
      "')};})";
  }).join("\n");
}

var browserifyExports = writeFile('/browserify-exports.js', generateNpmStubs([
  'rethinkdb',
  'rethinkdb-websocket-client'
]));

var testNpmModules = browserify(browserifyExports, {
  entries: ['./browserify-exports.js'],
  outputFile: '/assets/test-npm-modules.js'
});

module.exports = mergeTrees([loader, globalizedLoader, allMain,
  allGlobalized, mainWithTests, vendor, qunit, testSupport, testIndex,
  generatedBowerConfig, buildExtras, testNpmModules]);
<commit_msg>Fix broccoli pipeline<commit_after>var concat     = require('broccoli-sourcemap-concat');
var Funnel     = require('broccoli-funnel');
var mergeTrees = require('broccoli-merge-trees');
var compileES6Modules = require('broccoli-es6modules');
var transpileES6 = require('broccoli-babel-transpiler');
var jshintTree = require('broccoli-jshint');
var replace    = require('broccoli-string-replace');
var gitVersion = require('git-repo-version');
var browserify = require('broccoli-browserify');
var writeFile = require('broccoli-file-creator');
var jscs = require('broccoli-jscs');

// extract version from git
// note: remove leading `v` (since by default our tags use a `v` prefix)
var version = gitVersion().replace(/^v/, '');

var packages = [
  {
    name: 'orbit-rethinkdb',
    include: [/orbit-rethinkdb\/.*.js/]
  }
];

var loader = new Funnel('bower_components', {
  srcDir: 'loader',
  files: ['loader.js'],
  destDir: '/assets/'
});

var globalizedLoader = new Funnel('build-support', {
  srcDir: '/',
  files: ['globalized-loader.js'],
  destDir: '/assets/'
});

var generatedBowerConfig = new Funnel('build-support', {
  srcDir: '/',
  destDir: '/',
  files: ['bower.json']
});

generatedBowerConfig = replace(generatedBowerConfig, {
  files: ['bower.json'],
  pattern: {
    match: /VERSION_PLACEHOLDER/,
    replacement: function() {
      return version;
    }
  }
});

var tests = new Funnel('test', {
  srcDir: '/tests',
  include: [/.js$/],
  destDir: '/tests'
});

var buildExtras = new Funnel('build-support', {
  srcDir: '/',
  destDir: '/',
  files: ['README.md', 'LICENSE']
});

var lib = {};
var main = {};
var globalized = {};

packages.forEach(function(package) {
  lib[package.name] = new Funnel('lib', {
    srcDir: '/',
    include: package.include,
    exclude: package.exclude || [],
    destDir: '/'
  });

  main[package.name] = mergeTrees([ lib[package.name] ]);
  main[package.name] = new compileES6Modules(main[package.name]);
  main[package.name] = new transpileES6(main[package.name]);
  main[package.name] = concat(main[package.name], {
    inputFiles: ['**/*.js'],
    outputFile: '/' + package.name + '.amd.js'
  });

  var support = new Funnel('build-support', {
    srcDir: '/',
    files: ['iife-start.js', 'globalize-' + package.name + '.js', 'iife-stop.js'],
    destDir: '/'
  });

  var loaderTree = (package.name === 'orbit' ? loader : globalizedLoader);
  var loaderFile = (package.name === 'orbit' ? 'loader.js' : 'globalized-loader.js');

  globalized[package.name] = concat(mergeTrees([loaderTree, main[package.name], support]), {
    inputFiles: ['iife-start.js', 'assets/' + loaderFile, package.name + '.amd.js', 'globalize-' + package.name + '.js', 'iife-stop.js'],
    outputFile: '/' + package.name + '.js'
  });
});

var allLib = mergeTrees(Object.keys(lib).map(function(package) {
  return lib[package];
}));
var allMain = mergeTrees(Object.keys(main).map(function(package) {
  return main[package];
}));
var allGlobalized = mergeTrees(Object.keys(globalized).map(function(package) {
  return globalized[package];
}));

var jshintLib = jshintTree(allLib);
var jshintTest = jshintTree(tests);

var jscsLib = jscs(allLib, {esnext: true, enabled: true});
var jscsTest = jscs(tests, {esnext: true, enabled: true});

var mainWithTests = mergeTrees([allLib, tests, jshintLib, jshintTest, jscsLib, jscsTest]);

mainWithTests = new compileES6Modules(mainWithTests);
mainWithTests = new transpileES6(mainWithTests);

mainWithTests = concat(mainWithTests, {
  inputFiles: ['**/*.js'],
  outputFile: '/assets/tests.amd.js'
});

mainWithTests = replace(mainWithTests, {
  files: "/assets/tests.amd.js",
  patterns: []
});

var vendor = concat('bower_components', {
  inputFiles: [
    'jquery/dist/jquery.js',
    'rsvp/rsvp.js',
    'orbit.js/orbit.amd.js',
    'orbit.js/orbit-common.amd.js',
    'rxjs/dist/rx.all.js'],
  outputFile: '/assets/vendor.js'
});

var qunit = new Funnel('bower_components', {
  srcDir: '/qunit/qunit',
  files: ['qunit.js', 'qunit.css'],
  destDir: '/assets'
});

var testSupport = concat('test', {
  inputFiles: ['../test/test-support/sinon.js', '../test/test-support/test-shims.js', '../test/test-support/test-loader.js'],
  outputFile: '/assets/test-support.js'
});

var testIndex = new Funnel('test', {
  srcDir: '/',
  files: ['index.html'],
  destDir: '/tests'
});

function generateNpmStubs(moduleNames) {
  return moduleNames.map(function(moduleName){
    return "define('npm:" +
      moduleName +
      "', function(){ return { 'default': require('" +
      moduleName +
      "')};})";
  }).join("\n");
}

var browserifyExports = writeFile('/browserify-exports.js', generateNpmStubs([
  'rethinkdb',
  'rethinkdb-websocket-client'
]));

var testNpmModules = browserify(browserifyExports, {
  entries: ['./browserify-exports.js'],
  outputFile: '/assets/test-npm-modules.js'
});

module.exports = mergeTrees([loader, globalizedLoader, allMain,
  allGlobalized, mainWithTests, vendor, qunit, testSupport, testIndex,
  generatedBowerConfig, buildExtras, testNpmModules]);
<|endoftext|>