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

//Needed for monit/upstart
//Change directory into the script directory so includes resolve
process.chdir(__dirname);

var express = require('express'),
    path = require('path'),
    fs = require('fs'),
    YUI = require('yui3').YUI,
    DEBUG = true;

/**
* Create the external instance that will host our "express" server.
* For a performance gain, you can "use" common modules here, so they
* are available when a new instance is created per request.
*/
YUI({ debug: false }).use('express', 'node', function(Y) {

    //Create the express application
    var app = express.createServer();

    //Configure it with some simple configuration options.
    app.configure(function(){
        app.use(express.methodOverride());
        app.use(express.bodyDecoder());
        app.use(express.cookieDecoder());
        app.use(app.router);
        app.use(express.staticProvider(__dirname + '/assets'));
    });

    //Set the development environment to debug, so YUI modues echo log statements
    app.configure('development', function(){
        DEBUG = true;
    });
    //Set the production environment to halt all debug logs.
    app.configure('production', function(){
        DEBUG = false;
    });

    /**
    * This version of the YUIExpress engine comes with a simple YUI combo handler
    * So you can put "use" inside your locals var on render:
    *
    * res.render('index.html', {
    *       locals: {
    *           use: ['dd', 'tabview']
    *       }
    * });
    *
    * This will load a URL into the page like this:
    *
    *
    * Note, currently it has to be "/combo", the internal renderer doesn't
    * know what you set this to. Eventually we can add it to YUI.configure.
    */
    app.get('/combo', YUI.combo);

    /**
    * This is the "black magic" part. This tells Express to use YUI to render
    * all HTML pages
    */
    app.register('.html', YUI);
    //The same as other Express View Engines
    //app.register('.html', require('jade'));
    //app.register('.haml', require('haml-js'));

    /**
    * These partials will be added to every page served by YUI, good for templating.
    * They can be added to by locals.partials on a per page basis. A partial looks like this:
    * {
    *   name: 'header', //Name of the /views/partial/{name}.html file to load
    *   method: 'append', //append,prepend,appendChild
    *   node: '#conent', //Any valid selector
    *   enum: 'one', //one,all
    *   fn: function //The callback function to run after the action.
    * }
    * Defaults to enum: "one" and method: "append"
    */

    YUI.partials = [
        {
            name: 'layout_head',
            node: 'head'
        }
    ];

    /**
    * YUI.configure allows you to configure routes for the yui2 & yui3 assests.
    * With this config you will serve yui2 assets from /yui2/ and yui3 assets from
    * /yui3
    *
    */
    YUI.configure(app, {
        yui2: '/yui2/',
        yui3: '/yui3/'
    });

    /**
    * The route controller for the default page: /
    * This is a simple example of serving a static HTML page with a little
    * Javascript to enhance the page.
    */
    app.get('/', function(req, res) {
        //Render from ./views/index.html
        res.render('index.html', {
            //Locals used by the YUI renderer
            locals: {
                /**
                * This is the content placeholder in your ./views/layout.html file.
                * The content of index.html will be inserted here.
                */
                content: '#content',
                /**
                * Standard object hash to be passed to Y.Lang.sub after the
                * content has been loaded, but before it's inserted into the YUI
                * instance on render.
                */
                sub: {
                    title: 'YUI/Express JS Demo'
                },
                /**
                * The after method will be invoked after the layout.html file
                * has been loaded into the instance. This allows you to change
                * the total layout, after all the peices have been assembled.
                */
                after: function(Y, options, partial) {
                    Y.one('title').set('innerHTML', 'Home Page: Hello Word');
                }
            }
        });
    });

    /**
    * Pages 1, 2 & 3 are all the same HTML page template.
    * The simply change the content of that page after it's
    * loaded into the YUI instance. They use some of the same
    * properties as the one above, only they also use the "before" method.
    */
    app.get('/one', function(req, res){
        res.render('same.html', {
            locals: {
                content: '#content',
                sub: {
                    title: 'YUI/Express JS Demo'
                },
                /**
                * The before method is similar to the "after" method, only it's action is to
                * only deal with the content of the partial that was loaded. It allows you
                * to modify the partials HTML after that template was loaded into an instance.
                */
                before: function(Y) {
                    Y.one('h1').set('innerHTML', 'Welcome to Page #1');
                },
                after: function(Y, options, partial) {
                    //Set the title of the page
                    Y.one('title').set('innerHTML', 'Page #1');
                    //Update the nav and remove all selected nav items
                    Y.all('#nav li').removeClass('selected');
                    //Grab the one for page one and add selected.
                    Y.one('#nav li.one').addClass('selected');
                }
            }
        });
    });

    app.get('/two', function(req, res){
        res.render('same.html', {
            locals: {
                content: '#content',
                sub: {
                    title: 'YUI/Express JS Demo'
                },
                before: function(Y) {
                    Y.one('h1').set('innerHTML', 'Welcome to Page #2');
                },
                after: function(Y, options, partial) {
                    Y.one('title').set('innerHTML', 'Page #2');
                    Y.all('#nav li').removeClass('selected');
                    Y.one('#nav li.two').addClass('selected');
                }
            }
        });
    });

    app.get('/three', function(req, res){
        res.render('same.html', {
            locals: {
                content: '#content',
                sub: {
                    title: 'YUI/Express JS Demo'
                },
                before: function(Y) {
                    Y.one('h1').set('innerHTML', 'Welcome to Page #3');
                },
                after: function(Y, options, partial) {
                    Y.one('title').set('innerHTML', 'Page #3');
                    Y.all('#nav li').removeClass('selected');
                    Y.one('#nav li.three').addClass('selected');
                }
            }
        });
    });

    /**
    * This handler does a couple special things.
    *   Uses an external module (CODE REUSE)
    *   Uses YUI2
    *   Handles user action from requests
    */
    app.get('/calendar', function(req, res) {
        YUI({
            debug: DEBUG,
            modules: {
                'local-cal': {
                    //For more detail see this file..
                    fullpath: __dirname + '/modules/local-cal.js'
                }
            }
        }).use('node', 'local-cal', function(page) {
            //Calling a method inside an external module
            page.localCal(req, res);
        });
    });
    /**
    * This handler is similar to the /calendar, but it renders a DataTable instead.
    */
    app.get('/datatable', function(req, res) {
        YUI({
            debug: DEBUG,
            modules: {
                'local-dt': {
                    fullpath: __dirname + '/modules/local-dt.js'
                }
            },
        }).use('node', 'local-dt', function(page) {
            //Calling a method inside an external module
            page.localDT(req, res);

        });
    });

    var diggCache = null;

    app.get('/digg', function(req, res) {
        YUI({ debug: DEBUG }).use('node', 'io', function(page) {
            var ul = page.one('body').addClass('digg').appendChild(page.Node.create('

'));

            var sendRequest = function() {
                res.render('digg.html', {
                    locals: {
                        instance: page,
                        content: '#content',
                        sub: {
                            title: 'YUI/Express JS Demo'
                        },
                        after: function(Y, options, partial) {
                            Y.one('title').set('innerHTML', 'Digg Scrapping');
                            Y.all('#nav li').removeClass('selected');
                            Y.one('#nav li.digg').addClass('selected');
                        }
                    }
                });
            };

            if (diggCache) {
                //console.log('Loading Digg from cache');
                ul.set('innerHTML', diggCache);
                sendRequest();
            } else {
                //console.log('Fetching News');
                YUI({ debug: DEBUG }).use('node', function(remotePage) {

                    var url = 'http://digg.com/news';

                    //This will call io under the hood and get the content of the URL,
                    //It will then dump the content of that page into this sandboxed document.
                    remotePage.fetch(url, function() {
                        //Get all the news items from the remote page.
                        var newsItems = remotePage.all('#story-items h3');
                        //Iterate them
                        newsItems.each(function(n) {
                            //Import this "A" node into the outside instances document
                            var a = ul.importNode(n.one('a'), true);
                            //Clean up the relative URL's of hrefs
                            a.set('href', 'http://digg.com' + a.get('href'));
                            //Append the new node to the list
                            ul.appendChild(page.Node.create('

')).append(a);
                        });

                        diggCache = ul.get('innerHTML');

                        sendRequest();

                        setTimeout(function() {
                            //console.log('clear digg cache');
                            diggCache = null;
                        }, (1000 * 60 * 5));

                    });
                });
            }
        });
    });

    app.get('/notice', function(req, res) {
        res.render('notice.html', {
            locals: {
                content: '#content',
                sub: {
                    title: 'This is a notice'
                },
                after: function(Y) {
                    Y.one('#nav').remove();
                    Y.one('#doc').replaceClass('yui-t1', 'yui-t7');
                }
            }
        });
    });

    app.get('/tabview', function(req, res) {

        var selectedTab = 0;
        if (req.cookies.tabview) {
            selectedTab = req.cookies.tabview;
        }
        if (req.query.tab > -1) {
            selectedTab = req.query.tab;
        }

        YUI({ debug: DEBUG }).use('tabview', 'yql', function(page) {
            var div = page.Node.create('

');
            page.one('body').addClass('yui3-skin-sam').appendChild(div);

            page.log('Creating the TabView from script..');
            var tabview = new page.TabView({
                children: [{
                    label: 'foo',
                    content: '
foo content
'
                }, {
                    label: 'bar',
                    content: '
bar content
'
                }, {
                    label: 'baz',
                    content: '
baz content
'
                }]
            });

            tabview.render('#demo');
            var as = page.all('#demo .yui3-tab-label');
            as.each(function(v, k) {
                v.set('href', '/tabview?tab=' + k);
            });
            if (selectedTab) {
                tabview.selectChild(selectedTab);
            }

            res.render('tabview.html', {
                locals: {
                    instance: page,
                    use: ['tabview', 'cookie'],
                    //filter: 'debug',
                    content: '#content',
                    sub: {
                        title: 'YUI/Express JS Demo'
                    },
                    after: function(Y, options, partial) {
                        Y.Get.domScript('/tabview.js');
                        Y.one('title').set('innerHTML', 'YUI 3.x TabView');
                        Y.all('#nav li').removeClass('selected');
                        Y.one('#nav li.tabview').addClass('selected');
                    }
                }
            });
        });
    });

    app.get('/github/:id?', function(req, res) {
        var sql = "select * from github.repo.network where id='yui' and repo='yui3'";
        if (req.params.id) {
            sql = Y.Lang.sub("select * from github.user.info where id='{id}'", req.params);
        }

        YUI({ debug: DEBUG }).use('yql', 'node', function(page) {
            var title = 'Github YUI Followers';
            page.YQL(sql, function(r) {
                if (r.query.results.user) {
                    var parts = res.partial('github_member.html');
                    title = r.query.results.user.name;
                    parts = page.Lang.sub(parts, r.query.results.user);
                    page.one('body').append(parts);
                    var lis = page.all('#member li');
                    lis.each(function(n) {
                        //Need a sub method that fixes this stuff...
                        if (n.get('innerHTML').indexOf('Object') > -1) {
                            n.remove();
                        }
                        if (n.get('innerHTML').indexOf('{') > -1) {
                            n.remove();
                        }
                        if (n.get('innerHTML').indexOf('null') > -1) {
                            n.remove();
                        }
                    });
                } else {
                    var parts = res.partial('github_list.html');
                    var ul = page.Node.create('

');
                    page.one('body').append(ul);
                    page.each(r.query.results.network.network, function(d) {
                        ul.append(page.Lang.sub(parts, d));
                    });
                }

                res.render('github.html', {
                    locals: {
                        instance: page,
                        content: '#content',
                        sub: {
                            title: 'YUI3 Github Network'
                        },
                        after: function(Y) {
                            Y.one('title').set('innerHTML', 'YUI3 Github Network');
                            Y.one('#content h1').set('innerHTML', title);
                            Y.all('#nav li').removeClass('selected');
                            Y.one('#nav li.github').addClass('selected');
                        }
                    }
                });
            });

        });
    });

    app.listen(3200);
    if (DEBUG) {
        console.log('Server running at: http://localhost:3200/');
    }

});

<commit_msg>Changed homepage title for better bookmarking.<commit_after>#!/usr/bin/env node

//Needed for monit/upstart
//Change directory into the script directory so includes resolve
process.chdir(__dirname);

var express = require('express'),
    path = require('path'),
    fs = require('fs'),
    YUI = require('yui3').YUI,
    DEBUG = true;

/**
* Create the external instance that will host our "express" server.
* For a performance gain, you can "use" common modules here, so they
* are available when a new instance is created per request.
*/
YUI({ debug: false }).use('express', 'node', function(Y) {

    //Create the express application
    var app = express.createServer();

    //Configure it with some simple configuration options.
    app.configure(function(){
        app.use(express.methodOverride());
        app.use(express.bodyDecoder());
        app.use(express.cookieDecoder());
        app.use(app.router);
        app.use(express.staticProvider(__dirname + '/assets'));
    });

    //Set the development environment to debug, so YUI modues echo log statements
    app.configure('development', function(){
        DEBUG = true;
    });
    //Set the production environment to halt all debug logs.
    app.configure('production', function(){
        DEBUG = false;
    });

    /**
    * This version of the YUIExpress engine comes with a simple YUI combo handler
    * So you can put "use" inside your locals var on render:
    *
    * res.render('index.html', {
    *       locals: {
    *           use: ['dd', 'tabview']
    *       }
    * });
    *
    * This will load a URL into the page like this:
    *
    *
    * Note, currently it has to be "/combo", the internal renderer doesn't
    * know what you set this to. Eventually we can add it to YUI.configure.
    */
    app.get('/combo', YUI.combo);

    /**
    * This is the "black magic" part. This tells Express to use YUI to render
    * all HTML pages
    */
    app.register('.html', YUI);
    //The same as other Express View Engines
    //app.register('.html', require('jade'));
    //app.register('.haml', require('haml-js'));

    /**
    * These partials will be added to every page served by YUI, good for templating.
    * They can be added to by locals.partials on a per page basis. A partial looks like this:
    * {
    *   name: 'header', //Name of the /views/partial/{name}.html file to load
    *   method: 'append', //append,prepend,appendChild
    *   node: '#conent', //Any valid selector
    *   enum: 'one', //one,all
    *   fn: function //The callback function to run after the action.
    * }
    * Defaults to enum: "one" and method: "append"
    */

    YUI.partials = [
        {
            name: 'layout_head',
            node: 'head'
        }
    ];

    /**
    * YUI.configure allows you to configure routes for the yui2 & yui3 assests.
    * With this config you will serve yui2 assets from /yui2/ and yui3 assets from
    * /yui3
    *
    */
    YUI.configure(app, {
        yui2: '/yui2/',
        yui3: '/yui3/'
    });

    /**
    * The route controller for the default page: /
    * This is a simple example of serving a static HTML page with a little
    * Javascript to enhance the page.
    */
    app.get('/', function(req, res) {
        //Render from ./views/index.html
        res.render('index.html', {
            //Locals used by the YUI renderer
            locals: {
                /**
                * This is the content placeholder in your ./views/layout.html file.
                * The content of index.html will be inserted here.
                */
                content: '#content',
                /**
                * Standard object hash to be passed to Y.Lang.sub after the
                * content has been loaded, but before it's inserted into the YUI
                * instance on render.
                */
                sub: {
                    title: 'YUI/Express JS Demo'
                },
                /**
                * The after method will be invoked after the layout.html file
                * has been loaded into the instance. This allows you to change
                * the total layout, after all the peices have been assembled.
                */
                after: function(Y, options, partial) {
                    Y.one('title').set('innerHTML', 'YUI/Express JS Demo');
                }
            }
        });
    });

    /**
    * Pages 1, 2 & 3 are all the same HTML page template.
    * The simply change the content of that page after it's
    * loaded into the YUI instance. They use some of the same
    * properties as the one above, only they also use the "before" method.
    */
    app.get('/one', function(req, res){
        res.render('same.html', {
            locals: {
                content: '#content',
                sub: {
                    title: 'YUI/Express JS Demo'
                },
                /**
                * The before method is similar to the "after" method, only it's action is to
                * only deal with the content of the partial that was loaded. It allows you
                * to modify the partials HTML after that template was loaded into an instance.
                */
                before: function(Y) {
                    Y.one('h1').set('innerHTML', 'Welcome to Page #1');
                },
                after: function(Y, options, partial) {
                    //Set the title of the page
                    Y.one('title').set('innerHTML', 'Page #1');
                    //Update the nav and remove all selected nav items
                    Y.all('#nav li').removeClass('selected');
                    //Grab the one for page one and add selected.
                    Y.one('#nav li.one').addClass('selected');
                }
            }
        });
    });

    app.get('/two', function(req, res){
        res.render('same.html', {
            locals: {
                content: '#content',
                sub: {
                    title: 'YUI/Express JS Demo'
                },
                before: function(Y) {
                    Y.one('h1').set('innerHTML', 'Welcome to Page #2');
                },
                after: function(Y, options, partial) {
                    Y.one('title').set('innerHTML', 'Page #2');
                    Y.all('#nav li').removeClass('selected');
                    Y.one('#nav li.two').addClass('selected');
                }
            }
        });
    });

    app.get('/three', function(req, res){
        res.render('same.html', {
            locals: {
                content: '#content',
                sub: {
                    title: 'YUI/Express JS Demo'
                },
                before: function(Y) {
                    Y.one('h1').set('innerHTML', 'Welcome to Page #3');
                },
                after: function(Y, options, partial) {
                    Y.one('title').set('innerHTML', 'Page #3');
                    Y.all('#nav li').removeClass('selected');
                    Y.one('#nav li.three').addClass('selected');
                }
            }
        });
    });

    /**
    * This handler does a couple special things.
    *   Uses an external module (CODE REUSE)
    *   Uses YUI2
    *   Handles user action from requests
    */
    app.get('/calendar', function(req, res) {
        YUI({
            debug: DEBUG,
            modules: {
                'local-cal': {
                    //For more detail see this file..
                    fullpath: __dirname + '/modules/local-cal.js'
                }
            }
        }).use('node', 'local-cal', function(page) {
            //Calling a method inside an external module
            page.localCal(req, res);
        });
    });
    /**
    * This handler is similar to the /calendar, but it renders a DataTable instead.
    */
    app.get('/datatable', function(req, res) {
        YUI({
            debug: DEBUG,
            modules: {
                'local-dt': {
                    fullpath: __dirname + '/modules/local-dt.js'
                }
            },
        }).use('node', 'local-dt', function(page) {
            //Calling a method inside an external module
            page.localDT(req, res);

        });
    });

    var diggCache = null;

    app.get('/digg', function(req, res) {
        YUI({ debug: DEBUG }).use('node', 'io', function(page) {
            var ul = page.one('body').addClass('digg').appendChild(page.Node.create('

'));

            var sendRequest = function() {
                res.render('digg.html', {
                    locals: {
                        instance: page,
                        content: '#content',
                        sub: {
                            title: 'YUI/Express JS Demo'
                        },
                        after: function(Y, options, partial) {
                            Y.one('title').set('innerHTML', 'Digg Scrapping');
                            Y.all('#nav li').removeClass('selected');
                            Y.one('#nav li.digg').addClass('selected');
                        }
                    }
                });
            };

            if (diggCache) {
                //console.log('Loading Digg from cache');
                ul.set('innerHTML', diggCache);
                sendRequest();
            } else {
                //console.log('Fetching News');
                YUI({ debug: DEBUG }).use('node', function(remotePage) {

                    var url = 'http://digg.com/news';

                    //This will call io under the hood and get the content of the URL,
                    //It will then dump the content of that page into this sandboxed document.
                    remotePage.fetch(url, function() {
                        //Get all the news items from the remote page.
                        var newsItems = remotePage.all('#story-items h3');
                        //Iterate them
                        newsItems.each(function(n) {
                            //Import this "A" node into the outside instances document
                            var a = ul.importNode(n.one('a'), true);
                            //Clean up the relative URL's of hrefs
                            a.set('href', 'http://digg.com' + a.get('href'));
                            //Append the new node to the list
                            ul.appendChild(page.Node.create('

')).append(a);
                        });

                        diggCache = ul.get('innerHTML');

                        sendRequest();

                        setTimeout(function() {
                            //console.log('clear digg cache');
                            diggCache = null;
                        }, (1000 * 60 * 5));

                    });
                });
            }
        });
    });

    app.get('/notice', function(req, res) {
        res.render('notice.html', {
            locals: {
                content: '#content',
                sub: {
                    title: 'This is a notice'
                },
                after: function(Y) {
                    Y.one('#nav').remove();
                    Y.one('#doc').replaceClass('yui-t1', 'yui-t7');
                }
            }
        });
    });

    app.get('/tabview', function(req, res) {

        var selectedTab = 0;
        if (req.cookies.tabview) {
            selectedTab = req.cookies.tabview;
        }
        if (req.query.tab > -1) {
            selectedTab = req.query.tab;
        }

        YUI({ debug: DEBUG }).use('tabview', 'yql', function(page) {
            var div = page.Node.create('

');
            page.one('body').addClass('yui3-skin-sam').appendChild(div);

            page.log('Creating the TabView from script..');
            var tabview = new page.TabView({
                children: [{
                    label: 'foo',
                    content: '
foo content
'
                }, {
                    label: 'bar',
                    content: '
bar content
'
                }, {
                    label: 'baz',
                    content: '
baz content
'
                }]
            });

            tabview.render('#demo');
            var as = page.all('#demo .yui3-tab-label');
            as.each(function(v, k) {
                v.set('href', '/tabview?tab=' + k);
            });
            if (selectedTab) {
                tabview.selectChild(selectedTab);
            }

            res.render('tabview.html', {
                locals: {
                    instance: page,
                    use: ['tabview', 'cookie'],
                    //filter: 'debug',
                    content: '#content',
                    sub: {
                        title: 'YUI/Express JS Demo'
                    },
                    after: function(Y, options, partial) {
                        Y.Get.domScript('/tabview.js');
                        Y.one('title').set('innerHTML', 'YUI 3.x TabView');
                        Y.all('#nav li').removeClass('selected');
                        Y.one('#nav li.tabview').addClass('selected');
                    }
                }
            });
        });
    });

    app.get('/github/:id?', function(req, res) {
        var sql = "select * from github.repo.network where id='yui' and repo='yui3'";
        if (req.params.id) {
            sql = Y.Lang.sub("select * from github.user.info where id='{id}'", req.params);
        }

        YUI({ debug: DEBUG }).use('yql', 'node', function(page) {
            var title = 'Github YUI Followers';
            page.YQL(sql, function(r) {
                if (r.query.results.user) {
                    var parts = res.partial('github_member.html');
                    title = r.query.results.user.name;
                    parts = page.Lang.sub(parts, r.query.results.user);
                    page.one('body').append(parts);
                    var lis = page.all('#member li');
                    lis.each(function(n) {
                        //Need a sub method that fixes this stuff...
                        if (n.get('innerHTML').indexOf('Object') > -1) {
                            n.remove();
                        }
                        if (n.get('innerHTML').indexOf('{') > -1) {
                            n.remove();
                        }
                        if (n.get('innerHTML').indexOf('null') > -1) {
                            n.remove();
                        }
                    });
                } else {
                    var parts = res.partial('github_list.html');
                    var ul = page.Node.create('

');
                    page.one('body').append(ul);
                    page.each(r.query.results.network.network, function(d) {
                        ul.append(page.Lang.sub(parts, d));
                    });
                }

                res.render('github.html', {
                    locals: {
                        instance: page,
                        content: '#content',
                        sub: {
                            title: 'YUI3 Github Network'
                        },
                        after: function(Y) {
                            Y.one('title').set('innerHTML', 'YUI3 Github Network');
                            Y.one('#content h1').set('innerHTML', title);
                            Y.all('#nav li').removeClass('selected');
                            Y.one('#nav li.github').addClass('selected');
                        }
                    }
                });
            });

        });
    });

    app.listen(3200);
    if (DEBUG) {
        console.log('Server running at: http://localhost:3200/');
    }

});

<|endoftext|>


<commit_before>// Copyright 2012 and onwards 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.

/**
 * @fileoverview Externs for libraries used by this extension.
 * @author manas@google.com (Manas Tungare)
 */

/**
 * @param {Date|string=} opt_date
 * @param {Array.<string>|string=} opt_formatString
 * return {Moment}
 */
function moment(opt_date, opt_formatString) {};

/**
 * Externs for the Moment.js library.
 * @constructor
 */
function Moment() {};

/**
 * @param {string=} opt_locale
 */
Moment.lang = function(opt_locale) {};

/** @return {string} */
Moment.prototype.calendar = function() {};

/** @return {Moment} */
Moment.prototype.clone = function() {};

/**
 * @param {Moment} another
 * @param {string=} opt_unit
 * @param {boolean=} opt_float
 * @return {number}
 */
Moment.prototype.diff = function(another, opt_unit, opt_float) {};

/**
 * @param {string=} opt_formatString
 * @return {string}
 */
Moment.prototype.format = function(opt_formatString) {};

/** @return {string} */
Moment.prototype.fromNow = function() {};

/**
 * @param {number=} opt_hours
 * @return {number|Moment}
 */
Moment.prototype.hours = function(opt_hours) {};

/**
 * @param {number=} opt_minutes
 * @return {number|Moment}
 */
Moment.prototype.minutes = function(opt_minutes) {};

/**
 * @param {number=} opt_seconds
 * @return {number|Moment}
 */
Moment.prototype.seconds = function(opt_seconds) {};

/** @return {Date} */
Moment.prototype.toDate = function() {};

/** @return {number} */
Moment.prototype.year = function() {};

<commit_msg>Added externs for moment().valueOf().<commit_after>// Copyright 2012 and onwards 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.

/**
 * @fileoverview Externs for libraries used by this extension.
 * @author manas@google.com (Manas Tungare)
 */

/**
 * @param {Date|string=} opt_date
 * @param {Array.<string>|string=} opt_formatString
 * return {Moment}
 */
function moment(opt_date, opt_formatString) {};

/**
 * Externs for the Moment.js library.
 * @constructor
 */
function Moment() {};

/**
 * @param {string=} opt_locale
 */
Moment.lang = function(opt_locale) {};

/** @return {string} */
Moment.prototype.calendar = function() {};

/** @return {Moment} */
Moment.prototype.clone = function() {};

/**
 * @param {Moment} another
 * @param {string=} opt_unit
 * @param {boolean=} opt_float
 * @return {number}
 */
Moment.prototype.diff = function(another, opt_unit, opt_float) {};

/**
 * @param {string=} opt_formatString
 * @return {string}
 */
Moment.prototype.format = function(opt_formatString) {};

/** @return {string} */
Moment.prototype.fromNow = function() {};

/**
 * @param {number=} opt_hours
 * @return {number|Moment}
 */
Moment.prototype.hours = function(opt_hours) {};

/**
 * @param {number=} opt_minutes
 * @return {number|Moment}
 */
Moment.prototype.minutes = function(opt_minutes) {};

/**
 * @param {number=} opt_seconds
 * @return {number|Moment}
 */
Moment.prototype.seconds = function(opt_seconds) {};

/** @return {Date} */
Moment.prototype.toDate = function() {};

/** @return {number} */
Moment.prototype.valueOf = function() {};

/** @return {number} */
Moment.prototype.year = function() {};

<|endoftext|>


<commit_before>import { CancelToken, create } from 'axios';
import wriAPISerializer from 'wri-json-api-serializer';

import {
  GFW_API,
  GFW_STAGING_API,
  GFW_DATA_API,
  GFW_TILES_API,
  CARTO_API,
  MAPBOX_API,
  RESOURCE_WATCH_API,
} from 'utils/apis';

const ENVIRONMENT = process.env.NEXT_PUBLIC_FEATURE_ENV;
const DATA_API_KEY = process.env.NEXT_PUBLIC_DATA_API_KEY;
const GFW_API_URL = ENVIRONMENT === 'staging' ? GFW_STAGING_API : GFW_API;

const isServer = typeof window === 'undefined';

export const apiRequest = create({
  timeout: 30 * 1000,
  baseURL: GFW_API_URL,
  ...(ENVIRONMENT === 'staging' && {
    headers: {
      'x-api-key': DATA_API_KEY,
    },
  }),
  // transformResponse: [(data) => wriAPISerializer(JSON.parse(data))],
});

export const dataRequest = create({
  timeout: 30 * 1000,
  baseURL: GFW_DATA_API,
  transformResponse: [(data) => JSON.parse(data)?.data],
});

export const tilesRequest = create({
  timeout: 30 * 1000,
  baseURL: GFW_TILES_API,
  // transformResponse: [(data) => wriAPISerializer(JSON.parse(data))],
});

export const rwRequest = create({
  timeout: 30 * 1000,
  baseURL: RESOURCE_WATCH_API,
  transformResponse: [(data) => wriAPISerializer(JSON.parse(data))],
});

export const apiAuthRequest = create({
  timeout: 30 * 1000,
  baseURL: GFW_API_URL,
  headers: {
    'content-type': 'application/json',
    Authorization: `Bearer ${!isServer && localStorage.getItem('userToken')}`,
  },
  // transformResponse: [(data) => wriAPISerializer(JSON.parse(data))],
});

export const cartoRequest = create({
  timeout: 30 * 1000,
  baseURL: CARTO_API,
});

export const mapboxRequest = create({
  timeout: 30 * 1000,
  baseURL: MAPBOX_API,
});

export const cancelToken = () => CancelToken.source();

export default create({
  timeout: 30 * 1000,
});
<commit_msg>prefix env for data api key<commit_after>import { CancelToken, create } from 'axios';
import wriAPISerializer from 'wri-json-api-serializer';

import {
  GFW_API,
  GFW_STAGING_API,
  GFW_DATA_API,
  GFW_TILES_API,
  CARTO_API,
  MAPBOX_API,
  RESOURCE_WATCH_API,
} from 'utils/apis';

const ENVIRONMENT = process.env.NEXT_PUBLIC_FEATURE_ENV;
const DATA_API_KEY = process.env.NEXT_PUBLIC_DATA_API_KEY;
const GFW_API_URL = ENVIRONMENT === 'staging' ? GFW_STAGING_API : GFW_API;

const isServer = typeof window === 'undefined';

export const apiRequest = create({
  timeout: 30 * 1000,
  baseURL: GFW_API_URL,
  ...(ENVIRONMENT === 'staging' && {
    headers: {
      [`${ENVIRONMENT}-api-key`]: DATA_API_KEY,
    },
  }),
  // transformResponse: [(data) => wriAPISerializer(JSON.parse(data))],
});

export const dataRequest = create({
  timeout: 30 * 1000,
  baseURL: GFW_DATA_API,
  transformResponse: [(data) => JSON.parse(data)?.data],
});

export const tilesRequest = create({
  timeout: 30 * 1000,
  baseURL: GFW_TILES_API,
  // transformResponse: [(data) => wriAPISerializer(JSON.parse(data))],
});

export const rwRequest = create({
  timeout: 30 * 1000,
  baseURL: RESOURCE_WATCH_API,
  transformResponse: [(data) => wriAPISerializer(JSON.parse(data))],
});

export const apiAuthRequest = create({
  timeout: 30 * 1000,
  baseURL: GFW_API_URL,
  headers: {
    'content-type': 'application/json',
    Authorization: `Bearer ${!isServer && localStorage.getItem('userToken')}`,
  },
  // transformResponse: [(data) => wriAPISerializer(JSON.parse(data))],
});

export const cartoRequest = create({
  timeout: 30 * 1000,
  baseURL: CARTO_API,
});

export const mapboxRequest = create({
  timeout: 30 * 1000,
  baseURL: MAPBOX_API,
});

export const cancelToken = () => CancelToken.source();

export default create({
  timeout: 30 * 1000,
});
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */

import React, { Component } from 'react'

import utils from '../../core/utils';

export default class BrowserWarning extends Component {
  render() {
    var self = this;
    var downloadCopy =

;

    if (!utils.isMobile()) {
      downloadCopy = (

          Copy and paste
          <input type="text" className="blip-link-text" value="blip.tidepool.org"></input>
          into Chrome.

        <button className="btn browser-warning-copy-button" onClick={() => self.copyText()}>Copy link</button>

Or download Chrome here

);
    }

    return (

Blip's visualization is only certified to work on Chrome browser on a computer.

          {downloadCopy}

    );
  }

  copyText() {
    var copyText = document.querySelector('.blip-link-text');
    copyText.select();

    try {
      var copyCmd = document.execCommand('copy');
    } catch (err) {
      console.log('Unable to copy - unsupported browser');
    }
  }
}<commit_msg>Add in graceful degradation when working with Safari!<commit_after>/**
 * Copyright (c) 2016, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */

import React, { Component } from 'react'

import utils from '../../core/utils';

const COPY_STATUS_NULL = 0;
const COPY_STATUS_SUCCESS = 10;
const COPY_STATUS_FAIL = 20;

export default class BrowserWarning extends Component {
  constructor(props) {
    super(props);
    this.state = {
      copyStatus: COPY_STATUS_NULL
    };
  }
  render() {
    var self = this;
    var downloadCopy =

;
    var copyButton = <button className="btn browser-warning-copy-button" onClick={() => self.copyText()}>Copy link</button>;

    if (this.state.copyStatus === COPY_STATUS_SUCCESS) {
      copyButton = <button className="btn browser-warning-copy-button" onClick={() => self.copyText()}>Copied!</button>
    } else if (this.state.copyStatus === COPY_STATUS_FAIL) {
      copyButton = <button className="btn browser-warning-copy-button" onClick={() => self.copyText()}>Please press Ctrl + C now</button>
    }

    if (!utils.isMobile()) {
      downloadCopy = (

          Copy and paste
          <input type="text" className="blip-link-text" value="blip.tidepool.org"></input>
          into Chrome.

        {copyButton}

Or download Chrome here

);
    }

    return (

Blip's visualization is only certified to work on Chrome browser on a computer.

          {downloadCopy}

    );
  }

  copyText() {
    var copyText = document.querySelector('.blip-link-text');
    copyText.select();

    try {
      var copyCmd = document.execCommand('copy');
      this.setState( {
        copyStatus: (copyCmd) ? COPY_STATUS_SUCCESS : COPY_STATUS_FAIL
      });
    } catch (err) {
      console.log('Unable to copy - unsupported browser');
      this.setState({
        copyStatus: COPY_STATUS_FAIL
      });
    }
  }
}<|endoftext|>


<commit_before>// @flow
import { observable, action, computed } from 'mobx';
import { sortBy } from 'lodash';
import Store from './lib/Store';
import resolver from '../utils/imports';
import { ROUTES } from '../routes-config';
import { matchRoute } from '../utils/routing';
import environment from '../environment';

const sidebarConfig = resolver('config/sidebarConfig');
const { formattedWalletAmount } = resolver('utils/formatters');

export default class SidebarStore extends Store {

  CATEGORIES = sidebarConfig.CATEGORIES;

  @observable activeSidebarCategory: string = this.CATEGORIES[0].route;
  @observable isShowingSubMenus: boolean = true;

  setup() {
    const actions = this.actions.sidebar;
    actions.toggleSubMenus.listen(this._toggleSubMenus);
    actions.activateSidebarCategory.listen(this._onActivateSidebarCategory);
    actions.walletSelected.listen(this._onWalletSelected);
    this.registerReactions([
      this._syncSidebarRouteWithRouter,
      this._showSubMenusOnWalletsPageLoad,
    ]);
  }

  @computed get wallets(): Array<SidebarWalletType> {
    const { networkStatus } = this.stores;
    const { wallets } = this.stores[environment.API];
    const sortedWallets = sortBy(wallets.all, ['name']);
    return sortedWallets.map(w => ({
      id: w.id,
      title: w.name,
      info: formattedWalletAmount(w.amount),
      isConnected: networkStatus.isConnected,
    }));
  }

  @action _toggleSubMenus = () => {
    this.isShowingSubMenus = !this.isShowingSubMenus;
  };

  @action _onActivateSidebarCategory = (params: { category: string, showSubMenu?: boolean }) => {
    const { category, showSubMenu } = params;
    if (category !== this.activeSidebarCategory) {
      this.activeSidebarCategory = category;
      if (showSubMenu != null) this.isShowingSubMenus = showSubMenu;
      this.actions.router.goToRoute.trigger({ route: category });
    } else if (showSubMenu == null || this.isShowingSubMenus !== showSubMenu) {
      // If no explicit preferred state is given -> toggle sub menus
      this._toggleSubMenus();
    } else {
      this.isShowingSubMenus = showSubMenu;
    }
  };

  @action _onWalletSelected = ({ walletId }: { walletId: string }) => {
    this.stores[environment.API].wallets.goToWalletRoute(walletId);
  };

  @action _setActivateSidebarCategory = (category: string) => {
    this.activeSidebarCategory = category;
  };

  @action _showSubMenus = () => {
    this.isShowingSubMenus = true;
  };

  _syncSidebarRouteWithRouter = () => {
    const route = this.stores.app.currentRoute;
    this.CATEGORIES.forEach((category) => {
      // If the current route starts with the root of the category
      if (route.indexOf(category.route) === 0) this._setActivateSidebarCategory(category.route);
    });
  };

  _showSubMenusOnWalletsPageLoad = () => {
    const currentRoute = this.stores.app.currentRoute;
    if (matchRoute(ROUTES.WALLETS.ROOT, currentRoute)) {
      this._showSubMenus();
    }
  }

}

export type SidebarWalletType = {
  id: string,
  title: string,
  info: string,
  isConnected: bool,
};
<commit_msg>Revert sidebar wallet sorting<commit_after>// @flow
import { observable, action, computed } from 'mobx';
import Store from './lib/Store';
import resolver from '../utils/imports';
import { ROUTES } from '../routes-config';
import { matchRoute } from '../utils/routing';
import environment from '../environment';

const sidebarConfig = resolver('config/sidebarConfig');
const { formattedWalletAmount } = resolver('utils/formatters');

export default class SidebarStore extends Store {

  CATEGORIES = sidebarConfig.CATEGORIES;

  @observable activeSidebarCategory: string = this.CATEGORIES[0].route;
  @observable isShowingSubMenus: boolean = true;

  setup() {
    const actions = this.actions.sidebar;
    actions.toggleSubMenus.listen(this._toggleSubMenus);
    actions.activateSidebarCategory.listen(this._onActivateSidebarCategory);
    actions.walletSelected.listen(this._onWalletSelected);
    this.registerReactions([
      this._syncSidebarRouteWithRouter,
      this._showSubMenusOnWalletsPageLoad,
    ]);
  }

  @computed get wallets(): Array<SidebarWalletType> {
    const { networkStatus } = this.stores;
    const { wallets } = this.stores[environment.API];
    return wallets.all.map(w => ({
      id: w.id,
      title: w.name,
      info: formattedWalletAmount(w.amount),
      isConnected: networkStatus.isConnected,
    }));
  }

  @action _toggleSubMenus = () => {
    this.isShowingSubMenus = !this.isShowingSubMenus;
  };

  @action _onActivateSidebarCategory = (params: { category: string, showSubMenu?: boolean }) => {
    const { category, showSubMenu } = params;
    if (category !== this.activeSidebarCategory) {
      this.activeSidebarCategory = category;
      if (showSubMenu != null) this.isShowingSubMenus = showSubMenu;
      this.actions.router.goToRoute.trigger({ route: category });
    } else if (showSubMenu == null || this.isShowingSubMenus !== showSubMenu) {
      // If no explicit preferred state is given -> toggle sub menus
      this._toggleSubMenus();
    } else {
      this.isShowingSubMenus = showSubMenu;
    }
  };

  @action _onWalletSelected = ({ walletId }: { walletId: string }) => {
    this.stores[environment.API].wallets.goToWalletRoute(walletId);
  };

  @action _setActivateSidebarCategory = (category: string) => {
    this.activeSidebarCategory = category;
  };

  @action _showSubMenus = () => {
    this.isShowingSubMenus = true;
  };

  _syncSidebarRouteWithRouter = () => {
    const route = this.stores.app.currentRoute;
    this.CATEGORIES.forEach((category) => {
      // If the current route starts with the root of the category
      if (route.indexOf(category.route) === 0) this._setActivateSidebarCategory(category.route);
    });
  };

  _showSubMenusOnWalletsPageLoad = () => {
    const currentRoute = this.stores.app.currentRoute;
    if (matchRoute(ROUTES.WALLETS.ROOT, currentRoute)) {
      this._showSubMenus();
    }
  }

}

export type SidebarWalletType = {
  id: string,
  title: string,
  info: string,
  isConnected: bool,
};
<|endoftext|>


<commit_before>angular.module('dashboard', [])
    .controller('DashboardController', ['$scope', 'Container', 'Image', 'Settings', 'LineChart', function ($scope, Container, Image, Settings, LineChart) {
        $scope.predicate = '-Created';
        $scope.containers = [];

        var getStarted = function (data) {
            $scope.totalContainers = data.length;
            LineChart.build('#containers-started-chart', data, function (c) {
                return new Date(c.Created * 1000).toLocaleDateString();
            });
            var s = $scope;
            Image.query({}, function (d) {
                s.totalImages = d.length;
                LineChart.build('#images-created-chart', d, function (c) {
                    return new Date(c.Created * 1000).toLocaleDateString();
                });
            });
        };

        var opts = {animation: false};
        if (Settings.firstLoad) {
            opts.animation = true;
            Settings.firstLoad = false;
            localStorage.setItem('firstLoad', false);
            $('#masthead').show();

            setTimeout(function () {
                $('#masthead').slideUp('slow');
            }, 5000);
        }

        Container.query({all: 1}, function (d) {
            var running = 0;
            var ghost = 0;
            var stopped = 0;

            for (var i = 0; i < d.length; i++) {
                var item = d[i];

                if (item.Status === "Ghost") {
                    ghost += 1;
                } else if (item.Status.indexOf('Exit') !== -1) {
                    stopped += 1;
                } else {
                    running += 1;
                    $scope.containers.push(new ContainerViewModel(item));
                }
            }

            getStarted(d);

            var c = new Chart($('#containers-chart').get(0).getContext("2d"));
            var data = [
                {
                    value: running,
                    color: '#5bb75b',
                    title: 'Running'
                }, // running
                {
                    value: stopped,
                    color: '#C7604C',
                    title: 'Stopped'
                }, // stopped
                {
                    value: ghost,
                    color: '#E2EAE9',
                    title: 'Ghost'
                } // ghost
            ];

            c.Doughnut(data, opts);
            var lgd = $('#chart-legend').get(0);
            legend(lgd, data);
        });
    }]);
<commit_msg>add created status to doughnut<commit_after>angular.module('dashboard', [])
    .controller('DashboardController', ['$scope', 'Container', 'Image', 'Settings', 'LineChart', function ($scope, Container, Image, Settings, LineChart) {
        $scope.predicate = '-Created';
        $scope.containers = [];

        var getStarted = function (data) {
            $scope.totalContainers = data.length;
            LineChart.build('#containers-started-chart', data, function (c) {
                return new Date(c.Created * 1000).toLocaleDateString();
            });
            var s = $scope;
            Image.query({}, function (d) {
                s.totalImages = d.length;
                LineChart.build('#images-created-chart', d, function (c) {
                    return new Date(c.Created * 1000).toLocaleDateString();
                });
            });
        };

        var opts = {animation: false};
        if (Settings.firstLoad) {
            opts.animation = true;
            Settings.firstLoad = false;
            localStorage.setItem('firstLoad', false);
            $('#masthead').show();

            setTimeout(function () {
                $('#masthead').slideUp('slow');
            }, 5000);
        }

        Container.query({all: 1}, function (d) {
            var running = 0;
            var ghost = 0;
            var stopped = 0;
            var created = 0;

            for (var i = 0; i < d.length; i++) {
                var item = d[i];

                if (item.Status === "Ghost") {
                    ghost += 1;
                } else if (item.Status === "Created") {
                    created += 1;
                } else if (item.Status.indexOf('Exit') !== -1) {
                    stopped += 1;
                } else {
                    running += 1;
                    $scope.containers.push(new ContainerViewModel(item));
                }
            }

            getStarted(d);

            var c = new Chart($('#containers-chart').get(0).getContext("2d"));
            var data = [
                {
                    value: created,
                    color: '#000000',
                    title: 'Created'
                },
                {
                    value: running,
                    color: '#5bb75b',
                    title: 'Running'
                }, // running
                {
                    value: stopped,
                    color: '#C7604C',
                    title: 'Stopped'
                }, // stopped
                {
                    value: ghost,
                    color: '#E2EAE9',
                    title: 'Ghost'
                } // ghost
            ];

            c.Doughnut(data, opts);
            var lgd = $('#chart-legend').get(0);
            legend(lgd, data);
        });
    }]);
<|endoftext|>


<commit_before>import TemplateVisitor from "./template-visitor";
import { processOpcodes } from "./utils";
import { getAttrNamespace } from "../htmlbars-util";
import { forEach } from "../htmlbars-util/array-utils";
import { isHelper } from "../htmlbars-syntax/utils";
import { unwrapMustache } from "../htmlbars-syntax/utils";

function detectIsElementChecked(element){
  for (var i=0, len=element.attributes.length;i<len;i++) {
    if (element.attributes[i].name === 'checked') {
      return true;
    }
  }
  return false;
}

function HydrationOpcodeCompiler() {
  this.opcodes = [];
  this.paths = [];
  this.templateId = 0;
  this.currentDOMChildIndex = 0;
  this.morphs = [];
  this.morphNum = 0;
  this.attrMorphNum = 0;
  this.element = null;
  this.elementNum = -1;
}

export default HydrationOpcodeCompiler;

HydrationOpcodeCompiler.prototype.compile = function(ast) {
  var templateVisitor = new TemplateVisitor();
  templateVisitor.visit(ast);

  processOpcodes(this, templateVisitor.actions);

  return this.opcodes;
};

HydrationOpcodeCompiler.prototype.accept = function(node) {
  this[node.type](node);
};

HydrationOpcodeCompiler.prototype.opcode = function(type) {
  var params = [].slice.call(arguments, 1);
  this.opcodes.push([type, params]);
};

HydrationOpcodeCompiler.prototype.startProgram = function(program, c, blankChildTextNodes) {
  this.opcodes.length = 0;
  this.paths.length = 0;
  this.morphs.length = 0;
  this.templateId = 0;
  this.currentDOMChildIndex = -1;
  this.morphNum = 0;
  this.attrMorphNum = 0;

  var blockParams = program.blockParams || [];

  for (var i = 0; i < blockParams.length; i++) {
    this.opcode('printSetHook', blockParams[i], i);
  }

  if (blankChildTextNodes.length > 0) {
    this.opcode('repairClonedNode', blankChildTextNodes);
  }
};

HydrationOpcodeCompiler.prototype.endProgram = function() {
  distributeMorphs(this.morphs, this.opcodes);
};

HydrationOpcodeCompiler.prototype.text = function() {
  ++this.currentDOMChildIndex;
};

HydrationOpcodeCompiler.prototype.comment = function() {
  ++this.currentDOMChildIndex;
};

HydrationOpcodeCompiler.prototype.openElement = function(element, pos, len, mustacheCount, blankChildTextNodes) {
  distributeMorphs(this.morphs, this.opcodes);
  ++this.currentDOMChildIndex;

  this.element = this.currentDOMChildIndex;

  this.opcode('consumeParent', this.currentDOMChildIndex);

  // If our parent reference will be used more than once, cache its reference.
  if (mustacheCount > 1) {
    this.opcode('shareElement', ++this.elementNum);
    this.element = null; // Set element to null so we don't cache it twice
  }

  var isElementChecked = detectIsElementChecked(element);
  if (blankChildTextNodes.length > 0 || isElementChecked) {
    this.opcode( 'repairClonedNode',
                 blankChildTextNodes,
                 isElementChecked );
  }

  this.paths.push(this.currentDOMChildIndex);
  this.currentDOMChildIndex = -1;

  forEach(element.attributes, this.attribute, this);
  forEach(element.helpers, this.elementHelper, this);
};

HydrationOpcodeCompiler.prototype.closeElement = function() {
  distributeMorphs(this.morphs, this.opcodes);
  this.opcode('popParent');
  this.currentDOMChildIndex = this.paths.pop();
};

HydrationOpcodeCompiler.prototype.mustache = function(mustache, childIndex, childCount) {
  this.pushMorphPlaceholderNode(childIndex, childCount);

  var morphNum = this.morphNum++;
  var start = this.currentDOMChildIndex;
  var end = this.currentDOMChildIndex;
  this.morphs.push([morphNum, this.paths.slice(), start, end, mustache.escaped]);

  if (isHelper(mustache)) {
    prepareCommonOpcodes(this, mustache);
    this.opcode('printInlineHook', morphNum);
  } else {
    preparePath(this, mustache.path);
    this.opcode('printContentHook', morphNum);
  }
};

HydrationOpcodeCompiler.prototype.block = function(block, childIndex, childCount) {
  this.pushMorphPlaceholderNode(childIndex, childCount);

  var morphNum = this.morphNum++;
  var start = this.currentDOMChildIndex;
  var end = this.currentDOMChildIndex;
  this.morphs.push([morphNum, this.paths.slice(), start, end, true]);

  var templateId = this.templateId++;
  var inverseId = block.inverse === null ? null : this.templateId++;

  prepareCommonOpcodes(this, block);
  this.opcode('printBlockHook', morphNum, templateId, inverseId);
};

HydrationOpcodeCompiler.prototype.component = function(component, childIndex, childCount) {
  this.pushMorphPlaceholderNode(childIndex, childCount);

  var program = component.program || {};
  var blockParams = program.blockParams || [];

  var morphNum = this.morphNum++;
  var start = this.currentDOMChildIndex;
  var end = this.currentDOMChildIndex;
  this.morphs.push([morphNum, this.paths.slice(), start, end, true]);

  var attrs = component.attributes;
  for (var i = attrs.length - 1; i >= 0; i--) {
    var name = attrs[i].name;
    var value = attrs[i].value;

    // TODO: Introduce context specific AST nodes to avoid switching here.
    if (value.type === 'TextNode') {
      this.opcode('pushLiteral', value.chars);
    } else if (value.type === 'MustacheStatement') {
      this.accept(unwrapMustache(value));
    } else if (value.type === 'ConcatStatement') {
      prepareParams(this, value.parts);
      this.opcode('pushConcatHook');
    }

    this.opcode('pushLiteral', name);
  }

  this.opcode('prepareObject', attrs.length);
  this.opcode('pushLiteral', component.tag);
  this.opcode('printComponentHook', morphNum, this.templateId++, blockParams.length);
};

HydrationOpcodeCompiler.prototype.attribute = function(attr) {
  var value = attr.value;
  var escaped = true;
  var namespace = getAttrNamespace(attr.name);

  // TODO: Introduce context specific AST nodes to avoid switching here.
  if (value.type === 'TextNode') {
    return;
  } else if (value.type === 'MustacheStatement') {
    escaped = value.escaped;
    this.accept(unwrapMustache(value));
  } else if (value.type === 'ConcatStatement') {
    prepareParams(this, value.parts);
    this.opcode('pushConcatHook');
  }

  this.opcode('pushLiteral', attr.name);

  if (this.element !== null) {
    this.opcode('shareElement', ++this.elementNum);
    this.element = null;
  }

  var attrMorphNum = this.attrMorphNum++;
  this.opcode('createAttrMorph', attrMorphNum, this.elementNum, attr.name, escaped, namespace);
  this.opcode('printAttributeHook', attrMorphNum, this.elementNum);
};

HydrationOpcodeCompiler.prototype.elementHelper = function(sexpr) {
  prepareCommonOpcodes(this, sexpr);

  // If we have a helper in a node, and this element has not been cached, cache it
  if (this.element !== null) {
    this.opcode('shareElement', ++this.elementNum);
    this.element = null; // Reset element so we don't cache it more than once
  }

  this.opcode('printElementHook', this.elementNum);
};

HydrationOpcodeCompiler.prototype.pushMorphPlaceholderNode = function(childIndex, childCount) {
  if (this.paths.length === 0) {
    if (childIndex === 0) {
      this.opcode('openBoundary');
    }
    if (childIndex === childCount - 1) {
      this.opcode('closeBoundary');
    }
  }
  this.comment();
};

HydrationOpcodeCompiler.prototype.MustacheStatement = function(mustache) {
  prepareCommonOpcodes(this, mustache);
  this.opcode('pushSexprHook');
};

HydrationOpcodeCompiler.prototype.SubExpression = function(sexpr) {
  prepareCommonOpcodes(this, sexpr);
  this.opcode('pushSexprHook');
};

HydrationOpcodeCompiler.prototype.PathExpression = function(path) {
  this.opcode('pushGetHook', path.original);
};

HydrationOpcodeCompiler.prototype.StringLiteral = function(node) {
  this.opcode('pushLiteral', node.value);
};

HydrationOpcodeCompiler.prototype.BooleanLiteral = function(node) {
  this.opcode('pushLiteral', node.value);
};

HydrationOpcodeCompiler.prototype.NumberLiteral = function(node) {
  this.opcode('pushLiteral', node.value);
};

function preparePath(compiler, path) {
  compiler.opcode('pushLiteral', path.original);
}

function prepareParams(compiler, params) {
  for (var i = params.length - 1; i >= 0; i--) {
    var param = params[i];
    compiler[param.type](param);
  }

  compiler.opcode('prepareArray', params.length);
}

function prepareHash(compiler, hash) {
  var pairs = hash.pairs;

  for (var i = pairs.length - 1; i >= 0; i--) {
    var key = pairs[i].key;
    var value = pairs[i].value;

    compiler[value.type](value);
    compiler.opcode('pushLiteral', key);
  }

  compiler.opcode('prepareObject', pairs.length);
}

function prepareCommonOpcodes(compiler, node) {
  prepareHash(compiler, node.hash);
  prepareParams(compiler, node.params);
  preparePath(compiler, node.path);
}

function distributeMorphs(morphs, opcodes) {
  if (morphs.length === 0) {
    return;
  }

  // Splice morphs after the most recent shareParent/consumeParent.
  var o;
  for (o = opcodes.length - 1; o >= 0; --o) {
    var opcode = opcodes[o][0];
    if (opcode === 'shareElement' || opcode === 'consumeParent'  || opcode === 'popParent') {
      break;
    }
  }

  var spliceArgs = [o + 1, 0];
  for (var i = 0; i < morphs.length; ++i) {
    spliceArgs.push(['createMorph', morphs[i].slice()]);
  }
  opcodes.splice.apply(opcodes, spliceArgs);
  morphs.length = 0;
}
<commit_msg>Expand prepareCommonOpcodes to path params and hash<commit_after>import TemplateVisitor from "./template-visitor";
import { processOpcodes } from "./utils";
import { getAttrNamespace } from "../htmlbars-util";
import { forEach } from "../htmlbars-util/array-utils";
import { isHelper } from "../htmlbars-syntax/utils";
import { unwrapMustache } from "../htmlbars-syntax/utils";

function detectIsElementChecked(element){
  for (var i=0, len=element.attributes.length;i<len;i++) {
    if (element.attributes[i].name === 'checked') {
      return true;
    }
  }
  return false;
}

function HydrationOpcodeCompiler() {
  this.opcodes = [];
  this.paths = [];
  this.templateId = 0;
  this.currentDOMChildIndex = 0;
  this.morphs = [];
  this.morphNum = 0;
  this.attrMorphNum = 0;
  this.element = null;
  this.elementNum = -1;
}

export default HydrationOpcodeCompiler;

HydrationOpcodeCompiler.prototype.compile = function(ast) {
  var templateVisitor = new TemplateVisitor();
  templateVisitor.visit(ast);

  processOpcodes(this, templateVisitor.actions);

  return this.opcodes;
};

HydrationOpcodeCompiler.prototype.accept = function(node) {
  this[node.type](node);
};

HydrationOpcodeCompiler.prototype.opcode = function(type) {
  var params = [].slice.call(arguments, 1);
  this.opcodes.push([type, params]);
};

HydrationOpcodeCompiler.prototype.startProgram = function(program, c, blankChildTextNodes) {
  this.opcodes.length = 0;
  this.paths.length = 0;
  this.morphs.length = 0;
  this.templateId = 0;
  this.currentDOMChildIndex = -1;
  this.morphNum = 0;
  this.attrMorphNum = 0;

  var blockParams = program.blockParams || [];

  for (var i = 0; i < blockParams.length; i++) {
    this.opcode('printSetHook', blockParams[i], i);
  }

  if (blankChildTextNodes.length > 0) {
    this.opcode('repairClonedNode', blankChildTextNodes);
  }
};

HydrationOpcodeCompiler.prototype.endProgram = function() {
  distributeMorphs(this.morphs, this.opcodes);
};

HydrationOpcodeCompiler.prototype.text = function() {
  ++this.currentDOMChildIndex;
};

HydrationOpcodeCompiler.prototype.comment = function() {
  ++this.currentDOMChildIndex;
};

HydrationOpcodeCompiler.prototype.openElement = function(element, pos, len, mustacheCount, blankChildTextNodes) {
  distributeMorphs(this.morphs, this.opcodes);
  ++this.currentDOMChildIndex;

  this.element = this.currentDOMChildIndex;

  this.opcode('consumeParent', this.currentDOMChildIndex);

  // If our parent reference will be used more than once, cache its reference.
  if (mustacheCount > 1) {
    this.opcode('shareElement', ++this.elementNum);
    this.element = null; // Set element to null so we don't cache it twice
  }

  var isElementChecked = detectIsElementChecked(element);
  if (blankChildTextNodes.length > 0 || isElementChecked) {
    this.opcode( 'repairClonedNode',
                 blankChildTextNodes,
                 isElementChecked );
  }

  this.paths.push(this.currentDOMChildIndex);
  this.currentDOMChildIndex = -1;

  forEach(element.attributes, this.attribute, this);
  forEach(element.helpers, this.elementHelper, this);
};

HydrationOpcodeCompiler.prototype.closeElement = function() {
  distributeMorphs(this.morphs, this.opcodes);
  this.opcode('popParent');
  this.currentDOMChildIndex = this.paths.pop();
};

HydrationOpcodeCompiler.prototype.mustache = function(mustache, childIndex, childCount) {
  this.pushMorphPlaceholderNode(childIndex, childCount);

  var morphNum = this.morphNum++;
  var start = this.currentDOMChildIndex;
  var end = this.currentDOMChildIndex;
  this.morphs.push([morphNum, this.paths.slice(), start, end, mustache.escaped]);

  if (isHelper(mustache)) {
    prepareHash(this, mustache.hash);
    prepareParams(this, mustache.params);
    preparePath(this, mustache.path);
    this.opcode('printInlineHook', morphNum);
  } else {
    preparePath(this, mustache.path);
    this.opcode('printContentHook', morphNum);
  }
};

HydrationOpcodeCompiler.prototype.block = function(block, childIndex, childCount) {
  this.pushMorphPlaceholderNode(childIndex, childCount);

  var morphNum = this.morphNum++;
  var start = this.currentDOMChildIndex;
  var end = this.currentDOMChildIndex;
  this.morphs.push([morphNum, this.paths.slice(), start, end, true]);

  var templateId = this.templateId++;
  var inverseId = block.inverse === null ? null : this.templateId++;

  prepareHash(this, block.hash);
  prepareParams(this, block.params);
  preparePath(this, block.path);
  this.opcode('printBlockHook', morphNum, templateId, inverseId);
};

HydrationOpcodeCompiler.prototype.component = function(component, childIndex, childCount) {
  this.pushMorphPlaceholderNode(childIndex, childCount);

  var program = component.program || {};
  var blockParams = program.blockParams || [];

  var morphNum = this.morphNum++;
  var start = this.currentDOMChildIndex;
  var end = this.currentDOMChildIndex;
  this.morphs.push([morphNum, this.paths.slice(), start, end, true]);

  var attrs = component.attributes;
  for (var i = attrs.length - 1; i >= 0; i--) {
    var name = attrs[i].name;
    var value = attrs[i].value;

    // TODO: Introduce context specific AST nodes to avoid switching here.
    if (value.type === 'TextNode') {
      this.opcode('pushLiteral', value.chars);
    } else if (value.type === 'MustacheStatement') {
      this.accept(unwrapMustache(value));
    } else if (value.type === 'ConcatStatement') {
      prepareParams(this, value.parts);
      this.opcode('pushConcatHook');
    }

    this.opcode('pushLiteral', name);
  }

  this.opcode('prepareObject', attrs.length);
  this.opcode('pushLiteral', component.tag);
  this.opcode('printComponentHook', morphNum, this.templateId++, blockParams.length);
};

HydrationOpcodeCompiler.prototype.attribute = function(attr) {
  var value = attr.value;
  var escaped = true;
  var namespace = getAttrNamespace(attr.name);

  // TODO: Introduce context specific AST nodes to avoid switching here.
  if (value.type === 'TextNode') {
    return;
  } else if (value.type === 'MustacheStatement') {
    escaped = value.escaped;
    this.accept(unwrapMustache(value));
  } else if (value.type === 'ConcatStatement') {
    prepareParams(this, value.parts);
    this.opcode('pushConcatHook');
  }

  this.opcode('pushLiteral', attr.name);

  if (this.element !== null) {
    this.opcode('shareElement', ++this.elementNum);
    this.element = null;
  }

  var attrMorphNum = this.attrMorphNum++;
  this.opcode('createAttrMorph', attrMorphNum, this.elementNum, attr.name, escaped, namespace);
  this.opcode('printAttributeHook', attrMorphNum, this.elementNum);
};

HydrationOpcodeCompiler.prototype.elementHelper = function(sexpr) {
  prepareHash(this, sexpr.hash);
  prepareParams(this, sexpr.params);
  preparePath(this, sexpr.path);

  // If we have a helper in a node, and this element has not been cached, cache it
  if (this.element !== null) {
    this.opcode('shareElement', ++this.elementNum);
    this.element = null; // Reset element so we don't cache it more than once
  }

  this.opcode('printElementHook', this.elementNum);
};

HydrationOpcodeCompiler.prototype.pushMorphPlaceholderNode = function(childIndex, childCount) {
  if (this.paths.length === 0) {
    if (childIndex === 0) {
      this.opcode('openBoundary');
    }
    if (childIndex === childCount - 1) {
      this.opcode('closeBoundary');
    }
  }
  this.comment();
};

HydrationOpcodeCompiler.prototype.MustacheStatement = function(mustache) {
  prepareHash(this, mustache.hash);
  prepareParams(this, mustache.params);
  preparePath(this, mustache.path);
  this.opcode('pushSexprHook');
};

HydrationOpcodeCompiler.prototype.SubExpression = function(sexpr) {
  prepareHash(this, sexpr.hash);
  prepareParams(this, sexpr.params);
  preparePath(this, sexpr.path);
  this.opcode('pushSexprHook');
};

HydrationOpcodeCompiler.prototype.PathExpression = function(path) {
  this.opcode('pushGetHook', path.original);
};

HydrationOpcodeCompiler.prototype.StringLiteral = function(node) {
  this.opcode('pushLiteral', node.value);
};

HydrationOpcodeCompiler.prototype.BooleanLiteral = function(node) {
  this.opcode('pushLiteral', node.value);
};

HydrationOpcodeCompiler.prototype.NumberLiteral = function(node) {
  this.opcode('pushLiteral', node.value);
};

function preparePath(compiler, path) {
  compiler.opcode('pushLiteral', path.original);
}

function prepareParams(compiler, params) {
  for (var i = params.length - 1; i >= 0; i--) {
    var param = params[i];
    compiler[param.type](param);
  }

  compiler.opcode('prepareArray', params.length);
}

function prepareHash(compiler, hash) {
  var pairs = hash.pairs;

  for (var i = pairs.length - 1; i >= 0; i--) {
    var key = pairs[i].key;
    var value = pairs[i].value;

    compiler[value.type](value);
    compiler.opcode('pushLiteral', key);
  }

  compiler.opcode('prepareObject', pairs.length);
}

function distributeMorphs(morphs, opcodes) {
  if (morphs.length === 0) {
    return;
  }

  // Splice morphs after the most recent shareParent/consumeParent.
  var o;
  for (o = opcodes.length - 1; o >= 0; --o) {
    var opcode = opcodes[o][0];
    if (opcode === 'shareElement' || opcode === 'consumeParent'  || opcode === 'popParent') {
      break;
    }
  }

  var spliceArgs = [o + 1, 0];
  for (var i = 0; i < morphs.length; ++i) {
    spliceArgs.push(['createMorph', morphs[i].slice()]);
  }
  opcodes.splice.apply(opcodes, spliceArgs);
  morphs.length = 0;
}
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	errorHandler = require('./errors'),
	Committee = mongoose.model('Committee'),
	User = mongoose.model('User'),
	nodemailer = require('nodemailer'),
	//wellknown = requrie('nodemailer-wellknown'),
	_ = require('lodash');

var sync = require('synchronize');
var fiber = sync.fiber;
var await = sync.await;
var defer = sync.defer;

var transporter = nodemailer.createTransport({
	service: 'gmail',
	auth:{
		user: 'CACTUS.cen3031@gmail.com',
		pass: 'cen3031cactus'
	}
});

/**
 * Create a Committee
 */
exports.create = function(req, res) {
	var committee = new Committee(req.body);
	committee.user = req.user;

	committee.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committee);
		}
	});
};

/**
 * Show the current Committee
 */
exports.read = function(req, res) {
	res.jsonp(req.committee);
};

/**
 * Update a Committee
 */
exports.update = function(req, res) {
	var committee = req.committee ;

	committee = _.extend(committee , req.body);

	committee.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committee);
		}
	});
};

/**
 * Delete an Committee
 */
exports.delete = function(req, res) {
	var committee = req.committee;

	committee.remove(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committee);
		}
	});
};

/**
 * List of Committees
 */
exports.list = function(req, res) {
	Committee.find().sort('-created').populate('user', 'displayName').exec(function(err, committees) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committees);
		}
	});
};
/**
 * List of Committee Members
 */
exports.getMembers = function(req, res) {
	var committee = req.committee;

	User.find({'_id':{$in: committee.members}}).exec(function(err, members) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(members);
		}
	});
};

/**
 * Add Committee Member
 */
exports.addMember = function(req, res) {
	var userById = req.params.userId;
	var committeeById = req.committee._id;

	Committee.update({'_id': committeeById}, {$addToSet:{'members': userById}}, function(err,data){
		if(err){
			return res.status(401).send({
				message: errorHandler.getErrorMessage(err)
			});
		}
		else{
			User.find({'_id': userById}).exec(function(err2, data2){
				if(err2){
					return res.status(401).send({
						message: errorHandler.getErrorMessage(err)
					});
				}
				else{
					var mailOptions = {
							from: 'CACTUS <CACTUS.cen3031@gmail.com>',
							to: data2[0].displayName+'<'+data2[0].email+'>',
							subject: 'Added to a committee',
							text: 'You have been added to: '+req.committee.name,
						};
						transporter.sendMail(mailOptions, function(error, info){
							if(error) console.log(error);
							else console.log('message sent: '+info.response);
						});
				}
				res.jsonp(data[0]);
			});
		}
	});
/*

	try{
		var committee = await()
	}
	catch(err){
		console.log(err);
	}

	var print = Committee.update({'_id': committeeById}, {$addToSet:{'members': userById}} ).exec(function(err, data){
		if(err){
			return res.status(401).send({
				message: errorHandler.getErrorMessage(err)
			});
		}
		else committee = data[0];
	});
console.log(print);*/

	/*
	Committee.update({'_id': committeeById}, {$addToSet:{'members': userById}} ).exec(function(err, committee){
		if(err){
			return res.status(401).send({
				message: errorHandler.getErrorMessage(err)
			});
		}
		else{
			User.find({'_id': userById}).exec(function(err2, getUser){

				if(err2){
					return res.status(401).send({
						message: errorHandler.getErrorMessage(err)
					});
				}
				else{
					user = getUser[0];
				}
			});

	res.jsonp(committee[0]);
		}
	});	*/

};

/**
 * Remove Committee Member
 */
exports.removeMember = function(req, res) {
	var committeeById = req.committee._id;
	var memberById = req.params.userId;

	console.log(committeeById);
	console.log(memberById);

	Committee.update({'_id':committeeById},{$pull:{'members': memberById}}).exec(function(err, committee) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committee[0]);
		}
	});
};

/**
 * Get Committee Chair
 */
exports.getChair = function(req, res) {
	var chairById = req.committee.chair;
	User.find({'_id': chairById}).exec(function(err, chair) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(chair[0]);
		}
	});
};

/**
 * Remove Committee Chair
 */
exports.removeChair = function(req, res) {
	var committeeById = req.committee._id;
	var chairById = req.committee.chair;

	console.log(committeeById);
	console.log(chairById);

	Committee.update({'_id':committeeById},{'chair': ''}).exec(function(err, committee) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committee[0]);
		}
	});
};

/**
 * Change Committee Chair
 */
exports.updateChair = function(req, res) {
	var committeeById = req.committee._id;
	var chairById = req.committee.chair;

	console.log(committeeById);
	console.log(chairById);

	Committee.update({'_id':committeeById},{'chair': chairById}).exec(function(err, committee) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committee[0]);
		}
	});
};

/**
 * Committee middleware
 */
exports.committeeByID = function(req, res, next, id) { Committee.findById(id).populate('user', 'displayName').exec(function(err, committee) {
		if (err) return next(err);
		if (! committee) return next(new Error('Failed to load Committee ' + id));
		req.committee = committee ;
		next();
	});
};

/**
 * Committee authorization middleware
 */
exports.hasAuthorization = function(req, res, next) {
	if (req.committee.user.id !== req.user.id) {
		return res.status(403).send('User is not authorized');
	}
	next();
};<commit_msg>update<commit_after>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	errorHandler = require('./errors'),
	Committee = mongoose.model('Committee'),
	User = mongoose.model('User'),
	nodemailer = require('nodemailer'),
	//wellknown = requrie('nodemailer-wellknown'),
	_ = require('lodash');

var transporter = nodemailer.createTransport({
	service: 'gmail',
	auth:{
		user: 'CACTUS.cen3031@gmail.com',
		pass: 'cen3031cactus'
	}
});

/**
 * Create a Committee
 */
exports.create = function(req, res) {
	var committee = new Committee(req.body);
	committee.user = req.user;

	committee.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committee);
		}
	});
};

/**
 * Show the current Committee
 */
exports.read = function(req, res) {
	res.jsonp(req.committee);
};

/**
 * Update a Committee
 */
exports.update = function(req, res) {
	var committee = req.committee ;

	committee = _.extend(committee , req.body);

	committee.save(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committee);
		}
	});
};

/**
 * Delete an Committee
 */
exports.delete = function(req, res) {
	var committee = req.committee;

	committee.remove(function(err) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committee);
		}
	});
};

/**
 * List of Committees
 */
exports.list = function(req, res) {
	Committee.find().sort('-created').populate('user', 'displayName').exec(function(err, committees) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committees);
		}
	});
};
/**
 * List of Committee Members
 */
exports.getMembers = function(req, res) {
	var committee = req.committee;

	User.find({'_id':{$in: committee.members}}).exec(function(err, members) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(members);
		}
	});
};

/**
 * Add Committee Member
 */
exports.addMember = function(req, res) {
	var userById = req.params.userId;
	var committeeById = req.committee._id;

	Committee.update({'_id': committeeById}, {$addToSet:{'members': userById}}, function(err,data){
		if(err){
			return res.status(401).send({
				message: errorHandler.getErrorMessage(err)
			});
		}
		else{
			User.find({'_id': userById}).exec(function(err2, data2){
				if(err2){
					return res.status(401).send({
						message: errorHandler.getErrorMessage(err)
					});
				}
				else{
					var mailOptions = {
							from: 'CACTUS <CACTUS.cen3031@gmail.com>',
							to: data2[0].displayName+'<'+data2[0].email+'>',
							subject: 'Added to a committee',
							text: 'You have been added to: '+req.committee.name,
						};
						transporter.sendMail(mailOptions, function(error, info){
							if(error) console.log(error);
							else console.log('message sent: '+info.response);
						});
				}
				res.jsonp(data[0]);
			});
		}
	});
/*

	try{
		var committee = await()
	}
	catch(err){
		console.log(err);
	}

	var print = Committee.update({'_id': committeeById}, {$addToSet:{'members': userById}} ).exec(function(err, data){
		if(err){
			return res.status(401).send({
				message: errorHandler.getErrorMessage(err)
			});
		}
		else committee = data[0];
	});
console.log(print);*/

	/*
	Committee.update({'_id': committeeById}, {$addToSet:{'members': userById}} ).exec(function(err, committee){
		if(err){
			return res.status(401).send({
				message: errorHandler.getErrorMessage(err)
			});
		}
		else{
			User.find({'_id': userById}).exec(function(err2, getUser){

				if(err2){
					return res.status(401).send({
						message: errorHandler.getErrorMessage(err)
					});
				}
				else{
					user = getUser[0];
				}
			});

	res.jsonp(committee[0]);
		}
	});	*/

};

/**
 * Remove Committee Member
 */
exports.removeMember = function(req, res) {
	var committeeById = req.committee._id;
	var memberById = req.params.userId;

	console.log(committeeById);
	console.log(memberById);

	Committee.update({'_id':committeeById},{$pull:{'members': memberById}}).exec(function(err, committee) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committee[0]);
		}
	});
};

/**
 * Get Committee Chair
 */
exports.getChair = function(req, res) {
	var chairById = req.committee.chair;
	User.find({'_id': chairById}).exec(function(err, chair) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(chair[0]);
		}
	});
};

/**
 * Remove Committee Chair
 */
exports.removeChair = function(req, res) {
	var committeeById = req.committee._id;
	var chairById = req.committee.chair;

	console.log(committeeById);
	console.log(chairById);

	Committee.update({'_id':committeeById},{'chair': ''}).exec(function(err, committee) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committee[0]);
		}
	});
};

/**
 * Change Committee Chair
 */
exports.updateChair = function(req, res) {
	var committeeById = req.committee._id;
	var chairById = req.committee.chair;

	console.log(committeeById);
	console.log(chairById);

	Committee.update({'_id':committeeById},{'chair': chairById}).exec(function(err, committee) {
		if (err) {
			return res.status(400).send({
				message: errorHandler.getErrorMessage(err)
			});
		} else {
			res.jsonp(committee[0]);
		}
	});
};

/**
 * Committee middleware
 */
exports.committeeByID = function(req, res, next, id) { Committee.findById(id).populate('user', 'displayName').exec(function(err, committee) {
		if (err) return next(err);
		if (! committee) return next(new Error('Failed to load Committee ' + id));
		req.committee = committee ;
		next();
	});
};

/**
 * Committee authorization middleware
 */
exports.hasAuthorization = function(req, res, next) {
	if (req.committee.user.id !== req.user.id) {
		return res.status(403).send('User is not authorized');
	}
	next();
};<|endoftext|>