<commit_before>/**
 * slippry v1.2 - Simple responsive content slider
 * http://slippry.com
 *
 * Author(s): Lukas Jakob Hafner - @saftsaak
 *
 * Copyright 2013, booncon oy - http://booncon.com
 *
 * Thanks @ http://bxslider.com for the inspiration!
 *
 * Released under the MIT license - http://opensource.org/licenses/MIT
 */
(function($){"use strict";var g;g={slippryWrapper:'
',slideWrapper:'
',slideCrop:'
',boxClass:'sy-list',elements:'li',activeClass:'sy-active',fillerClass:'sy-filler',loadingClass:'sy-loading',adaptiveHeight:true,start:1,loop:true,captionsSrc:'img',captions:'overlay',captionsEl:'.sy-caption',initSingle:true,responsive:true,preload:'visible',pager:true,pagerClass:'sy-pager',controls:true,controlClass:'sy-controls',prevClass:'sy-prev',prevText:'Previous',nextClass:'sy-next',nextText:'Next',hideOnEnd:true,transition:'fade',kenZoom:120,slideMargin:0,transClass:'transition',speed:800,easing:'swing',continuous:true,useCSS:true,auto:true,autoDirection:'next',autoHover:true,autoHoverDelay:100,autoDelay:500,pause:4000,onSliderLoad:function(){return this},onSlideBefore:function(){return this},onSlideAfter:function(){return this}};$.fn.slippry=function(e){var f,el,prepareFiller,getFillerProportions,init,updateCaption,initPager,initControls,ready,transitionDone,whichTransitionEvent,initCaptions,updatePager,setFillerProportions,doTransition,updateSlide,updateControls,updatePos,supports,preload,start,elFromSel,doKens;el=this;if(el.length===0){return this}if(el.length>1){el.each(function(){$(this).slippry(e)});return this}f={};f.vars={};whichTransitionEvent=function(){var t,div,transitions;div=document.createElement('div');transitions={'WebkitTransition':'webkitTransitionEnd','MozTransition':'transitionend','MSTransition':'msTransitionEnd','OTransition':'oTransitionEnd','transition':'transitionEnd transitionend'};for(t in transitions){if(div.style[t]!==undefined){return transitions[t]}}};supports=(function(){var c=document.createElement('div'),vendors=['Khtml','Ms','O','Moz','Webkit'],len=vendors.length;return function(b){if(b in c.style){return true}b=b.replace(/^[a-z]/,function(a){return a.toUpperCase()});while(len--){if(vendors[len]+b in c.style){return true}}return false}}());elFromSel=function(b,c){var d,newelement,id,className;d=c.split('.');newelement=$(b);id='';className='';$.each(d,function(i,a){if(a.indexOf('#')>=0){id+=a.replace(/^#/,'')}else{className+=a+' '}});if(id.length){newelement.attr('id',id)}if(className.length){newelement.attr('class',className.trim())}return newelement};doKens=function(){var a,kenTime,animProp,cssProp;animProp={};cssProp={};a=100-f.settings.kenZoom;cssProp.width=f.settings.kenZoom+'%';if(f.vars.active.index()%2===0){cssProp.left=a+'%';cssProp.top=a+'%';animProp.left='0%';animProp.top='0%'}else{cssProp.left='0%';cssProp.top='0%';animProp.left=a+'%';animProp.top=a+'%'}kenTime=f.settings.pause+f.settings.speed*2;f.vars.active.css(cssProp);f.vars.active.animate(animProp,{duration:kenTime,easing:f.settings.easing,queue:false})};ready=function(){if(f.vars.fresh){f.vars.slippryWrapper.removeClass(f.settings.loadingClass);f.vars.fresh=false;if(f.settings.auto){el.startAuto()}if(!f.settings.useCSS&&f.settings.transition==='kenburns'){doKens()}f.settings.onSliderLoad.call(undefined,f.vars.active.index())}else{$('.'+f.settings.fillerClass,f.vars.slideWrapper).addClass('ready')}};setFillerProportions=function(a,b){var c,p_top,$filler;c=a/b;p_top=1/c*100+'%';$filler=$('.'+f.settings.fillerClass,f.vars.slideWrapper);$filler.css({paddingTop:p_top});ready()};getFillerProportions=function(a){var b,height;if(($('img',a).attr("src")!==undefined)){$("").load(function(){b=a.width();height=a.height();setFillerProportions(b,height)}).attr("src",$('img',a).attr("src"))}else{b=a.width();height=a.height();setFillerProportions(b,height)}};prepareFiller=function(){if($('.'+f.settings.fillerClass,f.vars.slideWrapper).length===0){f.vars.slideWrapper.append($('
'))}if(f.settings.adaptiveHeight===true){getFillerProportions($('.'+f.settings.activeClass,el))}else{var a,height,loop;height=0;loop=0;$(f.vars.slides).each(function(){if($(this).height()>height){a=$(this);height=a.height()}loop=loop+1;if(loop===f.vars.count){if(a===undefined){a=$($(f.vars.slides)[0])}getFillerProportions(a)}})}};updatePager=function(){if(f.settings.pager){$('.'+f.settings.pagerClass+' li',f.vars.slippryWrapper).removeClass(f.settings.activeClass);$($('.'+f.settings.pagerClass+' li',f.vars.slippryWrapper)[f.vars.active.index()]).addClass(f.settings.activeClass)}};updateControls=function(){if(!f.settings.loop&&f.settings.hideOnEnd){$('.'+f.settings.prevClass,f.vars.slippryWrapper)[f.vars.first?'hide':'show']();$('.'+f.settings.nextClass,f.vars.slippryWrapper)[f.vars.last?'hide':'show']()}};updateCaption=function(){var a,wrapper;if(f.settings.captions!==false){if(f.settings.captionsSrc!=='img'){a=f.vars.active.attr('title')}else{a=$('img',f.vars.active).attr('title')!==undefined?$('img',f.vars.active).attr('title'):$('img',f.vars.active).attr('alt')}if(f.settings.captions!=='custom'){wrapper=$(f.settings.captionsEl,f.vars.slippryWrapper)}else{wrapper=$(f.settings.captionsEl)}if((a!==undefined)&&(a!=='')){wrapper.html(a).show()}else{wrapper.hide()}}};el.startAuto=function(){if((f.vars.timer===undefined)&&(f.vars.delay===undefined)){f.vars.delay=window.setTimeout(function(){f.vars.autodelay=false;f.vars.timer=window.setInterval(function(){f.vars.trigger='auto';el.goToSlide(f.settings.autoDirection)},f.settings.pause)},f.vars.autodelay?f.settings.autoHoverDelay:f.settings.autoDelay)}if(f.settings.autoHover){f.vars.slideWrapper.unbind('mouseenter').unbind('mouseleave').bind('mouseenter',function(){if(f.vars.timer!==undefined){f.vars.hoverStop=true;el.stopAuto()}else{f.vars.hoverStop=false}}).bind('mouseleave',function(){if(f.vars.hoverStop){f.vars.autodelay=true;el.startAuto()}})}};el.stopAuto=function(){window.clearInterval(f.vars.timer);f.vars.timer=undefined;window.clearTimeout(f.vars.delay);f.vars.delay=undefined};el.refresh=function(){f.vars.slides.removeClass(f.settings.activeClass);f.vars.active.addClass(f.settings.activeClass);if(f.settings.responsive){prepareFiller()}else{ready()}updateControls();updatePager();updateCaption()};updateSlide=function(){el.refresh()};transitionDone=function(){f.vars.moving=false;f.vars.active.removeClass(f.settings.transClass);if(!f.vars.fresh){f.vars.old.removeClass('sy-ken')}f.vars.old.removeClass(f.settings.transClass);f.settings.onSlideAfter.call(undefined,f.vars.active,f.vars.old.index(),f.vars.active.index())};doTransition=function(){var a,jump,old_left,old_pos,kenTime,ref,cssProp;f.settings.onSlideBefore.call(undefined,f.vars.active,f.vars.old.index(),f.vars.active.index());if(f.settings.transition!==false){f.vars.moving=true;if((f.settings.transition==='fade')||(f.settings.transition==='kenburns')){if(f.vars.fresh){if(f.settings.useCSS){f.vars.slides.css({transitionDuration:f.settings.speed+'ms',opacity:0})}else{f.vars.slides.css({opacity:0})}f.vars.active.css('opacity',1);if(f.settings.transition==='kenburns'){if(f.settings.useCSS){kenTime=f.settings.pause+f.settings.speed*2;f.vars.slides.css({animationDuration:kenTime+'ms'});f.vars.active.addClass('sy-ken')}}transitionDone()}else{if(f.settings.useCSS){f.vars.old.addClass(f.settings.transClass).css('opacity',0);f.vars.active.addClass(f.settings.transClass).css('opacity',1);if(f.settings.transition==='kenburns'){f.vars.active.addClass('sy-ken')}$(window).off('focus').on('focus',function(){if(f.vars.moving){f.vars.old.trigger(f.vars.transition)}});f.vars.old.one(f.vars.transition,function(){transitionDone();return this})}else{if(f.settings.transition==='kenburns'){doKens()}f.vars.old.addClass(f.settings.transClass).animate({opacity:0},f.settings.speed,f.settings.easing,function(){transitionDone()});f.vars.active.addClass(f.settings.transClass).css('opacity',0).animate({opacity:1},f.settings.speed,f.settings.easing)}}updateSlide()}else if((f.settings.transition==='horizontal')||(f.settings.transition==='vertical')){ref=(f.settings.transition==='horizontal')?'left':'top';a='-'+f.vars.active.index()*(100+f.settings.slideMargin)+'%';if(f.vars.fresh){el.css(ref,a);transitionDone()}else{cssProp={};if(f.settings.continuous){if(f.vars.jump&&((f.vars.trigger==='controls')||(f.vars.trigger==='auto'))){jump=true;old_pos=a;if(f.vars.first){old_left=0;f.vars.active.css(ref,f.vars.count*(100+f.settings.slideMargin)+'%');a='-'+f.vars.count*(100+f.settings.slideMargin)+'%'}else{old_left=(f.vars.count-1)*(100+f.settings.slideMargin)+'%';f.vars.active.css(ref,-(100+f.settings.slideMargin)+'%');a=(100+f.settings.slideMargin)+'%'}}}f.vars.active.addClass(f.settings.transClass);if(f.settings.useCSS){cssProp[ref]=a;cssProp['transitionDuration']=f.settings.speed+'ms';el.addClass(f.settings.transition);el.css(cssProp);$(window).off('focus').on('focus',function(){if(f.vars.moving){el.trigger(f.vars.transition)}});el.one(f.vars.transition,function(){el.removeClass(f.settings.transition);if(jump){f.vars.active.css(ref,old_left);cssProp[ref]=old_pos;cssProp['transitionDuration']='0ms';el.css(cssProp)}transitionDone();return this})}else{cssProp[ref]=a;el.stop().animate(cssProp,f.settings.speed,f.settings.easing,function(){if(jump){f.vars.active.css(ref,old_left);el.css(ref,old_pos)}transitionDone();return this})}}updateSlide()}}else{updateSlide();transitionDone()}};updatePos=function(a){f.vars.first=false;f.vars.last=false;if((a==='prev')||(a===0)){f.vars.first=true}else if((a==='next')||(a===f.vars.count-1)){f.vars.last=true}};el.goToSlide=function(a){var b;if(!f.vars.moving){b=f.vars.active.index();if(a==='prev'){if(b>0){a=b-1}else if(f.settings.loop){a=f.vars.count-1}}else if(a==='next'){if(b<f.vars.count-1){a=b+1}else if(f.settings.loop){a=0}}else{a=a-1}f.vars.jump=false;if((a!=='prev')&&(a!=='next')&&((a!==b)||(f.vars.fresh))){updatePos(a);f.vars.old=f.vars.active;f.vars.active=$(f.vars.slides[a]);if(((b===0)&&(a===f.vars.count-1))||((b===f.vars.count-1)&&(a===0))){f.vars.jump=true}doTransition()}}};el.goToNextSlide=function(){el.goToSlide('next')};el.goToPrevSlide=function(){el.goToSlide('prev')};initPager=function(){if((f.settings.pager)&&(f.vars.count>1)){var a,loop,pager;a=f.vars.slides.length;pager=$('
');for(loop=1;loop<a+1;loop=loop+1){pager.append($('
').append($(''+loop+'')))}f.vars.slippryWrapper.append(pager);$('.'+f.settings.pagerClass+' a',f.vars.slippryWrapper).click(function(){f.vars.trigger='pager';el.goToSlide(parseInt(this.hash.split('#')[1],10));return false});updatePager()}};initControls=function(){if((f.settings.controls)&&(f.vars.count>1)){f.vars.slideWrapper.append($('
').append('
'+f.settings.prevText+'
').append('
'+f.settings.nextText+'
'));$('.'+f.settings.controlClass+' a',f.vars.slippryWrapper).click(function(){f.vars.trigger='controls';el.goToSlide(this.hash.split('#')[1]);return false});updateControls()}};initCaptions=function(){if(f.settings.captions!==false){if(f.settings.captions==='overlay'){f.vars.slideWrapper.append($('
').html(elFromSel('
',f.settings.captionsEl)))}else if(f.settings.captions==='below'){f.vars.slippryWrapper.append($('
').html(elFromSel('
',f.settings.captionsEl)))}}};start=function(){el.goToSlide(f.vars.active.index()+1)};preload=function(a){var b,loop,elements,container;container=(f.settings.preload==='all')?a:f.vars.active;elements=$('img, iframe',container);b=elements.length;if(b===0){start();return}loop=0;elements.each(function(){$(this).one('load error',function(){if(++loop===b){start()}}).each(function(){if(this.complete){$(this).load()}})})};el.getCurrentSlide=function(){return f.vars.active};el.getSlideCount=function(){return f.vars.count};el.destroySlider=function(){if(f.vars.fresh===false){el.stopAuto();f.vars.moving=false;f.vars.slides.each(function(){if($(this).data("sy-cssBckup")!==undefined){$(this).attr("style",$(this).data("sy-cssBckup"))}else{$(this).removeAttr('style')}if($(this).data("sy-classBckup")!==undefined){$(this).attr("class",$(this).data("sy-classBckup"))}else{$(this).removeAttr('class')}});if(el.data("sy-cssBckup")!==undefined){el.attr("style",el.data("sy-cssBckup"))}else{el.removeAttr('style')}if(el.data("sy-classBckup")!==undefined){el.attr("class",el.data("sy-classBckup"))}else{el.removeAttr('class')}f.vars.slippryWrapper.before(el);f.vars.slippryWrapper.remove();f.vars.fresh=undefined}};el.reloadSlider=function(){el.destroySlider();init()};init=function(){var a;f.settings=$.extend({},g,e);f.vars.slides=$(f.settings.elements,el);f.vars.count=f.vars.slides.length;if(f.settings.useCSS){if(!supports('transition')){f.settings.useCSS=false}f.vars.transition=whichTransitionEvent()}el.data('sy-cssBckup',el.attr('style'));el.data('sy-classBackup',el.attr('class'));el.addClass(f.settings.boxClass).wrap(f.settings.slippryWrapper).wrap(f.settings.slideWrapper).wrap(f.settings.slideCrop);f.vars.slideWrapper=el.parent().parent();f.vars.slippryWrapper=f.vars.slideWrapper.parent().addClass(f.settings.loadingClass);f.vars.fresh=true;f.vars.slides.each(function(){$(this).addClass('sy-slide '+f.settings.transition);if(f.settings.useCSS){$(this).addClass('useCSS')}if(f.settings.transition==='horizontal'){$(this).css('left',$(this).index()*(100+f.settings.slideMargin)+'%')}else if(f.settings.transition==='vertical'){$(this).css('top',$(this).index()*(100+f.settings.slideMargin)+'%')}});if((f.vars.count>1)||(f.settings.initSingle)){if($('.'+f.settings.activeClass,el).index()===-1){if(f.settings.start==='random'){a=Math.round(Math.random()*(f.vars.count-1))}else if(f.settings.start>0&&f.settings.start<=f.vars.count){a=f.settings.start-1}else{a=0}f.vars.active=$(f.vars.slides[a]).addClass(f.settings.activeClass)}else{f.vars.active=$('.'+f.settings.activeClass,el)}initControls();initPager();initCaptions();preload(f.vars.slides)}else{return this}};init();return this}}(jQuery));<commit_msg>Delete slippry.min.js<commit_after><|endoftext|>


<commit_before>"use strict";
// SMTP client object and class. This allows for every part of the client
// protocol to be hooked for different levels of control, such as
// smtp_forward and smtp_proxy queue plugins.
/* jshint node: true */

var events = require('events');
var util = require('util');
var generic_pool = require('generic-pool');
var line_socket = require('./line_socket');
var logger = require('./logger');
var uuid = require('./utils').uuid;
var utils = require('./utils');

var smtp_regexp = /^([0-9]{3})([ -])(.*)/;
var STATE_IDLE = 1;
var STATE_ACTIVE = 2;
var STATE_RELEASED = 3;
var STATE_DESTROYED = 4;

var tls_key;
var tls_cert;

function SMTPClient(port, host, connect_timeout, idle_timeout) {
    events.EventEmitter.call(this);
    this.uuid = uuid();
    this.socket = line_socket.connect(port, host);
    this.socket.setTimeout(((connect_timeout === undefined) ? 30 : connect_timeout) * 1000);
    this.socket.setKeepAlive(true);
    this.state = STATE.IDLE;
    this.command = 'greeting';
    this.response = [];
    this.connected = false;
    this.authenticated = false;
    this.auth_capabilities = [];
    var self = this;

    this.socket.on('line', function (line) {
        self.emit('server_protocol', line);
        var matches = smtp_regexp.exec(line);
        if (!matches) {
            self.emit('error', self.uuid + ': Unrecognised response from upstream server: ' + line);
            self.destroy();
            return;
        }

        var code = matches[1],
            cont = matches[2],
            msg = matches[3];
        self.response.push(msg);
        if (cont !== ' ') {
            return;
        }

        if (self.command === 'ehlo') {
            if (code.match(/^5/)) {
                // Handle fallback to HELO if EHLO is rejected
                self.emit('greeting', 'HELO');
                return;
            }
            self.emit('capabilities');
            if (self.command != 'ehlo') {
                return;
            }
        }
        if (self.command === 'xclient' && code.match(/^5/)) {
            // XCLIENT command was rejected (no permission?)
            // Carry on without XCLIENT
            self.command = 'helo';
        }
        else if (code.match(/^[45]/)) {
            self.emit('bad_code', code, self.response.join(' '));
            if (self.state != STATE.ACTIVE) {
                return;
            }
        }
        switch (self.command) {
            case 'xclient':
                self.xclient = true;
                self.emit('xclient', 'EHLO');
                break;
            case 'starttls':
                if (tls_key && tls_cert) {
                    this.upgrade({key: tls_key, cert: tls_cert});
                }
                break;
            case 'greeting':
                self.connected = true;
                self.emit('greeting', 'EHLO');
                break;
            case 'ehlo':
                self.emit('helo');
                break;
            case 'helo':
            case 'mail':
            case 'rcpt':
            case 'data':
            case 'dot':
            case 'rset':
            case 'auth':
                self.emit(self.command);
                break;
            case 'quit':
                self.emit('quit');
                self.destroy();
                break;
            default:
                throw new Error("Unknown command: " + self.command);
        }
    });

    this.socket.on('connect', function () {
        // Remove connection timeout and set idle timeout
        self.socket.setTimeout(((idle_timeout) ? idle_timeout : 300) * 1000);
    });

    var closed = function (msg) {
        return function (error) {
            if (!error) {
                error = '';
            }
            if (self.state === STATE.ACTIVE) {
                self.emit('error', self.uuid + ': SMTP connection ' + msg + ' ' + error);
                self.destroy();
            }
            else {
                logger.logdebug('[smtp_client_pool] ' + self.uuid + ': SMTP connection ' + msg + ' ' + error + ' (state=' + self.state + ')');
                if (self.state === STATE_IDLE) {
                    self.destroy();
                }
                else if (self.state === STATE.RELEASED) {
                    self.destroy();
                }
            }
        };
    };

    this.socket.on('error', closed('errored'));
    this.socket.on('timeout', closed('timed out'));
    this.socket.on('close', closed('closed'));
    this.socket.on('end', closed('ended'));
}

util.inherits(SMTPClient, events.EventEmitter);

SMTPClient.prototype.send_command = function (command, data) {
    var line = (command === 'dot') ? '.' : command + (data ? (' ' + data) : '');
    this.emit('client_protocol', line);
    this.command = command.toLowerCase();
    this.response = [];
    this.socket.write(line + "\r\n");
};

SMTPClient.prototype.start_data = function (data) {
    this.response = [];
    this.command = 'dot';
    data.pipe(this.socket, { dot_stuffing: true, ending_dot: true, end: false });
};

SMTPClient.prototype.release = function () {
    if (!this.connected || this.command === 'data' || this.command === 'mailbody') {
        // Destroy here, we can't reuse a connection that was mid-data.
        this.destroy();
        return;
    }

    logger.logdebug('[smtp_client_pool] ' + this.uuid + ' resetting, state=' + this.state);
    if (this.state === STATE.DESTROYED) {
        return;
    }
    this.state = STATE.RELEASED;
    this.removeAllListeners('greeting');
    this.removeAllListeners('capabilities');
    this.removeAllListeners('xclient');
    this.removeAllListeners('helo');
    this.removeAllListeners('mail');
    this.removeAllListeners('rcpt');
    this.removeAllListeners('data');
    this.removeAllListeners('dot');
    this.removeAllListeners('rset');
    this.removeAllListeners('auth');
    this.removeAllListeners('client_protocol');
    this.removeAllListeners('server_protocol');
    this.removeAllListeners('error');
    this.removeAllListeners('bad_code');

    this.on('bad_code', function (code, msg) {
        this.destroy();
    });

    this.on('rset', function () {
        logger.logdebug('[smtp_client_pool] ' + this.uuid + ' releasing, state=' + this.state);
        if (this.state === STATE.DESTROYED) {
            return;
        }
        this.state = STATE.IDLE;
        this.removeAllListeners('rset');
        this.removeAllListeners('bad_code');
        this.pool.release(this);
    });

    this.send_command('RSET');
};

SMTPClient.prototype.destroy = function () {
    if (this.state !== STATE.DESTROYED) {
        this.pool.destroy(this);
    }
};

SMTPClient.prototype.is_dead_sender = function (plugin, connection) {
    if (!connection.transaction) {
        // This likely means the sender went away on us, cleanup.
        connection.logwarn(
          plugin, "transaction went away, releasing smtp_client"
        );
        this.release();
        return true;
    }

    return false;
};

// Separate pools are kept for each set of server attributes.
exports.get_pool = function (server, port, host, connect_timeout, pool_timeout, max) {
    port = port || 25;
    host = host || 'localhost';
    connect_timeout = (connect_timeout === undefined) ? 30 : connect_timeout;
    pool_timeout = (pool_timeout === undefined) ? 300 : pool_timeout;
    var name = port + ':' + host + ':' + pool_timeout;
    if (!server.notes.pool) {
        server.notes.pool = {};
    }
    if (!server.notes.pool[name]) {
        var pool = generic_pool.Pool({
            name: name,
            create: function (callback) {
                var smtp_client = new SMTPClient(port, host, connect_timeout);
                logger.logdebug('[smtp_client_pool] uuid=' + smtp_client.uuid + ' host=' + host +
                    ' port=' + port + ' pool_timeout=' + pool_timeout + ' created');
                callback(null, smtp_client);
            },
            destroy: function(smtp_client) {
                logger.logdebug('[smtp_client_pool] ' + smtp_client.uuid + ' destroyed, state=' + smtp_client.state);
                smtp_client.state = STATE.DESTROYED;
                smtp_client.socket.destroy();
                // Remove pool object from server notes once empty
                var size = pool.getPoolSize();
                if (size === 0) {
                    delete server.notes.pool[name];
                }
            },
            max: max || 1000,
            idleTimeoutMillis: pool_timeout * 1000,
            log: function (str, level) {
                level = (level === 'verbose') ? 'debug' : level;
                logger['log' + level]('[smtp_client_pool] [' + name + '] ' + str);
            }
        });

        var acquire = pool.acquire;
        pool.acquire = function (callback, priority) {
            var callback_wrapper = function (err, smtp_client) {
                smtp_client.pool = pool;
                smtp_client.state = STATE_ACTIVE;
                callback(err, smtp_client);
            };
            acquire.call(pool, callback_wrapper, priority);
        };
        server.notes.pool[name] = pool;
    }
    return server.notes.pool[name];
};

// Get a smtp_client for the given attributes.
exports.get_client = function (server, callback, port, host, connect_timeout, pool_timeout, max) {
    var pool = exports.get_pool(server, port, host, connect_timeout, pool_timeout, max);
    pool.acquire(callback);
};

// Get a smtp_client for the given attributes and set it up the common
// config and listeners for plugins. Currently this is what smtp_proxy and
// smtp_forward have in common.
exports.get_client_plugin = function (plugin, connection, config, callback) {
    var c = config.main;
    var pool = exports.get_pool(connection.server, c.port, c.host,
                                c.connect_timeout, c.timeout, c.max_connections);
    pool.acquire(function (err, smtp_client) {
        connection.logdebug(plugin, 'Got smtp_client: ' + smtp_client.uuid);

        var secured = false;

        smtp_client.call_next = function (retval, msg) {
            if (this.next) {
                var next = this.next;
                delete this.next;
                next(retval, msg);
            }
        };

        smtp_client.on('client_protocol', function (line) {
            connection.logprotocol(plugin, 'C: ' + line);
        });

        smtp_client.on('server_protocol', function (line) {
            connection.logprotocol(plugin, 'S: ' + line);
        });

        var helo = function (command) {
            if (smtp_client.xclient) {
                smtp_client.send_command(command, connection.hello_host);
            }
            else {
                smtp_client.send_command(command, plugin.config.get('me'));
            }
        };
        smtp_client.on('greeting', helo);
        smtp_client.on('xclient', helo);

        smtp_client.on('capabilities', function () {
            var on_secured = function () {
                secured = true;
                smtp_client.emit('greeting', 'EHLO');
            };
            for (var line in smtp_client.response) {
                if (smtp_client.response[line].match(/^XCLIENT/)) {
                    if(!smtp_client.xclient) {
                        smtp_client.send_command('XCLIENT',
                            'ADDR=' + connection.remote_ip);
                        return;
                    }
                }
                if (smtp_client.response[line].match(/^STARTTLS/) && !secured) {
                    if (c.enable_tls) {
                        tls_key = plugin.config.get('tls_key.pem', 'binary');
                        tls_cert = plugin.config.get('tls_cert.pem', 'binary');
                        if (tls_key && tls_cert) {
                            smtp_client.socket.on('secure', on_secured);
                            smtp_client.send_command('STARTTLS');
                            return;
                        }
                    }
                }

                var auth_matches = smtp_client.response[line].match(/^AUTH (.*)$/);
                if (auth_matches) {
                    smtp_client.auth_capabilities = [];
                    auth_matches = auth_matches[1].split(' ');
                    for (var i = 0; i < auth_matches.length; i++) {
                        smtp_client.auth_capabilities.push(auth_matches[i].toLowerCase());
                    }
                }
            }
        });

        smtp_client.on('helo', function () {
            if (!config.auth || smtp_client.authenticated) {
                if (smtp_client.is_dead_sender(plugin, connection)) {
                    return;
                }
                smtp_client.send_command('MAIL', 'FROM:' + connection.transaction.mail_from);
                return;
            }

            if (config.auth.type === null || typeof(config.auth.type) === 'undefined') { return; } // Ignore blank
            var auth_type = config.auth.type.toLowerCase();
            if (smtp_client.auth_capabilities.indexOf(auth_type) == -1) {
                throw new Error("Auth type \"" + auth_type + "\" not supported by server (supports: " + smtp_client.auth_capabilities.join(',') + ")");
            }
            switch (auth_type) {
                case 'plain':
                    if (!config.auth.user || !config.auth.pass) {
                        throw new Error("Must include auth.user and auth.pass for PLAIN auth.");
                    }
                    logger.logdebug('[smtp_client_pool] uuid=' + smtp_client.uuid + ' authenticating as "' + config.auth.user + '"');
                    smtp_client.send_command('AUTH',
                        'PLAIN ' + utils.base64(config.auth.user + "\0" + config.auth.user + "\0" + config.auth.pass) );
                    break;
                case 'cram-md5':
                    throw new Error("Not implemented");
                default:
                    throw new Error("Unknown AUTH type: " + auth_type);
            }
        });

        smtp_client.on('auth', function () {
            if (smtp_client.is_dead_sender(plugin, connection)) {
              return;
            }
            smtp_client.authenticated = true;
            smtp_client.send_command('MAIL',
                'FROM:' + connection.transaction.mail_from);
        });

        smtp_client.on('error', function (msg) {
            connection.logwarn(plugin, msg);
            smtp_client.call_next();
        });

        if (smtp_client.connected) {
            if (smtp_client.xclient) {
                smtp_client.send_command('XCLIENT',
                    'ADDR=' + connection.remote_ip);
            }
            else {
                smtp_client.emit('helo');
            }
        }

        callback(err, smtp_client);
    });
};
<commit_msg>alter formatting of STATE{}<commit_after>"use strict";
// SMTP client object and class. This allows for every part of the client
// protocol to be hooked for different levels of control, such as
// smtp_forward and smtp_proxy queue plugins.
/* jshint node: true */

var events = require('events');
var util = require('util');
var generic_pool = require('generic-pool');
var line_socket = require('./line_socket');
var logger = require('./logger');
var uuid = require('./utils').uuid;
var utils = require('./utils');

var smtp_regexp = /^([0-9]{3})([ -])(.*)/;
var STATE = {
    IDLE: 1,
    ACTIVE: 2,
    RELEASED: 3,
    DESTROYED: 4,
};

var tls_key;
var tls_cert;

function SMTPClient(port, host, connect_timeout, idle_timeout) {
    events.EventEmitter.call(this);
    this.uuid = uuid();
    this.socket = line_socket.connect(port, host);
    this.socket.setTimeout(((connect_timeout === undefined) ? 30 : connect_timeout) * 1000);
    this.socket.setKeepAlive(true);
    this.state = STATE.IDLE;
    this.command = 'greeting';
    this.response = [];
    this.connected = false;
    this.authenticated = false;
    this.auth_capabilities = [];
    var self = this;

    this.socket.on('line', function (line) {
        self.emit('server_protocol', line);
        var matches = smtp_regexp.exec(line);
        if (!matches) {
            self.emit('error', self.uuid + ': Unrecognised response from upstream server: ' + line);
            self.destroy();
            return;
        }

        var code = matches[1],
            cont = matches[2],
            msg = matches[3];
        self.response.push(msg);
        if (cont !== ' ') {
            return;
        }

        if (self.command === 'ehlo') {
            if (code.match(/^5/)) {
                // Handle fallback to HELO if EHLO is rejected
                self.emit('greeting', 'HELO');
                return;
            }
            self.emit('capabilities');
            if (self.command != 'ehlo') {
                return;
            }
        }
        if (self.command === 'xclient' && code.match(/^5/)) {
            // XCLIENT command was rejected (no permission?)
            // Carry on without XCLIENT
            self.command = 'helo';
        }
        else if (code.match(/^[45]/)) {
            self.emit('bad_code', code, self.response.join(' '));
            if (self.state != STATE.ACTIVE) {
                return;
            }
        }
        switch (self.command) {
            case 'xclient':
                self.xclient = true;
                self.emit('xclient', 'EHLO');
                break;
            case 'starttls':
                if (tls_key && tls_cert) {
                    this.upgrade({key: tls_key, cert: tls_cert});
                }
                break;
            case 'greeting':
                self.connected = true;
                self.emit('greeting', 'EHLO');
                break;
            case 'ehlo':
                self.emit('helo');
                break;
            case 'helo':
            case 'mail':
            case 'rcpt':
            case 'data':
            case 'dot':
            case 'rset':
            case 'auth':
                self.emit(self.command);
                break;
            case 'quit':
                self.emit('quit');
                self.destroy();
                break;
            default:
                throw new Error("Unknown command: " + self.command);
        }
    });

    this.socket.on('connect', function () {
        // Remove connection timeout and set idle timeout
        self.socket.setTimeout(((idle_timeout) ? idle_timeout : 300) * 1000);
    });

    var closed = function (msg) {
        return function (error) {
            if (!error) {
                error = '';
            }
            if (self.state === STATE.ACTIVE) {
                self.emit('error', self.uuid + ': SMTP connection ' + msg + ' ' + error);
                self.destroy();
            }
            else {
                logger.logdebug('[smtp_client_pool] ' + self.uuid + ': SMTP connection ' + msg + ' ' + error + ' (state=' + self.state + ')');
                if (self.state === STATE_IDLE) {
                    self.destroy();
                }
                else if (self.state === STATE.RELEASED) {
                    self.destroy();
                }
            }
        };
    };

    this.socket.on('error', closed('errored'));
    this.socket.on('timeout', closed('timed out'));
    this.socket.on('close', closed('closed'));
    this.socket.on('end', closed('ended'));
}

util.inherits(SMTPClient, events.EventEmitter);

SMTPClient.prototype.send_command = function (command, data) {
    var line = (command === 'dot') ? '.' : command + (data ? (' ' + data) : '');
    this.emit('client_protocol', line);
    this.command = command.toLowerCase();
    this.response = [];
    this.socket.write(line + "\r\n");
};

SMTPClient.prototype.start_data = function (data) {
    this.response = [];
    this.command = 'dot';
    data.pipe(this.socket, { dot_stuffing: true, ending_dot: true, end: false });
};

SMTPClient.prototype.release = function () {
    if (!this.connected || this.command === 'data' || this.command === 'mailbody') {
        // Destroy here, we can't reuse a connection that was mid-data.
        this.destroy();
        return;
    }

    logger.logdebug('[smtp_client_pool] ' + this.uuid + ' resetting, state=' + this.state);
    if (this.state === STATE.DESTROYED) {
        return;
    }
    this.state = STATE.RELEASED;
    this.removeAllListeners('greeting');
    this.removeAllListeners('capabilities');
    this.removeAllListeners('xclient');
    this.removeAllListeners('helo');
    this.removeAllListeners('mail');
    this.removeAllListeners('rcpt');
    this.removeAllListeners('data');
    this.removeAllListeners('dot');
    this.removeAllListeners('rset');
    this.removeAllListeners('auth');
    this.removeAllListeners('client_protocol');
    this.removeAllListeners('server_protocol');
    this.removeAllListeners('error');
    this.removeAllListeners('bad_code');

    this.on('bad_code', function (code, msg) {
        this.destroy();
    });

    this.on('rset', function () {
        logger.logdebug('[smtp_client_pool] ' + this.uuid + ' releasing, state=' + this.state);
        if (this.state === STATE.DESTROYED) {
            return;
        }
        this.state = STATE.IDLE;
        this.removeAllListeners('rset');
        this.removeAllListeners('bad_code');
        this.pool.release(this);
    });

    this.send_command('RSET');
};

SMTPClient.prototype.destroy = function () {
    if (this.state !== STATE.DESTROYED) {
        this.pool.destroy(this);
    }
};

SMTPClient.prototype.is_dead_sender = function (plugin, connection) {
    if (!connection.transaction) {
        // This likely means the sender went away on us, cleanup.
        connection.logwarn(
          plugin, "transaction went away, releasing smtp_client"
        );
        this.release();
        return true;
    }

    return false;
};

// Separate pools are kept for each set of server attributes.
exports.get_pool = function (server, port, host, connect_timeout, pool_timeout, max) {
    port = port || 25;
    host = host || 'localhost';
    connect_timeout = (connect_timeout === undefined) ? 30 : connect_timeout;
    pool_timeout = (pool_timeout === undefined) ? 300 : pool_timeout;
    var name = port + ':' + host + ':' + pool_timeout;
    if (!server.notes.pool) {
        server.notes.pool = {};
    }
    if (!server.notes.pool[name]) {
        var pool = generic_pool.Pool({
            name: name,
            create: function (callback) {
                var smtp_client = new SMTPClient(port, host, connect_timeout);
                logger.logdebug('[smtp_client_pool] uuid=' + smtp_client.uuid + ' host=' + host +
                    ' port=' + port + ' pool_timeout=' + pool_timeout + ' created');
                callback(null, smtp_client);
            },
            destroy: function(smtp_client) {
                logger.logdebug('[smtp_client_pool] ' + smtp_client.uuid + ' destroyed, state=' + smtp_client.state);
                smtp_client.state = STATE.DESTROYED;
                smtp_client.socket.destroy();
                // Remove pool object from server notes once empty
                var size = pool.getPoolSize();
                if (size === 0) {
                    delete server.notes.pool[name];
                }
            },
            max: max || 1000,
            idleTimeoutMillis: pool_timeout * 1000,
            log: function (str, level) {
                level = (level === 'verbose') ? 'debug' : level;
                logger['log' + level]('[smtp_client_pool] [' + name + '] ' + str);
            }
        });

        var acquire = pool.acquire;
        pool.acquire = function (callback, priority) {
            var callback_wrapper = function (err, smtp_client) {
                smtp_client.pool = pool;
                smtp_client.state = STATE_ACTIVE;
                callback(err, smtp_client);
            };
            acquire.call(pool, callback_wrapper, priority);
        };
        server.notes.pool[name] = pool;
    }
    return server.notes.pool[name];
};

// Get a smtp_client for the given attributes.
exports.get_client = function (server, callback, port, host, connect_timeout, pool_timeout, max) {
    var pool = exports.get_pool(server, port, host, connect_timeout, pool_timeout, max);
    pool.acquire(callback);
};

// Get a smtp_client for the given attributes and set it up the common
// config and listeners for plugins. Currently this is what smtp_proxy and
// smtp_forward have in common.
exports.get_client_plugin = function (plugin, connection, config, callback) {
    var c = config.main;
    var pool = exports.get_pool(connection.server, c.port, c.host,
                                c.connect_timeout, c.timeout, c.max_connections);
    pool.acquire(function (err, smtp_client) {
        connection.logdebug(plugin, 'Got smtp_client: ' + smtp_client.uuid);

        var secured = false;

        smtp_client.call_next = function (retval, msg) {
            if (this.next) {
                var next = this.next;
                delete this.next;
                next(retval, msg);
            }
        };

        smtp_client.on('client_protocol', function (line) {
            connection.logprotocol(plugin, 'C: ' + line);
        });

        smtp_client.on('server_protocol', function (line) {
            connection.logprotocol(plugin, 'S: ' + line);
        });

        var helo = function (command) {
            if (smtp_client.xclient) {
                smtp_client.send_command(command, connection.hello_host);
            }
            else {
                smtp_client.send_command(command, plugin.config.get('me'));
            }
        };
        smtp_client.on('greeting', helo);
        smtp_client.on('xclient', helo);

        smtp_client.on('capabilities', function () {
            var on_secured = function () {
                secured = true;
                smtp_client.emit('greeting', 'EHLO');
            };
            for (var line in smtp_client.response) {
                if (smtp_client.response[line].match(/^XCLIENT/)) {
                    if(!smtp_client.xclient) {
                        smtp_client.send_command('XCLIENT',
                            'ADDR=' + connection.remote_ip);
                        return;
                    }
                }
                if (smtp_client.response[line].match(/^STARTTLS/) && !secured) {
                    if (c.enable_tls) {
                        tls_key = plugin.config.get('tls_key.pem', 'binary');
                        tls_cert = plugin.config.get('tls_cert.pem', 'binary');
                        if (tls_key && tls_cert) {
                            smtp_client.socket.on('secure', on_secured);
                            smtp_client.send_command('STARTTLS');
                            return;
                        }
                    }
                }

                var auth_matches = smtp_client.response[line].match(/^AUTH (.*)$/);
                if (auth_matches) {
                    smtp_client.auth_capabilities = [];
                    auth_matches = auth_matches[1].split(' ');
                    for (var i = 0; i < auth_matches.length; i++) {
                        smtp_client.auth_capabilities.push(auth_matches[i].toLowerCase());
                    }
                }
            }
        });

        smtp_client.on('helo', function () {
            if (!config.auth || smtp_client.authenticated) {
                if (smtp_client.is_dead_sender(plugin, connection)) {
                    return;
                }
                smtp_client.send_command('MAIL', 'FROM:' + connection.transaction.mail_from);
                return;
            }

            if (config.auth.type === null || typeof(config.auth.type) === 'undefined') { return; } // Ignore blank
            var auth_type = config.auth.type.toLowerCase();
            if (smtp_client.auth_capabilities.indexOf(auth_type) == -1) {
                throw new Error("Auth type \"" + auth_type + "\" not supported by server (supports: " + smtp_client.auth_capabilities.join(',') + ")");
            }
            switch (auth_type) {
                case 'plain':
                    if (!config.auth.user || !config.auth.pass) {
                        throw new Error("Must include auth.user and auth.pass for PLAIN auth.");
                    }
                    logger.logdebug('[smtp_client_pool] uuid=' + smtp_client.uuid + ' authenticating as "' + config.auth.user + '"');
                    smtp_client.send_command('AUTH',
                        'PLAIN ' + utils.base64(config.auth.user + "\0" + config.auth.user + "\0" + config.auth.pass) );
                    break;
                case 'cram-md5':
                    throw new Error("Not implemented");
                default:
                    throw new Error("Unknown AUTH type: " + auth_type);
            }
        });

        smtp_client.on('auth', function () {
            if (smtp_client.is_dead_sender(plugin, connection)) {
              return;
            }
            smtp_client.authenticated = true;
            smtp_client.send_command('MAIL',
                'FROM:' + connection.transaction.mail_from);
        });

        smtp_client.on('error', function (msg) {
            connection.logwarn(plugin, msg);
            smtp_client.call_next();
        });

        if (smtp_client.connected) {
            if (smtp_client.xclient) {
                smtp_client.send_command('XCLIENT',
                    'ADDR=' + connection.remote_ip);
            }
            else {
                smtp_client.emit('helo');
            }
        }

        callback(err, smtp_client);
    });
};
<|endoftext|>


<commit_before>// This script will edit the ID of a blog
// Run this on my blogs in production first
// before incrementally rolling it out to
// ensure all blogs have IDs which are guuids

// Things to think about:

// acquire a sync lock for the blog before doing any of this
// any logged in sessions, any blog info in a session will need to be reset

// template keys, owners, lists of templates
// domain key, handle key
// client databases, etc...
// blog search engine keys
// blog entry keys
// rename /blogs/{id} directory
// rename /static/{id} file directory

var oldBlogID = process.argv[2];
var newBlogID = process.argv[3];

var keys = require("../redis/keys");
var async = require("async");
var client = require("../../app/models/client");

var User = require("../../app/models/user");
var Blog = require("../../app/models/blog");

if (require.main === module) {
  main(process.argv[2], process.argv[3], function(err) {
    if (err) throw err;
    console.log("Done!");
  });
}

function main(oldBlogID, newBlogID, callback) {
  Blog.get({ id: oldBlogID }, function(err, blog) {
    if (err) return callback(err);

    var multi = client.multi();

    multi.set("handle:" + blog.handle, newBlogID);

    // also set the www subdomain alternate key...
    if (blog.domain) multi.set("domain:" + blog.domain, newBlogID);

    multi.exec(function(err) {
      if (err) return callback(err);

      updateUser(blog.owner, oldBlogID, newBlogID, function(err) {
        if (err) return callback(err);

        renamePatterns(oldBlogID, newBlogID, function(err) {
          if (err) return callback(err);

          callback();
        });
      });
    });
  });
}

function renamePatterns(oldBlogID, newBlogID, callback) {
  var patterns = [
    "blog:" + oldBlogID + ":*",
    "template:" + oldBlogID + ":*",
    "template:owned_by:" + oldBlogID
  ];

  async.each(
    patterns,
    function(pattern, next) {
      keys(pattern, function(err, keys) {
        async.each(
          keys,
          function(key, next) {
            client.rename(
              key,
              key.split(":" + oldBlogID + ":").join(":" + newBlogID + ":"),
              next
            );
          },
          next
        );
      });
    },
    callback
  );
}

function updateUser(uid, oldBlogID, newBlogID, callback) {
  User.getById(uid, function(err, user) {
    if (err) return callback(err);
    user.blogs = user.blogs.filter(function(id) {
      return id !== oldBlogID;
    });

    user.blogs.push(newBlogID);

    User.set(user.uid, user, callback);
  });
}

// 'template:owned_by:' + blogID,
// 'handle:' + blog.handle,
// 'domain:' // also www version...
// "blog:" + blogID + ":dropbox:account";

// git client should just work

// Redis set whoses members are the blog IDs
// connected to this dropbox account.
// function blogsKey(account_id) {
//   return "clients:dropbox:" + account_id;
// }
<commit_msg>Updated script to set blog ID<commit_after>// This script will edit the ID of a blog
// Run this on my blogs in production first
// before incrementally rolling it out to
// ensure all blogs have IDs which are guuids

// Things to think about:

// acquire a sync lock for the blog before doing any of this
// any logged in sessions, any blog info in a session will need to be reset

// template keys, owners, lists of templates
// domain key, handle key
// client databases, etc...
// blog search engine keys
// blog entry keys
// rename /blogs/{id} directory
// rename /static/{id} file directory

// 'template:owned_by:' + blogID,
// 'handle:' + blog.handle,
// 'domain:' // also www version...
// "blog:" + blogID + ":dropbox:account";

// git client should just work

// Redis set whoses members are the blog IDs
// connected to this dropbox account.
// function blogsKey(account_id) {
//   return "clients:dropbox:" + account_id;
// }

var keys = require("../redis/keys");
var async = require("async");
var client = require("../../app/models/client");
var User = require("../../app/models/user");
var Blog = require("../../app/models/blog");
var debug = require("debug")("blot:scripts:set-blog-id");
var fs = require("fs-extra");
var localPath = require("helper").localPath;
var staticDirectory = require("config").blog_static_files_dir;

if (require.main === module) {
  var oldBlogID = process.argv[2];
  var newBlogID = process.argv[3];

  main(oldBlogID, newBlogID, function(err) {
    if (err) throw err;

    console.log("Done!");
  });
}

function main(oldBlogID, newBlogID, callback) {
  debug("Switching blog with", oldBlogID, "to", newBlogID);

  Blog.get({ id: oldBlogID }, function(err, oldBlog) {
    if (err) return callback(err);

    if (!oldBlog) return callback(new Error("No blog with ID: " + oldBlogID));

    renameKeys(oldBlog, newBlogID, function(err) {
      if (err) return callback(err);
      updateUser(oldBlog.owner, oldBlogID, newBlogID, function(err) {
        if (err) return callback(err);

        moveDirectories(oldBlogID, newBlogID, function(err) {
          if (err) return callback(err);

          callback();
        });
      });
    });
  });
}

function renameKeys(oldBlog, newBlogID, callback) {
  var multi = client.multi();
  var patterns = ["template:" + oldBlog.id + ":*", "blog:" + oldBlog.id + ":*"];

  async.map(patterns, keys, function(err, patterns) {
    patterns[0].forEach(function(key) {
      multi.RENAMENX(
        key,
        key
          .split("template:" + oldBlog.id + ":")
          .join("template:" + newBlogID + ":")
      );
    });

    patterns[1].forEach(function(key) {
      multi.RENAMENX(
        key,
        key.split("blog:" + oldBlog.id + ":").join("blog:" + newBlogID + ":")
      );
    });

    multi.set("handle:" + oldBlog.handle, newBlogID);
    multi.set("template:owned_by:" + oldBlog.id, newBlogID);

    // also set the www subdomain alternate key...
    if (oldBlog.domain) {
      multi.set("domain:" + oldBlog.domain, newBlogID);

      if (oldBlog.domain.indexOf("www.") === 0)
        multi.set("domain:" + oldBlog.domain.slice("www.".length), newBlogID);
      else multi.set("domain:" + "www." + oldBlog.domain, newBlogID);
    }

    multi.exec(callback);
  });
}

function updateUser(uid, oldBlogID, newBlogID, callback) {
  User.getById(uid, function(err, user) {
    if (err) return callback(err);
    user.blogs = user.blogs.filter(function(id) {
      return id !== oldBlogID;
    });

    user.blogs.push(newBlogID);

    User.set(user.uid, user, callback);
  });
}

function moveDirectories(oldBlogID, newBlogID, callback) {
  var oldBlogDir = localPath(oldBlogID, "/").slice(0, -1);
  var newBlogDir = localPath(newBlogID, "/").slice(0, -1);

  var oldStaticFilesDir = staticDirectory + "/" + oldBlogID;
  var newStaticFilesDir = staticDirectory + "/" + newBlogID;

  debug("Moving folder", oldBlogDir, "to", newBlogDir);
  fs.move(oldBlogDir, newBlogDir, function(err) {
    if (err) return callback(err);

    debug("Moving folder", oldStaticFilesDir, "to", newStaticFilesDir);
    fs.move(oldStaticFilesDir, newStaticFilesDir, callback);
  });
}
<|endoftext|>


<commit_before>function(doc){
	if(doc.geometry && doc.properties){
		emit(doc.geometry, {geometry:doc.geometry,properties:doc.properties,type: "Feature"});
	}
}

<commit_msg>added id and rev to properties<commit_after>function(doc){
	if(doc.geometry && doc.properties && doc._id){
		var outP = {id:doc._id,rev:doc._rev}
		for(key in doc.properties){
			outP[key]=doc.properties[key];
		}
		emit(doc.geometry, {"geometry":doc.geometry,"properties":outP});
	}
}

<|endoftext|>


<commit_before>const CSON_FILES = [
  'menu_darwin.cson',
  'menu_linux.cson',
  'menu_win32.cson',
  'context.cson',
  'settings.cson',
  'about.cson',
  'welcome.cson',
]

const ATOM_VERSION = 'v1.21.0'

module.exports = {
  CSON_FILES,
  ATOM_VERSION,
}
<commit_msg>bump config atom version to v1.22.0-beta0 for validation<commit_after>const CSON_FILES = [
  'menu_darwin.cson',
  'menu_linux.cson',
  'menu_win32.cson',
  'context.cson',
  'settings.cson',
  'about.cson',
  'welcome.cson',
]

const ATOM_VERSION = 'v1.22.0-beta0'

module.exports = {
  CSON_FILES,
  ATOM_VERSION,
}
<|endoftext|>


<commit_before>'use strict';

import rome from 'rome';
import moment from 'moment';
import {
  Polymer
} from "./../_assets/js/polymer";
import {
  UtilBehavior
} from "./../_behaviors/behaviors.es6";
import {
  NoteClab
} from "./../note/script.es6";

export class CalendarClab {

  get behaviors() {
    return [UtilBehavior];
  }

  beforeRegister() {
    this.is = "calendar-clab";
    this.properties = {
      label: String,
      disabled: {
        type: Boolean,
        value: false
      },
      valueStr: {
        type: String,
        value: null,
        notify: true
      },
      inline: {
        type: Boolean,
        value: false
      },
      options: {
        type: Object,
        value: {}
      },
      placeholder: String,
      type: String,
      noteType: String
    }
  }

  attached() {
    setTimeout(() => {
      this.inline ? this._createInstance('div.inline-cal') : this._createInstance("input");
    }, 50);
  }

  detached() {
    const calendar = rome.find(this.querySelector('input'));
    calendar ? calendar.destroy() : null;
  }

  /*----------
  EVENT HANDLERS
  ----------*/
  _checkClear(evt) {
    const newDate = evt.target.value;
    if (newDate === this.valueStr) return;

    if (evt.keyCode === 13) {
      if (newDate !== "") {
        this.valueStr = newDate;

        this.dispatchEvent(new CustomEvent('datechange', {
          bubbles: true,
          composed: true,
          detail: {
            date: newDate,
            dateISO: moment(new Date(newDate)).format()
          }
        }));
      }
      this.getRomeInstance().hide();
    }

    if (newDate === "" && this.valueStr !== null) {
      this.clear();
      this.dispatchEvent(new CustomEvent('datechange', {
        bubbles: true,
        composed: true,
        detail: {
          date: undefined,
          dateISO: undefined
        }
      }));
    }
  }

  _focusElement(evt) {
    if (!this.disabled) {
      evt.stopPropagation();
      this.getRomeInstance().show();
    }
  }

  /*----------
  METHODS
  ----------*/
  _createInstance(selector) {
    this.setLocale();
    const obj = typeof this.options === 'object' ? this.options : this.getRomeInstance().options();
    const currentCalendar = this.$$(selector);
    const cal = rome(currentCalendar, obj);

    cal.on('data', this._changeDate.bind(this))
    cal.on('next', evt => {
      this.cancelAsync(this._fireDate);
    })
    cal.on('back', evt => {
      this.cancelAsync(this._fireDate);
    })

    this.dispatchEvent(new CustomEvent('instance-created', {
      bubbles: true,
      composed: true,
      detail: currentCalendar,
    }));
  }

  _changeDate(newDate) {
    if (newDate === this.valueStr) return;

    this.cancelAsync(this._fireDate);
    this._fireDate = this.async(() => {
      this.valueStr = newDate;
      this.dispatchEvent(new CustomEvent('datechange', {
        bubbles: true,
        composed: true,
        detail: {
          date: newDate,
          dateISO: moment(new Date(newDate)).format()
        }
      }));
    }, 250);
  }

  /*----------
  COMPUTED
  ----------*/
  _computeType(str, type) {
    return [str, type].join(' ');
  }

  /*----------
  UTILS
  ----------*/
  _getFormat() {
    let thisFormat = this.options.inputFormat ? this.options.inputFormat : this.getRomeInstance().options().inputFormat;
    return thisFormat;
  }

  _getLocale() {
    let thisLocale = this.options.locale ? this.options.locale : 'en';
    return thisLocale;
  }

  /*----------
  PUBLIC METHODS
  ----------*/
  setValue(userValue) {
    this.valueStr = moment(userValue).format(this._getFormat());
  }

  getValue() {
    let formatted = moment(this.valueStr, this._getFormat()).format();
    return this.valueStr ? formatted : undefined;
  }

  setLocale() {
    let thisLocale = this._getLocale();
    rome.moment.locale(thisLocale);
  }

  getLocale() {
    return rome.moment.locale();
  }

  getRomeInstance() {
    return rome.find(this.querySelector('input'));
  }

  restore() {
    const selector = this.inline ? 'div.inline-cal' : 'input';
    const currentCalendar = this.$$(selector);
    rome(currentCalendar).restore(this.options);
    return currentCalendar;
  }

  clear() {
    this.value = '';
    this.valueStr = null;
    let rome = this.getRomeInstance();
    rome.setValue(moment().format());
  }

}

Polymer(CalendarClab);
<commit_msg>fix of calendar's restore()<commit_after>'use strict';

import rome from 'rome';
import moment from 'moment';
import {
  Polymer
} from "./../_assets/js/polymer";
import {
  UtilBehavior
} from "./../_behaviors/behaviors.es6";
import {
  NoteClab
} from "./../note/script.es6";

export class CalendarClab {

  get behaviors() {
    return [UtilBehavior];
  }

  beforeRegister() {
    this.is = "calendar-clab";
    this.properties = {
      label: String,
      disabled: {
        type: Boolean,
        value: false
      },
      valueStr: {
        type: String,
        value: null,
        notify: true
      },
      inline: {
        type: Boolean,
        value: false
      },
      options: {
        type: Object,
        value: {}
      },
      placeholder: String,
      type: String,
      noteType: String
    }
  }

  attached() {
    setTimeout(() => {
      this.inline ? this._createInstance('div.inline-cal') : this._createInstance("input");
    }, 50);
  }

  detached() {
    const calendar = rome.find(this.querySelector('input'));
    calendar ? calendar.destroy() : null;
  }

  /*----------
  EVENT HANDLERS
  ----------*/
  _checkClear(evt) {
    const newDate = evt.target.value;
    if (newDate === this.valueStr) return;

    if (evt.keyCode === 13) {
      if (newDate !== "") {
        this.valueStr = newDate;

        this.dispatchEvent(new CustomEvent('datechange', {
          bubbles: true,
          composed: true,
          detail: {
            date: newDate,
            dateISO: moment(new Date(newDate)).format()
          }
        }));
      }
      this.getRomeInstance().hide();
    }

    if (newDate === "" && this.valueStr !== null) {
      this.clear();
      this.dispatchEvent(new CustomEvent('datechange', {
        bubbles: true,
        composed: true,
        detail: {
          date: undefined,
          dateISO: undefined
        }
      }));
    }
  }

  _focusElement(evt) {
    if (!this.disabled) {
      evt.stopPropagation();
      this.getRomeInstance().show();
    }
  }

  /*----------
  METHODS
  ----------*/
  _createInstance(selector) {
    this.setLocale();
    const obj = typeof this.options === 'object' ? this.options : this.getRomeInstance().options();
    const currentCalendar = this.$$(selector);
    const cal = rome(currentCalendar, obj);

    cal.on('data', this._changeDate.bind(this))
    cal.on('next', evt => {
      this.cancelAsync(this._fireDate);
    })
    cal.on('back', evt => {
      this.cancelAsync(this._fireDate);
    })

    this.dispatchEvent(new CustomEvent('instance-created', {
      bubbles: true,
      composed: true,
      detail: currentCalendar,
    }));
  }

  _changeDate(newDate) {
    if (newDate === this.valueStr) return;

    this.cancelAsync(this._fireDate);
    this._fireDate = this.async(() => {
      this.valueStr = newDate;
      this.dispatchEvent(new CustomEvent('datechange', {
        bubbles: true,
        composed: true,
        detail: {
          date: newDate,
          dateISO: moment(new Date(newDate)).format()
        }
      }));
    }, 250);
  }

  /*----------
  COMPUTED
  ----------*/
  _computeType(str, type) {
    return [str, type].join(' ');
  }

  /*----------
  UTILS
  ----------*/
  _getFormat() {
    let thisFormat = this.options.inputFormat ? this.options.inputFormat : this.getRomeInstance().options().inputFormat;
    return thisFormat;
  }

  _getLocale() {
    let thisLocale = this.options.locale ? this.options.locale : 'en';
    return thisLocale;
  }

  /*----------
  PUBLIC METHODS
  ----------*/
  setValue(userValue) {
    this.valueStr = moment(userValue).format(this._getFormat());
  }

  getValue() {
    let formatted = moment(this.valueStr, this._getFormat()).format();
    return this.valueStr ? formatted : undefined;
  }

  setLocale() {
    let thisLocale = this._getLocale();
    rome.moment.locale(thisLocale);
  }

  getLocale() {
    return rome.moment.locale();
  }

  getRomeInstance() {
    return rome.find(this.querySelector('input'));
  }

  restore(options) {
    const selector = this.inline ? 'div.inline-cal' : 'input';
    const currentCalendar = this.$$(selector);
    rome(currentCalendar).destroy();
    rome(currentCalendar).restore(options || this.options);
    return currentCalendar;
  }

  clear() {
    this.value = '';
    this.valueStr = null;
    let rome = this.getRomeInstance();
    rome.setValue(moment().format());
  }

}

Polymer(CalendarClab);
<|endoftext|>


<commit_before>var sql = window.SQL;
// The db variable gets set every time a level is loaded.
var db;

// Return an HTML table as a string, given SQL.js results
var table_from_results = function(res) {
  var table_string = '
';
  if (res) {
    table_string += '
';
    for (var index in res[0].columns) {
      table_string += '' + res[0].columns[index] + '	';
    }
    table_string += '
';
    for (var row_index in res[0].values) {
      table_string += '
';
      for (var col_index in res[0].values[row_index]) {
        table_string += '' + res[0].values[row_index][col_index] + '	';
      }
      table_string += '
';
    }
  }
  table_string += '
';
  return table_string;
};

var grade_results = function(results, correct_answer) {
  if (!results) {
    return false;
  }

  return JSON.stringify(results[0].columns) == JSON.stringify(correct_answer.columns) &&
    JSON.stringify(results[0].values) == JSON.stringify(correct_answer.values);
}

var show_is_correct = function(is_correct) {
  if (is_correct) {
    is_correct_html = 'Congrats!  That is correct!
';
    if (current_level < levels.length) {
      is_correct_html += 'Next Lesson';
    } else {
      is_correct_html += 'That is currently the end of the tutorial.  Please check back later for more!';
    }
    $('#answer-correctness').html(is_correct_html);
  } else {
    $('#answer-correctness').text('That was incorrect.  Please try again.');
  }
  $('#answer-correctness').show();
};

// Onclick handler for when you click "Run SQL"
$('#sql-link').click(function() {
  var answer = levels[current_level - 1]['answer'];
  try {
    var results = db.exec($('#sql-input').val());
    $('#results').html(table_from_results(results));
    show_is_correct(grade_results(results, answer));
  } catch (err) {
    $('#results').html('');
    show_is_correct(false);
  }
  $('.expected-results-container').show();
  $('#expected-results').html(table_from_results([answer]));
  return false;
});

// Stores the prompts and answers for each level number
var levels = [{'name': 'SELECT *',
               'short_name': 'select',
               'database_type': 'family',
               'answer': {'columns': ['id', 'name', 'gender', 'species', 'age'],
                           'values': [[1, 'Dave', 'male', 'human', 28],
                                      [2, 'Mary', 'female', 'human', 27],
                                      [3, 'Pickles', 'male', 'dog', 4]]},
               'prompt': 'In SQL, data is usually organized in various tables. For example, a sports team database might have the tables teams, players, and games. A wedding database might have tables guests, vendors, and music_playlist.

Imagine we have a table that stores family members with each member\'s name, age, species, and gender.

Let\'s start by grabbing all of the data in one table.  We have a table called family_members that is shown below.  In order to grab all of that data, please run the following command:
SELECT * FROM family_members;'},

              {'name': 'WHERE ... Equals',
               'short_name': 'where_equals',
               'database_type': 'family',
               'answer': {'columns': ['id', 'name', 'gender', 'species', 'age'],
                          'values': [[3, 'Pickles', 'male', 'dog', 4]]},
               'prompt': 'In order to select particular rows from this table, we use the WHERE keyword.  So for example, if we wanted to grab all of the rows that correspond to humans, we would type
SELECT * FROM family_members WHERE species = \'human\';
  Note that the quotes have to be around the word human.

Can you run a query that returns all of the rows that refer to dogs?'},

              {'name': 'WHERE ... Greater than',
               'short_name': 'where_greater_than',
               'database_type': 'family',
               'answer': {'columns': ['id', 'name', 'gender', 'species', 'age'],
                          'values': [[1, 'Dave', 'male', 'human', 28]]},
               'prompt': 'If we want to only select family members based on a numerical field, we can also use the WHERE keyword.  For example, if we wanted to select family members older than 10, we would type
SELECT * FROM family_members WHERE age > 10;

  Can you run return all rows of members with age greater than 27?'},

              {'name': 'WHERE ... Greater than or equal',
               'short_name': 'where_greater_than_or_equal',
               'database_type': 'family',
               'answer': {'columns': ['id', 'name', 'gender', 'species', 'age'],
                          'values': [[2, 'Mary', 'female', 'human', 27],
                                     [3, 'Pickles', 'male', 'dog', 4]]},
               'prompt': 'SQL accepts various inequality symbols, including:
= "equal to"
> "greater than"
< "less than"
>= "greater than or equal to"
<= "less than or equal to"

 Can you return all rows in family_members with an age less than or equal to 27?'},

              {'name': 'SELECT specific columns',
               'short_name': 'select_columns',
               'database_type': 'family',
               'answer': {'columns': ['name', 'species'],
                          'values': [['Dave', 'human'],
                                     ['Mary', 'human'],
                                     ['Pickles', 'dog']]},
               'prompt': 'SELECT * grabs all fields (called columns) in a table. If we only wanted to see the name and age columns, we would type SELECT name, age from family_members;.

Can you return just the name and species columns?'},

              {'name': 'LIMIT # of returned rows',
               'short_name': 'limit',
               'database_type': 'family',
               'answer': {'columns': ['id', 'name', 'gender', 'species', 'age'],
                          'values': [[1, 'Dave', 'male', 'human', 28]]},
               'prompt': 'Often, tables contain millions of rows, and it can take a while to grab everything. If we just want to see a few examples of the data in a table, we can select only a few rows. If we want to select 2 rows, we would add LIMIT 2 at the end of the query.

 Can you return just the first row (and all columns) of family_members?'},

              {'name': 'COUNT(*)',
               'short_name': 'count',
               'database_type': 'family',
               'answer': {'columns': ['COUNT(*)'],
                          'values': [[3]]},
               'prompt': 'Another way to explore a table is to check the number of rows in it. For example, if we are querying a table states_of_us we\'d expect 50 rows, or 500 rows in a table called fortune_500_companies.

SELECT COUNT(*) FROM family_members; returns the total number of rows in the table family_members. Try this for yourself.'},

              {'name': 'COUNT(*) ... WHERE',
               'short_name': 'count_where',
               'database_type': 'family',
               'answer': {'columns': ['COUNT(*)'],
                          'values': [[1]]},
               'prompt': 'We can combine COUNT(*) with WHERE. For example, SELECT COUNT(*) FROM family_members WHERE species = \'human\'; returns 2.

Can you return the number of rows in family_members where the species is a dog?'},
              {'name': 'NULL',
               'short_name': 'null',
               'database_type': 'family_null',
               'answer': {'columns': ['id', 'name', 'gender', 'species', 'age', 'favorite_book'],
                           'values': [[1, 'Dave', 'male', 'human', 28, 'To Kill a Mockingbird'],
                                      [2, 'Mary', 'female', 'human', 27, 'Gone with the Wind']]},
               'prompt': 'Sometimes, in a given row, there is no value at all for a given column.  For example, a dog does not have a favorite book, so in that case there is no point in putting a value in the favorite_book column, and the value is NULL.  In order to find the rows where the value for a column is or is not NULL, you would use IS NULL or IS NOT NULL.

Can you return all of the rows of family_members where favorite_book is not null?'}
              ];

// Create the SQL database
var load_database = function(db_type) {
  var database, sqlstr, results;
  switch (db_type) {
    case 'family':
      database = new sql.Database();
      sqlstr = "CREATE TABLE family_members (id int, name char, gender char, species char, age int);";
      sqlstr += "INSERT INTO family_members VALUES (1, 'Dave', 'male', 'human', 28);"
      sqlstr += "INSERT INTO family_members VALUES (2, 'Mary', 'female', 'human', 27);"
      sqlstr += "INSERT INTO family_members VALUES (3, 'Pickles', 'male', 'dog', 4);"
      database.run(sqlstr);
      results = database.exec("SELECT * FROM family_members;");
      $('#current-tables').html(table_from_results(results));
      return database;
    case 'family_null':
      database = new sql.Database();
      sqlstr = "CREATE TABLE family_members (id int, name char, gender char, species char, age int, favorite_book char);";
      sqlstr += "INSERT INTO family_members VALUES (1, 'Dave', 'male', 'human', 28, 'To Kill a Mockingbird');"
      sqlstr += "INSERT INTO family_members VALUES (2, 'Mary', 'female', 'human', 27, 'Gone with the Wind');"
      sqlstr += "INSERT INTO family_members VALUES (3, 'Pickles', 'male', 'dog', 4, NULL);"
      database.run(sqlstr);
      results = database.exec("SELECT * FROM family_members;");
      $('#current-tables').html(table_from_results(results));
      return database;
  }
};

var current_level;
var current_level_name;

var load_level = function() {
  var hash_code = window.location.hash.substr(2);
  // The current level is 1 by default, unless the hash code matches the short name for a level.
  current_level = 1;
  for (var index in levels) {
    if (hash_code == levels[index]['short_name']) {
      current_level = parseInt(index, 10) + 1;
      break;
    }
  }
  var database = load_database(levels[current_level-1]['database_type']);
  // Set text for current level
  lesson_name = levels[current_level-1]['name'];
  $('#lesson-name').text("Lesson " + current_level + ": " + lesson_name);
  $('#prompt').html(levels[current_level-1]['prompt']);

  // Add "next" and "previous" links if it makes sense.
  if (current_level > 1) {
    $('#previous-link').attr('href', '#!' + levels[current_level-2]['short_name']);
    $('#previous-link').show();
  } else {
    $('#previous-link').hide();
  }
  if (current_level < levels.length) {
    $('#next-link').attr('href', '#!' + levels[current_level]['short_name']);
    $('#next-link').show();
  } else {
    $('#next-link').hide();
  }

  // Add links to menu
  var menu_html = '';
  for (var index in levels) {
    if (index == (current_level - 1)) {
      menu_html += '';
    }
    menu_html += '' + levels[index]['name'] + '';
    if (index == (current_level - 1)) {
      menu_html += '';
    }
  }
  $('.menu').html(menu_html);

  // Clear out old data
  $('#answer-correctness').hide();
  $('#sql-input').val('');
  $('#results').html('');
  $('.expected-results-container').hide();
  return database;
};
db = load_level();

// When the URL after the # changes, we load a new level,
// and let Google Analytics know that the page has changed.
$(window).bind('hashchange', function() {
  db = load_level();
  ga('send', 'pageview', {'page': location.pathname + location.search  + location.hash});
});
<commit_msg>Date tutorial<commit_after>var sql = window.SQL;
// The db variable gets set every time a level is loaded.
var db;

// Return an HTML table as a string, given SQL.js results
var table_from_results = function(res) {
  var table_string = '
';
  if (res) {
    table_string += '
';
    for (var index in res[0].columns) {
      table_string += '' + res[0].columns[index] + '	';
    }
    table_string += '
';
    for (var row_index in res[0].values) {
      table_string += '
';
      for (var col_index in res[0].values[row_index]) {
        table_string += '' + res[0].values[row_index][col_index] + '	';
      }
      table_string += '
';
    }
  }
  table_string += '
';
  return table_string;
};

var grade_results = function(results, correct_answer) {
  if (!results) {
    return false;
  }

  return JSON.stringify(results[0].columns) == JSON.stringify(correct_answer.columns) &&
    JSON.stringify(results[0].values) == JSON.stringify(correct_answer.values);
}

var show_is_correct = function(is_correct) {
  if (is_correct) {
    is_correct_html = 'Congrats!  That is correct!
';
    if (current_level < levels.length) {
      is_correct_html += 'Next Lesson';
    } else {
      is_correct_html += 'That is currently the end of the tutorial.  Please check back later for more!';
    }
    $('#answer-correctness').html(is_correct_html);
  } else {
    $('#answer-correctness').text('That was incorrect.  Please try again.');
  }
  $('#answer-correctness').show();
};

// Onclick handler for when you click "Run SQL"
$('#sql-link').click(function() {
  var answer = levels[current_level - 1]['answer'];
  try {
    var results = db.exec($('#sql-input').val());
    $('#results').html(table_from_results(results));
    show_is_correct(grade_results(results, answer));
  } catch (err) {
    $('#results').html('');
    show_is_correct(false);
  }
  $('.expected-results-container').show();
  $('#expected-results').html(table_from_results([answer]));
  return false;
});

// Stores the prompts and answers for each level number
var levels = [{'name': 'SELECT *',
               'short_name': 'select',
               'database_type': 'family',
               'answer': {'columns': ['id', 'name', 'gender', 'species', 'age'],
                           'values': [[1, 'Dave', 'male', 'human', 28],
                                      [2, 'Mary', 'female', 'human', 27],
                                      [3, 'Pickles', 'male', 'dog', 4]]},
               'prompt': 'In SQL, data is usually organized in various tables. For example, a sports team database might have the tables teams, players, and games. A wedding database might have tables guests, vendors, and music_playlist.

Imagine we have a table that stores family members with each member\'s name, age, species, and gender.

Let\'s start by grabbing all of the data in one table.  We have a table called family_members that is shown below.  In order to grab all of that data, please run the following command:
SELECT * FROM family_members;'},

              {'name': 'WHERE ... Equals',
               'short_name': 'where_equals',
               'database_type': 'family',
               'answer': {'columns': ['id', 'name', 'gender', 'species', 'age'],
                          'values': [[3, 'Pickles', 'male', 'dog', 4]]},
               'prompt': 'In order to select particular rows from this table, we use the WHERE keyword.  So for example, if we wanted to grab all of the rows that correspond to humans, we would type
SELECT * FROM family_members WHERE species = \'human\';
  Note that the quotes have to be around the word human.

Can you run a query that returns all of the rows that refer to dogs?'},

              {'name': 'WHERE ... Greater than',
               'short_name': 'where_greater_than',
               'database_type': 'family',
               'answer': {'columns': ['id', 'name', 'gender', 'species', 'age'],
                          'values': [[1, 'Dave', 'male', 'human', 28]]},
               'prompt': 'If we want to only select family members based on a numerical field, we can also use the WHERE keyword.  For example, if we wanted to select family members older than 10, we would type
SELECT * FROM family_members WHERE age > 10;

  Can you run return all rows of members with age greater than 27?'},

              {'name': 'WHERE ... Greater than or equal',
               'short_name': 'where_greater_than_or_equal',
               'database_type': 'family',
               'answer': {'columns': ['id', 'name', 'gender', 'species', 'age'],
                          'values': [[2, 'Mary', 'female', 'human', 27],
                                     [3, 'Pickles', 'male', 'dog', 4]]},
               'prompt': 'SQL accepts various inequality symbols, including:
= "equal to"
> "greater than"
< "less than"
>= "greater than or equal to"
<= "less than or equal to"

 Can you return all rows in family_members with an age less than or equal to 27?'},

              {'name': 'SELECT specific columns',
               'short_name': 'select_columns',
               'database_type': 'family',
               'answer': {'columns': ['name', 'species'],
                          'values': [['Dave', 'human'],
                                     ['Mary', 'human'],
                                     ['Pickles', 'dog']]},
               'prompt': 'SELECT * grabs all fields (called columns) in a table. If we only wanted to see the name and age columns, we would type SELECT name, age from family_members;.

Can you return just the name and species columns?'},

              {'name': 'LIMIT # of returned rows',
               'short_name': 'limit',
               'database_type': 'family',
               'answer': {'columns': ['id', 'name', 'gender', 'species', 'age'],
                          'values': [[1, 'Dave', 'male', 'human', 28]]},
               'prompt': 'Often, tables contain millions of rows, and it can take a while to grab everything. If we just want to see a few examples of the data in a table, we can select only a few rows. If we want to select 2 rows, we would add LIMIT 2 at the end of the query.

 Can you return just the first row (and all columns) of family_members?'},

              {'name': 'COUNT(*)',
               'short_name': 'count',
               'database_type': 'family',
               'answer': {'columns': ['COUNT(*)'],
                          'values': [[3]]},
               'prompt': 'Another way to explore a table is to check the number of rows in it. For example, if we are querying a table states_of_us we\'d expect 50 rows, or 500 rows in a table called fortune_500_companies.

SELECT COUNT(*) FROM family_members; returns the total number of rows in the table family_members. Try this for yourself.'},

              {'name': 'COUNT(*) ... WHERE',
               'short_name': 'count_where',
               'database_type': 'family',
               'answer': {'columns': ['COUNT(*)'],
                          'values': [[1]]},
               'prompt': 'We can combine COUNT(*) with WHERE. For example, SELECT COUNT(*) FROM family_members WHERE species = \'human\'; returns 2.

Can you return the number of rows in family_members where the species is a dog?'},
              {'name': 'NULL',
               'short_name': 'null',
               'database_type': 'family_null',
               'answer': {'columns': ['id', 'name', 'gender', 'species', 'age', 'favorite_book'],
                          'values': [[1, 'Dave', 'male', 'human', 28, 'To Kill a Mockingbird'],
                                     [2, 'Mary', 'female', 'human', 27, 'Gone with the Wind']]},
               'prompt': 'Sometimes, in a given row, there is no value at all for a given column.  For example, a dog does not have a favorite book, so in that case there is no point in putting a value in the favorite_book column, and the value is NULL.  In order to find the rows where the value for a column is or is not NULL, you would use IS NULL or IS NOT NULL.

Can you return all of the rows of family_members where favorite_book is not null?'},
              {'name': 'Date',
               'short_name': 'date',
               'database_type': 'celebs_born',
               'answer': {'columns': ['id', 'name', 'birthdate'],
                          'values': [[2, 'Justin Timberlake', '1981-01-31'],
                                     [3, 'Taylor Swift', '1989-12-13']]},
               'prompt': 'Sometimes, a column can contain a date value, which represents some specific time.  The first 4 digits represents the year, the next 2 digits represents the month, and the next 2 digits represents the day of the month.  For example, 1985-07-20 would mean July 20, 1985.

You can compare dates by using < and >.  For example, SELECT * FROM celebs_born WHERE birthdate < \'1985-08-17\'; returns a list of celebrities that were born before August 17th, 1985.

Can you return a list of celebrities that were born after September 1st, 1980?'},
              ];

// Create the SQL database
var load_database = function(db_type) {
  var database, sqlstr, results;
  switch (db_type) {
    case 'family':
      database = new sql.Database();
      sqlstr = "CREATE TABLE family_members (id int, name char, gender char, species char, age int);";
      sqlstr += "INSERT INTO family_members VALUES (1, 'Dave', 'male', 'human', 28);"
      sqlstr += "INSERT INTO family_members VALUES (2, 'Mary', 'female', 'human', 27);"
      sqlstr += "INSERT INTO family_members VALUES (3, 'Pickles', 'male', 'dog', 4);"
      database.run(sqlstr);
      results = database.exec("SELECT * FROM family_members;");
      $('#current-tables').html(table_from_results(results));
      return database;
    case 'family_null':
      database = new sql.Database();
      sqlstr = "CREATE TABLE family_members (id int, name char, gender char, species char, age int, favorite_book char);";
      sqlstr += "INSERT INTO family_members VALUES (1, 'Dave', 'male', 'human', 28, 'To Kill a Mockingbird');"
      sqlstr += "INSERT INTO family_members VALUES (2, 'Mary', 'female', 'human', 27, 'Gone with the Wind');"
      sqlstr += "INSERT INTO family_members VALUES (3, 'Pickles', 'male', 'dog', 4, NULL);"
      database.run(sqlstr);
      results = database.exec("SELECT * FROM family_members;");
      $('#current-tables').html(table_from_results(results));
      return database;
    case 'celebs_born':
      database = new sql.Database();
      sqlstr = "CREATE TABLE celebs_born (id int, name char, birthdate date);";
      sqlstr += "INSERT INTO celebs_born VALUES (1, 'Michael Jordan', '1963-02-17');"
      sqlstr += "INSERT INTO celebs_born VALUES (2, 'Justin Timberlake', '1981-01-31');"
      sqlstr += "INSERT INTO celebs_born VALUES (3, 'Taylor Swift', '1989-12-13');"
      database.run(sqlstr);
      results = database.exec("SELECT * FROM celebs_born;");
      $('#current-tables').html(table_from_results(results));
      return database;
  }
};

var current_level;
var current_level_name;

var load_level = function() {
  var hash_code = window.location.hash.substr(2);
  // The current level is 1 by default, unless the hash code matches the short name for a level.
  current_level = 1;
  for (var index in levels) {
    if (hash_code == levels[index]['short_name']) {
      current_level = parseInt(index, 10) + 1;
      break;
    }
  }
  var database = load_database(levels[current_level-1]['database_type']);
  // Set text for current level
  lesson_name = levels[current_level-1]['name'];
  $('#lesson-name').text("Lesson " + current_level + ": " + lesson_name);
  $('#prompt').html(levels[current_level-1]['prompt']);

  // Add "next" and "previous" links if it makes sense.
  if (current_level > 1) {
    $('#previous-link').attr('href', '#!' + levels[current_level-2]['short_name']);
    $('#previous-link').show();
  } else {
    $('#previous-link').hide();
  }
  if (current_level < levels.length) {
    $('#next-link').attr('href', '#!' + levels[current_level]['short_name']);
    $('#next-link').show();
  } else {
    $('#next-link').hide();
  }

  // Add links to menu
  var menu_html = '';
  for (var index in levels) {
    if (index == (current_level - 1)) {
      menu_html += '';
    }
    menu_html += '' + levels[index]['name'] + '';
    if (index == (current_level - 1)) {
      menu_html += '';
    }
  }
  $('.menu').html(menu_html);

  // Clear out old data
  $('#answer-correctness').hide();
  $('#sql-input').val('');
  $('#results').html('');
  $('.expected-results-container').hide();
  return database;
};
db = load_level();

// When the URL after the # changes, we load a new level,
// and let Google Analytics know that the page has changed.
$(window).bind('hashchange', function() {
  db = load_level();
  ga('send', 'pageview', {'page': location.pathname + location.search  + location.hash});
});
<|endoftext|>


<commit_before>/**
 * Created by bantonides on 1/29/14.
 */
var _path = require('path');

function mapState(path, state) {
  if (state) {
    return {
      id: state.elementId,
      name: state.name,
      self: _path.join(path, '../../../state')
    };
  } else { return null; }
}

function mapLocality(path, locality) {
  if (locality) {
    return {
      id: locality.elementId,
      name: locality.name,
      self: _path.join(path, '../../../state/localities/', locality.elementId.toString())
    };
  } else { return null; }
}

function mapPrecinct(path, precinct) {
  if (precinct) {
    return {
      id: precinct.elementId,
      name: precinct.name,
      self: _path.join(path, '../../../state/localities/', precinct.localityId.toString(), 'precincts', precinct.elementId.toString())
    };
  } else { return null; }
}

function mapPrecinctSplit(path, split) {
  if (split) {
    return {
      id: split.elementId,
      name: split.name,
      self: _path.join(path, '../../../state/localities/', split._precinct.localityId.toString(), '/precincts', split.precinctId.toString(), 'precinctsplits', split.elementId.toString())
    };
  } else { return null; }
}

function mapElectoralDistrict(path, district) {
  if (district) {
    return {
      id: district.elementId,
      name: district.name,
      self: _path.join(path, '../../electoraldistrict')
    }
  } else { return null; }
}

function mapContestSummary(path, contest) {
  return contest ? {
    id: contest.elementId,
    type: contest.type,
    office: contest.office,
    self: _path.join(path, '../..')
  } : null;
}

function mapCandidateSummary(path, candidate) {
  return candidate ? {
    id: candidate.elementId,
    name: candidate.name,
    party: candidate.party,
    self: _path.join(path, '../../ballot/candidates/', candidate.elementId.toString())
  } : null;
}

function mapContestResult(path, contestResult) {
  return {
    id: contestResult.elementId,
    entire_district: contestResult.entireDistrict,
    total_votes: contestResult.totalVotes,
    total_valid_votes: contestResult.totalValidVotes,
    overvotes: contestResult.overvotes,
    blank_votes: contestResult.blankVotes,
    accepted_provisional_votes: contestResult.acceptedProvisionalVotes,
    rejected_votes: contestResult.rejectedVotes,
    certification: contestResult.certification,
    contest: mapContestSummary(path, contestResult._contest),
    jurisdiction: mapState(path, contestResult._state) || mapLocality(path, contestResult._locality) ||
      mapPrecinct(path, contestResult._precinct) || mapPrecinctSplit(path, contestResult._precinctSplit) ||
      mapElectoralDistrict(path, contestResult._electoralDistrict)
  };
}

function mapBallotLineResultSummary(path, blr) {
  return {
    id: blr.elementId,
    candidate_id: blr.candidateId,
    response_id: blr.ballotResponseId,
    votes: blr.votes,
    certification: blr.certification,
    self: _path.join(path, '/ballotlineresults', blr.elementId.toString())
  };
}

function mapBallotLineResults(path, ballotLineResults) {
  return ballotLineResults.map(mapBallotLineResultSummary.bind(undefined, path));
}

function mapBallotLineResult(path, ballotLineResult) {
  return {
    id: ballotLineResult.elementId,
    votes: ballotLineResult.votes,
    victorious: ballotLineResult.victorious,
    certification: ballotLineResult.certification,
    response_text: ballotLineResult._ballotResponse ? ballotLineResult._ballotResponse.text : null,
    candidate: mapCandidateSummary(path, ballotLineResult._candidate),
    contest: mapContestSummary(path, ballotLineResult._contest),
    jurisdiction: mapState(path, ballotLineResult._state) || mapLocality(path, ballotLineResult._locality) ||
      mapPrecinct(path, ballotLineResult._precinct) || mapPrecinctSplit(path, ballotLineResult._precinctSplit) ||
      mapElectoralDistrict(path, ballotLineResult._electoralDistrict)
  };
}

exports.mapContestResult = mapContestResult;
exports.mapBallotLineResults = mapBallotLineResults;
exports.mapBallotLineResult = mapBallotLineResult;
<commit_msg>created two contest summary functions one for ballot line results and one for contest results because both of the self paths are diffrent.<commit_after>/**
 * Created by bantonides on 1/29/14.
 */
var _path = require('path');

function mapState(path, state) {
  if (state) {
    return {
      id: state.elementId,
      name: state.name,
      self: _path.join(path, '../../../state')
    };
  } else { return null; }
}

function mapLocality(path, locality) {
  if (locality) {
    return {
      id: locality.elementId,
      name: locality.name,
      self: _path.join(path, '../../../state/localities/', locality.elementId.toString())
    };
  } else { return null; }
}

function mapPrecinct(path, precinct) {
  if (precinct) {
    return {
      id: precinct.elementId,
      name: precinct.name,
      self: _path.join(path, '../../../state/localities/', precinct.localityId.toString(), 'precincts', precinct.elementId.toString())
    };
  } else { return null; }
}

function mapPrecinctSplit(path, split) {
  if (split) {
    return {
      id: split.elementId,
      name: split.name,
      self: _path.join(path, '../../../state/localities/', split._precinct.localityId.toString(), '/precincts', split.precinctId.toString(), 'precinctsplits', split.elementId.toString())
    };
  } else { return null; }
}

function mapElectoralDistrict(path, district) {
  if (district) {
    return {
      id: district.elementId,
      name: district.name,
      self: _path.join(path, '../../electoraldistrict')
    }
  } else { return null; }
}

function mapBallotLineResultContestSummary(path, contest) {
  return contest ? {
    id: contest.elementId,
    type: contest.type,
    office: contest.office,
    self: _path.join(path, '../..')
  } : null;
}

function mapContestResultContestSummary(path, contest) {
  return contest ? {
    id: contest.elementId,
    type: contest.type,
    office: contest.office,
    self: _path.join(path, '..')
  } : null;
}

function mapCandidateSummary(path, candidate) {
  return candidate ? {
    id: candidate.elementId,
    name: candidate.name,
    party: candidate.party,
    self: _path.join(path, '../../ballot/candidates/', candidate.elementId.toString())
  } : null;
}

function mapContestResult(path, contestResult) {
  return {
    id: contestResult.elementId,
    entire_district: contestResult.entireDistrict,
    total_votes: contestResult.totalVotes,
    total_valid_votes: contestResult.totalValidVotes,
    overvotes: contestResult.overvotes,
    blank_votes: contestResult.blankVotes,
    accepted_provisional_votes: contestResult.acceptedProvisionalVotes,
    rejected_votes: contestResult.rejectedVotes,
    certification: contestResult.certification,
    contest: mapContestResultContestSummary(path, contestResult._contest),
    jurisdiction: mapState(path, contestResult._state) || mapLocality(path, contestResult._locality) ||
      mapPrecinct(path, contestResult._precinct) || mapPrecinctSplit(path, contestResult._precinctSplit) ||
      mapElectoralDistrict(path, contestResult._electoralDistrict)
  };
}

function mapBallotLineResultSummary(path, blr) {
  return {
    id: blr.elementId,
    candidate_id: blr.candidateId,
    response_id: blr.ballotResponseId,
    votes: blr.votes,
    certification: blr.certification,
    self: _path.join(path, '/ballotlineresults', blr.elementId.toString())
  };
}

function mapBallotLineResults(path, ballotLineResults) {
  return ballotLineResults.map(mapBallotLineResultSummary.bind(undefined, path));
}

function mapBallotLineResult(path, ballotLineResult) {
  return {
    id: ballotLineResult.elementId,
    votes: ballotLineResult.votes,
    victorious: ballotLineResult.victorious,
    certification: ballotLineResult.certification,
    response_text: ballotLineResult._ballotResponse ? ballotLineResult._ballotResponse.text : null,
    candidate: mapCandidateSummary(path, ballotLineResult._candidate),
    contest: mapBallotLineResultContestSummary(path, ballotLineResult._contest),
    jurisdiction: mapState(path, ballotLineResult._state) || mapLocality(path, ballotLineResult._locality) ||
      mapPrecinct(path, ballotLineResult._precinct) || mapPrecinctSplit(path, ballotLineResult._precinctSplit) ||
      mapElectoralDistrict(path, ballotLineResult._electoralDistrict)
  };
}

exports.mapContestResult = mapContestResult;
exports.mapBallotLineResults = mapBallotLineResults;
exports.mapBallotLineResult = mapBallotLineResult;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Button, Glyphicon } from 'react-bootstrap';

class Campers extends Component {
  constructor(props){
    super(props);
    var date = new Date(this.props.camper.endTime).toTimeString();
    var setup = Array.from(this.props.camper.setup);
    setup.splice(setup.length-1, 1); //to remove the extra comma
    this.state = { end: (date.substr(0,5) + ' ' + date.substr(9, date.length)),
                   techSetup: setup.join(", ")};
  }

  render() {
    return (

        {this.props.camper.username}

        {this.props.camper.interests}

        Preferred Pairing Technology(s): {this.state.techSetup}

        Available until: {this.state.end}
        <form action={'https://enigmatic-dawn-95873.herokuapp.com/api/v1/' + this.props.camper._id} id={this.props.camper._id} method='post'>
          <input type='hidden' name='idToDelete' id='idToDelete' value={this.props.camper_id} />
          <Button type='submit' className='circle-button' bsStyle="danger" bsSize="small">
            Delete Post <Glyphicon glyph='trash' />
          </Button>
        </form>

    );
  }
}

export default Campers;
<commit_msg>Wrap user card info in a div<commit_after>import React, { Component } from 'react';
import { Button, Glyphicon } from 'react-bootstrap';

class Campers extends Component {
  constructor(props){
    super(props);
    var date = new Date(this.props.camper.endTime).toTimeString();
    var setup = Array.from(this.props.camper.setup);
    setup.splice(setup.length-1, 1); //to remove the extra comma
    this.state = { end: (date.substr(0,5) + ' ' + date.substr(9, date.length)),
                   techSetup: setup.join(", ")};
  }

  render() {
    return (

          {this.props.camper.username}

          {this.props.camper.interests}

          Preferred Pairing Technology(s): {this.state.techSetup}

          Available until: {this.state.end}
          <form action={'https://enigmatic-dawn-95873.herokuapp.com/api/v1/' + this.props.camper._id} id={this.props.camper._id} method='post'>
            <input type='hidden' name='idToDelete' id='idToDelete' value={this.props.camper_id} />
            <Button type='submit' className='circle-button' bsStyle="danger" bsSize="small">
              Delete Post <Glyphicon glyph='trash' />
            </Button>
          </form>

    );
  }
}

export default Campers;
<|endoftext|>