<commit_before>var ical = require('./ical')
  , request = require('request')
  , fs = require('fs')

exports.fromURL = function(url, opts, cb){
  if (!cb)
    return;
  request(url, opts, function(err, r, data){
    if (err)
      return cb(err, null);
    cb(undefined, ical.parseICS(data));
  })
}

exports.parseFile = function(filename){
  return ical.parseICS(fs.readFileSync(filename, 'utf8'))
}

var rrule = require('rrule-alt').RRule
var rrulestr = rrule.rrulestr

ical.objectHandlers['RRULE'] = function(val, params, curr, stack, line){
  curr.rrule = line;
  return curr
}
var originalEnd = ical.objectHandlers['END'];
ical.objectHandlers['END'] = function(val, params, curr, stack){
  if (curr.rrule) {
    var rule = curr.rrule;
    if (rule.indexOf('DTSTART') === -1) {

      if (curr.start.length === 8) {
        var comps = /^(\d{4})(\d{2})(\d{2})$/.exec(curr.start);
        if (comps) {
         curr.start = new Date (comps[1], comps[2] - 1, comps[3]);
        }
      }

      rule += ' DTSTART:' + curr.start.toISOString().replace(/[-:]/g, '');
      rule = rule.replace(/\.[0-9]{3}/, '');
    }
    for (var i in curr.exdates) {
      rule += ' EXDATE:' + curr.exdates[i].toISOString().replace(/[-:]/g, '');
      rule = rule.replace(/\.[0-9]{3}/, '');
    }
    try {
      curr.rrule = rrulestr(rule);
    }
    catch(err) {
      console.log("Unrecognised element in calendar feed, ignoring: " + rule);
      curr.rrule = null;
    }
  }
  return originalEnd.call(this, val, params, curr, stack);
}
<commit_msg>curr.start is not always a date type (depends on ics file). A type check has been added.<commit_after>var ical = require('./ical')
  , request = require('request')
  , fs = require('fs')

exports.fromURL = function(url, opts, cb){
  if (!cb)
    return;
  request(url, opts, function(err, r, data){
    if (err)
      return cb(err, null);
    cb(undefined, ical.parseICS(data));
  })
}

exports.parseFile = function(filename){
  return ical.parseICS(fs.readFileSync(filename, 'utf8'))
}

var rrule = require('rrule-alt').RRule
var rrulestr = rrule.rrulestr

ical.objectHandlers['RRULE'] = function(val, params, curr, stack, line){
  curr.rrule = line;
  return curr
}
var originalEnd = ical.objectHandlers['END'];
ical.objectHandlers['END'] = function(val, params, curr, stack){
  if (curr.rrule) {
    var rule = curr.rrule;
    if (rule.indexOf('DTSTART') === -1) {

      if (curr.start.length === 8) {
        var comps = /^(\d{4})(\d{2})(\d{2})$/.exec(curr.start);
        if (comps) {
         curr.start = new Date (comps[1], comps[2] - 1, comps[3]);
        }
      }

      if( typeof (curr.start) === "date") {
          rule += ' DTSTART:' + curr.start.toISOString().replace(/[-:]/g, '');
          rule = rule.replace(/\.[0-9]{3}/, '');
      }
    }
    for (var i in curr.exdates) {
      rule += ' EXDATE:' + curr.exdates[i].toISOString().replace(/[-:]/g, '');
      rule = rule.replace(/\.[0-9]{3}/, '');
    }
    try {
      curr.rrule = rrulestr(rule);
    }
    catch(err) {
      console.log("Unrecognised element in calendar feed, ignoring: " + rule);
      curr.rrule = null;
    }
  }
  return originalEnd.call(this, val, params, curr, stack);
}
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const path = require('path');
const async = require('async');
const log = require('util').log;
const config = require('../../config.js');
const utils = require('../../utils');

let builder = {

    /**
     * Function that writes the default upstream.conf file for soajs.controller
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Function} cb      Callback function
     *
     */
    writeUpstream(options, cb) {
        if(!options.count) {
            log('No upstream entries available for SOAJS controllers, default upstream file won\'t be written');
            return cb();
        }

        log("Writing upstream.conf in " + options.loc);
        let wstream = fs.createWriteStream(options.loc + 'upstream.conf');
        wstream.write("upstream " + options.upstreamName + " {\n");
        for (let i = 1; i <= options.count; i++) {
            if (process.env[options.ipEnvName + i]) {
                wstream.write("  server " + process.env[options.ipEnvName + i] + ":" + options.port + ";\n");
            }
            else {
                log("ERROR: Unable to find environment variable " + options.ipEnvName + i);
            }
        }
        wstream.write("}\n");
        wstream.end();
        return cb(null);
    },

    /**
     * Function that writes nginx config for static location
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Object}   wstream An instance of fs.writeStream
     *
     */
    writeStaticLocation(options, wstream) {
    	let rootPath = options.path;

        wstream.write("  location / {\n");
        wstream.write("    root  " + rootPath + ";\n");
        wstream.write("    sendfile       off;\n");
        wstream.write("    index  index.html index.htm;\n");
        wstream.write("  }\n");
    },

    /**
     * Function that writes nginx config for proxy location
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Object}   wstream An instance of fs.writeStream
     *
     */
    writeProxyLocation(options, wstream) {
        if(!options.count) {
            log('No upstream entries available for SOAJS controllers, proxy location will not be written');
            return;
        }

        wstream.write("  location / {\n");
        wstream.write("    proxy_pass 		    http://" + options.upstreamName + ";\n");
        wstream.write("    proxy_set_header   	X-Forwarded-Proto 	    $scheme;\n");
        wstream.write("    proxy_set_header   	X-Forwarded-For 	    $remote_addr;\n");
        wstream.write("    proxy_set_header   	Host             		$http_host;\n");
        wstream.write("    proxy_set_header   	X-NginX-Proxy     	    true;\n");
        wstream.write("    proxy_set_header   	Connection        	    \"\";\n");
        wstream.write("  }\n");
    },

    /**
     * Function that writes nginx config for server redirect
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Object}   wstream An instance of fs.writeStream
     *
     */
    writeServerRedirect(options, wstream) {
        wstream.write("server {\n");
        wstream.write("  listen       " + options.port + ";\n");
        wstream.write("  server_name  " + options.domain + ";\n");
        wstream.write("  client_max_body_size 100m;\n");
        wstream.write("  rewrite ^/(.*) https://" + options.domain + "/$1 permanent;\n");
        wstream.write("}\n");
    },

    /**
     * Function that writes nginx SSL config
     * @param  {Object}   options An object that contains params passed to the function
     *
     */
    writeServerSSL(wstream) {
        let certsLocation = path.join(config.nginx.location, '/ssl');
        if (config.nginx.config.ssl.customCerts) certsLocation = config.nginx.config.ssl.customCertsPath;

        wstream.write("  ssl_certificate         " + certsLocation + "/tls.crt;\n");
        wstream.write("  ssl_certificate_key     " + certsLocation + "/tls.key;\n");
        wstream.write("  include " + config.nginx.location + "/ssl/ssl.conf;\n");
    },

    /**
     * Function that writes nginx config for server
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Object}   wstream An instance of fs.writeStream
     *
     */
    writeServer(options, wstream) {
    	log("writing server entry for", options.domain);
        wstream.write("server {\n");
        wstream.write("  listen       " + options.port + ";\n");
        wstream.write("  server_name  " + options.domain + ";\n");
        wstream.write("  client_max_body_size 100m;\n");
        if (options.https)
            builder.writeServerSSL(wstream);
        if (options.location == "proxy")
            builder.writeProxyLocation(options, wstream);
        else if (options.location == "static")
            builder.writeStaticLocation(options, wstream);
        wstream.write("}\n");
    },

    /**
     * Function that redirects to proper write function for api config based on passed params
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Function} cb      Callback function
     *
     */
    writeApiConf(options, cb) {
        log("Writing api conf in " + options.loc + " " + options.confFileName);
        let wstream = fs.createWriteStream(options.loc + options.confFileName);
        let httpsApi = config.nginx.config.ssl.httpsApi;
        let httpApiRedirect = config.nginx.config.ssl.httpApiRedirect;

        options.location = "proxy";

        if (httpsApi) {
            if (httpApiRedirect) {
                options.port = "80";
                builder.writeServerRedirect(options, wstream);
            }
            options.https = true;
            options.port = "443 ssl";
            builder.writeServer(options, wstream);
        }
        else if (!httpApiRedirect){
            options.port = "80";
            builder.writeServer(options, wstream);
        }

        wstream.end();
        return cb(null);
    },

    /**
     * Function that redirects to proper write function for site config based on passed params
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Function} cb      Callback function
     *
     */
    writeSiteConf(options, cb) {
    	let fileLocation = options.loc + options.confFileName;
	    options.domain = process.env.SOAJS_NX_SITE_DOMAIN;
    	//check if dashboard site.conf
	    if (process.env.SOAJS_ENV) {
	    	if(process.env.SOAJS_ENV.toLowerCase() === 'dashboard'){
			    fileLocation = options.loc + "dash.conf";
		    }
		    else if(process.env.SOAJS_ENV.toLowerCase() === 'portal'){
			    fileLocation = options.loc + "portal.conf";
		    }
	    }

        log("Writing site conf in " + fileLocation);
        let wstream = fs.createWriteStream(fileLocation);

        let httpsSite = config.nginx.config.ssl.httpsSite;
        let httpSiteRedirect = config.nginx.config.ssl.httpSiteRedirect;

        options.location = "static";

        if (httpsSite) {
	        if (httpSiteRedirect) {
		        options.port = "80";
		        builder.writeServerRedirect(options, wstream);
	        }
	        options.https = true;
	        options.port = "443 ssl";
	        builder.writeServer(options, wstream);
        }
        else if (!httpSiteRedirect){
	        options.port = "80";
	        builder.writeServer(options, wstream);
        }

        wstream.end();
        setTimeout(function(){
            return cb(null);
        }, 100);
    },

    /**
     * Function that writes the default nginx.conf file from templates and replaces placeholders with appropriate values
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Function} cb Callback function
     *
     */
    writeDefaultNginxConf(options, cb) {
        //read nginx.conf from templates directory
        log('Writing default nginx.conf ...');
        options.source = 'template';
        options.content = 'nginx';
        options.type = 'nginx.conf';
        options.target = options.nginx.location;
        utils.import(options, (error) => {
            if (error) throw new Error(error);

            log('nginx.conf written successfully ...');
            return cb();
        });
    },

    /**
     * Function that copies ssl.conf from templates directory to nginx directory
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Function} cb Callback function
     *
     */
    copySSLConf(options, cb) {
        //copy ssl.conf from templates directory to nginx directory
        log('Copying ssl.conf ...');
        let readStream = fs.createReadStream(path.join(options.paths.templates.nginx.path, 'ssl.conf'));
        let writeStream = fs.createWriteStream(path.join(options.nginx.location, '/ssl/ssl.conf'));

        readStream.on('error', (error) => {
            log('Unable to read ssl.conf ...');
            throw new Error(error);
        });
        writeStream.on('error', (error) => {
            log('Unable to write ssl.conf ...');
            throw new Error(error);
        });
        writeStream.on('close', () => {
            log('Successfully copied ssl.conf ...');
            return cb();
        });

        readStream.pipe(writeStream);
    },

    /**
     * Function that calls writeUpstream, writeApiConf, and writeSiteConf
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Object}   wstream An instance of fs.writeStream
     *
     */
    write(options, cb) {
        let nxOs = options.nginx.os;
        builder.writeDefaultNginxConf(options, () => {
            builder.copySSLConf(options, () => {
                builder.writeUpstream({
                    loc: options.nginx.location + ((nxOs === 'mac') ? "/servers/" : ( nxOs === 'ubuntu') ? "/conf.d/" : "/nginx/"),
                    port: options.nginx.config.upstream.ctrlPort,
                    ipEnvName: options.nginx.config.upstream.ipEnvName,
                    upstreamName: options.nginx.config.upstream.upstreamName,
                    count: options.nginx.config.upstream.count,
                }, () => {
                    log('SOAJS Controller Upstream was written successfully');
                    builder.writeApiConf({
                        loc: options.nginx.location + ((nxOs === 'mac') ? "/servers/" : ( nxOs === 'ubuntu') ? "/sites-enabled/" : "/nginx/"),
                        confFileName: options.nginx.config.apiConf.fileName,
                        domain: options.nginx.config.apiConf.domain,
                        upstreamName: options.nginx.config.upstream.upstreamName,
                    }, () => {
                        log('Nginx API config was written successfully');
                        if (options.nginx.config.siteConf.domain) {
                            builder.writeSiteConf({
                                loc: options.nginx.location + ((nxOs === 'mac') ? "/servers/" : ( nxOs === 'ubuntu') ? "/sites-enabled/" : "/nginx/"),
                                confFileName: options.nginx.config.siteConf.fileName,
                                domain: options.nginx.config.siteConf.domain,
                                path: options.nginx.config.siteConf.path
                            }, () => {
                                log('Nginx Site config was written successfully');
                                return cb();
                            });
                        }
                        else {
                            return cb();
                        }
                    });
                });
            });
        });
    }

};

module.exports = {
    write: builder.write
};
<commit_msg>Minor update<commit_after>'use strict';

const fs = require('fs');
const path = require('path');
const async = require('async');
const log = require('util').log;
const config = require('../../config.js');
const utils = require('../../utils');

let builder = {

    /**
     * Function that writes the default upstream.conf file for soajs.controller
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Function} cb      Callback function
     *
     */
    writeUpstream(options, cb) {
        if(!options.count) {
            log('No upstream entries available for SOAJS controllers, default upstream file won\'t be written');
            return cb();
        }

        log("Writing upstream.conf in " + options.loc);
        let wstream = fs.createWriteStream(options.loc + 'upstream.conf');
        wstream.write("upstream " + options.upstreamName + " {\n");
        for (let i = 1; i <= options.count; i++) {
            if (process.env[options.ipEnvName + i]) {
                wstream.write("  server " + process.env[options.ipEnvName + i] + ":" + options.port + ";\n");
            }
            else {
                log("ERROR: Unable to find environment variable " + options.ipEnvName + i);
            }
        }
        wstream.write("}\n");
        wstream.end();
        return cb(null);
    },

    /**
     * Function that writes nginx config for static location
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Object}   wstream An instance of fs.writeStream
     *
     */
    writeStaticLocation(options, wstream) {
    	let rootPath = options.path;

        wstream.write("  location / {\n");
        wstream.write("    root  " + rootPath + ";\n");
        wstream.write("    sendfile       off;\n");
        wstream.write("    index  index.html index.htm;\n");
        wstream.write("  }\n");
    },

    /**
     * Function that writes nginx config for proxy location
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Object}   wstream An instance of fs.writeStream
     *
     */
    writeProxyLocation(options, wstream) {
        if(!options.count) {
            log('No upstream entries available for SOAJS controllers, proxy location will not be written');
            return;
        }

        wstream.write("  location / {\n");
        wstream.write("    proxy_pass 		    http://" + options.upstreamName + ";\n");
        wstream.write("    proxy_set_header   	X-Forwarded-Proto 	    $scheme;\n");
        wstream.write("    proxy_set_header   	X-Forwarded-For 	    $remote_addr;\n");
        wstream.write("    proxy_set_header   	Host             		$http_host;\n");
        wstream.write("    proxy_set_header   	X-NginX-Proxy     	    true;\n");
        wstream.write("    proxy_set_header   	Connection        	    \"\";\n");
        wstream.write("  }\n");
    },

    /**
     * Function that writes nginx config for server redirect
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Object}   wstream An instance of fs.writeStream
     *
     */
    writeServerRedirect(options, wstream) {
        wstream.write("server {\n");
        wstream.write("  listen       " + options.port + ";\n");
        wstream.write("  server_name  " + options.domain + ";\n");
        wstream.write("  client_max_body_size 100m;\n");
        wstream.write("  rewrite ^/(.*) https://" + options.domain + "/$1 permanent;\n");
        wstream.write("}\n");
    },

    /**
     * Function that writes nginx SSL config
     * @param  {Object}   options An object that contains params passed to the function
     *
     */
    writeServerSSL(wstream) {
        let certsLocation = path.join(config.nginx.location, '/ssl');
        if (config.nginx.config.ssl.customCerts) certsLocation = config.nginx.config.ssl.customCertsPath;

        wstream.write("  ssl_certificate         " + certsLocation + "/tls.crt;\n");
        wstream.write("  ssl_certificate_key     " + certsLocation + "/tls.key;\n");
        wstream.write("  include " + config.nginx.location + "/ssl/ssl.conf;\n");
    },

    /**
     * Function that writes nginx config for server
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Object}   wstream An instance of fs.writeStream
     *
     */
    writeServer(options, wstream) {
        if (options.location == "proxy" && !options.count) {
            log('No API server entry will be written, SOAJS controller count is missing');
            return;
        }

    	log("writing server entry for", options.domain);
        wstream.write("server {\n");
        wstream.write("  listen       " + options.port + ";\n");
        wstream.write("  server_name  " + options.domain + ";\n");
        wstream.write("  client_max_body_size 100m;\n");
        if (options.https)
            builder.writeServerSSL(wstream);
        if (options.location == "proxy")
            builder.writeProxyLocation(options, wstream);
        else if (options.location == "static")
            builder.writeStaticLocation(options, wstream);
        wstream.write("}\n");
    },

    /**
     * Function that redirects to proper write function for api config based on passed params
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Function} cb      Callback function
     *
     */
    writeApiConf(options, cb) {
        log("Writing api conf in " + options.loc + " " + options.confFileName);
        let wstream = fs.createWriteStream(options.loc + options.confFileName);
        let httpsApi = config.nginx.config.ssl.httpsApi;
        let httpApiRedirect = config.nginx.config.ssl.httpApiRedirect;

        options.location = "proxy";

        if (httpsApi) {
            if (httpApiRedirect) {
                options.port = "80";
                builder.writeServerRedirect(options, wstream);
            }
            options.https = true;
            options.port = "443 ssl";
            builder.writeServer(options, wstream);
        }
        else if (!httpApiRedirect){
            options.port = "80";
            builder.writeServer(options, wstream);
        }

        wstream.end();
        return cb(null);
    },

    /**
     * Function that redirects to proper write function for site config based on passed params
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Function} cb      Callback function
     *
     */
    writeSiteConf(options, cb) {
    	let fileLocation = options.loc + options.confFileName;
	    options.domain = process.env.SOAJS_NX_SITE_DOMAIN;
    	//check if dashboard site.conf
	    if (process.env.SOAJS_ENV) {
	    	if(process.env.SOAJS_ENV.toLowerCase() === 'dashboard'){
			    fileLocation = options.loc + "dash.conf";
		    }
		    else if(process.env.SOAJS_ENV.toLowerCase() === 'portal'){
			    fileLocation = options.loc + "portal.conf";
		    }
	    }

        log("Writing site conf in " + fileLocation);
        let wstream = fs.createWriteStream(fileLocation);

        let httpsSite = config.nginx.config.ssl.httpsSite;
        let httpSiteRedirect = config.nginx.config.ssl.httpSiteRedirect;

        options.location = "static";

        if (httpsSite) {
	        if (httpSiteRedirect) {
		        options.port = "80";
		        builder.writeServerRedirect(options, wstream);
	        }
	        options.https = true;
	        options.port = "443 ssl";
	        builder.writeServer(options, wstream);
        }
        else if (!httpSiteRedirect){
	        options.port = "80";
	        builder.writeServer(options, wstream);
        }

        wstream.end();
        setTimeout(function(){
            return cb(null);
        }, 100);
    },

    /**
     * Function that writes the default nginx.conf file from templates and replaces placeholders with appropriate values
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Function} cb Callback function
     *
     */
    writeDefaultNginxConf(options, cb) {
        //read nginx.conf from templates directory
        log('Writing default nginx.conf ...');
        options.source = 'template';
        options.content = 'nginx';
        options.type = 'nginx.conf';
        options.target = options.nginx.location;
        utils.import(options, (error) => {
            if (error) throw new Error(error);

            log('nginx.conf written successfully ...');
            return cb();
        });
    },

    /**
     * Function that copies ssl.conf from templates directory to nginx directory
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Function} cb Callback function
     *
     */
    copySSLConf(options, cb) {
        //copy ssl.conf from templates directory to nginx directory
        log('Copying ssl.conf ...');
        let readStream = fs.createReadStream(path.join(options.paths.templates.nginx.path, 'ssl.conf'));
        let writeStream = fs.createWriteStream(path.join(options.nginx.location, '/ssl/ssl.conf'));

        readStream.on('error', (error) => {
            log('Unable to read ssl.conf ...');
            throw new Error(error);
        });
        writeStream.on('error', (error) => {
            log('Unable to write ssl.conf ...');
            throw new Error(error);
        });
        writeStream.on('close', () => {
            log('Successfully copied ssl.conf ...');
            return cb();
        });

        readStream.pipe(writeStream);
    },

    /**
     * Function that calls writeUpstream, writeApiConf, and writeSiteConf
     * @param  {Object}   options An object that contains params passed to the function
     * @param  {Object}   wstream An instance of fs.writeStream
     *
     */
    write(options, cb) {
        let nxOs = options.nginx.os;
        builder.writeDefaultNginxConf(options, () => {
            builder.copySSLConf(options, () => {
                builder.writeUpstream({
                    loc: options.nginx.location + ((nxOs === 'mac') ? "/servers/" : ( nxOs === 'ubuntu') ? "/conf.d/" : "/nginx/"),
                    port: options.nginx.config.upstream.ctrlPort,
                    ipEnvName: options.nginx.config.upstream.ipEnvName,
                    upstreamName: options.nginx.config.upstream.upstreamName,
                    count: options.nginx.config.upstream.count,
                }, () => {
                    log('SOAJS Controller Upstream was written successfully');
                    builder.writeApiConf({
                        loc: options.nginx.location + ((nxOs === 'mac') ? "/servers/" : ( nxOs === 'ubuntu') ? "/sites-enabled/" : "/nginx/"),
                        confFileName: options.nginx.config.apiConf.fileName,
                        domain: options.nginx.config.apiConf.domain,
                        upstreamName: options.nginx.config.upstream.upstreamName,
                        count: options.nginx.config.upstream.count
                    }, () => {
                        log('Nginx API config was written successfully');
                        if (options.nginx.config.siteConf.domain) {
                            builder.writeSiteConf({
                                loc: options.nginx.location + ((nxOs === 'mac') ? "/servers/" : ( nxOs === 'ubuntu') ? "/sites-enabled/" : "/nginx/"),
                                confFileName: options.nginx.config.siteConf.fileName,
                                domain: options.nginx.config.siteConf.domain,
                                path: options.nginx.config.siteConf.path
                            }, () => {
                                log('Nginx Site config was written successfully');
                                return cb();
                            });
                        }
                        else {
                            return cb();
                        }
                    });
                });
            });
        });
    }

};

module.exports = {
    write: builder.write
};
<|endoftext|>


<commit_before><commit_msg>update demo version<commit_after><|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc overview
 * @name pooApp
 * @description
 * # pooApp
 *
 * Main module of the application.
 */
angular
  .module('designTest', [
    'ngRoute'
  ])
  .config(function ($routeProvider,$sceProvider) {
    $sceProvider.enabled(false);
    $routeProvider
      .when('/', {
        templateUrl: 'views/platform.html'
      })
      .when('/login', {
        templateUrl: 'views/login.html',
        controller: 'loginCtrl'
      })
      .when('/welcome', {
        templateUrl: 'views/welcome.html',
        controller: 'welcomeCtrl'
      })
      .when('/placesmap', {
        templateUrl: 'views/placesmap.html',
        controller: 'placesmapCtrl'
      })
      .when('/placeslist', {
        templateUrl: 'views/placeslist.html',
        controller: 'placeslistCtrl'
      })
      .when('/placesdetail', {
        templateUrl: 'views/placesdetail.html',
        controller: 'placedetailCtrl'
      })
      .when('/recommend', {
        templateUrl: 'views/recommend.html',
        controller: 'recommendCtrl'
      })
      .when('/ask', {
        templateUrl: 'views/ask.html',
        controller: 'askCtrl'
      })
      .when('/tip', {
        templateUrl: 'views/tip.html',
        controller: 'tipCtrl'
      })
      .when('/thanks', {
        templateUrl: 'views/thanks.html',
        controller: 'thanksCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  });<commit_msg>modified routing in app.js to filter heatmaps screen wise<commit_after>'use strict';

/**
 * @ngdoc overview
 * @name pooApp
 * @description
 * # pooApp
 *
 * Main module of the application.
 */
angular
  .module('designTest', [
    'ngRoute'
  ])
  .config(function ($routeProvider,$sceProvider) {
    $sceProvider.enabled(false);
    $routeProvider
      .when('/?screen="platform"', {
        templateUrl: 'views/platform.html'
      })
      .when('/login?screen="login"', {
        templateUrl: 'views/login.html',
        controller: 'loginCtrl'
      })
      .when('/welcome?screen="welcome"', {
        templateUrl: 'views/welcome.html',
        controller: 'welcomeCtrl'
      })
      .when('/placesmap?screen="placesmap"', {
        templateUrl: 'views/placesmap.html',
        controller: 'placesmapCtrl'
      })
      .when('/placeslist?screen="placeslist"', {
        templateUrl: 'views/placeslist.html',
        controller: 'placeslistCtrl'
      })
      .when('/placesdetail?screen="placesdetail"', {
        templateUrl: 'views/placesdetail.html',
        controller: 'placedetailCtrl'
      })
      .when('/recommend?screen="recommend"', {
        templateUrl: 'views/recommend.html',
        controller: 'recommendCtrl'
      })
      .when('/ask?screen="ask"', {
        templateUrl: 'views/ask.html',
        controller: 'askCtrl'
      })
      .when('/tip?screen="tip"', {
        templateUrl: 'views/tip.html',
        controller: 'tipCtrl'
      })
      .when('/thanks?screen=thanks', {
        templateUrl: 'views/thanks.html',
        controller: 'thanksCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  });<|endoftext|>


<commit_before>'use strict'
require('./check-versions')()

process.env.NODE_ENV = 'production'

const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')

const spinner = ora('building for production...')
spinner.start()

rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
  if (err) throw err
  webpack(webpackConfig, function (err, stats) {
    spinner.stop()
    if (err) throw err
    // process.stdout.write(stats.toString({
    //   colors: true,
    //   modules: false,
    //   children: false,
    //   chunks: false,
    //   chunkModules: false
    // }) + '\n\n')

    if (stats.hasErrors()) {
      console.log(chalk.red('  Build failed with errors.\n'))
      process.exit(1)
    }

    console.log(chalk.cyan('  Build complete.\n'))
    console.log(chalk.yellow(
      '  Tip: built files are meant to be served over an HTTP server.\n' +
      '  Opening index.html over file:// won\'t work.\n'
    ))
  })
})
<commit_msg>aaaaa<commit_after>'use strict'
require('./check-versions')()

process.env.NODE_ENV = 'production'

const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')

const spinner = ora('building for production...')
spinner.start()

rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
  if (err) throw err
  webpack(webpackConfig, function (err, stats) {
    spinner.stop()
    //if (err) throw err
    // process.stdout.write(stats.toString({
    //   colors: true,
    //   modules: false,
    //   children: false,
    //   chunks: false,
    //   chunkModules: false
    // }) + '\n\n')

    if (stats.hasErrors()) {
      console.log(chalk.red('  Build failed with errors.\n'))
      process.exit(1)
    }

    console.log(chalk.cyan('  Build complete.\n'))
    console.log(chalk.yellow(
      '  Tip: built files are meant to be served over an HTTP server.\n' +
      '  Opening index.html over file:// won\'t work.\n'
    ))
  })
})
<|endoftext|>


<commit_before>$(function() {
	function initTimestamps()
	{
		$('span.timestamp').each(function() {
			var $this = $(this);
			var date = new Date($this.data('timestamp'));
			$this.html(date.toLocaleString());
		});
	}
	initTimestamps();
	$(document).on('pjax:complete', initTimestamps);
});<commit_msg>time fix<commit_after>$(function() {
	function initTimestamps()
	{
		$('span.timestamp').each(function() {
			var $this = $(this);
			var date = new Date($this.data('timestamp'));
			$this.html(date.format('d.m.Y H:i:s'));
		});
	}
	initTimestamps();
	$(document).on('pjax:complete', initTimestamps);
});

(function() {

	Date.shortMonths = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
	Date.longMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
	Date.shortDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
	Date.longDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

	// defining patterns
	var replaceChars = {
		// Day
		d: function() { return (this.getDate() < 10 ? '0' : '') + this.getDate(); },
		D: function() { return Date.shortDays[this.getDay()]; },
		j: function() { return this.getDate(); },
		l: function() { return Date.longDays[this.getDay()]; },
		N: function() { return (this.getDay() == 0 ? 7 : this.getDay()); },
		S: function() { return (this.getDate() % 10 == 1 && this.getDate() != 11 ? 'st' : (this.getDate() % 10 == 2 && this.getDate() != 12 ? 'nd' : (this.getDate() % 10 == 3 && this.getDate() != 13 ? 'rd' : 'th'))); },
		w: function() { return this.getDay(); },
		z: function() { var d = new Date(this.getFullYear(),0,1); return Math.ceil((this - d) / 86400000); }, // Fixed now
		// Week
		W: function() {
			var target = new Date(this.valueOf());
			var dayNr = (this.getDay() + 6) % 7;
			target.setDate(target.getDate() - dayNr + 3);
			var firstThursday = target.valueOf();
			target.setMonth(0, 1);
			if (target.getDay() !== 4) {
				target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7);
			}
			return 1 + Math.ceil((firstThursday - target) / 604800000);
		},
		// Month
		F: function() { return Date.longMonths[this.getMonth()]; },
		m: function() { return (this.getMonth() < 9 ? '0' : '') + (this.getMonth() + 1); },
		M: function() { return Date.shortMonths[this.getMonth()]; },
		n: function() { return this.getMonth() + 1; },
		t: function() { var d = new Date(); return new Date(d.getFullYear(), d.getMonth(), 0).getDate() }, // Fixed now, gets #days of date
		// Year
		L: function() { var year = this.getFullYear(); return (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0)); },   // Fixed now
		o: function() { var d  = new Date(this.valueOf());  d.setDate(d.getDate() - ((this.getDay() + 6) % 7) + 3); return d.getFullYear();}, //Fixed now
		Y: function() { return this.getFullYear(); },
		y: function() { return ('' + this.getFullYear()).substr(2); },
		// Time
		a: function() { return this.getHours() < 12 ? 'am' : 'pm'; },
		A: function() { return this.getHours() < 12 ? 'AM' : 'PM'; },
		B: function() { return Math.floor((((this.getUTCHours() + 1) % 24) + this.getUTCMinutes() / 60 + this.getUTCSeconds() / 3600) * 1000 / 24); }, // Fixed now
		g: function() { return this.getHours() % 12 || 12; },
		G: function() { return this.getHours(); },
		h: function() { return ((this.getHours() % 12 || 12) < 10 ? '0' : '') + (this.getHours() % 12 || 12); },
		H: function() { return (this.getHours() < 10 ? '0' : '') + this.getHours(); },
		i: function() { return (this.getMinutes() < 10 ? '0' : '') + this.getMinutes(); },
		s: function() { return (this.getSeconds() < 10 ? '0' : '') + this.getSeconds(); },
		u: function() { var m = this.getMilliseconds(); return (m < 10 ? '00' : (m < 100 ?
			'0' : '')) + m; },
		// Timezone
		e: function() { return /\((.*)\)/.exec(new Date().toString())[1]; },
		I: function() {
			var DST = null;
			for (var i = 0; i < 12; ++i) {
				var d = new Date(this.getFullYear(), i, 1);
				var offset = d.getTimezoneOffset();

				if (DST === null) DST = offset;
				else if (offset < DST) { DST = offset; break; }                     else if (offset > DST) break;
			}
			return (this.getTimezoneOffset() == DST) | 0;
		},
		O: function() { return (-this.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(this.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(this.getTimezoneOffset() / 60)) + '00'; },
		P: function() { return (-this.getTimezoneOffset() < 0 ? '-' : '+') + (Math.abs(this.getTimezoneOffset() / 60) < 10 ? '0' : '') + (Math.abs(this.getTimezoneOffset() / 60)) + ':00'; }, // Fixed now
		T: function() { return this.toTimeString().replace(/^.+ \(?([^\)]+)\)?$/, '$1'); },
		Z: function() { return -this.getTimezoneOffset() * 60; },
		// Full Date/Time
		c: function() { return this.format("Y-m-d\\TH:i:sP"); }, // Fixed now
		r: function() { return this.toString(); },
		U: function() { return this.getTime() / 1000; }
	};

	// Simulates PHP's date function
	Date.prototype.format = function(format) {
		var date = this;
		return format.replace(/(\\?)(.)/g, function(_, esc, chr) {
			return (esc === '' && replaceChars[chr]) ? replaceChars[chr].call(date) : chr;
		});
	};

})();<|endoftext|>


<commit_before>import path from 'path';

const env = process.env.NODE_ENV || 'development';

const configPath = path.join(__dirname, 'environments', env);

import config from './config.default';

const envConfig = require(configPath);

Object.assign(config, envConfig, {
  NODE_ENV: env,
  env: {
    isDevelopment: function() {
      return env === 'development';
    },
    isTest: function() {
      return env === 'test';
    },
    isStaging: function() {
      return env === 'staging';
    },
    isProduction: function() {
      return env === 'production';
    }
  }
});

export default config;
<commit_msg>Fix envConfig default<commit_after>import path from 'path';

const env = process.env.NODE_ENV || 'development';

const configPath = path.join(__dirname, 'environments', env);

import config from './config.default';

const envConfig = require(configPath).default;

Object.assign(config, envConfig, {
  NODE_ENV: env,
  env: {
    isDevelopment: function() {
      return env === 'development';
    },
    isTest: function() {
      return env === 'test';
    },
    isStaging: function() {
      return env === 'staging';
    },
    isProduction: function() {
      return env === 'production';
    }
  }
});

export default config;
<|endoftext|>


<commit_before>'use strict';

// This alternative WebpackDevServer combines the functionality of:
// https://github.com/webpack/webpack-dev-server/blob/webpack-1/client/index.js
// https://github.com/webpack/webpack/blob/webpack-1/hot/dev-server.js

// It only supports their simplest configuration (hot updates on same server).
// It makes some opinionated choices on top, like adding a syntax error overlay
// that looks similar to our console output. The error overlay is inspired by:
// https://github.com/glenjamin/webpack-hot-middleware

var SockJS = require('sockjs-client');
var stripAnsi = require('strip-ansi');
var url = require('url');
var launchEditorEndpoint = require('react-dev-utils/launchEditorEndpoint');
var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
var ErrorOverlay = require('react-error-overlay');

ErrorOverlay.setEditorHandler(function editorHandler(errorLocation) {
  // Keep this sync with errorOverlayMiddleware.js
  fetch(
    url.format({
      protocol: window.location.protocol,
      hostname: window.location.hostname,
      port: parseInt(process.env.PORT || window.location.port, 10) + 1,
      pathname: launchEditorEndpoint,
      search:
        '?fileName=' +
        window.encodeURIComponent(errorLocation.fileName) +
        '&lineNumber=' +
        window.encodeURIComponent(errorLocation.lineNumber || 1) +
        '&colNumber=' +
        window.encodeURIComponent(errorLocation.colNumber || 1),
    }),
    { mode: 'no-cors' }
  );
});

// We need to keep track of if there has been a runtime error.
// Essentially, we cannot guarantee application state was not corrupted by the
// runtime error. To prevent confusing behavior, we forcibly reload the entire
// application. This is handled below when we are notified of a compile (code
// change).
// See https://github.com/facebookincubator/create-react-app/issues/3096
var hadRuntimeError = false;
ErrorOverlay.startReportingRuntimeErrors({
  onError: function() {
    hadRuntimeError = true;
  },
  filename: process.env.REACT_BUNDLE_PATH || '/static/js/bundle.js',
});

if (module.hot && typeof module.hot.dispose === 'function') {
  module.hot.dispose(function() {
    // TODO: why do we need this?
    ErrorOverlay.stopReportingRuntimeErrors();
  });
}

// Connect to WebpackDevServer via a socket.
var connection = new SockJS(
  url.format({
    protocol: window.location.protocol,
    hostname: window.location.hostname,
    port: parseInt(process.env.PORT || window.location.port, 10) + 1,
    // Hardcoded in WebpackDevServer
    pathname: '/sockjs-node',
  })
);

// Unlike WebpackDevServer client, we won't try to reconnect
// to avoid spamming the console. Disconnect usually happens
// when developer stops the server.
connection.onclose = function() {
  if (typeof console !== 'undefined' && typeof console.info === 'function') {
    console.info(
      'The development server has disconnected.\nRefresh the page if necessary.'
    );
  }
};

// Remember some state related to hot module replacement.
var isFirstCompilation = true;
var mostRecentCompilationHash = null;
var hasCompileErrors = false;

function clearOutdatedErrors() {
  // Clean up outdated compile errors, if any.
  if (typeof console !== 'undefined' && typeof console.clear === 'function') {
    if (hasCompileErrors) {
      console.clear();
    }
  }
}

// Successful compilation.
function handleSuccess() {
  clearOutdatedErrors();

  var isHotUpdate = !isFirstCompilation;
  isFirstCompilation = false;
  hasCompileErrors = false;

  // Attempt to apply hot updates or reload.
  if (isHotUpdate) {
    tryApplyUpdates(function onHotUpdateSuccess() {
      // Only dismiss it when we're sure it's a hot update.
      // Otherwise it would flicker right before the reload.
      ErrorOverlay.dismissBuildError();
    });
  }
}

// Compilation with warnings (e.g. ESLint).
function handleWarnings(warnings) {
  clearOutdatedErrors();

  var isHotUpdate = !isFirstCompilation;
  isFirstCompilation = false;
  hasCompileErrors = false;

  function printWarnings() {
    // Print warnings to the console.
    var formatted = formatWebpackMessages({
      warnings: warnings,
      errors: [],
    });

    if (typeof console !== 'undefined' && typeof console.warn === 'function') {
      for (var i = 0; i < formatted.warnings.length; i++) {
        if (i === 5) {
          console.warn(
            'There were more warnings in other files.\n' +
              'You can find a complete log in the terminal.'
          );
          break;
        }
        console.warn(stripAnsi(formatted.warnings[i]));
      }
    }
  }

  // Attempt to apply hot updates or reload.
  if (isHotUpdate) {
    tryApplyUpdates(function onSuccessfulHotUpdate() {
      // Only print warnings if we aren't refreshing the page.
      // Otherwise they'll disappear right away anyway.
      printWarnings();
      // Only dismiss it when we're sure it's a hot update.
      // Otherwise it would flicker right before the reload.
      ErrorOverlay.dismissBuildError();
    });
  } else {
    // Print initial warnings immediately.
    printWarnings();
  }
}

// Compilation with errors (e.g. syntax error or missing modules).
function handleErrors(errors) {
  clearOutdatedErrors();

  isFirstCompilation = false;
  hasCompileErrors = true;

  // "Massage" webpack messages.
  var formatted = formatWebpackMessages({
    errors: errors,
    warnings: [],
  });

  // Only show the first error.
  ErrorOverlay.reportBuildError(formatted.errors[0]);

  // Also log them to the console.
  if (typeof console !== 'undefined' && typeof console.error === 'function') {
    for (var i = 0; i < formatted.errors.length; i++) {
      console.error(stripAnsi(formatted.errors[i]));
    }
  }

  // Do not attempt to reload now.
  // We will reload on next success instead.
}

// There is a newer version of the code available.
function handleAvailableHash(hash) {
  // Update last known compilation hash.
  mostRecentCompilationHash = hash;
}

// Handle messages from the server.
connection.onmessage = function(e) {
  var message = JSON.parse(e.data);
  switch (message.type) {
    case 'hash':
      handleAvailableHash(message.data);
      break;
    case 'still-ok':
    case 'ok':
      handleSuccess();
      break;
    case 'content-changed':
      // Triggered when a file from `contentBase` changed.
      window.location.reload();
      break;
    case 'warnings':
      handleWarnings(message.data);
      break;
    case 'errors':
      handleErrors(message.data);
      break;
    default:
    // Do nothing.
  }
};

// Is there a newer version of this code available?
function isUpdateAvailable() {
  /* globals __webpack_hash__ */
  // __webpack_hash__ is the hash of the current compilation.
  // It's a global variable injected by Webpack.
  return mostRecentCompilationHash !== __webpack_hash__;
}

// Webpack disallows updates in other states.
function canApplyUpdates() {
  return module.hot.status() === 'idle';
}

// Attempt to update code on the fly, fall back to a hard reload.
function tryApplyUpdates(onHotUpdateSuccess) {
  if (!module.hot) {
    // HotModuleReplacementPlugin is not in Webpack configuration.
    window.location.reload();
    return;
  }

  if (!isUpdateAvailable() || !canApplyUpdates()) {
    return;
  }

  function handleApplyUpdates(err, updatedModules) {
    if (err || !updatedModules || hadRuntimeError) {
      window.location.reload();
      return;
    }

    if (typeof onHotUpdateSuccess === 'function') {
      // Maybe we want to do something.
      onHotUpdateSuccess();
    }

    if (isUpdateAvailable()) {
      // While we were updating, there was a new update! Do it again.
      tryApplyUpdates();
    }
  }

  // https://webpack.github.io/docs/hot-module-replacement.html#check
  var result = module.hot.check(/* autoApply */ true, handleApplyUpdates);

  // // Webpack 2 returns a Promise instead of invoking a callback
  if (result && result.then) {
    result.then(
      function(updatedModules) {
        handleApplyUpdates(null, updatedModules);
      },
      function(err) {
        handleApplyUpdates(err, null);
      }
    );
  }
}
<commit_msg>Handle window.location.port = 80 or 443 when PORT env var hasn't been set (#581)<commit_after>'use strict';

// This alternative WebpackDevServer combines the functionality of:
// https://github.com/webpack/webpack-dev-server/blob/webpack-1/client/index.js
// https://github.com/webpack/webpack/blob/webpack-1/hot/dev-server.js

// It only supports their simplest configuration (hot updates on same server).
// It makes some opinionated choices on top, like adding a syntax error overlay
// that looks similar to our console output. The error overlay is inspired by:
// https://github.com/glenjamin/webpack-hot-middleware

var SockJS = require('sockjs-client');
var stripAnsi = require('strip-ansi');
var url = require('url');
var launchEditorEndpoint = require('react-dev-utils/launchEditorEndpoint');
var formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
var ErrorOverlay = require('react-error-overlay');

// To get the server port, prefer the env var if available
// If it's not set, (e.g. for a Docker image that has to run in multiple environments)
// use window.location.port in client-side code like this.
// Note that window.location.port is '' if the port is not part of the url (it can be inferred from
// window.location.protocol)
var serverPort = process.env.PORT
  ? parseInt(process.env.PORT, 10)
  : window.location.port
    ? parseInt(window.location.port, 10)
    : window.location.protocol === 'http:'
      ? 80
      : 443;

// the client-side build (webpack-dev-server) is on a different port
var sockJsPort = serverPort + 1;

ErrorOverlay.setEditorHandler(function editorHandler(errorLocation) {
  // Keep this sync with errorOverlayMiddleware.js
  fetch(
    url.format({
      protocol: window.location.protocol,
      hostname: window.location.hostname,
      port: sockJsPort,
      pathname: launchEditorEndpoint,
      search:
        '?fileName=' +
        window.encodeURIComponent(errorLocation.fileName) +
        '&lineNumber=' +
        window.encodeURIComponent(errorLocation.lineNumber || 1) +
        '&colNumber=' +
        window.encodeURIComponent(errorLocation.colNumber || 1),
    }),
    { mode: 'no-cors' }
  );
});

// We need to keep track of if there has been a runtime error.
// Essentially, we cannot guarantee application state was not corrupted by the
// runtime error. To prevent confusing behavior, we forcibly reload the entire
// application. This is handled below when we are notified of a compile (code
// change).
// See https://github.com/facebookincubator/create-react-app/issues/3096
var hadRuntimeError = false;
ErrorOverlay.startReportingRuntimeErrors({
  onError: function() {
    hadRuntimeError = true;
  },
  filename: process.env.REACT_BUNDLE_PATH || '/static/js/bundle.js',
});

if (module.hot && typeof module.hot.dispose === 'function') {
  module.hot.dispose(function() {
    // TODO: why do we need this?
    ErrorOverlay.stopReportingRuntimeErrors();
  });
}

// Connect to WebpackDevServer via a socket.
var connection = new SockJS(
  url.format({
    protocol: window.location.protocol,
    hostname: window.location.hostname,
    port: sockJsPort,
    // Hardcoded in WebpackDevServer
    pathname: '/sockjs-node',
  })
);

// Unlike WebpackDevServer client, we won't try to reconnect
// to avoid spamming the console. Disconnect usually happens
// when developer stops the server.
connection.onclose = function() {
  if (typeof console !== 'undefined' && typeof console.info === 'function') {
    console.info(
      'The development server has disconnected.\nRefresh the page if necessary.'
    );
  }
};

// Remember some state related to hot module replacement.
var isFirstCompilation = true;
var mostRecentCompilationHash = null;
var hasCompileErrors = false;

function clearOutdatedErrors() {
  // Clean up outdated compile errors, if any.
  if (typeof console !== 'undefined' && typeof console.clear === 'function') {
    if (hasCompileErrors) {
      console.clear();
    }
  }
}

// Successful compilation.
function handleSuccess() {
  clearOutdatedErrors();

  var isHotUpdate = !isFirstCompilation;
  isFirstCompilation = false;
  hasCompileErrors = false;

  // Attempt to apply hot updates or reload.
  if (isHotUpdate) {
    tryApplyUpdates(function onHotUpdateSuccess() {
      // Only dismiss it when we're sure it's a hot update.
      // Otherwise it would flicker right before the reload.
      ErrorOverlay.dismissBuildError();
    });
  }
}

// Compilation with warnings (e.g. ESLint).
function handleWarnings(warnings) {
  clearOutdatedErrors();

  var isHotUpdate = !isFirstCompilation;
  isFirstCompilation = false;
  hasCompileErrors = false;

  function printWarnings() {
    // Print warnings to the console.
    var formatted = formatWebpackMessages({
      warnings: warnings,
      errors: [],
    });

    if (typeof console !== 'undefined' && typeof console.warn === 'function') {
      for (var i = 0; i < formatted.warnings.length; i++) {
        if (i === 5) {
          console.warn(
            'There were more warnings in other files.\n' +
              'You can find a complete log in the terminal.'
          );
          break;
        }
        console.warn(stripAnsi(formatted.warnings[i]));
      }
    }
  }

  // Attempt to apply hot updates or reload.
  if (isHotUpdate) {
    tryApplyUpdates(function onSuccessfulHotUpdate() {
      // Only print warnings if we aren't refreshing the page.
      // Otherwise they'll disappear right away anyway.
      printWarnings();
      // Only dismiss it when we're sure it's a hot update.
      // Otherwise it would flicker right before the reload.
      ErrorOverlay.dismissBuildError();
    });
  } else {
    // Print initial warnings immediately.
    printWarnings();
  }
}

// Compilation with errors (e.g. syntax error or missing modules).
function handleErrors(errors) {
  clearOutdatedErrors();

  isFirstCompilation = false;
  hasCompileErrors = true;

  // "Massage" webpack messages.
  var formatted = formatWebpackMessages({
    errors: errors,
    warnings: [],
  });

  // Only show the first error.
  ErrorOverlay.reportBuildError(formatted.errors[0]);

  // Also log them to the console.
  if (typeof console !== 'undefined' && typeof console.error === 'function') {
    for (var i = 0; i < formatted.errors.length; i++) {
      console.error(stripAnsi(formatted.errors[i]));
    }
  }

  // Do not attempt to reload now.
  // We will reload on next success instead.
}

// There is a newer version of the code available.
function handleAvailableHash(hash) {
  // Update last known compilation hash.
  mostRecentCompilationHash = hash;
}

// Handle messages from the server.
connection.onmessage = function(e) {
  var message = JSON.parse(e.data);
  switch (message.type) {
    case 'hash':
      handleAvailableHash(message.data);
      break;
    case 'still-ok':
    case 'ok':
      handleSuccess();
      break;
    case 'content-changed':
      // Triggered when a file from `contentBase` changed.
      window.location.reload();
      break;
    case 'warnings':
      handleWarnings(message.data);
      break;
    case 'errors':
      handleErrors(message.data);
      break;
    default:
    // Do nothing.
  }
};

// Is there a newer version of this code available?
function isUpdateAvailable() {
  /* globals __webpack_hash__ */
  // __webpack_hash__ is the hash of the current compilation.
  // It's a global variable injected by Webpack.
  return mostRecentCompilationHash !== __webpack_hash__;
}

// Webpack disallows updates in other states.
function canApplyUpdates() {
  return module.hot.status() === 'idle';
}

// Attempt to update code on the fly, fall back to a hard reload.
function tryApplyUpdates(onHotUpdateSuccess) {
  if (!module.hot) {
    // HotModuleReplacementPlugin is not in Webpack configuration.
    window.location.reload();
    return;
  }

  if (!isUpdateAvailable() || !canApplyUpdates()) {
    return;
  }

  function handleApplyUpdates(err, updatedModules) {
    if (err || !updatedModules || hadRuntimeError) {
      window.location.reload();
      return;
    }

    if (typeof onHotUpdateSuccess === 'function') {
      // Maybe we want to do something.
      onHotUpdateSuccess();
    }

    if (isUpdateAvailable()) {
      // While we were updating, there was a new update! Do it again.
      tryApplyUpdates();
    }
  }

  // https://webpack.github.io/docs/hot-module-replacement.html#check
  var result = module.hot.check(/* autoApply */ true, handleApplyUpdates);

  // // Webpack 2 returns a Promise instead of invoking a callback
  if (result && result.then) {
    result.then(
      function(updatedModules) {
        handleApplyUpdates(null, updatedModules);
      },
      function(err) {
        handleApplyUpdates(err, null);
      }
    );
  }
}
<|endoftext|>


<commit_before>
import Base64 from 'slate-base64-serializer'

import findDOMNode from './find-dom-node'
import getWindow from 'get-window'
import { IS_CHROME, IS_SAFARI } from '../constants/environment'

/**
 * Prepares a Slate document fragment to be copied to the clipboard.
 *
 * @param {Event} event
 * @param {Value} value
 * @param {Document} [fragment]
 */

function cloneFragment(event, value, fragment = value.fragment) {
  const window = getWindow(event.target)
  const native = window.getSelection()
  const { startKey, endKey, startText, endBlock, endInline } = value
  const isVoidBlock = endBlock && endBlock.isVoid
  const isVoidInline = endInline && endInline.isVoid
  const isVoid = isVoidBlock || isVoidInline

  // If the selection is collapsed, and it isn't inside a void node, abort.
  if (native.isCollapsed && !isVoid) return

  // Create a fake selection so that we can add a Base64-encoded copy of the
  // fragment to the HTML, to decode on future pastes.
  const encoded = Base64.serializeNode(fragment)
  const range = native.getRangeAt(0)
  let contents = range.cloneContents()
  let attach = contents.childNodes[0]

  // If the end node is a void node, we need to move the end of the range from
  // the void node's spacer span, to the end of the void node's content.
  if (isVoid) {
    const r = range.cloneRange()
    const n = isVoidBlock ? endBlock : endInline
    const node = findDOMNode(n, window)
    r.setEndAfter(node)
    contents = r.cloneContents()
    attach = contents.childNodes[contents.childNodes.length - 1].firstChild
  }

  // COMPAT: in Safari and Chrome when selecting a single marked word,
  // marks are not preserved when copying.
  // If the attatched is not void, and the startKey and endKey is the same,
  // check if there is marks involved. If so, set the range start just before the
  // startText node
  if ((IS_CHROME || IS_SAFARI) && !isVoid && startKey === endKey) {
    const hasMarks = startText.characters
      .slice(value.selection.anchorOffset, value.selection.focusOffset)
      .filter(char => char.marks.size !== 0)
      .size !== 0
    if (hasMarks) {
      const r = range.cloneRange()
      const node = findDOMNode(startText, window)
      r.setStartBefore(node)
      contents = r.cloneContents()
      attach = contents.childNodes[contents.childNodes.length - 1].firstChild
    }
  }

  // Remove any zero-width space spans from the cloned DOM so that they don't
  // show up elsewhere when pasted.
  const zws = [].slice.call(contents.querySelectorAll('[data-slate-zero-width]'))
  zws.forEach(zw => zw.parentNode.removeChild(zw))

  // COMPAT: In Chrome and Safari, if the last element in the selection to
  // copy has `contenteditable="false"` the copy will fail, and nothing will
  // be put in the clipboard. So we remove them all. (2017/05/04)
  if (IS_CHROME || IS_SAFARI) {
    const els = [].slice.call(contents.querySelectorAll('[contenteditable="false"]'))
    els.forEach(el => el.removeAttribute('contenteditable'))
  }

  // Set a `data-slate-fragment` attribute on a non-empty node, so it shows up
  // in the HTML, and can be used for intra-Slate pasting. If it's a text
  // node, wrap it in a `<span>` so we have something to set an attribute on.
  if (attach.nodeType == 3) {
    const span = window.document.createElement('span')

    // COMPAT: In Chrome and Safari, if we don't add the `white-space` style
    // then leading and trailing spaces will be ignored. (2017/09/21)
    span.style.whiteSpace = 'pre'

    span.appendChild(attach)
    contents.appendChild(span)
    attach = span
  }

  attach.setAttribute('data-slate-fragment', encoded)

  // Add the phony content to the DOM, and select it, so it will be copied.
  const body = window.document.querySelector('body')
  const div = window.document.createElement('div')
  div.setAttribute('contenteditable', true)
  div.style.position = 'absolute'
  div.style.left = '-9999px'

  // COMPAT: In Firefox, the viewport jumps to find the phony div, so it
  // should be created at the current scroll offset with `style.top`.
  // The box model attributes which can interact with 'top' are also reset.
  div.style.border = '0px'
  div.style.padding = '0px'
  div.style.margin = '0px'
  div.style.top = `${window.pageYOffset || window.document.documentElement.scrollTop}px`

  div.appendChild(contents)
  body.appendChild(div)

  // COMPAT: In Firefox, trying to use the terser `native.selectAllChildren`
  // throws an error, so we use the older `range` equivalent. (2016/06/21)
  const r = window.document.createRange()
  r.selectNodeContents(div)
  native.removeAllRanges()
  native.addRange(r)

  // Revert to the previous selection right after copying.
  window.requestAnimationFrame(() => {
    body.removeChild(div)
    native.removeAllRanges()
    native.addRange(range)
  })
}

export default cloneFragment
<commit_msg>Append copied fragment to editor DOM node instead of page body (#1533)<commit_after>
import Base64 from 'slate-base64-serializer'

import findDOMNode from './find-dom-node'
import getWindow from 'get-window'
import { IS_CHROME, IS_SAFARI } from '../constants/environment'

/**
 * Prepares a Slate document fragment to be copied to the clipboard.
 *
 * @param {Event} event
 * @param {Value} value
 * @param {Document} [fragment]
 */

function cloneFragment(event, value, fragment = value.fragment) {
  const window = getWindow(event.target)
  const native = window.getSelection()
  const { startKey, endKey, startText, endBlock, endInline } = value
  const isVoidBlock = endBlock && endBlock.isVoid
  const isVoidInline = endInline && endInline.isVoid
  const isVoid = isVoidBlock || isVoidInline

  // If the selection is collapsed, and it isn't inside a void node, abort.
  if (native.isCollapsed && !isVoid) return

  // Create a fake selection so that we can add a Base64-encoded copy of the
  // fragment to the HTML, to decode on future pastes.
  const encoded = Base64.serializeNode(fragment)
  const range = native.getRangeAt(0)
  let contents = range.cloneContents()
  let attach = contents.childNodes[0]

  // If the end node is a void node, we need to move the end of the range from
  // the void node's spacer span, to the end of the void node's content.
  if (isVoid) {
    const r = range.cloneRange()
    const n = isVoidBlock ? endBlock : endInline
    const node = findDOMNode(n, window)
    r.setEndAfter(node)
    contents = r.cloneContents()
    attach = contents.childNodes[contents.childNodes.length - 1].firstChild
  }

  // COMPAT: in Safari and Chrome when selecting a single marked word,
  // marks are not preserved when copying.
  // If the attatched is not void, and the startKey and endKey is the same,
  // check if there is marks involved. If so, set the range start just before the
  // startText node
  if ((IS_CHROME || IS_SAFARI) && !isVoid && startKey === endKey) {
    const hasMarks = startText.characters
      .slice(value.selection.anchorOffset, value.selection.focusOffset)
      .filter(char => char.marks.size !== 0)
      .size !== 0
    if (hasMarks) {
      const r = range.cloneRange()
      const node = findDOMNode(startText, window)
      r.setStartBefore(node)
      contents = r.cloneContents()
      attach = contents.childNodes[contents.childNodes.length - 1].firstChild
    }
  }

  // Remove any zero-width space spans from the cloned DOM so that they don't
  // show up elsewhere when pasted.
  const zws = [].slice.call(contents.querySelectorAll('[data-slate-zero-width]'))
  zws.forEach(zw => zw.parentNode.removeChild(zw))

  // COMPAT: In Chrome and Safari, if the last element in the selection to
  // copy has `contenteditable="false"` the copy will fail, and nothing will
  // be put in the clipboard. So we remove them all. (2017/05/04)
  if (IS_CHROME || IS_SAFARI) {
    const els = [].slice.call(contents.querySelectorAll('[contenteditable="false"]'))
    els.forEach(el => el.removeAttribute('contenteditable'))
  }

  // Set a `data-slate-fragment` attribute on a non-empty node, so it shows up
  // in the HTML, and can be used for intra-Slate pasting. If it's a text
  // node, wrap it in a `<span>` so we have something to set an attribute on.
  if (attach.nodeType == 3) {
    const span = window.document.createElement('span')

    // COMPAT: In Chrome and Safari, if we don't add the `white-space` style
    // then leading and trailing spaces will be ignored. (2017/09/21)
    span.style.whiteSpace = 'pre'

    span.appendChild(attach)
    contents.appendChild(span)
    attach = span
  }

  attach.setAttribute('data-slate-fragment', encoded)

  // Add the phony content to the DOM, and select it, so it will be copied.
  const editor = window.document.querySelector('[data-slate-editor]')
  const div = window.document.createElement('div')
  div.setAttribute('contenteditable', true)
  div.style.position = 'absolute'
  div.style.left = '-9999px'

  // COMPAT: In Firefox, the viewport jumps to find the phony div, so it
  // should be created at the current scroll offset with `style.top`.
  // The box model attributes which can interact with 'top' are also reset.
  div.style.border = '0px'
  div.style.padding = '0px'
  div.style.margin = '0px'
  div.style.top = `${window.pageYOffset || window.document.documentElement.scrollTop}px`

  div.appendChild(contents)
  editor.appendChild(div)

  // COMPAT: In Firefox, trying to use the terser `native.selectAllChildren`
  // throws an error, so we use the older `range` equivalent. (2016/06/21)
  const r = window.document.createRange()
  r.selectNodeContents(div)
  native.removeAllRanges()
  native.addRange(r)

  // Revert to the previous selection right after copying.
  window.requestAnimationFrame(() => {
    editor.removeChild(div)
    native.removeAllRanges()
    native.addRange(range)
  })
}

export default cloneFragment
<|endoftext|>


<commit_before>import Base64 from 'slate-base64-serializer'
import Plain from 'slate-plain-serializer'
import getWindow from 'get-window'
import invariant from 'tiny-invariant'
import { IS_IE } from 'slate-dev-environment'
import { Value } from 'slate'

import TRANSFER_TYPES from '../constants/transfer-types'
import removeAllRanges from './remove-all-ranges'
import findDOMNode from './find-dom-node'
import DATA_ATTRS from '../constants/data-attributes'
import SELECTORS from '../constants/selectors'

const { FRAGMENT, HTML, TEXT } = TRANSFER_TYPES

/**
 * Prepares a Slate document fragment to be copied to the clipboard.
 *
 * @param {Event} event
 * @param {Editor} editor
 */

function cloneFragment(event, editor, callback = () => undefined) {
  invariant(
    !Value.isValue(editor),
    'As of Slate 0.42.0, the `cloneFragment` utility takes an `editor` instead of a `value`.'
  )

  const window = getWindow(event.target)
  const native = window.getSelection()
  const { value } = editor
  const { document, fragment, selection } = value
  const { start, end } = selection
  const startVoid = document.getClosestVoid(start.path, editor)
  const endVoid = document.getClosestVoid(end.path, editor)

  // If the selection is collapsed, and it isn't inside a void node, abort.
  if (native.isCollapsed && !startVoid) return

  // Create a fake selection so that we can add a Base64-encoded copy of the
  // fragment to the HTML, to decode on future pastes.
  const encoded = Base64.serializeNode(fragment)
  const range = native.getRangeAt(0)
  let contents = range.cloneContents()
  let attach = contents.childNodes[0]

  // Make sure attach is a non-empty node, since empty nodes will not get copied
  contents.childNodes.forEach(node => {
    if (node.textContent && node.textContent.trim() !== '') {
      attach = node
    }
  })

  // COMPAT: If the end node is a void node, we need to move the end of the
  // range from the void node's spacer span, to the end of the void node's
  // content, since the spacer is before void's content in the DOM.
  if (endVoid) {
    const r = range.cloneRange()
    const node = findDOMNode(endVoid, window)
    r.setEndAfter(node)
    contents = r.cloneContents()
  }

  // COMPAT: If the start node is a void node, we need to attach the encoded
  // fragment to the void node's content node instead of the spacer, because
  // attaching it to empty `<div>/<span>` nodes will end up having it erased by
  // most browsers. (2018/04/27)
  if (startVoid) {
    attach = contents.childNodes[0].childNodes[1].firstChild
  }

  // Remove any zero-width space spans from the cloned DOM so that they don't
  // show up elsewhere when pasted.
  ;[].slice
    .call(contents.querySelectorAll(SELECTORS.ZERO_WIDTH))
    .forEach(zw => {
      const isNewline = zw.getAttribute(DATA_ATTRS.ZERO_WIDTH) === 'n'
      zw.textContent = isNewline ? '\n' : ''
    })

  // Set a `data-slate-fragment` attribute on a non-empty node, so it shows up
  // in the HTML, and can be used for intra-Slate pasting. If it's a text
  // node, wrap it in a `<span>` so we have something to set an attribute on.
  if (attach.nodeType === 3) {
    const span = window.document.createElement('span')

    // COMPAT: In Chrome and Safari, if we don't add the `white-space` style
    // then leading and trailing spaces will be ignored. (2017/09/21)
    span.style.whiteSpace = 'pre'

    span.appendChild(attach)
    contents.appendChild(span)
    attach = span
  }

  attach.setAttribute(DATA_ATTRS.FRAGMENT, encoded)

  //  Creates value from only the selected blocks
  //  Then gets plaintext for clipboard with proper linebreaks for BLOCK elements
  //  Via Plain serializer
  const valFromSelection = Value.create({ document: fragment })
  const plainText = Plain.serialize(valFromSelection)

  // Add the phony content to a div element. This is needed to copy the
  // contents into the html clipboard register.
  const div = window.document.createElement('div')
  div.appendChild(contents)

  // For browsers supporting it, we set the clipboard registers manually,
  // since the result is more predictable.
  // COMPAT: IE supports the setData method, but only in restricted sense.
  // IE doesn't support arbitrary MIME types or common ones like 'text/plain';
  // it only accepts "Text" (which gets mapped to 'text/plain') and "Url"
  // (mapped to 'text/url-list'); so, we should only enter block if !IS_IE
  if (event.clipboardData && event.clipboardData.setData && !IS_IE) {
    event.preventDefault()
    event.clipboardData.setData(TEXT, plainText)
    event.clipboardData.setData(FRAGMENT, encoded)
    event.clipboardData.setData(HTML, div.innerHTML)
    callback()
    return
  }

  // COMPAT: For browser that don't support the Clipboard API's setData method,
  // we must rely on the browser to natively copy what's selected.
  // So we add the div (containing our content) to the DOM, and select it.
  const editorEl = event.target.closest(SELECTORS.EDITOR)
  div.setAttribute('contenteditable', true)
  div.style.position = 'absolute'
  div.style.left = '-9999px'
  editorEl.appendChild(div)
  native.selectAllChildren(div)

  // Revert to the previous selection right after copying.
  window.requestAnimationFrame(() => {
    editorEl.removeChild(div)
    removeAllRanges(native)
    native.addRange(range)
    callback()
  })
}

export default cloneFragment
<commit_msg>Replace deprecated findDOMNode with editor.findDOMNode in cloneFragment (#3018)<commit_after>import Base64 from 'slate-base64-serializer'
import Plain from 'slate-plain-serializer'
import getWindow from 'get-window'
import invariant from 'tiny-invariant'
import { IS_IE } from 'slate-dev-environment'
import { Value } from 'slate'

import TRANSFER_TYPES from '../constants/transfer-types'
import removeAllRanges from './remove-all-ranges'
import DATA_ATTRS from '../constants/data-attributes'
import SELECTORS from '../constants/selectors'

const { FRAGMENT, HTML, TEXT } = TRANSFER_TYPES

/**
 * Prepares a Slate document fragment to be copied to the clipboard.
 *
 * @param {Event} event
 * @param {Editor} editor
 */

function cloneFragment(event, editor, callback = () => undefined) {
  invariant(
    !Value.isValue(editor),
    'As of Slate 0.42.0, the `cloneFragment` utility takes an `editor` instead of a `value`.'
  )

  const window = getWindow(event.target)
  const native = window.getSelection()
  const { value } = editor
  const { document, fragment, selection } = value
  const { start, end } = selection
  const startVoid = document.getClosestVoid(start.path, editor)
  const endVoid = document.getClosestVoid(end.path, editor)

  // If the selection is collapsed, and it isn't inside a void node, abort.
  if (native.isCollapsed && !startVoid) return

  // Create a fake selection so that we can add a Base64-encoded copy of the
  // fragment to the HTML, to decode on future pastes.
  const encoded = Base64.serializeNode(fragment)
  const range = native.getRangeAt(0)
  let contents = range.cloneContents()
  let attach = contents.childNodes[0]

  // Make sure attach is a non-empty node, since empty nodes will not get copied
  contents.childNodes.forEach(node => {
    if (node.textContent && node.textContent.trim() !== '') {
      attach = node
    }
  })

  // COMPAT: If the end node is a void node, we need to move the end of the
  // range from the void node's spacer span, to the end of the void node's
  // content, since the spacer is before void's content in the DOM.
  if (endVoid) {
    const r = range.cloneRange()
    const path = document.getPath(endVoid.key)

    if (path) {
      const node = editor.findDOMNode(path)
      r.setEndAfter(node)
      contents = r.cloneContents()
    }
  }

  // COMPAT: If the start node is a void node, we need to attach the encoded
  // fragment to the void node's content node instead of the spacer, because
  // attaching it to empty `<div>/<span>` nodes will end up having it erased by
  // most browsers. (2018/04/27)
  if (startVoid) {
    attach = contents.childNodes[0].childNodes[1].firstChild
  }

  // Remove any zero-width space spans from the cloned DOM so that they don't
  // show up elsewhere when pasted.
  ;[].slice
    .call(contents.querySelectorAll(SELECTORS.ZERO_WIDTH))
    .forEach(zw => {
      const isNewline = zw.getAttribute(DATA_ATTRS.ZERO_WIDTH) === 'n'
      zw.textContent = isNewline ? '\n' : ''
    })

  // Set a `data-slate-fragment` attribute on a non-empty node, so it shows up
  // in the HTML, and can be used for intra-Slate pasting. If it's a text
  // node, wrap it in a `<span>` so we have something to set an attribute on.
  if (attach.nodeType === 3) {
    const span = window.document.createElement('span')

    // COMPAT: In Chrome and Safari, if we don't add the `white-space` style
    // then leading and trailing spaces will be ignored. (2017/09/21)
    span.style.whiteSpace = 'pre'

    span.appendChild(attach)
    contents.appendChild(span)
    attach = span
  }

  attach.setAttribute(DATA_ATTRS.FRAGMENT, encoded)

  //  Creates value from only the selected blocks
  //  Then gets plaintext for clipboard with proper linebreaks for BLOCK elements
  //  Via Plain serializer
  const valFromSelection = Value.create({ document: fragment })
  const plainText = Plain.serialize(valFromSelection)

  // Add the phony content to a div element. This is needed to copy the
  // contents into the html clipboard register.
  const div = window.document.createElement('div')
  div.appendChild(contents)

  // For browsers supporting it, we set the clipboard registers manually,
  // since the result is more predictable.
  // COMPAT: IE supports the setData method, but only in restricted sense.
  // IE doesn't support arbitrary MIME types or common ones like 'text/plain';
  // it only accepts "Text" (which gets mapped to 'text/plain') and "Url"
  // (mapped to 'text/url-list'); so, we should only enter block if !IS_IE
  if (event.clipboardData && event.clipboardData.setData && !IS_IE) {
    event.preventDefault()
    event.clipboardData.setData(TEXT, plainText)
    event.clipboardData.setData(FRAGMENT, encoded)
    event.clipboardData.setData(HTML, div.innerHTML)
    callback()
    return
  }

  // COMPAT: For browser that don't support the Clipboard API's setData method,
  // we must rely on the browser to natively copy what's selected.
  // So we add the div (containing our content) to the DOM, and select it.
  const editorEl = event.target.closest(SELECTORS.EDITOR)
  div.setAttribute('contenteditable', true)
  div.style.position = 'absolute'
  div.style.left = '-9999px'
  editorEl.appendChild(div)
  native.selectAllChildren(div)

  // Revert to the previous selection right after copying.
  window.requestAnimationFrame(() => {
    editorEl.removeChild(div)
    removeAllRanges(native)
    native.addRange(range)
    callback()
  })
}

export default cloneFragment
<|endoftext|>


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

    angular
        .module('dpHeader')
        .directive('dpSearch', dpSearchDirective);

    dpSearchDirective.$inject = ['$timeout', 'autocompleteData', 'sharedConfig', 'store', 'ACTIONS'];

    function dpSearchDirective ($timeout, autocompleteData, sharedConfig, store, ACTIONS) {
        return {
            restrict: 'E',
            scope: {
                query: '@',
                placeholder: '@',
                type: '@',
                payload: '<',
                searchOnly: '<'
            },
            templateUrl: 'modules/header/components/search/search.html',
            link: linkFunction
        };

        function linkFunction (scope, element) {
            var searchbox = element[0].querySelector('.js-search-input');

            scope.activeSuggestionIndex = -1;
            scope.originalQuery = scope.query;
            scope.placeholder = scope.placeholder || 'Zoek op adres of postcode, kadastrale aanduiding, etc.';

            scope.formSubmit = function (event) {
                event.preventDefault();

                search();

                removeSuggestions();
            };

            scope.clear = function () {
                scope.query = '';
                scope.getSuggestions();
                scope.setFocus();
            };

            scope.getSuggestions = function () {
                /**
                 * Cancel the last request (if any), this way we ensure that a resolved autocompleteData.search() call
                 * always has the latest data.
                 */
                if (scope.searchOnly) {
                    if (scope.query.trim() === '') {
                        search();
                    }
                } else {
                    scope.activeSuggestionIndex = -1;
                    scope.originalQuery = scope.query;

                    if (angular.isString(scope.query) && scope.query.length) {
                        autocompleteData.search(scope.query).then(function (suggestions) {
                            // Only load suggestions if they are still relevant.
                            if (suggestions.query === scope.query) {
                                scope.suggestions = suggestions.data;
                                scope.numberOfSuggestions = suggestions.count;
                            }
                        });
                    } else {
                        scope.suggestions = [];
                        scope.numberOfSuggestions = 0;
                    }
                }
            };

            scope.navigateSuggestions = function (event) {
                // Cancel outstanding requests, we don't want suggestions to 'refresh' while navigating.
                switch (event.keyCode) {
                    // Arrow up
                    case 38:
                        // By default the up arrow puts the cursor at the beginning of the input, we don't want that!
                        event.preventDefault();

                        scope.activeSuggestionIndex = Math.max(scope.activeSuggestionIndex - 1, -1);

                        if (scope.activeSuggestionIndex === -1) {
                            scope.query = scope.originalQuery;
                        } else {
                            setSuggestedQuery();
                        }

                        break;

                    // Arrow down
                    case 40:
                        scope.activeSuggestionIndex = Math.min(
                            scope.activeSuggestionIndex + 1,
                            scope.numberOfSuggestions - 1
                        );

                        setSuggestedQuery();
                        break;

                    // Escape
                    case 27:
                        scope.query = scope.originalQuery;
                        removeSuggestions();
                        break;
                }
            };

            scope.goToDetail = function (uri) {
                scope.setQuery('');

                store.dispatch({
                    type: ACTIONS.FETCH_DETAIL,
                    payload: sharedConfig.API_ROOT + uri
                });
            };

            scope.setQuery = function (query) {
                scope.query = query;
            };

            scope.setFocus = function () {
                searchbox.focus();
            };

            scope.removeSuggestions = removeSuggestions;

            function search () {
                const searchType = scope.type || 'FETCH_SEARCH_RESULTS_BY_QUERY';

                if (scope.activeSuggestionIndex === -1) {
                    // Load the search results
                    let payload = scope.query;
                    if (angular.isObject(scope.payload)) {
                        payload = angular.merge({}, scope.payload, {
                            query: scope.query
                        });
                    }
                    store.dispatch({
                        type: ACTIONS[searchType],
                        payload: payload
                    });
                } else {
                    const activeSuggestion = autocompleteData.getSuggestionByIndex(
                        scope.suggestions,
                        scope.activeSuggestionIndex
                    );

                    scope.goToDetail(activeSuggestion.uri);
                }
            }

            function removeSuggestions (event) {
                if (angular.isDefined(event) && event.type === 'blur') {
                    /**
                     * Clicking a suggestion link, which is outside the search box, triggers the blur event on the
                     * search box. This delay is needed to make sure suggestions can be clicked before they are hidden
                     * by removeSuggestionFromScope.
                     */

                    $timeout(removeSuggestionFromScope, 200);
                } else {
                    removeSuggestionFromScope();
                }

                function removeSuggestionFromScope () {
                    scope.suggestions = [];
                    scope.numberOfSuggestions = 0;
                    scope.activeSuggestionIndex = -1;
                    scope.originalQuery = scope._display;
                }
            }

            function setSuggestedQuery () {
                scope.query = autocompleteData.getSuggestionByIndex(
                    scope.suggestions,
                    scope.activeSuggestionIndex
                )._display;
            }
        }
    }
})();
<commit_msg>Updated placeholder for search<commit_after>(function () {
    'use strict';

    angular
        .module('dpHeader')
        .directive('dpSearch', dpSearchDirective);

    dpSearchDirective.$inject = ['$timeout', 'autocompleteData', 'sharedConfig', 'store', 'ACTIONS'];

    function dpSearchDirective ($timeout, autocompleteData, sharedConfig, store, ACTIONS) {
        return {
            restrict: 'E',
            scope: {
                query: '@',
                placeholder: '@',
                type: '@',
                payload: '<',
                searchOnly: '<'
            },
            templateUrl: 'modules/header/components/search/search.html',
            link: linkFunction
        };

        function linkFunction (scope, element) {
            var searchbox = element[0].querySelector('.js-search-input');

            scope.activeSuggestionIndex = -1;
            scope.originalQuery = scope.query;
            scope.placeholder = scope.placeholder || 'Zoek data op adres, ' +
                'postcode, kadastrale aanduiding, etc. Of datasets op trefwoord.';

            scope.formSubmit = function (event) {
                event.preventDefault();

                search();

                removeSuggestions();
            };

            scope.clear = function () {
                scope.query = '';
                scope.getSuggestions();
                scope.setFocus();
            };

            scope.getSuggestions = function () {
                /**
                 * Cancel the last request (if any), this way we ensure that a resolved autocompleteData.search() call
                 * always has the latest data.
                 */
                if (scope.searchOnly) {
                    if (scope.query.trim() === '') {
                        search();
                    }
                } else {
                    scope.activeSuggestionIndex = -1;
                    scope.originalQuery = scope.query;

                    if (angular.isString(scope.query) && scope.query.length) {
                        autocompleteData.search(scope.query).then(function (suggestions) {
                            // Only load suggestions if they are still relevant.
                            if (suggestions.query === scope.query) {
                                scope.suggestions = suggestions.data;
                                scope.numberOfSuggestions = suggestions.count;
                            }
                        });
                    } else {
                        scope.suggestions = [];
                        scope.numberOfSuggestions = 0;
                    }
                }
            };

            scope.navigateSuggestions = function (event) {
                // Cancel outstanding requests, we don't want suggestions to 'refresh' while navigating.
                switch (event.keyCode) {
                    // Arrow up
                    case 38:
                        // By default the up arrow puts the cursor at the beginning of the input, we don't want that!
                        event.preventDefault();

                        scope.activeSuggestionIndex = Math.max(scope.activeSuggestionIndex - 1, -1);

                        if (scope.activeSuggestionIndex === -1) {
                            scope.query = scope.originalQuery;
                        } else {
                            setSuggestedQuery();
                        }

                        break;

                    // Arrow down
                    case 40:
                        scope.activeSuggestionIndex = Math.min(
                            scope.activeSuggestionIndex + 1,
                            scope.numberOfSuggestions - 1
                        );

                        setSuggestedQuery();
                        break;

                    // Escape
                    case 27:
                        scope.query = scope.originalQuery;
                        removeSuggestions();
                        break;
                }
            };

            scope.goToDetail = function (uri) {
                scope.setQuery('');

                store.dispatch({
                    type: ACTIONS.FETCH_DETAIL,
                    payload: sharedConfig.API_ROOT + uri
                });
            };

            scope.setQuery = function (query) {
                scope.query = query;
            };

            scope.setFocus = function () {
                searchbox.focus();
            };

            scope.removeSuggestions = removeSuggestions;

            function search () {
                const searchType = scope.type || 'FETCH_SEARCH_RESULTS_BY_QUERY';

                if (scope.activeSuggestionIndex === -1) {
                    // Load the search results
                    let payload = scope.query;
                    if (angular.isObject(scope.payload)) {
                        payload = angular.merge({}, scope.payload, {
                            query: scope.query
                        });
                    }
                    store.dispatch({
                        type: ACTIONS[searchType],
                        payload: payload
                    });
                } else {
                    const activeSuggestion = autocompleteData.getSuggestionByIndex(
                        scope.suggestions,
                        scope.activeSuggestionIndex
                    );

                    scope.goToDetail(activeSuggestion.uri);
                }
            }

            function removeSuggestions (event) {
                if (angular.isDefined(event) && event.type === 'blur') {
                    /**
                     * Clicking a suggestion link, which is outside the search box, triggers the blur event on the
                     * search box. This delay is needed to make sure suggestions can be clicked before they are hidden
                     * by removeSuggestionFromScope.
                     */

                    $timeout(removeSuggestionFromScope, 200);
                } else {
                    removeSuggestionFromScope();
                }

                function removeSuggestionFromScope () {
                    scope.suggestions = [];
                    scope.numberOfSuggestions = 0;
                    scope.activeSuggestionIndex = -1;
                    scope.originalQuery = scope._display;
                }
            }

            function setSuggestedQuery () {
                scope.query = autocompleteData.getSuggestionByIndex(
                    scope.suggestions,
                    scope.activeSuggestionIndex
                )._display;
            }
        }
    }
})();
<|endoftext|>


<commit_before>/*
---

name: ViewController.Stack

description: Provides a way to navigate from view to view and comming back.

license: MIT-style license.

authors:
	- Jean-Philippe Dery (jeanphilippe.dery@gmail.com)

requires:
	- Core
	- Request.ViewController
	- ViewController

provides:
	- ViewController.Stack

...
*/

Moobile.ViewController.Stack = new Class({

	Extends: Moobile.ViewController,

	topViewController: null,

	viewControllers: [],

	viewControllerRequest: null,

	initialize: function(view) {
		this.parent(view);
		this.viewControllerRequest = new Moobile.Request.ViewController(this);
		this.view.hide();
		return this;
	},

	loadView: function(view) {
		this.view = view || new Moobile.View.Stack(new Element('div'));
	},

	startup: function() {
		return this.parent();
	},

	shutdown: function() {
		return this.parent();
	},

	attachEvents: function() {
		return this.parent();
	},

	detachEvents: function() {
		return this.parent();
	},

	pushViewControllerFrom: function(remote) {
		this.viewControllerRequest.cancel();
		this.viewControllerRequest.getViewController(remote);
		return this;
	},

	pushViewController: function(viewController, viewControllerTransition) {
		viewController.viewControllerStack = this;
		viewController.viewControllerPanel = this.viewControllerPanel;
		this.viewControllers.push(viewController);

		if (this.viewControllers.length == 1) {
			this.view.addChildView(viewController.view);
			viewController.doStartup();
			viewController.viewWillEnter();
			viewController.viewDidEnter();
		} else {

			this.window.disableUserInput();

			var transition = viewControllerTransition || viewController.getTransition();
			if (transition && typeOf(transition) == 'class') {
				transition = Class.instanciate(transition);
			}

			this.view.addChildView(viewController.view);
			viewController.setTransition(transition);
			viewController.doStartup();
			viewController.viewWillEnter();

			this.viewControllers.getLast(1).viewWillLeave();

			if (transition) {
				transition.startup(viewController, this);
				transition.chain(this.bound('onPushTransitionCompleted'));
				transition.prepare('enter');
				transition.execute('enter');
			} else {
				this.onPushTransitionCompleted();
			}
		}

		this.topViewController = viewController;

		return this;
	},

	onPushTransitionCompleted: function() {
		this.viewControllers.getLast()
			.viewDidEnter();
		this.viewControllers.getLast(1)
			.viewDidLeave();

		this.window.enableUserInput();

		return this;
	},

	popViewController: function() {
		if (this.viewControllers.length) {
			this.viewControllers.getLast(1).viewWillEnter();
			this.viewControllers.getLast(0).viewWillLeave();

			this.window.disableUserInput();

			var transition = this.viewControllers.getLast().getTransition();
			if (transition) {
				transition.chain(this.bound('onPopTransitionCompleted'));
				transition.prepare('leave');
				transition.execute('leave');
			} else {
				this.onPopTransitionCompleted();
			}

			this.topViewController = this.viewControllers.getLast(1);
		}
		return this;
	},

	onPopTransitionCompleted: function() {
		this.viewControllers.getLast(1)
			.viewDidEnter();
		this.viewControllers.getLast()
			.viewDidLeave();
		this.viewControllers.pop()
			.viewDidRemove()
			.doShutdown();

		this.window.enableUserInput();

		return this;
	},

	getViewControllers: function() {
		return this.viewControllers;
	},

	getViewControllerAt: function(offset) {
		return this.viewControllers.getLast(offset);
	},

	getTopViewController: function() {
		return this.topViewController;
	},

	orientationDidChange: function(orientation) {
		this.viewControllers.each(function(viewController) { viewController.orientationDidChange(orientation) });
		return this.parent();
	}

});<commit_msg>Removed unused methods in ViewController.Stack.<commit_after>/*
---

name: ViewController.Stack

description: Provides a way to navigate from view to view and comming back.

license: MIT-style license.

authors:
	- Jean-Philippe Dery (jeanphilippe.dery@gmail.com)

requires:
	- Core
	- Request.ViewController
	- ViewController

provides:
	- ViewController.Stack

...
*/

Moobile.ViewController.Stack = new Class({

	Extends: Moobile.ViewController,

	topViewController: null,

	viewControllers: [],

	viewControllerRequest: null,

	initialize: function(view) {
		this.parent(view);
		this.viewControllerRequest = new Moobile.Request.ViewController(this);
		this.view.hide();
		return this;
	},

	loadView: function(view) {
		this.view = view || new Moobile.View.Stack(new Element('div'));
	},

	pushViewControllerFrom: function(remote) {
		this.viewControllerRequest.cancel();
		this.viewControllerRequest.getViewController(remote);
		return this;
	},

	pushViewController: function(viewController, viewControllerTransition) {
		viewController.viewControllerStack = this;
		viewController.viewControllerPanel = this.viewControllerPanel;
		this.viewControllers.push(viewController);

		if (this.viewControllers.length == 1) {
			this.view.addChildView(viewController.view);
			viewController.doStartup();
			viewController.viewWillEnter();
			viewController.viewDidEnter();
		} else {

			this.window.disableUserInput();

			var transition = viewControllerTransition || viewController.getTransition();
			if (transition && typeOf(transition) == 'class') {
				transition = Class.instanciate(transition);
			}

			this.view.addChildView(viewController.view);
			viewController.setTransition(transition);
			viewController.doStartup();
			viewController.viewWillEnter();

			this.viewControllers.getLast(1).viewWillLeave();

			if (transition) {
				transition.startup(viewController, this);
				transition.chain(this.bound('onPushTransitionCompleted'));
				transition.prepare('enter');
				transition.execute('enter');
			} else {
				this.onPushTransitionCompleted();
			}
		}

		this.topViewController = viewController;

		return this;
	},

	onPushTransitionCompleted: function() {
		this.viewControllers.getLast()
			.viewDidEnter();
		this.viewControllers.getLast(1)
			.viewDidLeave();

		this.window.enableUserInput();

		return this;
	},

	popViewController: function() {
		if (this.viewControllers.length) {
			this.viewControllers.getLast(1).viewWillEnter();
			this.viewControllers.getLast(0).viewWillLeave();

			this.window.disableUserInput();

			var transition = this.viewControllers.getLast().getTransition();
			if (transition) {
				transition.chain(this.bound('onPopTransitionCompleted'));
				transition.prepare('leave');
				transition.execute('leave');
			} else {
				this.onPopTransitionCompleted();
			}

			this.topViewController = this.viewControllers.getLast(1);
		}
		return this;
	},

	onPopTransitionCompleted: function() {
		this.viewControllers.getLast(1)
			.viewDidEnter();
		this.viewControllers.getLast()
			.viewDidLeave();
		this.viewControllers.pop()
			.viewDidRemove()
			.doShutdown();

		this.window.enableUserInput();

		return this;
	},

	getViewControllers: function() {
		return this.viewControllers;
	},

	getViewControllerAt: function(offset) {
		return this.viewControllers.getLast(offset);
	},

	getTopViewController: function() {
		return this.topViewController;
	},

	orientationDidChange: function(orientation) {
		this.viewControllers.each(function(viewController) { viewController.orientationDidChange(orientation) });
		return this.parent();
	}

});<|endoftext|>