<commit_before>let routes = [{
    format: 'home',
}, {
    format: 'ano/{year}',
    // params: {
    //     page: 0,
    //     per_page_num: 25
    // },
}, {
    format: 'despesa/{year}/{code}',
}, {
    format: 'pessoa/{user}',
}, {
    format: 'pedido/{protocolo}',
}, {
    format: 'texto/{text}',
}]

let parsers = {
    year: parseInt,
    page: parseInt,
    per_page_num: parseInt
}

let defaultParams = {
    _root: 'home',
    year: new Date().getFullYear().toString(),
    lang: 'pt-br',
    page: 0,
    per_page_num: 25
}

class Router {

    constructor(routes, defaultParams, parsers) {
        riot.observable(this)

        this._currentView = {}

        this._innerRouteMark = '$'
        this._hashMark = '#'
        this._hashParamMark = '/'
        this._queryMark = '?'
        this._queryParamMark = '&'
        this._queryAttrMark = '='

        this.params = defaultParams
        this.defaultParams = defaultParams
        this._oldParams = {}
        // console.log('params:', this.params)

        this.routes = {}
        // Hash routes by name
        for (let route of routes) {
            let name = route.format.split(this._hashParamMark)[0]
            // Add view name for route
            route.view = `${name}-view`
            route.mainParamsNames = this._getMainParamsNames(route.format)
            this.routes[name] = route
        }
        this.parsers = parsers
        this._allPossibleParamsNames = this._listAllPossibleParamsNames()
        this._allPossibleQueryParamsNames = this._listAllPossibleQueryParamsNames()
        this._registerViewEvents()

        // // Change url parser
        // riot.route.parser(this.urlAutoParser.bind(this))

        // Change route callback
        riot.route(this._urlChanged.bind(this))

        // Init params
        this._urlToParams()
        // this.urlAutoParser(location.hash.slice(1))
    }

    init() {
        this._paramsToUrl()
    }

    _urlChanged() {
        // Riot says url changed, make sure
        if (location.hash.slice(1) != this._currentUrl) {
            this._urlToParams()
            this._paramsToUrl()
        }
    }

    _getMainParamsNames(template) {
        let match = template.replace(/\?.*/).match(/{([^}]*)}/g);
        if (!match) match = []
        return match.map((param) => {
            return param.substring(1, param.length - 1)
        })
    }

    _applyParser(name, value) {
        let parser = this.parsers[name]
        return parser ? parser(value) : value
    }

    _registerViewEvents() {
        for (let name of this._allPossibleParamsNames) {
            // console.log('router: register for VEC:', name)

            // Accepts loads like the other stores, even if
            // params could be accessed by getParam
            this.on(riot.VEL(name), () => {
                this.trigger(riot.SEC(name), this.getParam(name))
            })

            this.on(riot.VEC(name), (value) => {
                console.log('router:VEC name:', name, 'value:', value)
                this.params[name] = this._applyParser(name, value)
                this._paramsToUrl()
            })
        }
    }

    // Returns all the possible params names (main params or query)
    _listAllPossibleParamsNames() {
        return new Set(Object.keys(this.routes)
            .map(k => this.routes[k].mainParamsNames)
            .reduce((prev, cur) => prev.concat(cur),
                    Object.keys(this.defaultParams))).values()
    }

    // Returns all the possible query params names
    _listAllPossibleQueryParamsNames() {
        let mainParamsNames = Object.keys(this.routes)
            .reduce(
                (prev, k) => prev.concat(this.routes[k].mainParamsNames),
                ['_root']
            )
        return Object.keys(this.defaultParams)
            .filter((el) => mainParamsNames.indexOf(el) == -1)
    }

    // buildRoute() {
    //     let hash = [].slice.apply(arguments).join('/')// + query
    //     return this._hashMark + hash + this._innerRouteMark
    // }

    loadView(viewName) {
        if (this._currentView.root) {
            this._currentView.root.unmount(true)
        }
        this._currentView = {
            name: viewName,
            root: riot.mount('div#mainview', viewName, this.params)[0],
        }
    }

    getParam(name) {
        // console.log('getParams-name:', name, 'params:', this.params, 'this', this)
        return this.params[name]
    }

    getDefaultParam(name) {
        return this.defaultParams[name]
    }

    _urlToParams() {
        // TODO: Quando não acha a rota está indo para default,
        // será que não deveria mostrar 404?

        let hash = location.hash.slice(1),
            params = {_root: this.defaultParams._root}

        if (hash) {
            params = this.parseHash(hash)
        }

        let rootData = this.routes[this.params._root]

        // Get defaults + parsed
        this.params = Object.assign({}, this.defaultParams,
                                    rootData.params, params)
    }

    // Parse the params present in a hash
    parseHash(hash) {
        let raw = hash.split(this._queryMark),
            paths = raw[0].split(this._hashParamMark),
            query = raw[1],
            params = this._mainParamsToObj(paths)

        if (query) {
            for (let pair of query.split(this._queryParamMark)) {
                pair = pair.split(this._queryAttrMark)
                params[pair[0]] = pair[1]
            }
        }
        // console.log('router:parseHash - hash:', hash, 'params:', params)
        for (let name in params) {
            params[name] = this._applyParser(name, params[name])
        }

        return params
    }

    _paramsToUrl() {
        // console.log('router:paramsToUrl')
        // Loads new view if different from current
        let newViewName = this.routes[this.params._root].view
        if (newViewName != this._currentView.name)
            this.loadView(newViewName)

        this._broadcastParams()

        // Changes the urlif different from current
        this._currentUrl = this._createUrl()
        if (location.hash.slice(1) != this._currentUrl)
            location.hash = this._currentUrl
    }

    _mainParamsToObj(mainParamsValues) {
        let _root = mainParamsValues.shift(),
            names = this.routes[_root].mainParamsNames,
            obj = {_root}
        for (let i in mainParamsValues) {
            obj[names[i]] = mainParamsValues[i]
        }
        return obj
    }

    // Possibilities:
    // 'root id1 id2' {id3=id3, q1=q1}
    // {root=root, id1=id1}
    // {id2=id2}
    route(param1, params2) {
        let roots = null,
            root = null,
            params = {}

        // If the param1 is a string of route parts repared with ' '
        if (param1 && typeof param1 === 'string') {
            roots = param1.split(' ')
            params = this._mainParamsToObj(roots)
            if (params2) Object.assign(params, params2)
        } else {
            // param1 is an Obj, there is no param2
            params = param1
        }

        // Update params
        for (let name in params)
            this.params[name] = this._applyParser(name, params[name])

        this._paramsToUrl()
    }

    // Start default view
    routeDefault() {
        this.route(this._defaultRoute)
    }

    _createUrl() {
        let rootData = this.routes[this.params._root],
            url = rootData.format
        // Replace main params to str
        for (let name of rootData.mainParamsNames) {
            url = url.replace('{' + name + '}', this.params[name])
        }
        // Add query params if needed
        let nonDefault = []
        for (let name of this._allPossibleQueryParamsNames) {
            if (this.params[name] != this.defaultParams[name])
                nonDefault.push(name + this._queryAttrMark + this.params[name])
        }
        if (nonDefault.length) {
            url += this._queryMark + nonDefault.join(this._queryParamMark)
        }
        return url
    }

    _broadcastParams() {
        // Detect params changes
        let diff = []
        for (let name in this.params) {
            if (this._oldParams[name] != this.params[name]) {
                this._oldParams[name] = this.params[name]
                diff.push(name)
            }
        }

        // Broadcast params that changed
        for (let name of diff) {
            // console.log("router:broadcast:", name)
            this.trigger(riot.SEC(name), this.params[name])
        }
    }
}

let instance = new Router(routes, defaultParams, parsers)
riot.control.addStore(instance)
export default instance
<commit_msg>avoid using Set that would require more polyfills...<commit_after>let routes = [{
    format: 'home',
}, {
    format: 'ano/{year}',
    // params: {
    //     page: 0,
    //     per_page_num: 25
    // },
}, {
    format: 'despesa/{year}/{code}',
}, {
    format: 'pessoa/{user}',
}, {
    format: 'pedido/{protocolo}',
}, {
    format: 'texto/{text}',
}]

let parsers = {
    year: parseInt,
    page: parseInt,
    per_page_num: parseInt
}

let defaultParams = {
    _root: 'home',
    year: new Date().getFullYear().toString(),
    lang: 'pt-br',
    page: 0,
    per_page_num: 25
}

class Router {

    constructor(routes, defaultParams, parsers) {
        riot.observable(this)

        this._currentView = {}

        this._innerRouteMark = '$'
        this._hashMark = '#'
        this._hashParamMark = '/'
        this._queryMark = '?'
        this._queryParamMark = '&'
        this._queryAttrMark = '='

        this.params = defaultParams
        this.defaultParams = defaultParams
        this._oldParams = {}
        // console.log('params:', this.params)

        this.routes = {}
        // Hash routes by name
        for (let route of routes) {
            let name = route.format.split(this._hashParamMark)[0]
            // Add view name for route
            route.view = `${name}-view`
            route.mainParamsNames = this._getMainParamsNames(route.format)
            this.routes[name] = route
        }
        this.parsers = parsers
        this._allPossibleParamsNames = this._listAllPossibleParamsNames()
        this._allPossibleQueryParamsNames = this._listAllPossibleQueryParamsNames()
        this._registerViewEvents()

        // // Change url parser
        // riot.route.parser(this.urlAutoParser.bind(this))

        // Change route callback
        riot.route(this._urlChanged.bind(this))

        // Init params
        this._urlToParams()
        // this.urlAutoParser(location.hash.slice(1))
    }

    init() {
        this._paramsToUrl()
    }

    _urlChanged() {
        // Riot says url changed, make sure
        if (location.hash.slice(1) != this._currentUrl) {
            this._urlToParams()
            this._paramsToUrl()
        }
    }

    _getMainParamsNames(template) {
        let match = template.replace(/\?.*/).match(/{([^}]*)}/g);
        if (!match) match = []
        return match.map((param) => {
            return param.substring(1, param.length - 1)
        })
    }

    _applyParser(name, value) {
        let parser = this.parsers[name]
        return parser ? parser(value) : value
    }

    _registerViewEvents() {
        for (let name of this._allPossibleParamsNames) {
            // console.log('router: register for VEC:', name)

            // Accepts loads like the other stores, even if
            // params could be accessed by getParam
            this.on(riot.VEL(name), () => {
                this.trigger(riot.SEC(name), this.getParam(name))
            })

            this.on(riot.VEC(name), (value) => {
                console.log('router:VEC name:', name, 'value:', value)
                this.params[name] = this._applyParser(name, value)
                this._paramsToUrl()
            })
        }
    }

    // Returns all the possible params names (main params or query)
    _listAllPossibleParamsNames() {
        return Object.keys(this.routes)
            .map(k => this.routes[k].mainParamsNames)
            .reduce((prev, cur) => prev.concat(cur),
                    Object.keys(this.defaultParams))
            .filter((item, pos, self) =>
                    self.indexOf(item) == pos)
    }

    // Returns all the possible query params names
    _listAllPossibleQueryParamsNames() {
        let mainParamsNames = Object.keys(this.routes)
            .reduce(
                (prev, k) => prev.concat(this.routes[k].mainParamsNames),
                ['_root']
            )
        return Object.keys(this.defaultParams)
            .filter((el) => mainParamsNames.indexOf(el) == -1)
    }

    // buildRoute() {
    //     let hash = [].slice.apply(arguments).join('/')// + query
    //     return this._hashMark + hash + this._innerRouteMark
    // }

    loadView(viewName) {
        if (this._currentView.root) {
            this._currentView.root.unmount(true)
        }
        this._currentView = {
            name: viewName,
            root: riot.mount('div#mainview', viewName, this.params)[0],
        }
    }

    getParam(name) {
        // console.log('getParams-name:', name, 'params:', this.params, 'this', this)
        return this.params[name]
    }

    getDefaultParam(name) {
        return this.defaultParams[name]
    }

    _urlToParams() {
        // TODO: Quando não acha a rota está indo para default,
        // será que não deveria mostrar 404?

        let hash = location.hash.slice(1),
            params = {_root: this.defaultParams._root}

        if (hash) {
            params = this.parseHash(hash)
        }

        let rootData = this.routes[this.params._root]

        // Get defaults + parsed
        this.params = Object.assign({}, this.defaultParams,
                                    rootData.params, params)
    }

    // Parse the params present in a hash
    parseHash(hash) {
        let raw = hash.split(this._queryMark),
            paths = raw[0].split(this._hashParamMark),
            query = raw[1],
            params = this._mainParamsToObj(paths)

        if (query) {
            for (let pair of query.split(this._queryParamMark)) {
                pair = pair.split(this._queryAttrMark)
                params[pair[0]] = pair[1]
            }
        }
        // console.log('router:parseHash - hash:', hash, 'params:', params)
        for (let name in params) {
            params[name] = this._applyParser(name, params[name])
        }

        return params
    }

    _paramsToUrl() {
        // console.log('router:paramsToUrl')
        // Loads new view if different from current
        let newViewName = this.routes[this.params._root].view
        if (newViewName != this._currentView.name)
            this.loadView(newViewName)

        this._broadcastParams()

        // Changes the urlif different from current
        this._currentUrl = this._createUrl()
        if (location.hash.slice(1) != this._currentUrl)
            location.hash = this._currentUrl
    }

    _mainParamsToObj(mainParamsValues) {
        let _root = mainParamsValues.shift(),
            names = this.routes[_root].mainParamsNames,
            obj = {_root}
        for (let i in mainParamsValues) {
            obj[names[i]] = mainParamsValues[i]
        }
        return obj
    }

    // Possibilities:
    // 'root id1 id2' {id3=id3, q1=q1}
    // {root=root, id1=id1}
    // {id2=id2}
    route(param1, params2) {
        let roots = null,
            root = null,
            params = {}

        // If the param1 is a string of route parts repared with ' '
        if (param1 && typeof param1 === 'string') {
            roots = param1.split(' ')
            params = this._mainParamsToObj(roots)
            if (params2) Object.assign(params, params2)
        } else {
            // param1 is an Obj, there is no param2
            params = param1
        }

        // Update params
        for (let name in params)
            this.params[name] = this._applyParser(name, params[name])

        this._paramsToUrl()
    }

    // Start default view
    routeDefault() {
        this.route(this._defaultRoute)
    }

    _createUrl() {
        let rootData = this.routes[this.params._root],
            url = rootData.format
        // Replace main params to str
        for (let name of rootData.mainParamsNames) {
            url = url.replace('{' + name + '}', this.params[name])
        }
        // Add query params if needed
        let nonDefault = []
        for (let name of this._allPossibleQueryParamsNames) {
            if (this.params[name] != this.defaultParams[name])
                nonDefault.push(name + this._queryAttrMark + this.params[name])
        }
        if (nonDefault.length) {
            url += this._queryMark + nonDefault.join(this._queryParamMark)
        }
        return url
    }

    _broadcastParams() {
        // Detect params changes
        let diff = []
        for (let name in this.params) {
            if (this._oldParams[name] != this.params[name]) {
                this._oldParams[name] = this.params[name]
                diff.push(name)
            }
        }

        // Broadcast params that changed
        for (let name of diff) {
            // console.log("router:broadcast:", name)
            this.trigger(riot.SEC(name), this.params[name])
        }
    }
}

let instance = new Router(routes, defaultParams, parsers)
riot.control.addStore(instance)
export default instance
<|endoftext|>


<commit_before>var gui = require('nw.gui');
var win = gui.Window.get();

var manifest = require('./package.json');
var platform = require('./components/platform');
var updater = require('./components/updater');
var menus = require('./components/menus');
var themer = require('./components/themer');
var settings = require('./components/settings');
var windowBehaviour = require('./components/window-behaviour');
var notification = require('./components/notification');

// Ensure there's an app shortcut for toast notifications to work on Windows
if (platform.isWindows) {
  gui.App.createShortcut(process.env.APPDATA + "\\Microsoft\\Windows\\Start Menu\\Programs\\Messenger.lnk");
}

// Run as menu bar app
if (settings.asMenuBarApp) {
  win.setShowInTaskbar(false);
  menus.loadTrayIcon(win);
}

// Window state
windowBehaviour.restoreWindowState(win);
windowBehaviour.bindWindowStateEvents(win);

// Check for update
updater.checkAndPrompt(manifest, win);

// Load the app menus
menus.loadMenuBar(win)
if (platform.isWindows) {
  menus.loadTrayIcon(win);
}

// Adjust the default behaviour of the main window
windowBehaviour.set(win);
windowBehaviour.setNewWinPolicy(win);
windowBehaviour.closeWithEscKey(win, doc); // doesn't seem to work

// Inject logic into the app when it's loaded
var iframe = document.querySelector('iframe');
iframe.onload = function() {
  // Hide the loader
  iframe.classList.remove('fade');
  document.querySelector('.loader').remove();

  // Load the theming module
  themer.apply(iframe.contentDocument);

  // Inject a callback in the notification API
  notification.inject(iframe.contentWindow, win);

  // Add a context menu
  menus.injectContextMenu(win, iframe.contentWindow, iframe.contentDocument);

  // Bind native events to the content window
  windowBehaviour.bindEvents(win, iframe.contentWindow);

  // Watch the iframe periodically to sync the title
  windowBehaviour.syncTitle(document, iframe.contentDocument);

  // Watch the iframe periodically to sync the badge
  windowBehaviour.syncBadge(win, document);
};
<commit_msg>Fixes typo<commit_after>var gui = require('nw.gui');
var win = gui.Window.get();

var manifest = require('./package.json');
var platform = require('./components/platform');
var updater = require('./components/updater');
var menus = require('./components/menus');
var themer = require('./components/themer');
var settings = require('./components/settings');
var windowBehaviour = require('./components/window-behaviour');
var notification = require('./components/notification');

// Ensure there's an app shortcut for toast notifications to work on Windows
if (platform.isWindows) {
  gui.App.createShortcut(process.env.APPDATA + "\\Microsoft\\Windows\\Start Menu\\Programs\\Messenger.lnk");
}

// Run as menu bar app
if (settings.asMenuBarApp) {
  win.setShowInTaskbar(false);
  menus.loadTrayIcon(win);
}

// Window state
windowBehaviour.restoreWindowState(win);
windowBehaviour.bindWindowStateEvents(win);

// Check for update
updater.checkAndPrompt(manifest, win);

// Load the app menus
menus.loadMenuBar(win)
if (platform.isWindows) {
  menus.loadTrayIcon(win);
}

// Adjust the default behaviour of the main window
windowBehaviour.set(win);
windowBehaviour.setNewWinPolicy(win);
windowBehaviour.closeWithEscKey(win, document); // doesn't seem to work

// Inject logic into the app when it's loaded
var iframe = document.querySelector('iframe');
iframe.onload = function() {
  // Hide the loader
  iframe.classList.remove('fade');
  document.querySelector('.loader').remove();

  // Load the theming module
  themer.apply(iframe.contentDocument);

  // Inject a callback in the notification API
  notification.inject(iframe.contentWindow, win);

  // Add a context menu
  menus.injectContextMenu(win, iframe.contentWindow, iframe.contentDocument);

  // Bind native events to the content window
  windowBehaviour.bindEvents(win, iframe.contentWindow);

  // Watch the iframe periodically to sync the title
  windowBehaviour.syncTitle(document, iframe.contentDocument);

  // Watch the iframe periodically to sync the badge
  windowBehaviour.syncBadge(win, document);
};
<|endoftext|>


<commit_before>import React from 'react'
import ReactDOM from 'react-dom'

import 'bootstrap/dist/css/bootstrap.css'
import './app.css'

import App from 'containers/App/App'

import {hashHistory} from 'react-router'
import makeRoutes from './routes'

const routes = makeRoutes()

const mountNode = document.querySelector('#root');
ReactDOM.render(
  <App history={hashHistory}
        routes={routes} />,
mountNode);
<commit_msg>because we're not worrying about deploying.<commit_after>import React from 'react'
import ReactDOM from 'react-dom'

import 'bootstrap/dist/css/bootstrap.css'
import './app.css'

import App from 'containers/App/App'

import {browserHistory} from 'react-router'
import makeRoutes from './routes'

const routes = makeRoutes()

const mountNode = document.querySelector('#root');
ReactDOM.render(
  <App history={browserHistory}
        routes={routes} />,
mountNode);
<|endoftext|>


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

    var appStoreURLs = {
        'gb': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_de&fallback=https%3A%2F%2Fitunes.apple.com%2Fgb%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'au': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_de&fallback=https%3A%2F%2Fitunes.apple.com%2Fau%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'fr': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_fr&fallback=https%3A%2F%2Fitunes.apple.com%2Ffr%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'it': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_it&fallback=https%3A%2F%2Fitunes.apple.com%2Fit%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'de': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_de&fallback=https%3A%2F%2Fitunes.apple.com%2Fde%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'ru': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_de&fallback=https%3A%2F%2Fitunes.apple.com%2Fru%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'br': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_de&fallback=https%3A%2F%2Fitunes.apple.com%2Fbr%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'pl': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_de&fallback=https%3A%2F%2Fitunes.apple.com%2Fpl%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'es': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_de&fallback=https%3A%2F%2Fitunes.apple.com%2Fes%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'cn': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_de&fallback=https%3A%2F%2Fitunes.apple.com%2Fcn%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'in': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_de&fallback=https%3A%2F%2Fitunes.apple.com%2Fin%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'mx': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_de&fallback=https%3A%2F%2Fitunes.apple.com%2Fmx%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'id': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_de&fallback=https%3A%2F%2Fitunes.apple.com%2Fid%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'jp': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_de&fallback=https%3A%2F%2Fitunes.apple.com%2Fjp%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8'
    };

    var form = new Mozilla.SendToDevice();

    form.geoCallback = function(countryCode) {
        // only take action on non-us country codes
        if (countryCode && countryCode !== 'us') {
            // make sure the user's countryCode is in our list
            if (appStoreURLs.hasOwnProperty(countryCode)) {
                $('#appStoreLink').attr('href', appStoreURLs[countryCode]);
            }
        }
    };

    form.init();
})(window.jQuery);
<commit_msg>[fix bug 1299336] Update App Store links on mobile download desktop page<commit_after>(function($) {
    'use strict';

    var appStoreURLs = {
        'au': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_au&fallback=https%3A%2F%2Fitunes.apple.com%2Fau%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'br': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_br&fallback=https%3A%2F%2Fitunes.apple.com%2Fbr%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'cn': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_cn&fallback=https%3A%2F%2Fitunes.apple.com%2Fcn%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'de': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_de&fallback=https%3A%2F%2Fitunes.apple.com%2Fde%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'es': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_es&fallback=https%3A%2F%2Fitunes.apple.com%2Fes%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'fr': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_fr&fallback=https%3A%2F%2Fitunes.apple.com%2Ffr%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'gb': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_gb&fallback=https%3A%2F%2Fitunes.apple.com%2Fgb%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'id': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_id&fallback=https%3A%2F%2Fitunes.apple.com%2Fid%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'in': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_in&fallback=https%3A%2F%2Fitunes.apple.com%2Fin%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'it': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_it&fallback=https%3A%2F%2Fitunes.apple.com%2Fit%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'jp': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_jp&fallback=https%3A%2F%2Fitunes.apple.com%2Fjp%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'mx': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_mx&fallback=https%3A%2F%2Fitunes.apple.com%2Fmx%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'pl': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_pl&fallback=https%3A%2F%2Fitunes.apple.com%2Fpl%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8',
        'ru': 'https://app.adjust.com/2uo1qc?campaign=Heartbeat&adgroup=iOS_App_Store&creative=badge_ru&fallback=https%3A%2F%2Fitunes.apple.com%2Fru%2Fapp%2Fapple-store%2Fid989804926%3Fpt%3D373246%26ct%3Dadjust_tracker%26mt%3D8'
    };

    var form = new Mozilla.SendToDevice();

    form.geoCallback = function(countryCode) {
        // only take action on non-us country codes
        if (countryCode && countryCode !== 'us') {
            // make sure the user's countryCode is in our list
            if (appStoreURLs.hasOwnProperty(countryCode)) {
                $('#appStoreLink').attr('href', appStoreURLs[countryCode]);
            }
        }
    };

    form.init();
})(window.jQuery);
<|endoftext|>


<commit_before>/**
 * .reel Unit Tests
 */
(function($){

  module('Computation', { teardown: function teardown(){
    $('.jquery-reel').trigger('teardown');
  }});

  asyncTest( '`fractionChange` accepts and normalizes any real fraction passed', function(){
    expect(10);
    var
      selector= '#image',
      $reel= $(selector).reel(),
      entries= {
        '3': 0,
        '-2.1': 0.9,
        '-3.7': 0.3,
        '1.8': 0.8,
        '3.4': 0.4,
        '3.5': 0.5,
        '-0.3': 0.7,
        '1.23456': 0.2346,
        '-1.23456': 0.7654,
        '-1.2': 0.8
      }
    $reel.one('loaded', function(){
      $.each(entries, function(ix,it){
        $reel.trigger('fractionChange', Number(ix));
        equal( $reel.data('fraction').toFixed(4), it, 'Passed '+ix);
      });
      start();
    });
  });

  asyncTest( '`rowChange` accepts and normalizes any real row fraction passed', function(){
    expect(7);
    var
      selector= '#image',
      $reel= $(selector).reel({ rows: 3 }),
      entries= {
        '4': 1,
        '-2.1': 0,
        '1.8': 0.4,
        '0.4': 0,
        '-0.3': 0,
        '1.23456': 0.1173,
        '-1.23456': 0
      }
    $reel.one('loaded', function(){
      $.each(entries, function(ix,it){
        $reel.trigger('rowChange', Number(ix));
        equal( $reel.data('row').toFixed(4), it, 'Fraction '+ix);
      });
      start();
    });
  });

  asyncTest( 'Positive direction/spped is not detected as reversed', function(){
    expect(1);
    var
      selector= '#image',
      $reel= $(selector).reel({ speed: 1 })

    equal( $reel.data('backwards'), false, 'Not reversed at positive speed');
    start();
  });

  asyncTest( 'Negative direction/spped is detected as reversed', function(){
    expect(1);
    var
      selector= '#image',
      $reel= $(selector).reel({ speed: -1 })

    equal( $reel.data('backwards'), true, 'Reversed at negative speeds');
    start();
  });

  test( 'Default `$.reel.math.spread`', function(){
    expect(11);
    var
      probes= {
        10: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10],
            frames: 10,
            frame: 1
          },
          ordered: '1,6,4,9,2,7,5,10,3,8'.split(/, ?/)
        },
        12: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12],
            frames: 12,
            frame: 1
          },
          ordered: '1,7,4,10,3,9,6,12,2,8,5,11'.split(/, ?/)
        },
        15: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],
            frames: 15,
            frame: 1
          },
          ordered: '1,9,5,13,3,11,7,15,2,10,6,14,4,12,8'.split(/, ?/)
        },
        18: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],
            frames: 18,
            frame: 1
          },
          ordered: '1,10,6,15,3,12,8,17,2,11,7,16,4,13,9,18,5,14'.split(/, ?/)
        },
        24: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],
            frames: 24,
            frame: 1
          },
          ordered: '1,13, 7,19, 4,16,10,22, 3,15,9,21,6,18,12,24, 2,14,8,20,5,17,11,23'.split(/, ?/)
        },
        36: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],
            frames: 36,
            frame: 1
          },
          ordered: '1,19, 10,28, 6,24,15,33, 3,21,12,30,8,26,17,35, 2,20,11,29,7,25,16,34,4,22,13,31,9,27,18,36, 5,23,14,32'.split(/, ?/)
        },
        48: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],
            frames: 48,
            frame: 1
          },
          ordered: '1,25, 13,37, 7,31,19,43, 4,28,16,40,10,34,22,46, 3,27,15,39,9,33,21,45,6,30,18,42,12,36,24,48, 2,26,14,38,8,32,20,44,5,29,17,41,11,35,23,47'.split(/, ?/)
        },

        // Atypicals with different starting points
        17: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],
            frames: 17,
            frame: 7
          },
          ordered: '7,16, 11,3, 9,1,13,5, 8,17,12,4,10,2,14,6, 15'.split(/, ?/)
        },
        23: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23],
            frames: 23,
            frame: 11
          },
          ordered: '11,23, 17,6, 14,3,20,9, 12,1,18,7,15,4,21,10, 13,2,19,8,16,5,22'.split(/, ?/)
        },
        27: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27],
            frames: 27,
            frame: 27
          },
          ordered: '27,14, 7,21, 3,17,10,24, 2,16,9,23,5,19,12,26, 1,15,8,22,4,18,11,25,6,20,13'.split(/, ?/)
        }
      }

    ok( typeof $.reel.math.spread == 'function', '`$.reel.math.spread` available');

    $.each(probes, function(ix, def){
      var
        $reel= $('#image').reel(def.options)
      deepEqual( $reel.data('images'), def.ordered, ix+' frames starting at frame '+def.options.frame);
    });

  });

})(jQuery);
<commit_msg>Adding multi-row and dual-orbit test cases. #10<commit_after>/**
 * .reel Unit Tests
 */
(function($){

  module('Computation', { teardown: function teardown(){
    $('.jquery-reel').trigger('teardown');
  }});

  asyncTest( '`fractionChange` accepts and normalizes any real fraction passed', function(){
    expect(10);
    var
      selector= '#image',
      $reel= $(selector).reel(),
      entries= {
        '3': 0,
        '-2.1': 0.9,
        '-3.7': 0.3,
        '1.8': 0.8,
        '3.4': 0.4,
        '3.5': 0.5,
        '-0.3': 0.7,
        '1.23456': 0.2346,
        '-1.23456': 0.7654,
        '-1.2': 0.8
      }
    $reel.one('loaded', function(){
      $.each(entries, function(ix,it){
        $reel.trigger('fractionChange', Number(ix));
        equal( $reel.data('fraction').toFixed(4), it, 'Passed '+ix);
      });
      start();
    });
  });

  asyncTest( '`rowChange` accepts and normalizes any real row fraction passed', function(){
    expect(7);
    var
      selector= '#image',
      $reel= $(selector).reel({ rows: 3 }),
      entries= {
        '4': 1,
        '-2.1': 0,
        '1.8': 0.4,
        '0.4': 0,
        '-0.3': 0,
        '1.23456': 0.1173,
        '-1.23456': 0
      }
    $reel.one('loaded', function(){
      $.each(entries, function(ix,it){
        $reel.trigger('rowChange', Number(ix));
        equal( $reel.data('row').toFixed(4), it, 'Fraction '+ix);
      });
      start();
    });
  });

  asyncTest( 'Positive direction/spped is not detected as reversed', function(){
    expect(1);
    var
      selector= '#image',
      $reel= $(selector).reel({ speed: 1 })

    equal( $reel.data('backwards'), false, 'Not reversed at positive speed');
    start();
  });

  asyncTest( 'Negative direction/spped is detected as reversed', function(){
    expect(1);
    var
      selector= '#image',
      $reel= $(selector).reel({ speed: -1 })

    equal( $reel.data('backwards'), true, 'Reversed at negative speeds');
    start();
  });

  test( 'Default `$.reel.math.spread`', function(){
    expect(14);
    var
      probes= {
        10: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10],
            frames: 10,
            frame: 1
          },
          ordered: '1,6,4,9,2,7,5,10,3,8'.split(/, ?/)
        },
        12: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12],
            frames: 12,
            frame: 1
          },
          ordered: '1,7,4,10,3,9,6,12,2,8,5,11'.split(/, ?/)
        },
        15: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],
            frames: 15,
            frame: 1
          },
          ordered: '1,9,5,13,3,11,7,15,2,10,6,14,4,12,8'.split(/, ?/)
        },
        18: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],
            frames: 18,
            frame: 1
          },
          ordered: '1,10,6,15,3,12,8,17,2,11,7,16,4,13,9,18,5,14'.split(/, ?/)
        },
        24: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],
            frames: 24,
            frame: 1
          },
          ordered: '1,13, 7,19, 4,16,10,22, 3,15,9,21,6,18,12,24, 2,14,8,20,5,17,11,23'.split(/, ?/)
        },
        36: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],
            frames: 36,
            frame: 1
          },
          ordered: '1,19, 10,28, 6,24,15,33, 3,21,12,30,8,26,17,35, 2,20,11,29,7,25,16,34,4,22,13,31,9,27,18,36, 5,23,14,32'.split(/, ?/)
        },
        48: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],
            frames: 48,
            frame: 1
          },
          ordered: '1,25, 13,37, 7,31,19,43, 4,28,16,40,10,34,22,46, 3,27,15,39,9,33,21,45,6,30,18,42,12,36,24,48, 2,26,14,38,8,32,20,44,5,29,17,41,11,35,23,47'.split(/, ?/)
        },

        // Atypicals with different starting points
        17: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],
            frames: 17,
            frame: 7
          },
          ordered: '7,16, 11,3, 9,1,13,5, 8,17,12,4,10,2,14,6, 15'.split(/, ?/)
        },
        23: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23],
            frames: 23,
            frame: 11
          },
          ordered: '11,23, 17,6, 14,3,20,9, 12,1,18,7,15,4,21,10, 13,2,19,8,16,5,22'.split(/, ?/)
        },
        27: {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27],
            frames: 27,
            frame: 27
          },
          ordered: '27,14, 7,21, 3,17,10,24, 2,16,9,23,5,19,12,26, 1,15,8,22,4,18,11,25,6,20,13'.split(/, ?/)
        },

        // Multi-rows
        '2x10': {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],
            frames: 10,
            frame: 1,
            rows: 2
          },
          ordered: '1,6, 4,9, 2,7,5,10, 3,8, 11,16, 14,19, 12,17,15,20, 13,18'.split(/, ?/)
        },
        '4x10': {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40],
            frames: 10,
            frame: 1,
            rows: 4,
            row: 2
          },
          ordered: '11,16, 14,19, 12,17,15,20, 13,18, 1,6,21,26,31,36, 4,9,24,29,34,39, 2,7,22,27,32,37,5,25,30,35,40, 3,8,23,28,33,38'.split(/, ?/)
        },
        'orbital': {
          options: {
            images: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],
            footage: 9,
            frame: 1,
            orbital: 3
          },
          ordered: '1,6, 3,8, 2,7,4,9, 5, 10,15, 12,17, 11,16,13,18, 14'.split(/, ?/)
        }
      }

    ok( typeof $.reel.math.spread == 'function', '`$.reel.math.spread` available');

    $.each(probes, function(ix, def){
      var
        $reel= $('#image').reel(def.options)
      deepEqual( $reel.data('images'), def.ordered, ix+' frames starting at frame '+def.options.frame);
    });

  });

})(jQuery);
<|endoftext|>


<commit_before>define([
    "backbone",
    "handlebars",
    "app/App",
    "authentication/Authentication",
    "corpus/Corpus",
    "data_list/DataList",
    "data_list/DataLists",
    "datum/Datum",
    "datum/DatumFields",
    "datum/Session",
    "datum/Sessions",
    "user/User",
    "libs/Utils"
], function(
    Backbone,
    Handlebars,
    App,
    Authentication,
    Corpus,
    DataList,
    DataLists,
    Datum,
    DatumFields,
    Session,
    Sessions,
    User
) {
  var UserWelcomeView = Backbone.View.extend(
  /** @lends UserWelcomeView.prototype */
  {
    /**
     * @class The UserWelcomeView invites the user to login using their existing
     *        name to sync their data, or to login as the sample user, sapir
     *
     * @extends Backbone.View
     * @constructs
     */
    initialize : function() {
      Utils.debug("USER welcome init: " + this.el);
      this.model = new User();
      this.model.set("username","YourNewUserNameGoesHere");
      this.model.bind("change", this.render, this);
    },

    /**
     * The underlying model of the UserWelcomeView is a User.
     */
    model : User,

    /**
     * Events that the UserWelcomeView is listening to and their handlers.
     */
    events : {
      "blur .username" : function() {
        if (this.$el.find(".username").val() != "YourNewUserNameGoesHere") {
            this.model.set("username",$(".username").val());
            $(".confirm-password").show();
        };
      },
//      "click .new-user-button" : function() {
//        $(".confirm-password").show();
//      },
      "click .register-new-user" : function() {
        Utils.debug("Attempting to register a new user: " + this.el);
        var dataToPost = {};
        dataToPost.login = $(".username").val();
        dataToPost.email = $(".email").val();
        dataToPost.username = $(".username").val();
        dataToPost.password = $(".password").val();
        //Send a corpusname to create
        var corpusConnection = Utils.defaultCouchConnection();
        corpusConnection.corpusname = "firstcorpus";
        dataToPost.corpuses = [corpusConnection];

        if (dataToPost.username != ""
          && (dataToPost.password == $(".to-confirm-password").val())
          && dataToPost.email != "") {
          Utils.debug("User has entered an email and the passwords match. ");
          var a = new App();
          a.createAppBackboneObjects($(".username").val()+"-firstcorpus");//this is the convention the server is currently using to create first corpora

          /*
           * Contact the server and register the new user
           */
          $.ajax({
            type : 'POST',
            url : Utils.authUrl + "/register",
            data : dataToPost,
            success : function(data) {
              if (data.errors != null) {
                $(".alert-error").html(data.errors.join("
")+" "+Utils.contactUs );
                $(".alert-error").show();
              } else if (data.user) {
                /*
                 * Create a new user, and put them into the authView, create a corpus, session and datalist for them then
                 * dismiss modal
                 */

//                a.createAppBackboneObjects(data.user.couchConnection.corpusname, function(){
                  // Faking a login behavior, copy pasted from authentication auth function
                  var auth  = a.get("authentication");
                  auth.set("state", "loggedIn");
                  auth.staleAuthentication = false;

                  var u = auth.get("userPrivate");
                  u.set("id",data.user._id); //set the backbone id to be the same as the mongodb id
                  u.set(data.user);//TODO maybe id conflicts are popping up here

                  // Over write the public copy with any (new) username/gravatar info set the backbone id of the userPublic to be the same as the mongodb id of the userPrivate
                  auth.get("userPublic").set("id", auth.get("userPrivate").get("id"));
                  if (data.user.publicSelf == null) {
                    // If the user hasnt already specified their public auth, then put in a username and gravatar,however they can add more details like their affiliation, name, research interests etc.
                    data.user.publicSelf = {};
                    data.user.publicSelf.username = auth.get("userPrivate").get("username");
                    data.user.publicSelf.gravatar = auth.get("userPrivate").get("gravatar");
                  }
                  auth.get("userPublic").set(data.user.publicSelf);
                  auth.get("userPublic").changeCorpus(data.user.corpuses[0].corpusname);
//                  auth.get("userPublic").save();

                  var c = a.get("corpus");
                  c.set({
                    "title" : data.user.username + "'s Corpus",
                    "titleAsUrl" : data.user.username + "Corpus",
                    "description" : "This is an untitled corpus, created by default.",
                    "dataLists" : new DataLists(),
                    "sessions" : new Sessions(),
                    "couchConnection" : data.user.corpuses[0],
                    "corpusname" : data.user.corpuses[0].corpusname
                  });

                  var s = a.get("currentSession");
                  s.get("sessionFields").where({label: "user"})[0].set("value", auth.get("userPrivate").get("username") );
                  s.get("sessionFields").where({label: "consultants"})[0].set("value", "AA");
                  s.get("sessionFields").where({label: "goal"})[0].set("value", "To explore the app and try entering/importing data");
                  s.get("sessionFields").where({label: "dateSEntered"})[0].set("value", new Date());
                  s.get("sessionFields").where({label: "dateElicited"})[0].set("value", "A few months ago, probably on a Monday night.");
                  s.set("corpusname", data.user.corpuses[0].corpusname);
                  s.changeCorpus(data.user.corpuses[0].corpusname);

                  c.get("sessions").add(s);

                  var dl = a.get("currentDataList");
                  dl.set({
                    "title" : data.user.username + "'s untitled data list",
                    "dateCreated" : "May 29, 2012",
                    "description" : "You can use datalists to create handouts or to prepare for sessions with consultants, export to LaTeX or to share with collaborators. ",
                    "corpusname" : data.user.corpuses[0].corpusname
                  });
                  dl.changeCorpus(data.user.corpuses[0].corpusname);
                  c.get("dataLists").add(dl);

                  c.changeCorpus(data.user.corpuses[0]);
                  // c.save(); //this is saving to add the corpus to the user's array of corpuses later on
                   window.startApp(a, function(){
//                     auth.get("userPrivate").addCurrentCorpusToUser();
                     window.setTimeout(function(){
                       /*
                        * Use the corpus just created to log the user into that corpus's couch server
                        */
                       var couchConnection = data.user.corpuses[0];
                       c.logUserIntoTheirCorpusServer(couchConnection, dataToPost.username, dataToPost.password, function() {
                         Utils.debug("Successfully authenticated user with their corpus server.");
                       });
                     }, 5000);
                     console.log("Loadded app for a new user.");
                   });
                   $('#user-welcome-modal').modal("hide");
//                });
              }
            },//end successful registration
            dataType : ""
          });
        } else{
          Utils.debug("User has not entered good info. ");
            $(".alert-error").html("Your passwords don't match, or you didn't enter an email. " + Utils.contactUs );
            $(".alert-error").show();
        }
      },
      "click .register-twitter" : function() {

      },
      "click .register-facebook" : function() {

      },

      "click .sync-sapir-data" : function() {
        console.log("hiding user welcome, syncing sapir");
        //Load a corpus, datalist, session and user
        a = new App();
        a.createAppBackboneObjects("sapir-firstcorpus",function() {
          $('#user-welcome-modal').modal("hide");
          window.startApp(a, function() {
            window.appView.loadSample();
          });
        });
      },

      "click .sync-my-data" : function() {
        console.log("hiding user welcome, syncing users data");
        var u = new User({username:$("#welcomeusername").val(), password: $("#welcomepassword").val() });
        a = new App();
        var auth = a.get("authentication");
        auth.authenticate(u, function(success, errors){
          if(success == null){
            $(".alert-error").html(
                errors.join("
") + " " + Utils.contactUs);
//            alert("Something went wrong, we were unable to contact the server, or something is wrong with your login info.");
            $(".alert-error").show();
            $('#user-welcome-modal').modal("show");
          }else{
            a.createAppBackboneObjects(auth.get("userPrivate").get("corpuses")[0].corpusname, function(){
              $('#user-welcome-modal').modal("hide");
              window.startApp(a, function(){
                var couchConnection = auth.get("userPrivate").get("corpuses")[0]; //TODO make this be the last corpus they edited so that we re-load their dashboard, or let them chooe which corpus they want.
                window.app.get("corpus").logUserIntoTheirCorpusServer(couchConnection, $("#welcomeusername").val(), $("#welcomepassword").val(), function(){
                  //Replicate user's corpus down to pouch
                  window.app.get("corpus").replicateCorpus(couchConnection, function(){
                    if(auth.get("userPrivate").get("mostRecentIds") == undefined){
                      //do nothing because they have no recent ids
                      Utils.debug("User does not have most recent ids, doing nothing.");
                    }else{
                      /*
                       *  Load their last corpus, session, datalist etc
                       */
                      var appids = auth.get("userPrivate").get("mostRecentIds");
                      window.app.loadBackboneObjectsById(couchConnection, appids);
                    }
                  });
                });
              });
            });

          }
        });
      },

      "click .dropdown-menu" : function(e) {
        e.stopPropagation();
      },

      },

    /**
     * The Handlebars template rendered as the UserWelcomeView
     */
    template : Handlebars.templates.user_welcome_modal,

    /**
     * Renders the UserWelcomeView and its partial.
     */
    render : function() {
      Utils.debug("USER render: " + this.el);

      if (this.model != undefined) {

        // Display the UserWelcomeView
        this.setElement($("#user-welcome-modal"));
        $(this.el).html(this.template(this.model.toJSON()));
        $(".username").focus();
      } else {
        Utils.debug("\User model was undefined");
      }

      return this;
    }
  });

  return UserWelcomeView;
}); <commit_msg>the text inside new username textbox is selected at one click<commit_after>define([
    "backbone",
    "handlebars",
    "app/App",
    "authentication/Authentication",
    "corpus/Corpus",
    "data_list/DataList",
    "data_list/DataLists",
    "datum/Datum",
    "datum/DatumFields",
    "datum/Session",
    "datum/Sessions",
    "user/User",
    "libs/Utils"
], function(
    Backbone,
    Handlebars,
    App,
    Authentication,
    Corpus,
    DataList,
    DataLists,
    Datum,
    DatumFields,
    Session,
    Sessions,
    User
) {
  var UserWelcomeView = Backbone.View.extend(
  /** @lends UserWelcomeView.prototype */
  {
    /**
     * @class The UserWelcomeView invites the user to login using their existing
     *        name to sync their data, or to login as the sample user, sapir
     *
     * @extends Backbone.View
     * @constructs
     */
    initialize : function() {
      Utils.debug("USER welcome init: " + this.el);
      this.model = new User();
      this.model.set("username","YourNewUserNameGoesHere");
      this.model.bind("change", this.render, this);
    },

    /**
     * The underlying model of the UserWelcomeView is a User.
     */
    model : User,

    /**
     * Events that the UserWelcomeView is listening to and their handlers.
     */
    events : {
      "click .username" : function(e){
        e.target.select();
      },

      "blur .username" : function() {
        if (this.$el.find(".username").val() != "YourNewUserNameGoesHere") {
            this.model.set("username",$(".username").val());
            $(".confirm-password").show();
        };
      },
//      "click .new-user-button" : function() {
//        $(".confirm-password").show();
//      },
      "click .register-new-user" : function() {
        Utils.debug("Attempting to register a new user: " + this.el);
        var dataToPost = {};
        dataToPost.login = $(".username").val();
        dataToPost.email = $(".email").val();
        dataToPost.username = $(".username").val();
        dataToPost.password = $(".password").val();
        //Send a corpusname to create
        var corpusConnection = Utils.defaultCouchConnection();
        corpusConnection.corpusname = "firstcorpus";
        dataToPost.corpuses = [corpusConnection];

        if (dataToPost.username != ""
          && (dataToPost.password == $(".to-confirm-password").val())
          && dataToPost.email != "") {
          Utils.debug("User has entered an email and the passwords match. ");
          var a = new App();
          a.createAppBackboneObjects($(".username").val()+"-firstcorpus");//this is the convention the server is currently using to create first corpora

          /*
           * Contact the server and register the new user
           */
          $.ajax({
            type : 'POST',
            url : Utils.authUrl + "/register",
            data : dataToPost,
            success : function(data) {
              if (data.errors != null) {
                $(".alert-error").html(data.errors.join("
")+" "+Utils.contactUs );
                $(".alert-error").show();
              } else if (data.user) {
                /*
                 * Create a new user, and put them into the authView, create a corpus, session and datalist for them then
                 * dismiss modal
                 */

//                a.createAppBackboneObjects(data.user.couchConnection.corpusname, function(){
                  // Faking a login behavior, copy pasted from authentication auth function
                  var auth  = a.get("authentication");
                  auth.set("state", "loggedIn");
                  auth.staleAuthentication = false;

                  var u = auth.get("userPrivate");
                  u.set("id",data.user._id); //set the backbone id to be the same as the mongodb id
                  u.set(data.user);//TODO maybe id conflicts are popping up here

                  // Over write the public copy with any (new) username/gravatar info set the backbone id of the userPublic to be the same as the mongodb id of the userPrivate
                  auth.get("userPublic").set("id", auth.get("userPrivate").get("id"));
                  if (data.user.publicSelf == null) {
                    // If the user hasnt already specified their public auth, then put in a username and gravatar,however they can add more details like their affiliation, name, research interests etc.
                    data.user.publicSelf = {};
                    data.user.publicSelf.username = auth.get("userPrivate").get("username");
                    data.user.publicSelf.gravatar = auth.get("userPrivate").get("gravatar");
                  }
                  auth.get("userPublic").set(data.user.publicSelf);
                  auth.get("userPublic").changeCorpus(data.user.corpuses[0].corpusname);
//                  auth.get("userPublic").save();

                  var c = a.get("corpus");
                  c.set({
                    "title" : data.user.username + "'s Corpus",
                    "titleAsUrl" : data.user.username + "Corpus",
                    "description" : "This is an untitled corpus, created by default.",
                    "dataLists" : new DataLists(),
                    "sessions" : new Sessions(),
                    "couchConnection" : data.user.corpuses[0],
                    "corpusname" : data.user.corpuses[0].corpusname
                  });

                  var s = a.get("currentSession");
                  s.get("sessionFields").where({label: "user"})[0].set("value", auth.get("userPrivate").get("username") );
                  s.get("sessionFields").where({label: "consultants"})[0].set("value", "AA");
                  s.get("sessionFields").where({label: "goal"})[0].set("value", "To explore the app and try entering/importing data");
                  s.get("sessionFields").where({label: "dateSEntered"})[0].set("value", new Date());
                  s.get("sessionFields").where({label: "dateElicited"})[0].set("value", "A few months ago, probably on a Monday night.");
                  s.set("corpusname", data.user.corpuses[0].corpusname);
                  s.changeCorpus(data.user.corpuses[0].corpusname);

                  c.get("sessions").add(s);

                  var dl = a.get("currentDataList");
                  dl.set({
                    "title" : data.user.username + "'s untitled data list",
                    "dateCreated" : "May 29, 2012",
                    "description" : "You can use datalists to create handouts or to prepare for sessions with consultants, export to LaTeX or to share with collaborators. ",
                    "corpusname" : data.user.corpuses[0].corpusname
                  });
                  dl.changeCorpus(data.user.corpuses[0].corpusname);
                  c.get("dataLists").add(dl);

                  c.changeCorpus(data.user.corpuses[0]);
                  // c.save(); //this is saving to add the corpus to the user's array of corpuses later on
                   window.startApp(a, function(){
//                     auth.get("userPrivate").addCurrentCorpusToUser();
                     window.setTimeout(function(){
                       /*
                        * Use the corpus just created to log the user into that corpus's couch server
                        */
                       var couchConnection = data.user.corpuses[0];
                       c.logUserIntoTheirCorpusServer(couchConnection, dataToPost.username, dataToPost.password, function() {
                         Utils.debug("Successfully authenticated user with their corpus server.");
                       });
                     }, 5000);
                     console.log("Loadded app for a new user.");
                   });
                   $('#user-welcome-modal').modal("hide");
//                });
              }
            },//end successful registration
            dataType : ""
          });
        } else{
          Utils.debug("User has not entered good info. ");
            $(".alert-error").html("Your passwords don't match, or you didn't enter an email. " + Utils.contactUs );
            $(".alert-error").show();
        }
      },
      "click .register-twitter" : function() {

      },
      "click .register-facebook" : function() {

      },

      "click .sync-sapir-data" : function() {
        console.log("hiding user welcome, syncing sapir");
        //Load a corpus, datalist, session and user
        a = new App();
        a.createAppBackboneObjects("sapir-firstcorpus",function() {
          $('#user-welcome-modal').modal("hide");
          window.startApp(a, function() {
            window.appView.loadSample();
          });
        });
      },

      "click .sync-my-data" : function() {
        console.log("hiding user welcome, syncing users data");
        var u = new User({username:$("#welcomeusername").val(), password: $("#welcomepassword").val() });
        a = new App();
        var auth = a.get("authentication");
        auth.authenticate(u, function(success, errors){
          if(success == null){
            $(".alert-error").html(
                errors.join("
") + " " + Utils.contactUs);
//            alert("Something went wrong, we were unable to contact the server, or something is wrong with your login info.");
            $(".alert-error").show();
            $('#user-welcome-modal').modal("show");
          }else{
            a.createAppBackboneObjects(auth.get("userPrivate").get("corpuses")[0].corpusname, function(){
              $('#user-welcome-modal').modal("hide");
              window.startApp(a, function(){
                var couchConnection = auth.get("userPrivate").get("corpuses")[0]; //TODO make this be the last corpus they edited so that we re-load their dashboard, or let them chooe which corpus they want.
                window.app.get("corpus").logUserIntoTheirCorpusServer(couchConnection, $("#welcomeusername").val(), $("#welcomepassword").val(), function(){
                  //Replicate user's corpus down to pouch
                  window.app.get("corpus").replicateCorpus(couchConnection, function(){
                    if(auth.get("userPrivate").get("mostRecentIds") == undefined){
                      //do nothing because they have no recent ids
                      Utils.debug("User does not have most recent ids, doing nothing.");
                    }else{
                      /*
                       *  Load their last corpus, session, datalist etc
                       */
                      var appids = auth.get("userPrivate").get("mostRecentIds");
                      window.app.loadBackboneObjectsById(couchConnection, appids);
                    }
                  });
                });
              });
            });

          }
        });
      },

      "click .dropdown-menu" : function(e) {
        e.stopPropagation();
      },

      },

    /**
     * The Handlebars template rendered as the UserWelcomeView
     */
    template : Handlebars.templates.user_welcome_modal,

    /**
     * Renders the UserWelcomeView and its partial.
     */
    render : function() {
      Utils.debug("USER render: " + this.el);

      if (this.model != undefined) {

        // Display the UserWelcomeView
        this.setElement($("#user-welcome-modal"));
        $(this.el).html(this.template(this.model.toJSON()));
        $(".username").focus();
      } else {
        Utils.debug("\User model was undefined");
      }

      return this;
    }
  });

  return UserWelcomeView;
}); <|endoftext|>


<commit_before>module.exports = function(grunt) {

    grunt.initConfig({

        less: {
            production: {
                options: {
                    compress: true,
                    yuicompress: true,
                    paths: ['bower_components/bootstrap/less']
                },
                files: {
                    'assets/css/bootstrap.min.css': 'bower_components/bootstrap/less/bootstrap.less'
                }
            }
        },
        uglify: {
            jquery: {
                files: {
                    'assets/js/jquery.min.js': 'bower_components/jquery/jquery.js'
                }
            }
        },
        copy: {
            styles: {
                files: [
                    {expand: true, cwd: 'css/', src: ['styles.css', 'main.css'], dest: 'assets/css/'}
                ]
            },
            normalize: {
                files: [
                    {expand: true, cwd: 'bower_components/normalize-css/', src: ['normalize.css'], dest: 'assets/css/'}
                ]
            },
            fontawesome: {
                files: [
                    {expand: true, cwd: 'bower_components/font-awesome/css/', src: ['font-awesome.min.css'], dest: 'assets/css/'},
                    {expand: true, cwd: 'bower_components/font-awesome/fonts/', src: ['*'], dest: 'assets/fonts/'}
                ]
            }
        },
        exec: {
            build: {
                cmd: 'jekyll build'
            },
            serve: {
                cmd: 'jekyll serve --watch'
            },
            deploy: {
                cmd: 'git push deploy master; git push origin master;'
            }
        }

    });

    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-exec');

    grunt.registerTask('default', [ 'less', 'uglify', 'copy', 'exec:build' ]);
    grunt.registerTask('serve', [ 'less', 'uglify', 'copy', 'exec:serve' ]);
    grunt.registerTask('deploy', [ 'exec:deploy' ]);

};
<commit_msg>Updating the Gruntfile to copy images to assets folder as well.<commit_after>module.exports = function(grunt) {

    grunt.initConfig({

        less: {
            production: {
                options: {
                    compress: true,
                    yuicompress: true,
                    paths: ['bower_components/bootstrap/less']
                },
                files: {
                    'assets/css/bootstrap.min.css': 'bower_components/bootstrap/less/bootstrap.less'
                }
            }
        },
        uglify: {
            jquery: {
                files: {
                    'assets/js/jquery.min.js': 'bower_components/jquery/jquery.js'
                }
            }
        },
        copy: {
            images: {
                files: [
                    {expand: true, cwd: 'img/', src: ['**'], dest: 'assets/img/'}
                ]
            },
            styles: {
                files: [
                    {expand: true, cwd: 'css/', src: ['styles.css', 'main.css'], dest: 'assets/css/'}
                ]
            },
            normalize: {
                files: [
                    {expand: true, cwd: 'bower_components/normalize-css/', src: ['normalize.css'], dest: 'assets/css/'}
                ]
            },
            fontawesome: {
                files: [
                    {expand: true, cwd: 'bower_components/font-awesome/css/', src: ['font-awesome.min.css'], dest: 'assets/css/'},
                    {expand: true, cwd: 'bower_components/font-awesome/fonts/', src: ['*'], dest: 'assets/fonts/'}
                ]
            }
        },
        exec: {
            build: {
                cmd: 'jekyll build'
            },
            serve: {
                cmd: 'jekyll serve --watch'
            },
            deploy: {
                cmd: 'git push deploy master; git push origin master;'
            }
        }

    });

    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-less');
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-exec');

    grunt.registerTask('default', [ 'less', 'uglify', 'copy', 'exec:build' ]);
    grunt.registerTask('serve', [ 'less', 'uglify', 'copy', 'exec:serve' ]);
    grunt.registerTask('deploy', [ 'exec:deploy' ]);

};
<|endoftext|>


<commit_before>// Generated on 2013-11-16 using generator-angular 0.6.0-rc.1
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {
	require('load-grunt-tasks')(grunt);
	require('time-grunt')(grunt);

	grunt.initConfig({
		yeoman: {
			// configurable paths
			app: require('./bower.json').appPath || 'app',
			dist: 'dist',
			tmp: '.tmp'
		},
		watch: {
			coffee: {
				files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'],
				tasks: ['coffee:dist']
			},
			coffeeTest: {
				files: ['test/spec/{,*/}*.coffee'],
				tasks: ['coffee:test']
			},
			styles: {
				files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
				tasks: ['copy:styles', 'autoprefixer']
			},
			livereload: {
				options: {
					livereload: '<%= connect.options.livereload %>'
				},
				files: [
					'<%= yeoman.app %>/{,*/}*.html',
					'.tmp/styles/{,*/}*.css',
					'{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
					'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
				]
			},
			jade: {
				files: '<%= yeoman.app %>/**/*.jade',
				tasks: ['jade']
			}
		},
		autoprefixer: {
			options: ['last 1 version'],
			dist: {
				files: [{
					expand: true,
					cwd: '.tmp/styles/',
					src: '{,*/}*.css',
					dest: '.tmp/styles/'
				}]
			}
		},
		connect: {
			options: {
				port: 9000,
				// Change this to '0.0.0.0' to access the server from outside.
				hostname: 'localhost',
				livereload: 35729
			},
			livereload: {
				options: {
					open: true,
					base: [
						'.tmp',
						'<%= yeoman.dist %>'
					]
				}
			},
			test: {
				options: {
					port: 9001,
					base: [
						'.tmp',
						'test',
						'<%= yeoman.app %>'
					]
				}
			},
			dist: {
				options: {
					base: '<%= yeoman.dist %>'
				}
			}
		},
		clean: {
			dist: {
				files: [{
					dot: true,
					src: [
						'.tmp',
						'<%= yeoman.dist %>/*',
						'!<%= yeoman.dist %>/.git*'
					]
				}]
			},
			server: '.tmp'
		},
		jshint: {
			options: {
				jshintrc: '.jshintrc',
				reporter: require('jshint-stylish')
			},
			all: [
				'Gruntfile.js',
				'<%= yeoman.app %>/scripts/{,*/}*.js'
			]
		},
		coffee: {
			options: {
				sourceMap: true,
				sourceRoot: ''
			},
			dist: {
				files: [{
					expand: true,
					cwd: '<%= yeoman.app %>/scripts',
					src: '{,*/}*.coffee',
					dest: '.tmp/scripts',
					ext: '.js'
				}]
			},
			test: {
				files: [{
					expand: true,
					cwd: 'test/spec',
					src: '{,*/}*.coffee',
					dest: '.tmp/spec',
					ext: '.js'
				}]
			}
		},
		rev: {
			dist: {
				files: {
					src: [
						'<%= yeoman.dist %>/scripts/{,*/}*.js',
						'<%= yeoman.dist %>/styles/{,*/}*.css',
						'<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
						'<%= yeoman.dist %>/styles/fonts/*'
					]
				}
			}
		},
		useminPrepare: {
			html: '<%= yeoman.dist %>/index.html',
			html: '<%= yeoman.dist %>/{,*/}*.html',
			options: {
				dest: '<%= yeoman.dist %>'
			}
		},
		usemin: {
			html: ['<%= yeoman.dist %>/{,*/}*.html'],
			css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
			options: {
				assetsDirs: ['<%= yeoman.dist %>']
			}
		},
		imagemin: {
			dist: {
				files: [{
					expand: true,
					cwd: '<%= yeoman.app %>/images',
					src: '{,*/}*.{png,jpg,jpeg}',
					dest: '<%= yeoman.dist %>/images'
				}]
			}
		},
		svgmin: {
			dist: {
				files: [{
					expand: true,
					cwd: '<%= yeoman.app %>/images',
					src: '{,*/}*.svg',
					dest: '<%= yeoman.dist %>/images'
				}]
			}
		},
		htmlmin: {
			dist: {
				options: {
					/*removeCommentsFromCDATA: true,
					 // https://github.com/yeoman/grunt-usemin/issues/44
					 //collapseWhitespace: true,
					 collapseBooleanAttributes: true,
					 removeAttributeQuotes: true,
					 removeRedundantAttributes: true,
					 useShortDoctype: true,
					 removeEmptyAttributes: true,
					 removeOptionalTags: true*/
				},
				files: [{
					expand: true,
					cwd: '<%= yeoman.app %>',
					src: ['*.html', 'views/*.html'],
					dest: '<%= yeoman.dist %>'
				}]
			}
		},
		// Put files not handled in other tasks here
		copy: {
			dist: {
				files: [{
					expand: true,
					dot: true,
					cwd: '<%= yeoman.app %>',
					dest: '<%= yeoman.dist %>',
					src: [
						'*.{ico,png,txt}',
						'.htaccess',
						'bower_components/**/*',
						'images/{,*/}*.{gif,webp}',
						'fonts/*'
					]
				}, {
					expand: true,
					cwd: '.tmp/images',
					dest: '<%= yeoman.dist %>/images',
					src: [
						'generated/*'
					]
				}]
			},
			styles: {
				expand: true,
				cwd: '<%= yeoman.app %>/styles',
				dest: '.tmp/styles/',
				src: '{,*/}*.css'
			}
		},
		concurrent: {
			server: [
				'coffee:dist',
				'copy:styles'
			],
			test: [
				'coffee',
				'copy:styles'
			],
			dist: [
				'coffee',
				'copy:styles',
				'imagemin',
				'svgmin',
				'htmlmin'
			]
		},
		karma: {
			unit: {
				configFile: 'karma.conf.js',
				singleRun: true
			}
		},
		cdnify: {
			dist: {
				html: ['<%= yeoman.dist %>/*.html']
			}
		},
		ngmin: {
			dist: {
				files: [{
					expand: true,
					cwd: '.tmp/concat/scripts',
					src: '*.js',
					dest: '.tmp/concat/scripts'
				}]
			}
		},
		uglify: {
			dist: {
				files: {
					'<%= yeoman.dist %>/scripts/scripts.js': [
						'<%= yeoman.dist %>/scripts/scripts.js'
					]
				}
			}
		},
		jade: {
			compile: {
				options: {
					data: {
						debug: false,
						timestamp: '<%= grunt.template.today() %>'
					}
				},
				files: {
					'<%= yeoman.dist %>/index.html': ['<%= yeoman.app %>/index.jade'],
					'<%= yeoman.dist %>/views/main.html': ['<%= yeoman.app %>/views/main.jade']
				}
			}
		}
	});

	grunt.registerTask('server', function (target) {
		if (target === 'dist') {
			return grunt.task.run(['build', 'connect:dist:keepalive']);
		}

		grunt.task.run([
			'clean:server',
			'jade',
			'concurrent:server',
			'autoprefixer',
			'connect:livereload',
			'watch'
		]);
	});

	grunt.registerTask('test', [
		'clean:server',
		'concurrent:test',
		'autoprefixer',
		'connect:test',
		'karma'
	]);

	grunt.registerTask('build', [
		'clean:dist',
		'jade',
		'useminPrepare',
		'concurrent:dist',
		'autoprefixer',
		'ngmin',
		'copy:dist',
		'cdnify',
		'uglify',
		'rev',
		'usemin'
	]);

	grunt.registerTask('default', [
		'jshint',
		'test',
		'build'
	]);
};
<commit_msg>Temporary shut off usemin task in Grunt<commit_after>// Generated on 2013-11-16 using generator-angular 0.6.0-rc.1
'use strict';

// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'

module.exports = function (grunt) {
	require('load-grunt-tasks')(grunt);
	require('time-grunt')(grunt);

	grunt.initConfig({
		yeoman: {
			// configurable paths
			app: require('./bower.json').appPath || 'app',
			dist: 'dist',
			tmp: '.tmp'
		},
		watch: {
			coffee: {
				files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee'],
				tasks: ['coffee:dist']
			},
			coffeeTest: {
				files: ['test/spec/{,*/}*.coffee'],
				tasks: ['coffee:test']
			},
			styles: {
				files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
				tasks: ['copy:styles', 'autoprefixer']
			},
			livereload: {
				options: {
					livereload: '<%= connect.options.livereload %>'
				},
				files: [
					'<%= yeoman.app %>/{,*/}*.html',
					'.tmp/styles/{,*/}*.css',
					'{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js',
					'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
				]
			},
			jade: {
				files: '<%= yeoman.app %>/**/*.jade',
				tasks: ['jade']
			}
		},
		autoprefixer: {
			options: ['last 1 version'],
			dist: {
				files: [{
					expand: true,
					cwd: '.tmp/styles/',
					src: '{,*/}*.css',
					dest: '.tmp/styles/'
				}]
			}
		},
		connect: {
			options: {
				port: 9000,
				// Change this to '0.0.0.0' to access the server from outside.
				hostname: 'localhost',
				livereload: 35729
			},
			livereload: {
				options: {
					open: true,
					base: [
						'.tmp',
						'<%= yeoman.dist %>'
					]
				}
			},
			test: {
				options: {
					port: 9001,
					base: [
						'.tmp',
						'test',
						'<%= yeoman.app %>'
					]
				}
			},
			dist: {
				options: {
					base: '<%= yeoman.dist %>'
				}
			}
		},
		clean: {
			dist: {
				files: [{
					dot: true,
					src: [
						'.tmp',
						'<%= yeoman.dist %>/*',
						'!<%= yeoman.dist %>/.git*'
					]
				}]
			},
			server: '.tmp'
		},
		jshint: {
			options: {
				jshintrc: '.jshintrc',
				reporter: require('jshint-stylish')
			},
			all: [
				'Gruntfile.js',
				'<%= yeoman.app %>/scripts/{,*/}*.js'
			]
		},
		coffee: {
			options: {
				sourceMap: true,
				sourceRoot: ''
			},
			dist: {
				files: [{
					expand: true,
					cwd: '<%= yeoman.app %>/scripts',
					src: '{,*/}*.coffee',
					dest: '.tmp/scripts',
					ext: '.js'
				}]
			},
			test: {
				files: [{
					expand: true,
					cwd: 'test/spec',
					src: '{,*/}*.coffee',
					dest: '.tmp/spec',
					ext: '.js'
				}]
			}
		},
		rev: {
			dist: {
				files: {
					src: [
						'<%= yeoman.dist %>/scripts/{,*/}*.js',
						'<%= yeoman.dist %>/styles/{,*/}*.css',
						'<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
						'<%= yeoman.dist %>/styles/fonts/*'
					]
				}
			}
		},
		useminPrepare: {
			html: '<%= yeoman.dist %>/{,*/}*.html',
			options: {
				dest: '<%= yeoman.dist %>'
			}
		},
		usemin: {
			html: ['<%= yeoman.dist %>/{,*/}*.html'],
			css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
			options: {
				assetsDirs: ['<%= yeoman.dist %>']
			}
		},
		imagemin: {
			dist: {
				files: [{
					expand: true,
					cwd: '<%= yeoman.app %>/images',
					src: '{,*/}*.{png,jpg,jpeg}',
					dest: '<%= yeoman.dist %>/images'
				}]
			}
		},
		svgmin: {
			dist: {
				files: [{
					expand: true,
					cwd: '<%= yeoman.app %>/images',
					src: '{,*/}*.svg',
					dest: '<%= yeoman.dist %>/images'
				}]
			}
		},
		htmlmin: {
			dist: {
				options: {
					/*removeCommentsFromCDATA: true,
					 // https://github.com/yeoman/grunt-usemin/issues/44
					 //collapseWhitespace: true,
					 collapseBooleanAttributes: true,
					 removeAttributeQuotes: true,
					 removeRedundantAttributes: true,
					 useShortDoctype: true,
					 removeEmptyAttributes: true,
					 removeOptionalTags: true*/
				},
				files: [{
					expand: true,
					cwd: '<%= yeoman.app %>',
					src: ['*.html', 'views/*.html'],
					dest: '<%= yeoman.dist %>'
				}]
			}
		},
		// Put files not handled in other tasks here
		copy: {
			dist: {
				files: [{
					expand: true,
					dot: true,
					cwd: '<%= yeoman.app %>',
					dest: '<%= yeoman.dist %>',
					src: [
						'*.{ico,png,txt}',
						'.htaccess',
						'bower_components/**/*',
						'images/{,*/}*.{gif,webp}',
						'fonts/*'
					]
				}, {
					expand: true,
					cwd: '.tmp/images',
					dest: '<%= yeoman.dist %>/images',
					src: [
						'generated/*'
					]
				}]
			},
			styles: {
				expand: true,
				cwd: '<%= yeoman.app %>/styles',
				dest: '.tmp/styles/',
				src: '{,*/}*.css'
			}
		},
		concurrent: {
			server: [
				'coffee:dist',
				'copy:styles'
			],
			test: [
				'coffee',
				'copy:styles'
			],
			dist: [
				'coffee',
				'copy:styles',
				'imagemin',
				'svgmin',
				'htmlmin'
			]
		},
		karma: {
			unit: {
				configFile: 'karma.conf.js',
				singleRun: true
			}
		},
		cdnify: {
			dist: {
				html: ['<%= yeoman.dist %>/*.html']
			}
		},
		ngmin: {
			dist: {
				files: [{
					expand: true,
					cwd: '.tmp/concat/scripts',
					src: '*.js',
					dest: '.tmp/concat/scripts'
				}]
			}
		},
		uglify: {
			dist: {
				files: {
					'<%= yeoman.dist %>/scripts/scripts.js': [
						'<%= yeoman.dist %>/scripts/scripts.js'
					]
				}
			}
		},
		jade: {
			compile: {
				options: {
					data: {
						debug: false,
						timestamp: '<%= grunt.template.today() %>'
					}
				},
				files: {
					'<%= yeoman.dist %>/index.html': ['<%= yeoman.app %>/index.jade'],
					'<%= yeoman.dist %>/views/main.html': ['<%= yeoman.app %>/views/main.jade']
				}
			}
		}
	});

	grunt.registerTask('server', function (target) {
		if (target === 'dist') {
			return grunt.task.run(['build', 'connect:dist:keepalive']);
		}

		grunt.task.run([
			'clean:server',
			'jade',
			'concurrent:server',
			'autoprefixer',
			'connect:livereload',
			'watch'
		]);
	});

	grunt.registerTask('test', [
		'clean:server',
		'concurrent:test',
		'autoprefixer',
		'connect:test',
		'karma'
	]);

	grunt.registerTask('build', [
		'clean:dist',
		'jade',
//		'useminPrepare',
		'concurrent:dist',
		'autoprefixer',
		'ngmin',
		'copy:dist',
		'cdnify',
		'uglify',
		'rev'
//		'usemin'
	]);

	grunt.registerTask('default', [
		'jshint',
		'test',
		'build'
	]);
};
<|endoftext|>


<commit_before>/* eslint max-statements: [1, 18] */
/* eslint complexity: [1, 10] */
import React from 'react';
import ace from 'brace';

const AceEditor = React.createClass({
    propTypes: {
        mode: React.PropTypes.string,
        theme: React.PropTypes.string,
        name: React.PropTypes.string,
        height: React.PropTypes.string,
        width: React.PropTypes.string,
        fontSize: React.PropTypes.number,
        showGutter: React.PropTypes.bool,
        onChange: React.PropTypes.func,
        defaultValue: React.PropTypes.string,
        value: React.PropTypes.string,
        onLoad: React.PropTypes.func,
        maxLines: React.PropTypes.number,
        readOnly: React.PropTypes.bool,
        highlightActiveLine: React.PropTypes.bool,
        showPrintMargin: React.PropTypes.bool,
        selectFirstLine: React.PropTypes.bool,
        wrapEnabled: React.PropTypes.bool
    },
    getDefaultProps() {
        return {
            name: 'brace-editor',
            mode: '',
            theme: '',
            height: '500px',
            width: '500px',
            defaultValue: '',
            value: '',
            fontSize: 12,
            showGutter: true,
            onChange: null,
            onLoad: null,
            maxLines: null,
            readOnly: false,
            highlightActiveLine: true,
            showPrintMargin: true,
            selectFirstLine: false,
            wrapEnabled: false
        };
    },
    onChange() {
        if (this.props.onChange) {
            const value = this.editor.getValue();
            this.props.onChange(value);
        }
    },
    componentDidMount() {
        this.editor = ace.edit(this.props.name);
        this.editor.getSession().setMode('ace/mode/' + this.props.mode);
        this.editor.setTheme('ace/theme/' + this.props.theme);
        this.editor.setFontSize(this.props.fontSize);
        this.editor.on('change', this.onChange);
        this.editor.setValue(this.props.defaultValue || this.props.value, (this.props.selectFirstLine === true ? -1 : null));
        this.editor.setOption('maxLines', this.props.maxLines);
        this.editor.setOption('readOnly', this.props.readOnly);
        this.editor.setOption('highlightActiveLine', this.props.highlightActiveLine);
        this.editor.setShowPrintMargin(this.props.setShowPrintMargin);
        this.editor.getSession().setUseWrapMode(this.props.wrapEnabled);
        this.editor.renderer.setShowGutter(this.props.showGutter);

        if (this.props.onLoad) {
            this.props.onLoad(this.editor);
        }
    },

    componentWillReceiveProps(nextProps) {
        let currentRange = this.editor.selection.getRange();

        // only update props if they are changed
        if (nextProps.mode !== this.props.mode) {
            this.editor.getSession().setMode('ace/mode/' + nextProps.mode);
        }
        if (nextProps.theme !== this.props.theme) {
            this.editor.setTheme('ace/theme/' + nextProps.theme);
        }
        if (nextProps.fontSize !== this.props.fontSize) {
            this.editor.setFontSize(nextProps.fontSize);
        }
        if (nextProps.maxLines !== this.props.maxLines) {
            this.editor.setOption('maxLines', nextProps.maxLines);
        }
        if (nextProps.readOnly !== this.props.readOnly) {
            this.editor.setOption('readOnly', nextProps.readOnly);
        }
        if (nextProps.highlightActiveLine !== this.props.highlightActiveLine) {
            this.editor.setOption('highlightActiveLine', nextProps.highlightActiveLine);
        }
        if (nextProps.setShowPrintMargin !== this.props.setShowPrintMargin) {
            this.editor.setShowPrintMargin(nextProps.setShowPrintMargin);
        }
        if (nextProps.wrapEnabled !== this.props.wrapEnabled) {
            this.editor.getSession().setUseWrapMode(nextProps.wrapEnabled);
        }
        if (nextProps.value && this.editor.getValue() !== nextProps.value) {
            this.editor.setValue(nextProps.value, (this.props.selectFirstLine === true ? -1 : null));
            if(currentRange && typeof currentRange === "object") {
                this.editor.getSession().getSelection().setSelectionRange(currentRange);
            }
        }
        if (nextProps.showGutter !== this.props.showGutter) {
            this.editor.renderer.setShowGutter(nextProps.showGutter);
        }
    },

    render() {
        const divStyle = {
            width: this.props.width,
            height: this.props.height,
        };

        return React.DOM.div({
            id: this.props.name,
            onChange: this.onChange,
            style: divStyle,
        });
    }
});

export default AceEditor;
<commit_msg>disable blockscrolling<commit_after>/* eslint max-statements: [1, 18] */
/* eslint complexity: [1, 10] */
import React from 'react';
import ace from 'brace';

const AceEditor = React.createClass({
    propTypes: {
        mode: React.PropTypes.string,
        theme: React.PropTypes.string,
        name: React.PropTypes.string,
        height: React.PropTypes.string,
        width: React.PropTypes.string,
        fontSize: React.PropTypes.number,
        showGutter: React.PropTypes.bool,
        onChange: React.PropTypes.func,
        defaultValue: React.PropTypes.string,
        value: React.PropTypes.string,
        onLoad: React.PropTypes.func,
        maxLines: React.PropTypes.number,
        readOnly: React.PropTypes.bool,
        highlightActiveLine: React.PropTypes.bool,
        showPrintMargin: React.PropTypes.bool,
        selectFirstLine: React.PropTypes.bool,
        wrapEnabled: React.PropTypes.bool
    },
    getDefaultProps() {
        return {
            name: 'brace-editor',
            mode: '',
            theme: '',
            height: '500px',
            width: '500px',
            defaultValue: '',
            value: '',
            fontSize: 12,
            showGutter: true,
            onChange: null,
            onLoad: null,
            maxLines: null,
            readOnly: false,
            highlightActiveLine: true,
            showPrintMargin: true,
            selectFirstLine: false,
            wrapEnabled: false
        };
    },
    onChange() {
        if (this.props.onChange) {
            const value = this.editor.getValue();
            this.props.onChange(value);
        }
    },
    componentDidMount() {
        this.editor = ace.edit(this.props.name);
        this.editor.$blockScrolling = Infinity;
        this.editor.getSession().setMode('ace/mode/' + this.props.mode);
        this.editor.setTheme('ace/theme/' + this.props.theme);
        this.editor.setFontSize(this.props.fontSize);
        this.editor.on('change', this.onChange);
        this.editor.setValue(this.props.defaultValue || this.props.value, (this.props.selectFirstLine === true ? -1 : null));
        this.editor.setOption('maxLines', this.props.maxLines);
        this.editor.setOption('readOnly', this.props.readOnly);
        this.editor.setOption('highlightActiveLine', this.props.highlightActiveLine);
        this.editor.setShowPrintMargin(this.props.setShowPrintMargin);
        this.editor.getSession().setUseWrapMode(this.props.wrapEnabled);
        this.editor.renderer.setShowGutter(this.props.showGutter);

        if (this.props.onLoad) {
            this.props.onLoad(this.editor);
        }
    },

    componentWillReceiveProps(nextProps) {
        let currentRange = this.editor.selection.getRange();

        // only update props if they are changed
        if (nextProps.mode !== this.props.mode) {
            this.editor.getSession().setMode('ace/mode/' + nextProps.mode);
        }
        if (nextProps.theme !== this.props.theme) {
            this.editor.setTheme('ace/theme/' + nextProps.theme);
        }
        if (nextProps.fontSize !== this.props.fontSize) {
            this.editor.setFontSize(nextProps.fontSize);
        }
        if (nextProps.maxLines !== this.props.maxLines) {
            this.editor.setOption('maxLines', nextProps.maxLines);
        }
        if (nextProps.readOnly !== this.props.readOnly) {
            this.editor.setOption('readOnly', nextProps.readOnly);
        }
        if (nextProps.highlightActiveLine !== this.props.highlightActiveLine) {
            this.editor.setOption('highlightActiveLine', nextProps.highlightActiveLine);
        }
        if (nextProps.setShowPrintMargin !== this.props.setShowPrintMargin) {
            this.editor.setShowPrintMargin(nextProps.setShowPrintMargin);
        }
        if (nextProps.wrapEnabled !== this.props.wrapEnabled) {
            this.editor.getSession().setUseWrapMode(nextProps.wrapEnabled);
        }
        if (nextProps.value && this.editor.getValue() !== nextProps.value) {
            this.editor.setValue(nextProps.value, (this.props.selectFirstLine === true ? -1 : null));
            if(currentRange && typeof currentRange === "object") {
                this.editor.getSession().getSelection().setSelectionRange(currentRange);
            }
        }
        if (nextProps.showGutter !== this.props.showGutter) {
            this.editor.renderer.setShowGutter(nextProps.showGutter);
        }
    },

    render() {
        const divStyle = {
            width: this.props.width,
            height: this.props.height,
        };

        return React.DOM.div({
            id: this.props.name,
            onChange: this.onChange,
            style: divStyle,
        });
    }
});

export default AceEditor;
<|endoftext|>