<commit_before>var objLinkList = [
            { href: "#blogs", linkText: "Blogs" },
            { href: "#herramientas", linkText: "Herramientas" },
            { href: "#recursos", linkText: "Recursos" }
        ];
var objBlogs =  [
    {
        url: "https://css-tricks.com/",
        linkText: "css-tricks",
        text: "Indudablemente una de las webs número uno de consulta para un frontend. Artículos y tutoriales de calidad y un buen número de snippets."
    },
    {
        url: "https://www.smashingmagazine.com/",
        linkText: "Smashing Magazine",
        text: "Todo un referente en el mundo de la web. Código, diseño, mobile, UX ... etc. Publican libros con colecciones de sus artículos más interesantes."
    },
    {
        url: "https://www.sitepoint.com/",
        linkText: "Site Point",
        text: "Artículos meticulosos de gran calidad, podcast, libros y cursos (a veces gratis). También imprescindible."
    },
    {
        url: "https://scotch.io/",
        linkText: "Scotch.io",
        text: "Tutoriales excelentes sobre el mundo frontend y backend javascript. Disponen de cursos free y premium. ¡¡No perdérselo!!"
    },
    {
        url: "https://davidwalsh.name/",
        linkText: "David Walsh Blog",
        text: "Blog del gurú JavaScript David Walsh. Nos mantiene al día con sus interesantes artículos. No solo habla de JavaScript, también aborda otras tecnologías web."
    },
    {
        url: "http://alistapart.com/articles",
        linkText: "A List Apart",
        text: "Artículos de todo lo relacionado con la web. Son artículos de una calidad tan extraordinaria que algunos son un referente."
    },
    {
        url: "https://webmasters.googleblog.com/",
        linkText: "Google Webmaster Blog",
        text: "No puede faltar el blog oficial de Google para webmasters."
    },
    {
        url: "http://lea.verou.me/",
        linkText: "Lea Verou",
        text: "La gran Lea Verou. Proyectos, charlas, artículos. Una eminencia en el CSS."
    },
    {
        url: "http://wesbos.com/blog/",
        linkText: "Web Bos",
        text: "Artículos, videos y tutoriales"
    },
    {
        url: "http://www.developerdrive.com/",
        linkText: "Developer Drive",
        text: "Artículos sobre todo tipo de tecnología de desarrollo web."
    },
    {
        url: "http://www.cssportal.com/",
        linkText: "CSS Portal",
        text: "Snippets, generadores y herramientas para desarrollar en CSS."
    },
    {
        url: "http://www.elmaquetadorweb.com/",
        linkText: "El maquetador web",
        text: "Excelente blog mantenido por Javi Luna y Pedro Marín donde nos cuentan muchos trucos en esto del CSS. Me encanta el nombre de maquetador, término en desuso hoy en día.  ;D"
    },
    {
        url: "https://toddmotto.com/",
        linkText: "Todd Motto",
        text: "Artículos y tutoriales sobre JavaScript, Angular y Typescript. Dispone de muy buenos cursos en premium."
    },
    {
        url: "http://valhead.com/blog/",
        linkText: "Val Head Blog",
        text: "Artículos y tutoriales de una especialista en animaciones CSS web."
    },
    {
        url: "https://codyhouse.co/",
        linkText: "Cody House",
        text: "Colecciones gratuitas de snippets de HTML, CSS y JavaScript. También disponen de cursos premium."
    },
    {
        url: "http://www.kylejlarson.com/blog/ ",
        linkText: "kyle J. Larson",
        text: "Buenos consejos para el diseño web."
    },
    {
        url: "http://www.naderdabit.me/#/",
        linkText: "Nader Dabit",
        text: "Tutoriales sobre ReactJS, Angular, NPM ."
    },
    {
        url: "http://mrbool.com/",
        linkText: "Mr. Bool",
        text: "Tutoriales y cursos. ES6, Node+NPM, Ionic, Angular, NoSQL."
    },
    {
        url: "http://www.marketingenredes.com/",
        linkText: "Marketing en redes",
        text: "Sin unos buenos consejos como estos de marketing digital, no somos nadie."
    }
];

var objHerramientas =  [
    {
        url: "https://github.com/",
        linkText: "github",
        text: "Web que permite tener subidos tus repositorios git y así poder trabajar de forma colaborativa. Tiene versión Premiun con muchas mejoras. Dispone de las github-pages que te permiten desplegar webs estáticas incluso en la versión gratuita."
    },
    {
        url: "http://codepen.io/",
        linkText: "Codepen.io",
        text: "Web app en la que poder realizar demos en HTML, CSS, y JavaScript en vivo. Admite usar cualquier preprocesador de CSS y transpilador JS. Puedes guardar tus trabajos."
    },
    {
        url: "http://plnkr.co/",
        linkText: "Plukr",
        text: "Plunkr permite realizar pruebas de concepto rápidas y se pueden compartir. Contiene plantillas para Angular, React, Kendo UI."
    },
    {
        url: "https://jsfiddle.net/",
        linkText: "jsfiddle",
        text: "Otro editor de código online muy al estilo de plunkr. También puedes compartir tus trabajos y/p ejemplos."
    },
    {
        url: "https://www.gitignore.io/",
        linkText: "gitignore",
        text: "Tras git init suele ser habitual crear un gitignore para configurar qué se debe ignorar en el historial. Esta aplicación nos ayudará mucho en esa tarea. Hay que indicarle qué tecnologías estamos usando y gitignore hace el resto."
    },
    {
        url: "http://web-dev.tools/",
        linkText: "Web Dev Tools",
        text: "Tres herramientas que te permiten generar tu propio framework CSS. Son, como si se tratase de los 3 mosqueteros, Gridifier, Typographier y Modulifier. Ideales para proyectos donde quieras ir con el menor peso posible."
    },
    {
        url: "https://www.draw.io/",
        linkText: "draw.io",
        text: "Para realizar todo tipo de diagramas, incluidos los de flujo de software que cada vez es más raro verlos  ;)"
    },
    {
        url: "http://www.regexr.com/",
        linkText: "Regexr",
        text: "Nos permite crear y probar en tiempo real expresiones regulares. Muy útil cuando ya estamos desesperados de buscar algo en stackoverflow y no damos con ello."
    },
    {
        url: "http://pxtoem.com/",
        linkText: "pxtoem",
        text: "Conversor de pixel a em y de em a pixel. Muy útil cuando recibimos diseños gráficos hechos en pixeles."
    },
    {
        url: "http://currentmillis.com/",
        linkText: "currentmillis",
        text: "¿Problemas con UTC time, local time, Epoch, Unix timestamp? Esta web te ayudará con ello."
    },
    {
        url: "http://bradfrost.github.io/this-is-responsive/patterns.html",
        linkText: "Plantillas responsive",
        text: "Sirven como boilerplates de una página, proyecto o landing page. No hay que redescubrir la rueda todos los días."
    },
    {
        url: "https://www.w3schools.com/colors/colors_converter.asp",
        linkText: "Convertidor códigos color",
        text: "Convierte todo tipo de códigos: RGB, Hex, HSL, CMYK y por nombre."
    },
    {
        url: "http://www.colorzilla.com/gradient-editor/",
        linkText: "ColorZilla Gradient Generator",
        text: "Herramienta para generar gradientes CSS. Se incluye soporte para IE9."
    },
    {
        url: "http://jeremyckahn.github.io/stylie/",
        linkText: "Stylie",
        text: "Una forma de ajustar tus animaciones CSS de forma visual sencilla."
    },
    {
        url: "http://www.tablesgenerator.com/",
        linkText: "Table generator",
        text: "Generador de tablas LaTex, HTML, Text tables, Markdown tables."
    },
    {
        url: "http://www.cssarrowplease.com/",
        linkText: "CSS arrow please",
        text: "Puedes configurar paneles con flecha, variando el tamaño y la posición de esta. Te da el código CSS para que llevártelo."
    },
    {
        url: "https://pixlr.com/",
        linkText: "Pixlr",
        text: "Una versión light y free de Photoshop online."
    },
    {
        url: "https://icomoon.io/",
        linkText: "Icomoon",
        text: "De las mejores herramientas para generar glifos para tu proyecto. Es modo freemium. Para cuando necesites algo más personalizado de Awesomefont."
    },
    {
        url: "http://lorempixel.com/",
        linkText: "Lorempixel",
        text: "Mientras recibimos las imágenes definitivas y estamos realizando ya la demo en paralelo, esta herramienta nos coloca una imagen al azar cada vez que la llamamos. Se pueden ajustar distintos parámetros como el tamaño y el tema. Creo que el nombre de lorempixel es bastante descriptivo ;)"
    },
    {
        url: "http://www.patternify.com/",
        linkText: "Patternify",
        text: "Generador para patrones de  CSS, ideal para lo que se conoce como grecas. Nos da la imagen en código Base 64."
    },
    {
        url: "https://coolors.co/",
        linkText: "Coolors",
        text: "Generador de paletas, 5 colores. Presenta un apartado para ver cómo se distingue tu paleta con distintas discapacidades."
    },
    {
        url: "https://gravit.io",
        linkText: "Gravit.io",
        text: "Herramienta de diseño gráfico. Una especie de Sketch online y gratuito."
    },
    {
        url: "https://developers.google.com/speed/pagespeed",
        linkText: "Google PageSpeed Insights",
        text: "Herramienta de Google que nos proporciona un informe de mejora rendimiento de nuestra web. Hay que introducir la URL pública y PageSpeed se encarga del resto."
    },
    {
        url: "https://mailchimp.com/",
        linkText: "Mailchimp",
        text: "Te permite realizar envios de email para comprobar tus propios diseños en los distintos clientes web. Puedes realizar incluso campañas, simplemente crea tu diseño o elige uno de sus plantillas y haz el envio."
    },
    {
        url: "http://makeappicon.com/",
        linkText: "MakeAppIcon",
        text: "Web que te genera a partir de una imagen toda la batería necesaria de iconos para incluir en una App Android e iOS."
    },
    {
        url: "https://www.mockaroo.com/",
        linkText: "Mockaroo",
        text: "Mockaroo nos permite generar nuestros JSONs mocks. También admite otros formatos como CSV, SQL, XML, Excel, y más."
    },
    {
        url: "https://www.getpostman.com/",
        linkText: "Postman",
        text: "Pocas cosas habrá mejor para realizar pruebas sobre una API RESTFul que esta app que se puede instalar como extensión de Chrome."
    }
];

var objRecursos =  [
    {
        url: "https://fonts.google.com/",
        linkText: "Google Fonts",
        text: "Google Font nos permite utilizar web fonts de forma sencilla."
    },
    {
        url: "http://cssreference.io/",
        linkText: "CSS reference",
        text: "Excelente guía de referencia general CSS. La mejor hasta el momento que haya visto !!!"
    },
    {
        url: "https://wordpress.org/themes/",
        linkText: "Wordpress themes",
        text: "Site oficial para los themes de Wordpress."
    }
];

var siteNavigation = new Vue({
    el: "#site-navigation",
    data: {
        linkList: objLinkList
    }
});
var blogs = new Vue({
    el: '#blogs',
    data: {
        sectionTitle: "Blogs",
        aryBlogs: objBlogs
    },
    mounted: function () {
       console.log("blogs is now rendered");
    }
});
var herramientas = new Vue({
    el: '#herramientas',
    data: {
        sectionTitle: "Herramientas",
        aryHerramientas: objHerramientas
    },
    mounted: function () {
       console.log("herramientas is now rendered");
    }
});
var recursos = new Vue({
    el: '#recursos',
    data: {
        sectionTitle: "Recursos",
        aryRecursos: objRecursos
    },
    mounted: function () {
       console.log("recursos is now rendered");
    }
});
var footer = new Vue({
  el: '#footer',
  data: {
    copyright: 'Copyright © ' + new Date().getFullYear() + ' Aitor Alejandro Herrera. MIT License'
  }
});
<commit_msg>Nader Dabit<commit_after>var objLinkList = [
            { href: "#blogs", linkText: "Blogs" },
            { href: "#herramientas", linkText: "Herramientas" },
            { href: "#recursos", linkText: "Recursos" }
        ];
var objBlogs =  [
    {
        url: "https://css-tricks.com/",
        linkText: "css-tricks",
        text: "Indudablemente una de las webs número uno de consulta para un frontend. Artículos y tutoriales de calidad y un buen número de snippets."
    },
    {
        url: "https://www.smashingmagazine.com/",
        linkText: "Smashing Magazine",
        text: "Todo un referente en el mundo de la web. Código, diseño, mobile, UX ... etc. Publican libros con colecciones de sus artículos más interesantes."
    },
    {
        url: "https://www.sitepoint.com/",
        linkText: "Site Point",
        text: "Artículos meticulosos de gran calidad, podcast, libros y cursos (a veces gratis). También imprescindible."
    },
    {
        url: "https://scotch.io/",
        linkText: "Scotch.io",
        text: "Tutoriales excelentes sobre el mundo frontend y backend javascript. Disponen de cursos free y premium. ¡¡No perdérselo!!"
    },
    {
        url: "https://davidwalsh.name/",
        linkText: "David Walsh Blog",
        text: "Blog del gurú JavaScript David Walsh. Nos mantiene al día con sus interesantes artículos. No solo habla de JavaScript, también aborda otras tecnologías web."
    },
    {
        url: "http://alistapart.com/articles",
        linkText: "A List Apart",
        text: "Artículos de todo lo relacionado con la web. Son artículos de una calidad tan extraordinaria que algunos son un referente."
    },
    {
        url: "https://webmasters.googleblog.com/",
        linkText: "Google Webmaster Blog",
        text: "No puede faltar el blog oficial de Google para webmasters."
    },
    {
        url: "http://lea.verou.me/",
        linkText: "Lea Verou",
        text: "La gran Lea Verou. Proyectos, charlas, artículos. Una eminencia en el CSS."
    },
    {
        url: "http://wesbos.com/blog/",
        linkText: "Web Bos",
        text: "Artículos, videos y tutoriales"
    },
    {
        url: "http://www.developerdrive.com/",
        linkText: "Developer Drive",
        text: "Artículos sobre todo tipo de tecnología de desarrollo web."
    },
    {
        url: "http://www.cssportal.com/",
        linkText: "CSS Portal",
        text: "Snippets, generadores y herramientas para desarrollar en CSS."
    },
    {
        url: "http://www.elmaquetadorweb.com/",
        linkText: "El maquetador web",
        text: "Excelente blog mantenido por Javi Luna y Pedro Marín donde nos cuentan muchos trucos en esto del CSS. Me encanta el nombre de maquetador, término en desuso hoy en día.  ;D"
    },
    {
        url: "https://toddmotto.com/",
        linkText: "Todd Motto",
        text: "Artículos y tutoriales sobre JavaScript, Angular y Typescript. Dispone de muy buenos cursos en premium."
    },
    {
        url: "http://valhead.com/blog/",
        linkText: "Val Head Blog",
        text: "Artículos y tutoriales de una especialista en animaciones CSS web."
    },
    {
        url: "https://codyhouse.co/",
        linkText: "Cody House",
        text: "Colecciones gratuitas de snippets de HTML, CSS y JavaScript. También disponen de cursos premium."
    },
    {
        url: "http://www.kylejlarson.com/blog/ ",
        linkText: "kyle J. Larson",
        text: "Buenos consejos para el diseño web."
    },
    {
        url: "http://mrbool.com/",
        linkText: "Mr. Bool",
        text: "Tutoriales y cursos. ES6, Node+NPM, Ionic, Angular, NoSQL."
    },
    {
        url: "http://www.marketingenredes.com/",
        linkText: "Marketing en redes",
        text: "Sin unos buenos consejos como estos de marketing digital, no somos nadie."
    }
];

var objHerramientas =  [
    {
        url: "https://github.com/",
        linkText: "github",
        text: "Web que permite tener subidos tus repositorios git y así poder trabajar de forma colaborativa. Tiene versión Premiun con muchas mejoras. Dispone de las github-pages que te permiten desplegar webs estáticas incluso en la versión gratuita."
    },
    {
        url: "http://codepen.io/",
        linkText: "Codepen.io",
        text: "Web app en la que poder realizar demos en HTML, CSS, y JavaScript en vivo. Admite usar cualquier preprocesador de CSS y transpilador JS. Puedes guardar tus trabajos."
    },
    {
        url: "http://plnkr.co/",
        linkText: "Plukr",
        text: "Plunkr permite realizar pruebas de concepto rápidas y se pueden compartir. Contiene plantillas para Angular, React, Kendo UI."
    },
    {
        url: "https://jsfiddle.net/",
        linkText: "jsfiddle",
        text: "Otro editor de código online muy al estilo de plunkr. También puedes compartir tus trabajos y/p ejemplos."
    },
    {
        url: "https://www.gitignore.io/",
        linkText: "gitignore",
        text: "Tras git init suele ser habitual crear un gitignore para configurar qué se debe ignorar en el historial. Esta aplicación nos ayudará mucho en esa tarea. Hay que indicarle qué tecnologías estamos usando y gitignore hace el resto."
    },
    {
        url: "http://web-dev.tools/",
        linkText: "Web Dev Tools",
        text: "Tres herramientas que te permiten generar tu propio framework CSS. Son, como si se tratase de los 3 mosqueteros, Gridifier, Typographier y Modulifier. Ideales para proyectos donde quieras ir con el menor peso posible."
    },
    {
        url: "https://www.draw.io/",
        linkText: "draw.io",
        text: "Para realizar todo tipo de diagramas, incluidos los de flujo de software que cada vez es más raro verlos  ;)"
    },
    {
        url: "http://www.regexr.com/",
        linkText: "Regexr",
        text: "Nos permite crear y probar en tiempo real expresiones regulares. Muy útil cuando ya estamos desesperados de buscar algo en stackoverflow y no damos con ello."
    },
    {
        url: "http://pxtoem.com/",
        linkText: "pxtoem",
        text: "Conversor de pixel a em y de em a pixel. Muy útil cuando recibimos diseños gráficos hechos en pixeles."
    },
    {
        url: "http://currentmillis.com/",
        linkText: "currentmillis",
        text: "¿Problemas con UTC time, local time, Epoch, Unix timestamp? Esta web te ayudará con ello."
    },
    {
        url: "http://bradfrost.github.io/this-is-responsive/patterns.html",
        linkText: "Plantillas responsive",
        text: "Sirven como boilerplates de una página, proyecto o landing page. No hay que redescubrir la rueda todos los días."
    },
    {
        url: "https://www.w3schools.com/colors/colors_converter.asp",
        linkText: "Convertidor códigos color",
        text: "Convierte todo tipo de códigos: RGB, Hex, HSL, CMYK y por nombre."
    },
    {
        url: "http://www.colorzilla.com/gradient-editor/",
        linkText: "ColorZilla Gradient Generator",
        text: "Herramienta para generar gradientes CSS. Se incluye soporte para IE9."
    },
    {
        url: "http://jeremyckahn.github.io/stylie/",
        linkText: "Stylie",
        text: "Una forma de ajustar tus animaciones CSS de forma visual sencilla."
    },
    {
        url: "http://www.tablesgenerator.com/",
        linkText: "Table generator",
        text: "Generador de tablas LaTex, HTML, Text tables, Markdown tables."
    },
    {
        url: "http://www.cssarrowplease.com/",
        linkText: "CSS arrow please",
        text: "Puedes configurar paneles con flecha, variando el tamaño y la posición de esta. Te da el código CSS para que llevártelo."
    },
    {
        url: "https://pixlr.com/",
        linkText: "Pixlr",
        text: "Una versión light y free de Photoshop online."
    },
    {
        url: "https://icomoon.io/",
        linkText: "Icomoon",
        text: "De las mejores herramientas para generar glifos para tu proyecto. Es modo freemium. Para cuando necesites algo más personalizado de Awesomefont."
    },
    {
        url: "http://lorempixel.com/",
        linkText: "Lorempixel",
        text: "Mientras recibimos las imágenes definitivas y estamos realizando ya la demo en paralelo, esta herramienta nos coloca una imagen al azar cada vez que la llamamos. Se pueden ajustar distintos parámetros como el tamaño y el tema. Creo que el nombre de lorempixel es bastante descriptivo ;)"
    },
    {
        url: "http://www.patternify.com/",
        linkText: "Patternify",
        text: "Generador para patrones de  CSS, ideal para lo que se conoce como grecas. Nos da la imagen en código Base 64."
    },
    {
        url: "https://coolors.co/",
        linkText: "Coolors",
        text: "Generador de paletas, 5 colores. Presenta un apartado para ver cómo se distingue tu paleta con distintas discapacidades."
    },
    {
        url: "https://gravit.io",
        linkText: "Gravit.io",
        text: "Herramienta de diseño gráfico. Una especie de Sketch online y gratuito."
    },
    {
        url: "https://developers.google.com/speed/pagespeed",
        linkText: "Google PageSpeed Insights",
        text: "Herramienta de Google que nos proporciona un informe de mejora rendimiento de nuestra web. Hay que introducir la URL pública y PageSpeed se encarga del resto."
    },
    {
        url: "https://mailchimp.com/",
        linkText: "Mailchimp",
        text: "Te permite realizar envios de email para comprobar tus propios diseños en los distintos clientes web. Puedes realizar incluso campañas, simplemente crea tu diseño o elige uno de sus plantillas y haz el envio."
    },
    {
        url: "http://makeappicon.com/",
        linkText: "MakeAppIcon",
        text: "Web que te genera a partir de una imagen toda la batería necesaria de iconos para incluir en una App Android e iOS."
    },
    {
        url: "https://www.mockaroo.com/",
        linkText: "Mockaroo",
        text: "Mockaroo nos permite generar nuestros JSONs mocks. También admite otros formatos como CSV, SQL, XML, Excel, y más."
    },
    {
        url: "https://www.getpostman.com/",
        linkText: "Postman",
        text: "Pocas cosas habrá mejor para realizar pruebas sobre una API RESTFul que esta app que se puede instalar como extensión de Chrome."
    }
];

var objRecursos =  [
    {
        url: "https://fonts.google.com/",
        linkText: "Google Fonts",
        text: "Google Font nos permite utilizar web fonts de forma sencilla."
    },
    {
        url: "http://cssreference.io/",
        linkText: "CSS reference",
        text: "Excelente guía de referencia general CSS. La mejor hasta el momento que haya visto !!!"
    },
    {
        url: "https://wordpress.org/themes/",
        linkText: "Wordpress themes",
        text: "Site oficial para los themes de Wordpress."
    }
];

var siteNavigation = new Vue({
    el: "#site-navigation",
    data: {
        linkList: objLinkList
    }
});
var blogs = new Vue({
    el: '#blogs',
    data: {
        sectionTitle: "Blogs",
        aryBlogs: objBlogs
    },
    mounted: function () {
       console.log("blogs is now rendered");
    }
});
var herramientas = new Vue({
    el: '#herramientas',
    data: {
        sectionTitle: "Herramientas",
        aryHerramientas: objHerramientas
    },
    mounted: function () {
       console.log("herramientas is now rendered");
    }
});
var recursos = new Vue({
    el: '#recursos',
    data: {
        sectionTitle: "Recursos",
        aryRecursos: objRecursos
    },
    mounted: function () {
       console.log("recursos is now rendered");
    }
});
var footer = new Vue({
  el: '#footer',
  data: {
    copyright: 'Copyright © ' + new Date().getFullYear() + ' Aitor Alejandro Herrera. MIT License'
  }
});
<|endoftext|>


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

'use strict';

function htmlToJs (html) {
  return html.replace(/\n/g, '').replace(/\"/g, '\\\"').replace(/\>\s+\</g, '><');
}

var colors = require('colors'),
    fs = require('fs'),
    path = require('path'),
    glob = require('glob'),
    cwd = function () {
      var paths = [process.cwd()];
      [].push.apply(paths, arguments);
      return path.join.apply(null, paths );
    },
    file = {
      read: function () {
        return fs.readFileSync( path.join.apply(null, arguments), { encoding: 'utf8' });
      },
      write: function (paths, text) {
        return fs.writeFileSync( typeof paths === 'string' ? paths : path.join(paths), text, { encoding: 'utf8' });
      }
    },
    cmd = {
      build: function () {
        var UglifyJS = require("uglify-js"),
            aplazameMin = UglifyJS.minify("src/main.js").code,
            iframeSrc = file.read('src/iframe.html');

        aplazameMin = aplazameMin.replace('::iframeHtml::', htmlToJs(iframeSrc) );
        file.write('aplazame.js', aplazameMin );

        console.log('aplazame.js', 'updated'.green);
      },
      watch: function () {
        var watch = require('node-watch');

        if( cmd.test(true) ) {
          cmd.build();
        }

        watch('src', function(filename) {
          console.log(filename.yellow, 'changed');
          if( cmd.test(true) ) {
            cmd.build();
          }
          console.log('\npress Ctrl-C to stop'.yellow, '\n', 'watching...'.blue);
        });

        console.log('\npress Ctrl-C to stop'.yellow, '\n', 'watching...'.blue);

      },
      jshint: function (noExit) {
        var JSHINT = require('jshint').JSHINT,
            jshintrc = JSON.parse(file.read('.jshintrc')),
            errorsLog = '';

        glob.sync('src/{,**/}*.js').concat(glob.sync('tests/{,**/}*.js')).forEach(function (fileName) {
          JSHINT( file.read(fileName).split(/\n/) );
          var res = JSHINT.data()

          if( res.errors ) {
            errorsLog += fileName.cyan + '\n';
            res.errors.forEach(function (err) {
              if( err === null ) {
                console.log('err', err);
                return;
              }
              errorsLog += '  line ' + (err.line + '').yellow + ', col ' + (err.character + '').cyan + ', ' + err.reason.yellow + '\n';
            });
          }
        });

        if( errorsLog ) {
          console.log( '\nJSHINT ERRORS'.red + '\n', errorsLog );
          if( !noExit ) {
            process.exit(1);
          }
        } else {
          console.log('\nJSHINT PASSED\n'.green);
        }

        return !errorsLog;
      }
    };

process.argv[2] && cmd[process.argv[2]] && cmd[process.argv[2]]();
<commit_msg>fixed run.js<commit_after>#!/usr/bin/env node

'use strict';

function htmlToJs (html) {
  return html.replace(/\n/g, '').replace(/\"/g, '\\\"').replace(/\>\s+\</g, '><');
}

var colors = require('colors'),
    fs = require('fs'),
    path = require('path'),
    glob = require('glob'),
    cwd = function () {
      var paths = [process.cwd()];
      [].push.apply(paths, arguments);
      return path.join.apply(null, paths );
    },
    file = {
      read: function () {
        return fs.readFileSync( path.join.apply(null, arguments), { encoding: 'utf8' });
      },
      write: function (paths, text) {
        return fs.writeFileSync( typeof paths === 'string' ? paths : path.join(paths), text, { encoding: 'utf8' });
      }
    },
    cmd = {
      build: function () {
        var UglifyJS = require("uglify-js"),
            aplazameMin = UglifyJS.minify("src/main.js").code,
            iframeSrc = file.read('src/iframe.html');

        aplazameMin = aplazameMin.replace('::iframeHtml::', htmlToJs(iframeSrc) );
        file.write('aplazame.js', aplazameMin );

        console.log('aplazame.js', 'updated'.green);
      },
      watch: function () {
        var watch = require('node-watch');

        if( cmd.test(true) ) {
          cmd.build();
        }

        watch('src', function(filename) {
          console.log(filename.yellow, 'changed');
          if( cmd.test(true) ) {
            cmd.build();
          }
          console.log('\npress Ctrl-C to stop'.yellow, '\n', 'watching...'.blue);
        });

        console.log('\npress Ctrl-C to stop'.yellow, '\n', 'watching...'.blue);

      },
      test: function () {
        cmd.jshint();
      },
      jshint: function (noExit) {
        var JSHINT = require('jshint').JSHINT,
            jshintrc = JSON.parse(file.read('.jshintrc')),
            errorsLog = '';

        glob.sync('src/{,**/}*.js').concat(glob.sync('tests/{,**/}*.js')).forEach(function (fileName) {
          JSHINT( file.read(fileName).split(/\n/) );
          var res = JSHINT.data()

          if( res.errors ) {
            errorsLog += fileName.cyan + '\n';
            res.errors.forEach(function (err) {
              if( err === null ) {
                console.log('err', err);
                return;
              }
              errorsLog += '  line ' + (err.line + '').yellow + ', col ' + (err.character + '').cyan + ', ' + err.reason.yellow + '\n';
            });
          }
        });

        if( errorsLog ) {
          console.log( '\nJSHINT ERRORS'.red + '\n', errorsLog );
          if( !noExit ) {
            process.exit(1);
          }
        } else {
          console.log('\nJSHINT PASSED\n'.green);
        }

        return !errorsLog;
      }
    };

process.argv[2] && cmd[process.argv[2]] && cmd[process.argv[2]]();
<|endoftext|>


<commit_before>Z.wrap('github/ionicabizau/list/v0.0.1/client/ui.js', function (require, module, exports) {

    module.exports = function (self) {
        var config = self._conf;
        this.render = function (docs) {
            for (var i = 0; docs.length; ++i) {
                var cDoc = docs[i];
                debugger;
            }
        };
    };

    return module;
});
<commit_msg>Render docs using the built-in render<commit_after>Z.wrap('github/ionicabizau/list/v0.0.1/client/ui.js', function (require, module, exports) {

    module.exports = function (self) {
        var config = self._conf;

        this.render = function (docs) {
            self.view.item.render(docs);
        };
    };

    return module;
});
<|endoftext|>


<commit_before>/* app.js
 *
 * Contains Class definitions for Game, Enemies, Player, and Model Objects
 * Input handling and game logic.
 */

/**
 * @description Enemies our player must avoid
 * @constructor
 * @param {number} row - The row the enemy will run on
 * @param {number} spd - An index used to determine speed
 */
var Enemy = function(row, spd) {
    // Start offscreen from the left
    this.x = -100;
    this.y = row * 83 + 50;
    this.speed = this.speeds[spd];
    this.sprite = 'images/enemy-bug.png';
};

/**
 * @description Array that holds the possible enemy speeds
 */
Enemy.prototype.speeds = [100,200,400];

/**
 * @description Updates the enemy's position
 * @param {number} dt - A time delta between ticks
 */
Enemy.prototype.update = function(dt) {
    /* Moves the enemy across the screen horizontally */
    this.x += this.speed*dt;

    /* Handles collision with the Player */
    if ((this.y == player.y) &&
        (this.x > (player.x - 83)) &&
        (this.x < (player.x + 83))){

        /* Subtract score, display notes, and reset player */
        var score = document.getElementById("score");
        var notes = document.getElementById("score-note");
        game.addScore(-1);
        score.innerHTML = 'Level: ' + game.level + ' | Score: ' + game.score;
        notes.innerHTML = 'You\'ve been hit! -1 point!';
        notes.style.color = 'red';
        player.reset();
        return;
    }

    /* Handles what happens once enemy finishes across the screen */
    if (this.x > 707) {
        this.x = -100;
        /* Resets enemy to the left of the canvas and randomly
         * changes the enemy's row and speed */
        this.speed = this.speeds[Math.floor((Math.random() * 3))];
        this.y = (Math.floor(Math.random() * 3)) * 83 + 50;
    }
};

/**
 * @description Draws the enemy on the screen, required method for game
 */
Enemy.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

/**
 * @description Represents the player
 * @constructor
 */
var Player = function() {
    this.x = 303;
    this.y = 382;
    this.key = null;

    /* How much the player moves per key input in each direction */
    this.moveY = 83;
    this.moveX = 101;
    this.sprite = 'images/char-boy.png';
};

/**
 * @description Updates the player's position
 * @param {number} dt - A time delta between ticks
 */
Player.prototype.update = function(dt) {
    if (this.key == 'left'){
        this.x -= this.moveX;
    } else if (this.key == 'up'){
        this.y -= this.moveY;
    } else if (this.key == 'down'){
        this.y += this.moveY;
    } else if (this.key == 'right'){
        this.x += this.moveX;
    }
    this.key = null;
};

/**
 * @description Draws the player on the screen
 */
Player.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

/**
 * @description Handles key input for player on the screen
 * @param (string)
 */
Player.prototype.handleInput = function(key){
    /* For string manipulation on the page */
    var score = document.getElementById('score');
    var notes = document.getElementById('score-note');

    /* Checks if move results in out-of-bounds */
    if (!this.legalMove(key)){
        notes.innerHTML = 'Illegal move.';
        notes.style.color = 'red';
        return;
    } else {
        notes.innerHTML = '';
    }

    /* Checks if move would result in touching river (goal) */
    if (this.riverTouch(key)){
        game.addScore(1);

        /* If score is enough to reach the next level */
        if(game.score == 3){
            score.innerHTML = 'You\'ve reached LEVEL ' + (game.level+1) + '!!';
            score.style.fontsize = '32px';
            game.nextLevel();
            this.reset();
        } else {
            score.innerHTML = 'Level: ' + game.level + ' | Score: ' + game.score;
            notes.innerHTML = 'You made it! +1 point!';
            notes.style.color = 'green';
            this.reset();
        }
        return;
    }
    score.innerHTML = "Level: " + game.level + " | Score: " + game.score;
    this.key = key;
};

/**
 * @description Checks if move would result in out of bounds
 */
Player.prototype.legalMove = function(key){
    if ((key == 'left' && (this.x - this.moveX < 0)) ||
        (key == 'right' && (this.x + this.moveX >= 617)) ||
        (key == 'down' && (this.y + this.moveY > 404))) {
        return false;
    }
    return true;
};

/**
 * @description Checks if player is touching the river
 */
Player.prototype.riverTouch = function(key){
    if (key == 'up' && (this.y - this.moveY <= 0)) {
        return true;
    }
};

/**
 * @description Resets the player's position to initial position
 */
Player.prototype.reset = function(){
    this.x = 303;
    this.y = 382;
};

/**
 * @description Object to hold game data
 * @constructor
 */
var Game = function(){
    this.level = 1;
    this.score = 0;
};

/**
 * @description Next level setup: Reset score, add enemy
 */
Game.prototype.nextLevel = function(){
    this.level++;
    this.score = 0;
    allEnemies[this.level+1] = new Enemy(Math.floor((Math.random()*3)), Math.floor((Math.random()*3)));
};

/**
 * @description Method to adjust the score
 * @param {number} value - The value to adjust the score by
 */
Game.prototype.addScore = function(value){
    this.score += value;
};

/**
 * @description Array to hold strings of sprite images
 */
var models = [
        'images/Key.png',
        'images/char-cat-girl.png',
        'images/char-horn-girl.png',
        'images/char-pink-girl.png',
        'images/char-princess-girl.png',
        'images/enemy-bug.png'];

/**
 * @description Draws the model on the screen
 * @constructor
 * @param {number} number - Index for models
 */
var Model = function(number) {
    this.x = (number > 2) ? 101 * (number + 1) : 101 * number;
    this.y = 382;
    this.sprite = models[number];
};

/**
 * @description Swaps the model sprite if chosen
 * @param {number} dt - A time delta between ticks
 */
Model.prototype.update = function(dt) {
    if (this.y == player.y && this.x == player.x){
        player.reset();
        player.sprite = [this.sprite, this.sprite = player.sprite][0];
    }
};

/**
 * @description Draws the player on the screen
 */
Model.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

/*
 * Instantiate all objects
 * Place all enemy objects in an array called allEnemies
 * Place the player object in a variable called player
 */
var game = new Game();
var player = new Player();
var allEnemies = [];
var allModels = [];

/* Create enemies (start with 3 enemies at level 1) */
for (var i=0; i<3; i++){
    allEnemies[i] = new Enemy(Math.floor((Math.random()*3)), Math.floor((Math.random()*3)));
}

 /* For each of the 6 different character models */
for (var i=0; i<6; i++){
    allModels[i] = new Model(i);
}

/**
 * @description This listens for key presses and sends the keys to your
 *              Player.handleInput() method.
 */
document.addEventListener('keyup', function(e) {
    var allowedKeys = {
        37: 'left',
        38: 'up',
        39: 'right',
        40: 'down'
    };
    player.handleInput(allowedKeys[e.keyCode]);
});<commit_msg>Score minimum set to 0<commit_after>/* app.js
 *
 * Contains Class definitions for Game, Enemies, Player, and Model Objects
 * Input handling and game logic.
 */

/**
 * @description Enemies our player must avoid
 * @constructor
 * @param {number} row - The row the enemy will run on
 * @param {number} spd - An index used to determine speed
 */
var Enemy = function(row, spd) {
    // Start offscreen from the left
    this.x = -100;
    this.y = row * 83 + 50;
    this.speed = this.speeds[spd];
    this.sprite = 'images/enemy-bug.png';
};

/**
 * @description Array that holds the possible enemy speeds
 */
Enemy.prototype.speeds = [100,200,400];

/**
 * @description Updates the enemy's position
 * @param {number} dt - A time delta between ticks
 */
Enemy.prototype.update = function(dt) {
    /* Moves the enemy across the screen horizontally */
    this.x += this.speed*dt;

    /* Handles collision with the Player */
    if ((this.y == player.y) &&
        (this.x > (player.x - 83)) &&
        (this.x < (player.x + 83))){

        /* Subtract score, display notes, and reset player */
        var score = document.getElementById("score");
        var notes = document.getElementById("score-note");
        if(game.score > 0){
            game.addScore(-1);
            notes.innerHTML = 'You\'ve been hit! -1 point!';
        } else {
            notes.innerHTML = 'You\'ve been hit!';
        }
        score.innerHTML = 'Level: ' + game.level + ' | Score: ' + game.score;
        notes.style.color = 'red';
        player.reset();
        return;
    }

    /* Handles what happens once enemy finishes across the screen */
    if (this.x > 707) {
        this.x = -100;
        /* Resets enemy to the left of the canvas and randomly
         * changes the enemy's row and speed */
        this.speed = this.speeds[Math.floor((Math.random() * 3))];
        this.y = (Math.floor(Math.random() * 3)) * 83 + 50;
    }
};

/**
 * @description Draws the enemy on the screen, required method for game
 */
Enemy.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

/**
 * @description Represents the player
 * @constructor
 */
var Player = function() {
    this.x = 303;
    this.y = 382;
    this.key = null;

    /* How much the player moves per key input in each direction */
    this.moveY = 83;
    this.moveX = 101;
    this.sprite = 'images/char-boy.png';
};

/**
 * @description Updates the player's position
 * @param {number} dt - A time delta between ticks
 */
Player.prototype.update = function(dt) {
    if (this.key == 'left'){
        this.x -= this.moveX;
    } else if (this.key == 'up'){
        this.y -= this.moveY;
    } else if (this.key == 'down'){
        this.y += this.moveY;
    } else if (this.key == 'right'){
        this.x += this.moveX;
    }
    this.key = null;
};

/**
 * @description Draws the player on the screen
 */
Player.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

/**
 * @description Handles key input for player on the screen
 * @param (string)
 */
Player.prototype.handleInput = function(key){
    /* For string manipulation on the page */
    var score = document.getElementById('score');
    var notes = document.getElementById('score-note');

    /* Checks if move results in out-of-bounds */
    if (!this.legalMove(key)){
        notes.innerHTML = 'Illegal move.';
        notes.style.color = 'red';
        return;
    } else {
        notes.innerHTML = '';
    }

    /* Checks if move would result in touching river (goal) */
    if (this.riverTouch(key)){
        game.addScore(1);

        /* If score is enough to reach the next level */
        if(game.score == 3){
            score.innerHTML = 'You\'ve reached LEVEL ' + (game.level+1) + '!!';
            score.style.fontsize = '32px';
            game.nextLevel();
            this.reset();
        } else {
            score.innerHTML = 'Level: ' + game.level + ' | Score: ' + game.score;
            notes.innerHTML = 'You made it! +1 point!';
            notes.style.color = 'green';
            this.reset();
        }
        return;
    }
    score.innerHTML = "Level: " + game.level + " | Score: " + game.score;
    this.key = key;
};

/**
 * @description Checks if move would result in out of bounds
 */
Player.prototype.legalMove = function(key){
    if ((key == 'left' && (this.x - this.moveX < 0)) ||
        (key == 'right' && (this.x + this.moveX >= 617)) ||
        (key == 'down' && (this.y + this.moveY > 404))) {
        return false;
    }
    return true;
};

/**
 * @description Checks if player is touching the river
 */
Player.prototype.riverTouch = function(key){
    if (key == 'up' && (this.y - this.moveY <= 0)) {
        return true;
    }
};

/**
 * @description Resets the player's position to initial position
 */
Player.prototype.reset = function(){
    this.x = 303;
    this.y = 382;
};

/**
 * @description Object to hold game data
 * @constructor
 */
var Game = function(){
    this.level = 1;
    this.score = 0;
};

/**
 * @description Next level setup: Reset score, add enemy
 */
Game.prototype.nextLevel = function(){
    this.level++;
    this.score = 0;
    allEnemies[this.level+1] = new Enemy(Math.floor((Math.random()*3)), Math.floor((Math.random()*3)));
};

/**
 * @description Method to adjust the score
 * @param {number} value - The value to adjust the score by
 */
Game.prototype.addScore = function(value){
    this.score += value;
};

/**
 * @description Array to hold strings of sprite images
 */
var models = [
        'images/Key.png',
        'images/char-cat-girl.png',
        'images/char-horn-girl.png',
        'images/char-pink-girl.png',
        'images/char-princess-girl.png',
        'images/enemy-bug.png'];

/**
 * @description Draws the model on the screen
 * @constructor
 * @param {number} number - Index for models
 */
var Model = function(number) {
    this.x = (number > 2) ? 101 * (number + 1) : 101 * number;
    this.y = 382;
    this.sprite = models[number];
};

/**
 * @description Swaps the model sprite if chosen
 * @param {number} dt - A time delta between ticks
 */
Model.prototype.update = function(dt) {
    if (this.y == player.y && this.x == player.x){
        player.reset();
        player.sprite = [this.sprite, this.sprite = player.sprite][0];
    }
};

/**
 * @description Draws the player on the screen
 */
Model.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

/*
 * Instantiate all objects
 * Place all enemy objects in an array called allEnemies
 * Place the player object in a variable called player
 */
var game = new Game();
var player = new Player();
var allEnemies = [];
var allModels = [];

/* Create enemies (start with 3 enemies at level 1) */
for (var i=0; i<3; i++){
    allEnemies[i] = new Enemy(Math.floor((Math.random()*3)), Math.floor((Math.random()*3)));
}

 /* For each of the 6 different character models */
for (var i=0; i<6; i++){
    allModels[i] = new Model(i);
}

/**
 * @description This listens for key presses and sends the keys to your
 *              Player.handleInput() method.
 */
document.addEventListener('keyup', function(e) {
    var allowedKeys = {
        37: 'left',
        38: 'up',
        39: 'right',
        40: 'down'
    };
    player.handleInput(allowedKeys[e.keyCode]);
});<|endoftext|>


<commit_before>var rescuers = [], listeners = [], push = [].push
var events = require('events')

function Delta (callback) {
    if (!(this instanceof Delta)) {
        return new Delta(callback)
    }
    this._callback = callback
    this._results = []
    this._waiting = 0
    this._listeners = []
    this._completed = false
    this._canceled = 0
    this._instance = INSTANCE++
}

Delta.prototype.ee = function (ee) {
    return new Constructor(this, ee)
}

Delta.prototype._unlisten = function () {
    this._listeners.forEach(function (listener) {
        unlisten(listener, this)
    }, this)
    this._listeners.length = 0
}

Delta.prototype.off = function (ee, name, f) {
    var listeners = this._listeners, i = 0, I = listeners.length, listener
    while (i < I) {
        listener = listeners[i]
        if (
            ee === listener.ee &&
            (!name || name == listener.name) &&
            (!f || f === listener.f)
        ) {
            if (listener.action === get && !--this._waiting) {
                this._done()
                break
            }
            unlisten(listener, this)
            listeners.splice(i, 1)
            I--
        } else {
            i++
        }
    }
}

Delta.prototype.cancel = function (vargs) {
    if (!this._completed) {
        this._completed = true
        this._canceled++
        this._unlisten()
        this._callback.apply(null, vargs)
    }
}

function unlisten (listener, delta) {
    if (listener.ee != null || typeof listener.ee.removeListener == 'function') {
        listener.f = null
        listener.ee.removeListener(listener.name, listener.listener)
        listener.heap.push(listener)
    } else {
        console.log('no removeListener')
        var stackTraceLimit = Error.stackTraceLimit
        Error.stackTraceLimit = Infinity
        console.log(new Error().stack)
        Error.stackTraceLimit = stackTraceLimit
        console.log('delta replaced', delta === listener.delta)
        console.log(listener)
        console.log(listener.ee)
        console.log(typeof listener.ee)
        console.log(listener.ee instanceof events.EventEmitter)
        if (listener.ee != null && typeof listener.ee == 'object') {
            console.log(listener.ee.constructor.name)
            console.log(listener.ee)
        }
    }
}

Delta.prototype._rescue = function (error, ee) {
    error.ee = ee
    this._unlisten()
    this._callback.call(null, error)
}

Delta.prototype._done = function () {
    var vargs = []
    for (var i = 0, I = this._results.length; i < I; i++) {
        push.apply(vargs, this._results[i])
    }
    if (vargs.length) {
        vargs.unshift(null)
    }
    this._unlisten()
    this._callback.apply(null, vargs)
    this._completed = true
}

var INSTANCE = 0

function Constructor (delta, ee) {
    var rescuer = rescuers.pop()
    if (rescuer == null) {
        rescuer = {
            instance: delta._instance,
            delta: delta,
            ee: ee,
            name: 'error',
            listener: function (error) {
                rescuer.delta._rescue(error, rescuer.ee)
                rescuers.push(rescuer)
            },
            heap: rescuers
        }
    } else {
        rescuer.delta = delta
        rescuer.ee = ee
        rescuer.instance = delta._instance
    }

    delta._listeners.push(rescuer)

    ee.on('error', rescuer.listener)

    this._delta = delta
    this._ee = ee
}

function gather (vargs) {
    push.apply(this.delta._results[this.index][0], vargs)
}

function get (vargs) {
    push.apply(this.delta._results[this.index], vargs)
    this.delta.off(this.ee, this.name)
}

function invoke (vargs) {
    try {
        this.f.apply(null, vargs)
    } catch (error) {
        this.delta._rescue(error)
    }
}

Constructor.prototype.on = function (name, object) {
    var listener = listeners.pop()

    if (listener == null) {
        listener = {
            instance: this._delta._instance,
            delta: this._delta,
            ee: this._ee,
            name: name,
            action: null,
            listening: true,
            index: 0,
            f: null,
            listener: function () {
                var vargs = new Array
                for (var i = 0, I = arguments.length; i < I; i++) {
                    vargs[i] = arguments[i]
                }
                listener.action(vargs)
            },
            heap: listeners
        }
    }

    listener.delta = this._delta
    listener.ee = this._ee
    listener.name = name
    listener.instance = this._delta._instance

    if (Array.isArray(object)) {
        this._delta._results.push([[]])
        listener.index = this._delta._results.length - 1
        listener.action = gather
    } else if (typeof object == 'function') {
        listener.action = invoke
        listener.f = object
    } else {
        this._delta._results.push([])
        this._delta._waiting++
        listener.index = this._delta._results.length - 1
        listener.action = get
    }

    this._delta._listeners.push(listener)
    this._ee.on(name, listener.listener)

    return this
}

Constructor.prototype.ee = function (ee) {
    return new Constructor(this._delta, ee)
}

Constructor.prototype.cancel = function (vargs) {
    this._delta.cancel(vargs)
}

module.exports = Delta
<commit_msg>Remove debug inspection of missing unlisten.<commit_after>var rescuers = [], listeners = [], push = [].push
var events = require('events')

function Delta (callback) {
    if (!(this instanceof Delta)) {
        return new Delta(callback)
    }
    this._callback = callback
    this._results = []
    this._waiting = 0
    this._listeners = []
    this._completed = false
    this._canceled = 0
    this._instance = INSTANCE++
}

Delta.prototype.ee = function (ee) {
    return new Constructor(this, ee)
}

Delta.prototype._unlisten = function () {
    this._listeners.forEach(function (listener) {
        unlisten(listener, this)
    }, this)
    this._listeners.length = 0
}

Delta.prototype.off = function (ee, name, f) {
    var listeners = this._listeners, i = 0, I = listeners.length, listener
    while (i < I) {
        listener = listeners[i]
        if (
            ee === listener.ee &&
            (!name || name == listener.name) &&
            (!f || f === listener.f)
        ) {
            if (listener.action === get && !--this._waiting) {
                this._done()
                break
            }
            unlisten(listener, this)
            listeners.splice(i, 1)
            I--
        } else {
            i++
        }
    }
}

Delta.prototype.cancel = function (vargs) {
    if (!this._completed) {
        this._completed = true
        this._canceled++
        this._unlisten()
        this._callback.apply(null, vargs)
    }
}

function unlisten (listener, delta) {
    listener.f = null
    listener.ee.removeListener(listener.name, listener.listener)
    listener.heap.push(listener)
}

Delta.prototype._rescue = function (error, ee) {
    error.ee = ee
    this._unlisten()
    this._callback.call(null, error)
}

Delta.prototype._done = function () {
    var vargs = []
    for (var i = 0, I = this._results.length; i < I; i++) {
        push.apply(vargs, this._results[i])
    }
    if (vargs.length) {
        vargs.unshift(null)
    }
    this._unlisten()
    this._callback.apply(null, vargs)
    this._completed = true
}

var INSTANCE = 0

function Constructor (delta, ee) {
    var rescuer = rescuers.pop()
    if (rescuer == null) {
        rescuer = {
            instance: delta._instance,
            delta: delta,
            ee: ee,
            name: 'error',
            listener: function (error) {
                rescuer.delta._rescue(error, rescuer.ee)
                rescuers.push(rescuer)
            },
            heap: rescuers
        }
    } else {
        rescuer.delta = delta
        rescuer.ee = ee
        rescuer.instance = delta._instance
    }

    delta._listeners.push(rescuer)

    ee.on('error', rescuer.listener)

    this._delta = delta
    this._ee = ee
}

function gather (vargs) {
    push.apply(this.delta._results[this.index][0], vargs)
}

function get (vargs) {
    push.apply(this.delta._results[this.index], vargs)
    this.delta.off(this.ee, this.name)
}

function invoke (vargs) {
    try {
        this.f.apply(null, vargs)
    } catch (error) {
        this.delta._rescue(error)
    }
}

Constructor.prototype.on = function (name, object) {
    var listener = listeners.pop()

    if (listener == null) {
        listener = {
            instance: this._delta._instance,
            delta: this._delta,
            ee: this._ee,
            name: name,
            action: null,
            listening: true,
            index: 0,
            f: null,
            listener: function () {
                var vargs = new Array
                for (var i = 0, I = arguments.length; i < I; i++) {
                    vargs[i] = arguments[i]
                }
                listener.action(vargs)
            },
            heap: listeners
        }
    }

    listener.delta = this._delta
    listener.ee = this._ee
    listener.name = name
    listener.instance = this._delta._instance

    if (Array.isArray(object)) {
        this._delta._results.push([[]])
        listener.index = this._delta._results.length - 1
        listener.action = gather
    } else if (typeof object == 'function') {
        listener.action = invoke
        listener.f = object
    } else {
        this._delta._results.push([])
        this._delta._waiting++
        listener.index = this._delta._results.length - 1
        listener.action = get
    }

    this._delta._listeners.push(listener)
    this._ee.on(name, listener.listener)

    return this
}

Constructor.prototype.ee = function (ee) {
    return new Constructor(this._delta, ee)
}

Constructor.prototype.cancel = function (vargs) {
    this._delta.cancel(vargs)
}

module.exports = Delta
<|endoftext|>


<commit_before>const fs = require('fs');
const keystone = require('keystone');
const utils = require('keystone-utils');
const transform = require('model-transform');
const _ = require('lodash');
const questions = require('../shared/questions.json');
const groups = require('../shared/groups.json');

const Types = keystone.Field.Types;

const getToken = () => utils.randomString(64);

const Volunteer = new keystone.List('Volunteer', {
   defaultSort: '-createdAt',
   sortable: true,
});

const storage = new keystone.Storage({
   adapter: keystone.Storage.Adapters.FS,
   fs: {
      path: 'uploads',
      publicPath: '/uploads/',
   },
});

Volunteer.add(
   {
      name: { type: Types.Name, initial: true, required: true, index: true },
      email: { type: Types.Email, initial: true, required: true, index: true, unique: true },
      birth: { type: Types.Date },
      phone: { type: String, width: 'short' },
      photo: { type: Types.File, storage, collapse: true },
      address: { type: Types.Textarea, collapse: true },
      emergencyContacts: { type: String, width: 'short' },
      languages: { type: String },
      citizenship: { type: String },
      citizenship2: { type: String },
      availabilities: { type: Types.List,
         fields: {
            from: { type: Types.Date, default: Date.now },
            till: { type: Types.Date, default: Date.now },
            confirmationTill: { type: Types.Date, default: Date.now, label: 'When do you need the assignment to be confirmed?' },
         },
      },
      notes: { type: Types.Textarea, collapse: true },
   },
   'Group & Qualification',
   {
      group: { type: Types.Select, options: groups.join(), default: 'helper' },
      driversLicence: { type: Boolean, indent: true },
      truckDriversLicence: { type: Boolean, indent: true, dependsOn: { driversLicence: true } },
      internationalDriversLicence: { type: Boolean, indent: true, dependsOn: { driversLicence: true } },
      internationalTruckDriversLicence: { type: Boolean, indent: true, dependsOn: { driversLicence: true } },
      paramedic: { type: Boolean, indent: true },
      doctor: { type: Boolean, indent: true },
      doctorSpecialization: { type: String, dependsOn: { doctor: true } },
      emergencydoctor: { type: Boolean, indent: true },
      lifeguard: { type: Boolean, indent: true },
      experienceOnSea: { type: Boolean, indent: true },
      boatDriverPermit: { type: Types.Select, options: 'Class 1, Class 2, Class 3' },
      workExperience: { type: Types.List,
         fields: {
            employer: { type: String, label: 'Name of employer' },
            role: { type: String, label: 'Title / role' },
            time: { type: String, label: 'Dates worked' },
            location: { type: String },
         },
      },
   },
   'Scans',
   {
      passport: { type: Types.File, storage },
      presscard: { type: Types.File, storage, dependsOn: { group: 'journalist' } },
      approbation: { type: Types.File, storage, dependsOn: { group: 'medic' } },
   }
);

_.each(questions, (content, name) => {
   const obj = {};
   _.each(content, (value, key) => {
      obj[key] = { type: String, note: value, label: _.capitalize(key.slice(2)) };
   });
   Volunteer.add(name, obj);
});

Volunteer.add('Permissions', {
   dataPrivacy: { type: Boolean, indent: true, initial: true, required: true, label: 'Accepted the data privacy conditions' },
   isVerified: { type: Boolean, indent: true, label: 'Has a verified email address' },
   token: { type: String },
});

Volunteer.schema.virtual('url').get(function () {
   return `/volunteer/${this.token}`;
});

Volunteer.relationship({ ref: 'Mission', path: 'missions', refPath: 'crew' });

Volunteer.schema.methods.wasActive = function () {
   this.lastActiveOn = new Date();
   return this;
};

Volunteer.schema.methods.verifyEmail = function () {
   if (this.isVerified) return;

   this.isVerified = true;
   this.save();
};

Volunteer.schema.methods.hasFile = function (filename) {
   return ['photo', 'passport', 'presscard', 'approbation']
      .some(name => this[name] && this[name].filename === filename);
};

Volunteer.schema.post('init', function () {
   this._original = this.toObject();
});

Volunteer.schema.pre('save', function (next) {
   if (this.isNew) {
      this.token = getToken();
   }

   ['photo', 'passport', 'presscard', 'approbation'].forEach(field => {
      if (this.isModified(field) && this._original[field].filename) {
         fs.unlinkSync(`uploads/${this._original[field].filename}`);
      }
   });

   next();
});

transform.toJSON(Volunteer);

Volunteer.track = true;
Volunteer.defaultColumns = 'name, email, group';

Volunteer.register();
<commit_msg>fixed crash if there’s no earlier version of a file<commit_after>const fs = require('fs');
const keystone = require('keystone');
const utils = require('keystone-utils');
const transform = require('model-transform');
const _ = require('lodash');
const questions = require('../shared/questions.json');
const groups = require('../shared/groups.json');

const Types = keystone.Field.Types;

const getToken = () => utils.randomString(64);

const Volunteer = new keystone.List('Volunteer', {
   defaultSort: '-createdAt',
   sortable: true,
});

const storage = new keystone.Storage({
   adapter: keystone.Storage.Adapters.FS,
   fs: {
      path: 'uploads',
      publicPath: '/uploads/',
   },
});

Volunteer.add(
   {
      name: { type: Types.Name, initial: true, required: true, index: true },
      email: { type: Types.Email, initial: true, required: true, index: true, unique: true },
      birth: { type: Types.Date },
      phone: { type: String, width: 'short' },
      photo: { type: Types.File, storage, collapse: true },
      address: { type: Types.Textarea, collapse: true },
      emergencyContacts: { type: String, width: 'short' },
      languages: { type: String },
      citizenship: { type: String },
      citizenship2: { type: String },
      availabilities: { type: Types.List,
         fields: {
            from: { type: Types.Date, default: Date.now },
            till: { type: Types.Date, default: Date.now },
            confirmationTill: { type: Types.Date, default: Date.now, label: 'When do you need the assignment to be confirmed?' },
         },
      },
      notes: { type: Types.Textarea, collapse: true },
   },
   'Group & Qualification',
   {
      group: { type: Types.Select, options: groups.join(), default: 'helper' },
      driversLicence: { type: Boolean, indent: true },
      truckDriversLicence: { type: Boolean, indent: true, dependsOn: { driversLicence: true } },
      internationalDriversLicence: { type: Boolean, indent: true, dependsOn: { driversLicence: true } },
      internationalTruckDriversLicence: { type: Boolean, indent: true, dependsOn: { driversLicence: true } },
      paramedic: { type: Boolean, indent: true },
      doctor: { type: Boolean, indent: true },
      doctorSpecialization: { type: String, dependsOn: { doctor: true } },
      emergencydoctor: { type: Boolean, indent: true },
      lifeguard: { type: Boolean, indent: true },
      experienceOnSea: { type: Boolean, indent: true },
      boatDriverPermit: { type: Types.Select, options: 'Class 1, Class 2, Class 3' },
      workExperience: { type: Types.List,
         fields: {
            employer: { type: String, label: 'Name of employer' },
            role: { type: String, label: 'Title / role' },
            time: { type: String, label: 'Dates worked' },
            location: { type: String },
         },
      },
   },
   'Scans',
   {
      passport: { type: Types.File, storage },
      presscard: { type: Types.File, storage, dependsOn: { group: 'journalist' } },
      approbation: { type: Types.File, storage, dependsOn: { group: 'medic' } },
   }
);

_.each(questions, (content, name) => {
   const obj = {};
   _.each(content, (value, key) => {
      obj[key] = { type: String, note: value, label: _.capitalize(key.slice(2)) };
   });
   Volunteer.add(name, obj);
});

Volunteer.add('Permissions', {
   dataPrivacy: { type: Boolean, indent: true, initial: true, required: true, label: 'Accepted the data privacy conditions' },
   isVerified: { type: Boolean, indent: true, label: 'Has a verified email address' },
   token: { type: String },
});

Volunteer.schema.virtual('url').get(function () {
   return `/volunteer/${this.token}`;
});

Volunteer.relationship({ ref: 'Mission', path: 'missions', refPath: 'crew' });

Volunteer.schema.methods.wasActive = function () {
   this.lastActiveOn = new Date();
   return this;
};

Volunteer.schema.methods.verifyEmail = function () {
   if (this.isVerified) return;

   this.isVerified = true;
   this.save();
};

Volunteer.schema.methods.hasFile = function (filename) {
   return ['photo', 'passport', 'presscard', 'approbation']
      .some(name => this[name] && this[name].filename === filename);
};

Volunteer.schema.post('init', function () {
   this._original = this.toObject();
});

Volunteer.schema.pre('save', function (next) {
   if (this.isNew) {
      this.token = getToken();
   }

   // if there's an earlier version of a file, delete it
   ['photo', 'passport', 'presscard', 'approbation'].forEach(field => {
      if (this.isModified(field) && this._original[field] && this._original[field].filename) {
         fs.unlinkSync(`uploads/${this._original[field].filename}`);
      }
   });

   next();
});

transform.toJSON(Volunteer);

Volunteer.track = true;
Volunteer.defaultColumns = 'name, email, group';

Volunteer.register();
<|endoftext|>


<commit_before>'use strict';
  // set up  global variables here

  // we'll need one to store the current step in the app
var preGameStep = 0;

  // an array to store beer quotes (test
)
var beerQuotes = [
  '\"Beer, if drunk in moderation, softens the temper, cheers the spirit and promotes health.\"
-Thomas Jefferson',
  '\"In a study, scientists report that drinking beer can be good for the liver. I’m sorry, did I say ‘scientists’? I meant Irish people.\"
-Tina Fey',
  '\"A man who lies about beer makes enemies.\"
-Stephen King',
  '\"He was a wise man who invented beer.\"
-Plato',
  '\"Always do sober what you said you\'d do drunk. That will teach you to keep your mouth shut.\"
-Ernest Hemingway',
  '\"You\'re not drunk if you can lie on the floor without holding on.\"
-Dean Martin',
  '\"Homer no function beer well without.\"
-Homer Simpsons',
  '\"Hold my beer!\"
-Bad Decisions',
  '\"24 hours in a day, 24 beers in a case. Coincidence?\"
-Stephen Wright',
  '\"Most people hate the taste of beer—to begin with. It is, however, a prejudice.\"
-Winston Churchill'
];

  // one to store wine quotes
var wineQuotes = [
  '\"What wine goes with Captain Crunch?\"
-George Carlin',
  '\"Cheers to pour decisions!\"
-Wine',
  '\"My only regret in life is that I didn’t drink enough Champagne.\"
-Robert Noecker',
  '\"Drink wine: it isn\'t good to keep things bottled up.\"
-Anonymous',
  '\"I shall drink no wine before it’s time! OK, it’s time.\"
-Groucho Marx',
  '\"I cook with wine; sometimes I even add it to the food.\"
-W.C. Fields',
  '\"Wine is sunlight, held together by water.\"
-Galileo',
  '\"Most of the confidence which I appear to feel, especially when influenced by noon wine, is only a pretense.\"
-Tennessee Williams',
  '\"Wine makes daily living easier, less hurried, with fewer tensions and more tolerance.\"
-Benjamin Franklin',
  '\"Today is a good day to drink.\"
-Worff, son of Mogh'
];

  // liquor quotes
var liquorQuotes = [
  '\"There are only two real ways to get ahead today - sell liquor or drink it.\"
-W. C. Fields',
  '\"Drink because you are happy, but never because you are miserable.\"
-G.K. Chesterton',
  '\"Keeping one’s guests supplied with liquor is the first law of hospitality.\"
-Margaret Way',
  '\"Alcohol may be a man’s worst enemy, but the bible says love your enemy.\"
-Frank Sinatra',
  '\"I have taken more out of alcohol than alcohol has taken out of me.\"
-Winston Churchill',
  '\"Alcohol gives you infinite patience for stupidity.\"
-Sammy Davis, Jr.',
  '\"To me, drink responsibly means don\'t spill it.\"
-Bill Murray',
  '\"Trust me, you can dance.\"
-Vodka',
  '\"Too much of anything is bad but too much of good whiskey is barely enough.\"
-Mark Twain',
  '\"Pouring out liquor is like burning books.\"
-William Faulkner'
];

  // we need an array to store all of the selections that are made in a session
var allSelections = [];

  // we need an array to store current sessions
var currentSelections = [];

  // buttonTargetLocation stores the class name that we'll drop buttons into
var buttonTargetLocation = 'choice-container';
// getButtonParent will store the DOM object associated with the buttonTargetLocation class name
var getButtonParent = document.getElementsByClassName(buttonTargetLocation)[0];

// Let's make some buttons!
function Button(name, type, icon, link) {
  this.name = name;
  this.type = type;
  this.icon = icon;
  this.fa = 'fa';
  this.iconClass = 'icon';
  this.selected = 0;
  this.parent = '';
  this.link = link;
}
// This'll get rid of the current set of buttons after one is clicked,
// then, it'll increment the current step of the pre-game app
Button.prototype.clearParent = function() {
  currentSelections.push(this.type);
  if (preGameStep < 3) {
    while(getButtonParent.firstChild){
      getButtonParent.removeChild(getButtonParent.firstChild);
    }
    preGameStep++;
    if (preGameStep === 1) {
      stepTwo();
    } else if (preGameStep === 2) {
      stepThree();
    } else {
      stepFour();
    }
  } else {
    nextAction();
  }
};
// This'll keep track of whether each button that's displayed was clicked or not.
Button.prototype.storeChoice = function() {
  this.selected++;
  console.log(this.type + ' ' + 'has been selected ' + this.selected + ' time(s).');
};
// This'll grab a random quote for each button type where one should exist
Button.prototype.randomQuote = function() {
  if (this.type == 'beer' || this.type == 'pale' || this.type == 'stout' || this.type == 'ipa') {
    return beerQuotes[Math.floor(Math.random() * beerQuotes.length)];
  } else if (this.type == 'wine' || this.type == 'red' || this.type == 'white' || this.type == 'bubbles') {
    return wineQuotes[Math.floor(Math.random() * wineQuotes.length)];
  } else if (this.type == 'liquor' || this.type == 'single' || this.type == 'double') {
    return liquorQuotes[Math.floor(Math.random() * liquorQuotes.length)];
  } else if (this.type == 'light' || this.type == 'medium' || this.type == 'heavy'){
    return 'temporary quote about eating when drinking';
  } else if (this.type == 'another') {
    if (allSelections.length > 5) {
      return 'Is it really a good idea to have another?';
    } else {
      return 'Go on, one more won\'t hurt!';
    }
  } else if (this.type == 'home') {
    return 'There\'s no place like home, there\'s no place like home!';
  }
};
//
Button.prototype.goHome = function() {
  window.location = 'index.html';
};
// This'll draw the button to the page! Magical!
Button.prototype.createBtn = function(parent) {
  // set the parent of the button inside the button
  this.parent = parent;
  // build out the structure of the button (button tags containing several divs)
  var button = document.createElement('button');
  var choice = document.createElement('div');
  choice.classList.add('choice');
  var choiceTop = document.createElement('div');
  choiceTop.classList.add('choice-top');
  var iconDiv = document.createElement('div');
  iconDiv.classList.add(this.iconClass);
  iconDiv.classList.add(this.type);
  iconDiv.classList.add(this.fa);
  iconDiv.classList.add(this.icon);
  iconDiv.classList.add('choice-descriptionIcon');
  var iconDesc = document.createElement('div');
  iconDesc.classList.add('choice-descriptionText');
  iconDesc.innerHTML = this.name;
  var choiceBottom = document.createElement('div');
  choiceBottom.classList.add('choice-bottom');
  choiceBottom.innerHTML = this.randomQuote();
  button.type = 'button';
  button.addEventListener('click', this.storeChoice.bind(this));
  button.addEventListener('click', this.clearParent.bind(this));
  if (this.link) {
    button.addEventListener('click', this.goHome.bind(this));
  }
  choiceTop.appendChild(iconDiv);
  choiceTop.appendChild(iconDesc);
  choice.appendChild(choiceTop);
  choice.appendChild(choiceBottom);
  button.appendChild(choice);
  parent.appendChild(button);
};

stepOne();

// This is the first screen
function stepOne() {
  // instantiate & append to body
  var light = new Button('Half Empty','light','fa-battery-empty');
  var medium = new Button('Half Full','medium','fa-battery-half');
  var heavy = new Button('Stuffed','heavy','fa-battery-full');
  light.createBtn(getButtonParent);
  medium.createBtn(getButtonParent);
  heavy.createBtn(getButtonParent);
}
// This is the second screen
function stepTwo() {
  // instantiate & append to body
  var beer = new Button('Beer','beer','fa-beer');
  var wine = new Button('Wine','wine','fa-glass');
  var liquor = new Button('Liquor','liquor','fa-flask');
  beer.createBtn(getButtonParent);
  wine.createBtn(getButtonParent);
  liquor.createBtn(getButtonParent);
}

function stepThree() {
  if (currentSelections[1] == 'beer') {
    var pale = new Button('Pale','pale','fa-beer');
    var stout = new Button('Stout','stout','fa-beer');
    var ipa = new Button('IPA','ipa','fa-beer');
    pale.createBtn(getButtonParent);
    stout.createBtn(getButtonParent);
    ipa.createBtn(getButtonParent);
  } else if (currentSelections[1] == 'wine') {
    var red = new Button('Red Wine','red','fa-glass');
    var white = new Button('White Wine','white','fa-glass');
    var bubbles = new Button('Champaigne','bubbles','fa-glass');
    red.createBtn(getButtonParent);
    white.createBtn(getButtonParent);
    bubbles.createBtn(getButtonParent);
  } else if (currentSelections[1] == 'liquor') {
    var single = new Button('Single shot','single','fa-circle');
    var double = new Button('Double shot','double','fa-dot-circle-o');
    single.createBtn(getButtonParent);
    double.createBtn(getButtonParent);
  }

}

function stepFour() {
  allSelections = allSelections.concat(currentSelections);
  var another = new Button('Add another?','another','fa-plus');
  var home = new Button('To the Menu','home','fa-home','index.html');
  another.createBtn(getButtonParent);
  home.createBtn(getButtonParent);
}

function nextAction() {
  preGameStep = 0;
  if (currentSelections[3] == 'home') {
    console.log('send the user to the app start screen');
    currentSelections = [];
  } else if (currentSelections[3] == 'another') {
    console.log('start from the top!');
    currentSelections = [];
    while(getButtonParent.firstChild){
      getButtonParent.removeChild(getButtonParent.firstChild);
    }
    stepOne();
  }
}
<commit_msg>minor change to button storage<commit_after>'use strict';
  // set up  global variables here

  // we'll need one to store the current step in the app
var preGameStep = 0;

  // an array to store beer quotes (test
)
var beerQuotes = [
  '\"Beer, if drunk in moderation, softens the temper, cheers the spirit and promotes health.\"
-Thomas Jefferson',
  '\"In a study, scientists report that drinking beer can be good for the liver. I’m sorry, did I say ‘scientists’? I meant Irish people.\"
-Tina Fey',
  '\"A man who lies about beer makes enemies.\"
-Stephen King',
  '\"He was a wise man who invented beer.\"
-Plato',
  '\"Always do sober what you said you\'d do drunk. That will teach you to keep your mouth shut.\"
-Ernest Hemingway',
  '\"You\'re not drunk if you can lie on the floor without holding on.\"
-Dean Martin',
  '\"Homer no function beer well without.\"
-Homer Simpsons',
  '\"Hold my beer!\"
-Bad Decisions',
  '\"24 hours in a day, 24 beers in a case. Coincidence?\"
-Stephen Wright',
  '\"Most people hate the taste of beer—to begin with. It is, however, a prejudice.\"
-Winston Churchill'
];

  // one to store wine quotes
var wineQuotes = [
  '\"What wine goes with Captain Crunch?\"
-George Carlin',
  '\"Cheers to pour decisions!\"
-Wine',
  '\"My only regret in life is that I didn’t drink enough Champagne.\"
-Robert Noecker',
  '\"Drink wine: it isn\'t good to keep things bottled up.\"
-Anonymous',
  '\"I shall drink no wine before it’s time! OK, it’s time.\"
-Groucho Marx',
  '\"I cook with wine; sometimes I even add it to the food.\"
-W.C. Fields',
  '\"Wine is sunlight, held together by water.\"
-Galileo',
  '\"Most of the confidence which I appear to feel, especially when influenced by noon wine, is only a pretense.\"
-Tennessee Williams',
  '\"Wine makes daily living easier, less hurried, with fewer tensions and more tolerance.\"
-Benjamin Franklin',
  '\"Today is a good day to drink.\"
-Worff, son of Mogh'
];

  // liquor quotes
var liquorQuotes = [
  '\"There are only two real ways to get ahead today - sell liquor or drink it.\"
-W. C. Fields',
  '\"Drink because you are happy, but never because you are miserable.\"
-G.K. Chesterton',
  '\"Keeping one’s guests supplied with liquor is the first law of hospitality.\"
-Margaret Way',
  '\"Alcohol may be a man’s worst enemy, but the bible says love your enemy.\"
-Frank Sinatra',
  '\"I have taken more out of alcohol than alcohol has taken out of me.\"
-Winston Churchill',
  '\"Alcohol gives you infinite patience for stupidity.\"
-Sammy Davis, Jr.',
  '\"To me, drink responsibly means don\'t spill it.\"
-Bill Murray',
  '\"Trust me, you can dance.\"
-Vodka',
  '\"Too much of anything is bad but too much of good whiskey is barely enough.\"
-Mark Twain',
  '\"Pouring out liquor is like burning books.\"
-William Faulkner'
];

  // we need an array to store all of the selections that are made in a session
var allSelections = [];

  // we need an array to store current sessions
var currentSelections = [];

  // buttonTargetLocation stores the class name that we'll drop buttons into
var buttonTargetLocation = 'choice-container';
// getButtonParent will store the DOM object associated with the buttonTargetLocation class name
var getButtonParent = document.getElementsByClassName(buttonTargetLocation)[0];

// Let's make some buttons!
function Button(name, type, icon, link) {
  this.name = name;
  this.type = type;
  this.icon = icon;
  this.fa = 'fa';
  this.iconClass = 'icon';
  this.selected = 0;
  this.parent = '';
  this.link = link;
}
// This'll get rid of the current set of buttons after one is clicked,
// then, it'll increment the current step of the pre-game app
Button.prototype.clearParent = function() {
  console.log(currentSelections);
  if (this.type != 'home' || this.type != 'another') {
    currentSelections.push(this);
  }
  if (preGameStep < 3) {
    while(getButtonParent.firstChild){
      getButtonParent.removeChild(getButtonParent.firstChild);
    }
    preGameStep++;
    if (preGameStep === 1) {
      stepTwo();
    } else if (preGameStep === 2) {
      stepThree();
    } else {
      stepFour();
    }
  } else {
    nextAction();
  }
};
// This'll keep track of whether each button that's displayed was clicked or not.
Button.prototype.storeChoice = function() {
  this.selected++;
  console.log(this.type + ' ' + 'has been selected ' + this.selected + ' time(s).');
};
// This'll grab a random quote for each button type where one should exist
Button.prototype.randomQuote = function() {
  if (this.type == 'beer' || this.type == 'pale' || this.type == 'stout' || this.type == 'ipa') {
    return beerQuotes[Math.floor(Math.random() * beerQuotes.length)];
  } else if (this.type == 'wine' || this.type == 'red' || this.type == 'white' || this.type == 'bubbles') {
    return wineQuotes[Math.floor(Math.random() * wineQuotes.length)];
  } else if (this.type == 'liquor' || this.type == 'single' || this.type == 'double') {
    return liquorQuotes[Math.floor(Math.random() * liquorQuotes.length)];
  } else if (this.type == 'light' || this.type == 'medium' || this.type == 'heavy'){
    return 'temporary quote about eating when drinking';
  } else if (this.type == 'another') {
    if (allSelections.length > 5) {
      return 'Is it really a good idea to have another?';
    } else {
      return 'Go on, one more won\'t hurt!';
    }
  } else if (this.type == 'home') {
    return 'There\'s no place like home, there\'s no place like home!';
  }
};
//
Button.prototype.goHome = function() {
  window.location = 'index.html';
};
// This'll draw the button to the page! Magical!
Button.prototype.createBtn = function(parent) {
  // set the parent of the button inside the button
  this.parent = parent;
  // build out the structure of the button (button tags containing several divs)
  var button = document.createElement('button');
  var choice = document.createElement('div');
  choice.classList.add('choice');
  var choiceTop = document.createElement('div');
  choiceTop.classList.add('choice-top');
  var iconDiv = document.createElement('div');
  iconDiv.classList.add(this.iconClass);
  iconDiv.classList.add(this.type);
  iconDiv.classList.add(this.fa);
  iconDiv.classList.add(this.icon);
  iconDiv.classList.add('choice-descriptionIcon');
  var iconDesc = document.createElement('div');
  iconDesc.classList.add('choice-descriptionText');
  iconDesc.innerHTML = this.name;
  var choiceBottom = document.createElement('div');
  choiceBottom.classList.add('choice-bottom');
  choiceBottom.innerHTML = this.randomQuote();
  button.type = 'button';
  button.addEventListener('click', this.storeChoice.bind(this));
  button.addEventListener('click', this.clearParent.bind(this));
  if (this.link) {
    button.addEventListener('click', this.goHome.bind(this));
  }
  choiceTop.appendChild(iconDiv);
  choiceTop.appendChild(iconDesc);
  choice.appendChild(choiceTop);
  choice.appendChild(choiceBottom);
  button.appendChild(choice);
  parent.appendChild(button);
};

stepOne();

// This is the first screen
function stepOne() {
  // instantiate & append to body
  var light = new Button('Half Empty','light','fa-battery-empty');
  var medium = new Button('Half Full','medium','fa-battery-half');
  var heavy = new Button('Stuffed','heavy','fa-battery-full');
  light.createBtn(getButtonParent);
  medium.createBtn(getButtonParent);
  heavy.createBtn(getButtonParent);
}
// This is the second screen
function stepTwo() {
  // instantiate & append to body
  var beer = new Button('Beer','beer','fa-beer');
  var wine = new Button('Wine','wine','fa-glass');
  var liquor = new Button('Liquor','liquor','fa-flask');
  beer.createBtn(getButtonParent);
  wine.createBtn(getButtonParent);
  liquor.createBtn(getButtonParent);
}

function stepThree() {
  if (currentSelections[1].type == 'beer') {
    var pale = new Button('Pale','pale','fa-beer');
    var stout = new Button('Stout','stout','fa-beer');
    var ipa = new Button('IPA','ipa','fa-beer');
    pale.createBtn(getButtonParent);
    stout.createBtn(getButtonParent);
    ipa.createBtn(getButtonParent);
  } else if (currentSelections[1].type == 'wine') {
    var red = new Button('Red Wine','red','fa-glass');
    var white = new Button('White Wine','white','fa-glass');
    var bubbles = new Button('Champaigne','bubbles','fa-glass');
    red.createBtn(getButtonParent);
    white.createBtn(getButtonParent);
    bubbles.createBtn(getButtonParent);
  } else if (currentSelections[1].type == 'liquor') {
    var single = new Button('Single shot','single','fa-circle');
    var double = new Button('Double shot','double','fa-dot-circle-o');
    single.createBtn(getButtonParent);
    double.createBtn(getButtonParent);
  }

}

function stepFour() {
  allSelections = allSelections.concat(currentSelections);
  console.log(allSelections);
  var another = new Button('Add another?','another','fa-plus');
  var home = new Button('To the Menu','home','fa-home','index.html');
  another.createBtn(getButtonParent);
  home.createBtn(getButtonParent);
}

function nextAction() {
  preGameStep = 0;
  if (currentSelections[3].type == 'home') {
    console.log('send the user to the app start screen');
    currentSelections = [];
  } else if (currentSelections[3].type == 'another') {
    console.log('start from the top!');
    currentSelections = [];
    while(getButtonParent.firstChild){
      getButtonParent.removeChild(getButtonParent.firstChild);
    }
    stepOne();
  }
}
<|endoftext|>


<commit_before>import db from './database/dbContext.js';
import Book from './viewModels/bookViewModel.js';

import errorHelper from './helpers/errorHelper.js';

class bookModel {
    addBook(title, author, category, isbn, price, pictureURL, kindleURL, description) {
        var book = new Book(title, author, category, isbn, +price, pictureURL, kindleURL, description);

        var promise = new Promise(function (resolve, reject) {
            var errors = errorHelper.getErrors();

            if (errors.length === 0) {
                db.add('Book', book);
                resolve()
            } else {
                reject(errors);
            }

            errors = [];
        });

        return promise;
    }

    getBooks() {
        return db.get('Book');
    }

    updateBook(book) {
        book.save(null, {
            success: function (bookObject) {
                bookObject.save();
            },
            error: function (bookObject, error) {
                console.log('Cannot access the given book' + object);
                console.log(error);
            }
        });
    }

    removeBookById(id) {
        return this.getBooks().get(id, {
            success: function(receivedBook) {
                receivedBook.destroy({
                  success: function(myObject) {
                    console.log('Book deleted successfully!');
                    // The object was deleted from the Parse Cloud.
                  },
                  error: function(myObject, error) {
                    console.log('Error at book destroying!');
                    // The delete failed.
                    // error is a Parse.Error with an error code and message.
                  }
                });
            }
        });
    }

    removeBookByTitle(title) {
        return this.getBooks().get(title, {
            success: function(receivedBook) {
                receivedBook.destroy({
                  success: function(myObject) {
                    console.log('Book deleted successfully!');
                    // The object was deleted from the Parse Cloud.
                  },
                  error: function(myObject, error) {
                    console.log('Error at book destroying!');
                    // The delete failed.
                    // error is a Parse.Error with an error code and message.
                  }
                });
            }
        });
    }

    removeBookByISBN(isbn) {
        return this.getBooks().get(isbn, {
            success: function(receivedBook) {
                receivedBook.destroy({
                  success: function(myObject) {
                    console.log('Book deleted successfully!');
                    // The object was deleted from the Parse Cloud.
                  },
                  error: function(myObject, error) {
                    console.log('Error at book destroying!');
                    // The delete failed.
                    // error is a Parse.Error with an error code and message.
                  }
                });
            }
        });
    }
}

export default new bookModel();
<commit_msg>Added method getBookBy(prop).<commit_after>import db from './database/dbContext.js';
import Book from './viewModels/bookViewModel.js';

import errorHelper from './helpers/errorHelper.js';

class bookModel {
    addBook(title, author, category, isbn, price, pictureURL, kindleURL, description) {
        var book = new Book(title, author, category, isbn, +price, pictureURL, kindleURL, description);

        var promise = new Promise(function (resolve, reject) {
            var errors = errorHelper.getErrors();

            if (errors.length === 0) {
                db.add('Book', book);
                resolve()
            } else {
                reject(errors);
            }

            errors = [];
        });

        return promise;
    }

    getBooks() {
        return db.get('Book');
    }

    updateBook(book) {
        book.save(null, {
            success: function (bookObject) {
                bookObject.save();
            },
            error: function (bookObject, error) {
                console.log('Cannot access the given book' + object);
                console.log(error);
            }
        });
    }

    getBookBy(prop) {
        var that = this;
        return new Promise(function(resolve) {
            that.getBooks().get(prop, {
                success: function(book) {
                    resolve(book);
                },
                error: function(book, error) {
                    reject(error);
                }
            });
        });
    }

    removeBookById(id) {
        return this.getBooks().get(id, {
            success: function(receivedBook) {
                receivedBook.destroy({
                  success: function(myObject) {
                    console.log('Book deleted successfully!');
                    // The object was deleted from the Parse Cloud.
                  },
                  error: function(myObject, error) {
                    console.log('Error at book destroying!');
                    // The delete failed.
                    // error is a Parse.Error with an error code and message.
                  }
                });
            }
        });
    }

    removeBookByTitle(title) {
        return this.getBooks().get(title, {
            success: function(receivedBook) {
                receivedBook.destroy({
                  success: function(myObject) {
                    console.log('Book deleted successfully!');
                    // The object was deleted from the Parse Cloud.
                  },
                  error: function(myObject, error) {
                    console.log('Error at book destroying!');
                    // The delete failed.
                    // error is a Parse.Error with an error code and message.
                  }
                });
            }
        });
    }

    removeBookByISBN(isbn) {
        return this.getBooks().get(isbn, {
            success: function(receivedBook) {
                receivedBook.destroy({
                  success: function(myObject) {
                    console.log('Book deleted successfully!');
                    // The object was deleted from the Parse Cloud.
                  },
                  error: function(myObject, error) {
                    console.log('Error at book destroying!');
                    // The delete failed.
                    // error is a Parse.Error with an error code and message.
                  }
                });
            }
        });
    }
}

export default new bookModel();
<|endoftext|>


<commit_before>page('/', function(){
  $('#landing-page').removeClass('hidden');
  $('#chat-page').addClass('hidden');
  $('#for-geeks-button').on('click', function(){
    $('#for-geeks').removeClass('closed');
  });
  setupLandingPage();
});

page('/:chatId', function(ctx){
  $('#chat-page').removeClass('hidden');
  $('#landing-page').addClass('hidden');
  var chatId = ctx.params.chatId;
  startChat(chatId);
});

page.start();

function setupLandingPage(){
  $('#new-chat-button').on('click', function(){
    var newChatId = uuid.v4();
    page.show('/' + newChatId);
  });
}

function startChat(roomId){

  // DOM refs
  var $chatPage = $('#chat-page'),
      $chatSettings = $('#chat-settings'),
      $chatInfoMessage = $('#chat-info-box'),
      $localVideo = $('#local-video'),
      $remoteVideo = $('#remote-video'),
      $messageInputContainer = $('#message-input'),
      $messageInput = $messageInputContainer.find('input'),
      $messages = $('#messages'),
      $messagesList = $messages.find('ul'),
      $inviteLink = $('#invite-link a');

  var inviteLink = "mailto:?subject=Let's chat together";
  inviteLink += '&body=Join me on '+ window.location.origin + '/' + roomId;
  $inviteLink.attr('href', inviteLink);
  // reference to the pair.
  var pair = null;

  $('i.settings-hide').on('click', function(){
    $chatSettings.removeClass('opened').addClass('closed');
  });

  $('i.settings-show').on('click', function(){
    $chatSettings.removeClass('closed').addClass('opened');
  });

  // make messages draggable
  $messages.drags({handle: 'ul'});

  var newInfoMessage = function(msg){
    $chatInfoMessage.html(msg);
    $chatPage.addClass('no-chat');
  };

  var renderMessage = function(message, ts, mine){
    var html = '
';
    }else{
      html += 'class="not-mine">';
    }
    html += message;
    html += '
';
    $messagesList.append(html);
    var $allMessages = $('#messages ul li');
    var scrollSize = $allMessages.innerHeight() * $allMessages.length;
    $messagesList.animate({scrollTop: scrollSize}, 300);
  };

  var chan = function(pair){
    // picking any channel here. Probably unreliable is the key in channels object
    var channelName = _.first(_.keys(pair.channels));
    return pair.channels[channelName];
  };

  var setupChatPage = function(pair){
    var dc = pair.getDataChannel('messagechannel');
    $chatPage.removeClass('no-chat').addClass('remote-video-started');
    $messageInput.on('keydown', function(evt) {
      if (evt.keyCode === 13) {
        var newMessage = $messageInput.val(),
            messageStr = JSON.stringify({ time: Date.now(), msg: newMessage});
        renderMessage(newMessage, Date.now(), true);
      dc.onmessage = renderNewMessage;
      dc.onopen = function () {
        console.log('datachannel opened');
      };
      if (dc.readyState === 'open') {
        dc.send(messageStr);
      }
        $messageInput.val('');
      }
    });
  };

  var unsetupChatPage = function(){
    $chatPage.addClass('no-chat').removeClass('remote-video-started');
    $messageInput.off('keydown');
  };
  var renderNewMessage = function(evt){
    console.log('received new message');
    var messageObj = JSON.parse(evt.data);
    renderMessage(messageObj.msg, Date.now(), false);
  };

  // Connect to GoInstant
  window.webrtc = new SimpleWebRTC({
    // the id/element dom element that will hold "our" video
    localVideoEl: 'local-video',
    // the id/element dom element that will hold remote videos
    remoteVideosEl: 'remote-video',
    // immediately ask for camera access
    autoRequestMedia: true,
    media: {
        video: true,
        audio: false
    },
  });

  webrtc.on('readyToCall', function () {
    console.log('ready to call');
    webrtc.createRoom(roomId, function (err, name) {
      if (err) {
        // join room
        webrtc.joinRoom(roomId);
      }
      console.log('room was created', err, name);
    });
  });

  webrtc.on('videoAdded', function (video, peer) {
    console.log('peer added', peer);
    // assign peer to only possible pair.
    if(!pair){
      pair = peer;
      setupChatPage(pair);
    }
  });

  webrtc.on('videoRemoved', function (video, peer) {
    if(peer){
      pair = null;
      unsetupChatPage();
      newInfoMessage('Seems like you are alone now...');
    }
  });
}
<commit_msg>minor progress with cleanup page after disconnect<commit_after>page('/', function(){
  $('#landing-page').removeClass('hidden');
  $('#chat-page').addClass('hidden');
  $('#for-geeks-button').on('click', function(){
    $('#for-geeks').removeClass('closed');
  });
  setupLandingPage();
});

page('/:chatId', function(ctx){
  $('#chat-page').removeClass('hidden');
  $('#landing-page').addClass('hidden');
  var chatId = ctx.params.chatId;
  startChat(chatId);
});

page.start();

function setupLandingPage(){
  $('#new-chat-button').on('click', function(){
    var newChatId = uuid.v4();
    page.show('/' + newChatId);
  });
}

function startChat(roomId){

  // DOM refs
  var $chatPage = $('#chat-page'),
      $chatSettings = $('#chat-settings'),
      $chatInfoMessage = $('#chat-info-box'),
      $localVideo = $('#local-video'),
      $remoteVideo = $('#remote-video'),
      $messageInputContainer = $('#message-input'),
      $messageInput = $messageInputContainer.find('input'),
      $messages = $('#messages'),
      $messagesList = $messages.find('ul'),
      $inviteLink = $('#invite-link a');

  var inviteLink = "mailto:?subject=Let's chat together";
  inviteLink += '&body=Join me on '+ window.location.origin + '/' + roomId;
  $inviteLink.attr('href', inviteLink);
  // reference to the pair.
  var pair = null;

  $('i.settings-hide').on('click', function(){
    $chatSettings.removeClass('opened').addClass('closed');
  });

  $('i.settings-show').on('click', function(){
    $chatSettings.removeClass('closed').addClass('opened');
  });

  // make messages draggable
  $messages.drags({handle: 'ul'});

  var newInfoMessage = function(msg){
    $chatInfoMessage.html(msg);
    $chatPage.addClass('no-chat');
  };

  var renderMessage = function(message, ts, mine){
    var html = '
';
    }else{
      html += 'class="not-mine">';
    }
    html += message;
    html += '
';
    $messagesList.append(html);
    var $allMessages = $('#messages ul li');
    var scrollSize = $allMessages.innerHeight() * $allMessages.length;
    $messagesList.animate({scrollTop: scrollSize}, 300);
  };

  var chan = function(pair){
    // picking any channel here. Probably unreliable is the key in channels object
    var channelName = _.first(_.keys(pair.channels));
    return pair.channels[channelName];
  };

  var setupChatPage = function(pair){
    var dc = pair.getDataChannel('messagechannel');
    $chatPage.removeClass('no-chat').addClass('remote-video-started');
    $messageInput.on('keydown', function(evt) {
      if (evt.keyCode === 13) {
        var newMessage = $messageInput.val(),
            messageStr = JSON.stringify({ time: Date.now(), msg: newMessage});
        renderMessage(newMessage, Date.now(), true);
      dc.onmessage = renderNewMessage;
      dc.onopen = function () {
        console.log('datachannel opened');
      };
      if (dc.readyState === 'open') {
        dc.send(messageStr);
      }
        $messageInput.val('');
      }
    });
  };

  var unsetupChatPage = function(){
    $chatPage.addClass('no-chat').removeClass('remote-video-started');
    $messageInput.off('keydown');
  };
  var renderNewMessage = function(evt){
    console.log('received new message');
    var messageObj = JSON.parse(evt.data);
    renderMessage(messageObj.msg, Date.now(), false);
  };

  // Connect to GoInstant
  window.webrtc = new SimpleWebRTC({
    // the id/element dom element that will hold "our" video
    localVideoEl: 'local-video',
    // the id/element dom element that will hold remote videos
    remoteVideosEl: 'remote-video',
    // immediately ask for camera access
    autoRequestMedia: true,
    media: {
        video: true,
        audio: false
    },
  });

  webrtc.on('readyToCall', function () {
    console.log('ready to call');
    webrtc.createRoom(roomId, function (err, name) {
      if (err) {
        // join room
        webrtc.joinRoom(roomId);
      }
      console.log('room was created', err, name);
    });
  });

  webrtc.on('videoAdded', function (video, peer) {
    console.log('peer added', peer);
    // assign peer to only possible pair.
    if(!pair){
      pair = peer;
      $remoteVideo.append(peer.video);
      setupChatPage(pair);
    }
  });

  webrtc.on('videoRemoved', function (video, peer) {
    if(peer){
      pair = null;
      unsetupChatPage();
      newInfoMessage('Seems like you are alone now...');
    }
  });
}
<|endoftext|>