<commit_before>
function createConnectionElement(j) {
  var e = document.createElement("div");
  e.setAttribute("class", "connection");
  var auth = document.createElement("div");
  auth.appendChild(document.createTextNode("Connection: "+j.name));
  // authentication state
  if (j.authed) {
    auth.setAttribute("class", "authed");
    auth.appendChild(document.createTextNode("(authenticated)"));
  } else {
    auth.appendChild(document.createTextNode("(not authenticated)"));
  }
  e.appendChild(auth);

  // connection mode
  var mode = document.createElement("div");
  mode.setAttribute("class", "mode");
  mode.appendChild(document.createTextNode("mode: "+j.mode));
  e.appendChild(mode);
  var backlog = document.createElement("div");
  backlog.setAttribute("class", "backlog");
  backlog.appendChild(document.createTextNode("backlog: "+j.backlog));
  e.appendChild(backlog);
  var pending = document.createElement("div");
  pending.setAttribute("class", "pending");
  // pending articles
  var articles = Object.keys(j.pending);
  pending.appendChild(document.createTextNode("pending articles: "+articles.length));
  for ( var idx = 0 ; idx < articles.length; idx ++ ) {
    var msgid = articles[idx];
    var state = j.pending[msgid];
    var elem = document.createElement("div");
    elem.appendChild(document.createTextNode(msgid + ": " + state));
    elem.setAttribute("class", "pending_item "+state);
    pending.appendChild(elem);
  }
  e.appendChild(pending);
  // e.appendChild(document.createTextNode(JSON.stringify(j)));
  return e;
}

function inject_nntp_feed_element(feed, elem) {
  elem.appendChild(document.createElement("hr"));
  var name = document.createElement("div");
  name.setAttribute("class", "feeds_name");
  name_elem = document.createTextNode("Name: "+feed.State.Config.Name);
  name.appendChild(name_elem);
  elem.appendChild(name);
  var conns = document.createElement("div");
  conns.setAttribute("class", "connections");
  for ( var idx = 0 ; idx < feed.Conns.length; idx ++ ) {
    conns.appendChild(createConnectionElement(feed.Conns[idx]));
  }
  elem.appendChild(conns);
}

function update_nntpchan_feed_ticker(elem, result_elem) {
  nntpchan_admin("feed.list", null, function(j) {
    if (j) {
      if (j.error) {
        console.log("nntpchan_feed_ticker: error, "+j.error);
      } else {
        // remove all children
        while(elem.children.length) {
          elem.children[0].remove();
        }
        var result = j.result;
        for (var idx = 0; idx < result.length; idx++) {
          var item = result[idx];
          var entry = document.createElement("div");
          inject_nntp_feed_element(item, entry);
          elem.appendChild(entry);
        }
      }
    }
  }, result_elem);
}

function nntp_feed_add() {
  var param = {};

  var e = document.getElementById("add_feed_name");
  param.name = e.value;
  e = document.getElementById("add_feed_host");
  param.host = e.value;
  e = document.getElementById("add_feed_port");
  param.port = parseInt(e.value);

  e = document.getElementById("nntpchan_feed_result");
  nntpchan_admin("feed.add", param, null, e);
}

function nntp_feed_del() {
  var e = document.getElementById("del_feed_name");
  var name = e.value;
  e = document.getElementById("nntpchan_feed_result");
  nntpchan_admin("feed.del", {name: name}, null, e);
}

function nntp_feed_update() {
  var e = document.getElementById("nntpchan_feeds");
  if (e) {
    setInterval(function(){
      var e1 = document.getElementById("nntpchan_feed_result");
      update_nntpchan_feed_ticker(e, e1);
    }, 1000);
  }
}
<commit_msg>fix bug in feeds<commit_after>
function createConnectionElement(j) {
  var e = document.createElement("div");
  e.setAttribute("class", "connection");
  var auth = document.createElement("div");
  auth.appendChild(document.createTextNode("Connection: "+j.name));
  // authentication state
  if (j.authed) {
    auth.setAttribute("class", "authed");
    auth.appendChild(document.createTextNode("(authenticated)"));
  } else {
    auth.appendChild(document.createTextNode("(not authenticated)"));
  }
  e.appendChild(auth);

  // connection mode
  var mode = document.createElement("div");
  mode.setAttribute("class", "mode");
  mode.appendChild(document.createTextNode("mode: "+j.mode));
  e.appendChild(mode);
  var backlog = document.createElement("div");
  backlog.setAttribute("class", "backlog");
  backlog.appendChild(document.createTextNode("backlog: "+j.backlog));
  e.appendChild(backlog);
  var pending = document.createElement("div");
  pending.setAttribute("class", "pending");
  // pending articles
  var articles = Object.keys(j.pending);
  pending.appendChild(document.createTextNode("pending articles: "+articles.length));
  for ( var idx = 0 ; idx < articles.length; idx ++ ) {
    var msgid = articles[idx];
    var state = j.pending[msgid];
    var elem = document.createElement("div");
    elem.appendChild(document.createTextNode(msgid + ": " + state));
    elem.setAttribute("class", "pending_item "+state);
    pending.appendChild(elem);
  }
  e.appendChild(pending);
  // e.appendChild(document.createTextNode(JSON.stringify(j)));
  return e;
}

function inject_nntp_feed_element(feed, elem) {
  elem.appendChild(document.createElement("hr"));
  var name = document.createElement("div");
  name.setAttribute("class", "feeds_name");
  name_elem = document.createTextNode("Name: "+feed.State.Config.Name);
  name.appendChild(name_elem);
  elem.appendChild(name);
  var conns = document.createElement("div");
  conns.setAttribute("class", "connections");
  if (feed.Conns) {
    for ( var idx = 0 ; idx < feed.Conns.length; idx ++ ) {
      conns.appendChild(createConnectionElement(feed.Conns[idx]));
    }
  }
  elem.appendChild(conns);
}

function update_nntpchan_feed_ticker(elem, result_elem) {
  nntpchan_admin("feed.list", null, function(j) {
    if (j) {
      if (j.error) {
        console.log("nntpchan_feed_ticker: error, "+j.error);
      } else {
        // remove all children
        while(elem.children.length) {
          elem.children[0].remove();
        }
        var result = j.result;
        for (var idx = 0; idx < result.length; idx++) {
          var item = result[idx];
          var entry = document.createElement("div");
          inject_nntp_feed_element(item, entry);
          elem.appendChild(entry);
        }
      }
    }
  }, result_elem);
}

function nntp_feed_add() {
  var param = {};

  var e = document.getElementById("add_feed_name");
  param.name = e.value;
  e = document.getElementById("add_feed_host");
  param.host = e.value;
  e = document.getElementById("add_feed_port");
  param.port = parseInt(e.value);

  e = document.getElementById("nntpchan_feed_result");
  nntpchan_admin("feed.add", param, null, e);
}

function nntp_feed_del() {
  var e = document.getElementById("del_feed_name");
  var name = e.value;
  e = document.getElementById("nntpchan_feed_result");
  nntpchan_admin("feed.del", {name: name}, null, e);
}

function nntp_feed_update() {
  var e = document.getElementById("nntpchan_feeds");
  if (e) {
    setInterval(function(){
      var e1 = document.getElementById("nntpchan_feed_result");
      update_nntpchan_feed_ticker(e, e1);
    }, 1000);
  }
}
<|endoftext|>


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

  function performTests() {
    var sites = [{
        sitename: 'Google+',
        type: 'desktop',
        slow: {
          url: 'https://plus.google.com/people/find'
        },
        fast: {
          url: 'https://www.google.com/404!'
        },
        minimum_delta: 700
      },
      {
      sitename: 'Google+ (mobile)',
        type: 'mobile',
        slow: {
          url: 'https://plus.google.com/app/basic/people/find?sview=7'
        },
        fast: {
          url: 'https://www.google.com/404!'
        },
        minimum_delta: 500
      },
      {
        sitename: 'LinkedIn',
        type: 'desktop',
        slow: {
          url: 'https://www.linkedin.com/vsearch/f?type=all'
        },
        fast: {
          url: 'https://www.linkedin.com/404!'
        },
        minimum_delta: 900
      },
      {
        sitename: 'LinkedIn (mobile)',
        type: 'mobile',
        slow: {
          url: 'https://www.linkedin.com/vsearch/f?type=all'
        },
        fast: {
          url: 'https://www.linkedin.com/404!'
        },
        minimum_delta: 700
      },
      {
        sitename: 'Facebook',
        type: 'desktop',
        slow: {
          url: 'https://www.facebook.com/?sk=h_nor'
        },
        fast: {
          url: 'https://www.facebook.com/?sk=1'
        },
        minimum_delta: 600
      }, {
        sitename: 'Twitter (unreliable)',
        type: 'desktop',
        slow: {
          url: 'https://twitter.com/i/users/recommendations?limit=300'
        },
        fast: {
          url: 'https://twitter.com/404!'
        },
        minimum_delta: 300
      },
      {
        sitename: 'Wikipedia',
        type: 'desktop',
        slow: {
          url: 'https://en.wikipedia.org/wiki/Special:Watchlist'
        },
        fast: {
          url: 'https://en.wikipedia.org/w/404!'
        },
        minimum_delta: 600
      }
    ];
    var q = new SyncLoader(sites);
    q.loadSites(function reportSite(site) {
      var report = document.getElementById('report');
      if (!report) throw new Error('Reporting element "report" does not exist.');
      var html = '';
      var status =
        site.slow.loadtime - site.fast.loadtime > site.minimum_delta ?
        'logged in' : 'logged out';
      html += '
' + site.sitename + '	' + status + '	';
      html += '';
      html += link(site.slow.url) + ' (slow for logged in users) loaded in ' +
        site.slow.loadtime.toFixed(2) + 'ms.
';
      html += link(site.fast.url) + ' (fast for logged in users) loaded in ' +
        site.fast.loadtime.toFixed(2) + 'ms.
';
      html += 'We consider a user logged in if the difference between' +
        ' the two exceeds ' + site.minimum_delta + ' ms.';
      html += '
';
      report.innerHTML += html;
    });
  }

  function link(url) {
    return '' + url + '';
  }

  function SyncLoader(sites) {
    this.sites = sites;
    this.queue = [];
    this.busy = false;
    this.loadSite = function(site, callback) {
      if (!this.busy) {
        this.busy = true;
        var urlObj = site.slow.loadtime ? site.fast : site.slow;
        urlObj.start = performance.now();
        var ti = document.createElement('script');
        ti.type = 'text/javascript';
        var self = this;
        var finish = function() {
          urlObj.finish = performance.now();
          urlObj.loadtime = urlObj.finish - urlObj.start;
          self.busy = false;
          if (site.fast.loadtime) { // Done for this site, report
            callback(site);
            if (self.queue.length) {
              self.loadSite(self.queue.shift(), callback);
            }
          } else // Need to re-run to get second measurement
            self.loadSite(site, callback);
        };
        window.onerror = finish; // fires in Firefox
        ti.onerror = finish; // fires in Chrome
        ti.src = urlObj.url;
        document.body.appendChild(ti);

      } else // Queue up unless we're still on the same site
      if (this.queue.indexOf(site) === -1)
        this.queue.push(site);
    };
    this.loadSites = function(callback) {
      var self = this;
      this.sites.forEach(function(site) {
        if((!isMobile.any && site.type === 'desktop') || (isMobile.any && site.type === 'mobile'))
        self.loadSite(site, callback);
      });
    };
  }
  performTests();
})();
<commit_msg>clarify wp entry<commit_after>(function() {
  'use strict';

  function performTests() {
    var sites = [{
        sitename: 'Google+',
        type: 'desktop',
        slow: {
          url: 'https://plus.google.com/people/find'
        },
        fast: {
          url: 'https://www.google.com/404!'
        },
        minimum_delta: 700
      },
      {
      sitename: 'Google+ (mobile)',
        type: 'mobile',
        slow: {
          url: 'https://plus.google.com/app/basic/people/find?sview=7'
        },
        fast: {
          url: 'https://www.google.com/404!'
        },
        minimum_delta: 500
      },
      {
        sitename: 'LinkedIn',
        type: 'desktop',
        slow: {
          url: 'https://www.linkedin.com/vsearch/f?type=all'
        },
        fast: {
          url: 'https://www.linkedin.com/404!'
        },
        minimum_delta: 900
      },
      {
        sitename: 'LinkedIn (mobile)',
        type: 'mobile',
        slow: {
          url: 'https://www.linkedin.com/vsearch/f?type=all'
        },
        fast: {
          url: 'https://www.linkedin.com/404!'
        },
        minimum_delta: 700
      },
      {
        sitename: 'Facebook',
        type: 'desktop',
        slow: {
          url: 'https://www.facebook.com/?sk=h_nor'
        },
        fast: {
          url: 'https://www.facebook.com/?sk=1'
        },
        minimum_delta: 600
      }, {
        sitename: 'Twitter (unreliable)',
        type: 'desktop',
        slow: {
          url: 'https://twitter.com/i/users/recommendations?limit=300'
        },
        fast: {
          url: 'https://twitter.com/404!'
        },
        minimum_delta: 300
      },
      {
        sitename: 'Wikipedia (en)',
        type: 'desktop',
        slow: {
          url: 'https://en.wikipedia.org/wiki/Special:Watchlist'
        },
        fast: {
          url: 'https://en.wikipedia.org/w/404!'
        },
        minimum_delta: 600
      }
    ];
    var q = new SyncLoader(sites);
    q.loadSites(function reportSite(site) {
      var report = document.getElementById('report');
      if (!report) throw new Error('Reporting element "report" does not exist.');
      var html = '';
      var status =
        site.slow.loadtime - site.fast.loadtime > site.minimum_delta ?
        'logged in' : 'logged out';
      html += '
' + site.sitename + '	' + status + '	';
      html += '';
      html += link(site.slow.url) + ' (slow for logged in users) loaded in ' +
        site.slow.loadtime.toFixed(2) + 'ms.
';
      html += link(site.fast.url) + ' (fast for logged in users) loaded in ' +
        site.fast.loadtime.toFixed(2) + 'ms.
';
      html += 'We consider a user logged in if the difference between' +
        ' the two exceeds ' + site.minimum_delta + ' ms.';
      html += '
';
      report.innerHTML += html;
    });
  }

  function link(url) {
    return '' + url + '';
  }

  function SyncLoader(sites) {
    this.sites = sites;
    this.queue = [];
    this.busy = false;
    this.loadSite = function(site, callback) {
      if (!this.busy) {
        this.busy = true;
        var urlObj = site.slow.loadtime ? site.fast : site.slow;
        urlObj.start = performance.now();
        var ti = document.createElement('script');
        ti.type = 'text/javascript';
        var self = this;
        var finish = function() {
          urlObj.finish = performance.now();
          urlObj.loadtime = urlObj.finish - urlObj.start;
          self.busy = false;
          if (site.fast.loadtime) { // Done for this site, report
            callback(site);
            if (self.queue.length) {
              self.loadSite(self.queue.shift(), callback);
            }
          } else // Need to re-run to get second measurement
            self.loadSite(site, callback);
        };
        window.onerror = finish; // fires in Firefox
        ti.onerror = finish; // fires in Chrome
        ti.src = urlObj.url;
        document.body.appendChild(ti);

      } else // Queue up unless we're still on the same site
      if (this.queue.indexOf(site) === -1)
        this.queue.push(site);
    };
    this.loadSites = function(callback) {
      var self = this;
      this.sites.forEach(function(site) {
        if((!isMobile.any && site.type === 'desktop') || (isMobile.any && site.type === 'mobile'))
        self.loadSite(site, callback);
      });
    };
  }
  performTests();
})();
<|endoftext|>


<commit_before>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict';

const log = require("../net2/logger.js")(__filename);

const rclient = require('../util/redis_manager.js').getRedisClient()

const DNSMASQ = require('../extension/dnsmasq/dnsmasq.js');
const dnsmasq = new DNSMASQ();

const Block = require('./Block.js');

const DNSTool = require('../net2/DNSTool.js')
const dnsTool = new DNSTool()

const dns = require('dns');
const util = require('util');
const resolver = new dns.Resolver();
let resolve4Async;
let resolve6Async;
const fc = require('../net2/config.js');
const dc = require('../extension/dnscrypt/dnscrypt');

const SysManager = require("../net2/SysManager.js")
const sysManager = new SysManager()

const sem = require('../sensor/SensorEventManager.js').getInstance()
const DomainUpdater = require('./DomainUpdater.js');
const domainUpdater = new DomainUpdater();
const DomainIPTool = require('./DomainIPTool.js');
const domainIPTool = new DomainIPTool();
class DomainBlock {

  constructor() {
    sem.once('IPTABLES_READY', async () => {
      sem.on('UPDATE_CATEGORY_DEFAULT_DOMAIN', async (event) => {
        if (event.category) {
          const PM2 = require('../alarm/PolicyManager2.js');
          const pm2 = new PM2();
          const policies = await pm2.loadActivePoliciesAsync();
          for (const policy of policies) {
            if (policy.type == "category" && policy.target == event.category && policy.dnsmasq_entry) {
              await pm2.tryPolicyEnforcement(policy, 'reenforce', policy)
            }
          }
        }
      })
    })
  }

  // a mapping from domain to ip is tracked in redis, so that we can apply block at ip level, which is more secure
  async blockDomain(domain, options) {
    options = options || {}
    log.info(`Implementing Block on ${domain}`);

    if (options.dnsmasq_entry) {
      await dnsmasq.addPolicyFilterEntry([domain], options).catch((err) => undefined);
      sem.emitEvent({
        type: 'ReloadDNSRule',
        message: 'DNSMASQ filter rule is updated',
        toProcess: 'FireMain',
        suppressEventLogging: true
      })
      return;
    }

    await this.syncDomainIPMapping(domain, options)
    domainUpdater.registerUpdate(domain, options);
    if (!options.ignoreApplyBlock) {
      await this.applyBlock(domain, options);
    }

    // setTimeout(() => {
    //   this.incrementalUpdateIPMapping(domain, options)
    // }, 60 * 1000) // reinforce in 60 seconds
  }

  async unblockDomain(domain, options) {
    if (options.dnsmasq_entry) {
      await dnsmasq.removePolicyFilterEntry([domain], options).catch((err) => undefined);
      sem.emitEvent({
        type: 'ReloadDNSRule',
        message: 'DNSMASQ filter rule is updated',
        toProcess: 'FireMain',
        suppressEventLogging: true,
      })
      return
    }
    if (!options.ignoreUnapplyBlock) {
      await this.unapplyBlock(domain, options);
    }

    if (!this.externalMapping) {
      await domainIPTool.removeDomainIPMapping(domain, options);
    }

    domainUpdater.unregisterUpdate(domain, options);
  }

  async applyBlock(domain, options) {
    const blockSet = options.blockSet || "blocked_domain_set"
    const addresses = await domainIPTool.getMappedIPAddresses(domain, options);
    if (addresses) {
      for (const addr of addresses) {
        try {
          await Block.block(addr, blockSet)
        } catch (err) { }
      }
    }
  }

  async unapplyBlock(domain, options) {
    const blockSet = options.blockSet || "blocked_domain_set"

    const addresses = await domainIPTool.getMappedIPAddresses(domain, options);
    if (addresses) {
      for (const addr of addresses) {
        try {
          Block.unblock(addr, blockSet)
        } catch (err) { }
      }
    }
  }

  resolve4WithTimeout(domain, timeout) {
    let callbackCalled = false
    return new Promise((resolve, reject) => {
      resolve4Async(domain).then((addresses) => {
        if (!callbackCalled) {
          callbackCalled = true
          resolve(addresses)
        }
      }).catch((err) => {
        if (!callbackCalled) {
          callbackCalled = true
          resolve([]) // return empty array in case any error
        }
      })
      setTimeout(() => {
        if (!callbackCalled) {
          callbackCalled = true
          resolve([]) // return empty array in case timeout
        }
      }, timeout)
    })
  }

  resolve6WithTimeout(domain, timeout) {
    let callbackCalled = false

    return new Promise((resolve, reject) => {
      resolve6Async(domain).then((addresses) => {
        if (!callbackCalled) {
          callbackCalled = true
          resolve(addresses)
        }
      }).catch((err) => {
        if (!callbackCalled) {
          callbackCalled = true
          resolve([]) // return empty array in case any error
        }
      })
      setTimeout(() => {
        if (!callbackCalled) {
          log.warn("Timeout when query domain", domain)
          callbackCalled = true
          resolve([]) // return empty array in case timeout
        }
      }, timeout)
    })
  }

  async resolveDomain(domain) {
    if (fc.isFeatureOn('doh')) {
      const server = `127.0.0.1:${dc.getLocalPort()}`;
      resolver.setServers([server]);
      resolve4Async = util.promisify(resolver.resolve4.bind(resolver));
      resolve6Async = util.promisify(resolver.resolve6.bind(resolver));
    } else {
      resolve4Async = util.promisify(dns.resolve4);
      resolve6Async = util.promisify(dns.resolve6);
    }
    const v4Addresses = await this.resolve4WithTimeout(domain, 3 * 1000).catch((err) => []); // 3 seconds for timeout
    await dnsTool.addReverseDns(domain, v4Addresses);

    const gateway6 = sysManager.myGateway6()
    if (gateway6) { // only query if ipv6 is supported
      const v6Addresses = await this.resolve6WithTimeout(domain, 3 * 1000).catch((err) => []);
      await dnsTool.addReverseDns(domain, v6Addresses);
      return v4Addresses.concat(v6Addresses)
    } else {
      return v4Addresses
    }
  }

  async syncDomainIPMapping(domain, options) {
    options = options || {}

    const key = domainIPTool.getDomainIPMappingKey(domain, options)

    await this.resolveDomain(domain); // this will resolve domain via dns and add entries into reverse dns directly

    let list = []

    // load other addresses from rdns, critical to apply instant blocking
    const addresses = await dnsTool.getIPsByDomain(domain).catch((err) => []);
    list.push.apply(list, addresses)  // concat arrays

    if (!options.exactMatch) {
      const patternAddresses = await dnsTool.getIPsByDomainPattern(domain).catch((err) => []);
      list.push.apply(list, patternAddresses)
    }

    return rclient.saddAsync(key, list)
  }

  // incremental update mapping to reinforce ip blocking
  // this function should be executed in a serial way with other policy enforcements to avoid race conditions
  async incrementalUpdateIPMapping(domain, options) {
    options = options || {}

    log.info("Incrementally updating blocking list for", domain)

    const key = domainIPTool.getDomainIPMappingKey(domain, options)

    const existing = await rclient.existsAsync(key);

    if (!existing) {
      return
    }

    await this.resolveDomain(domain); // this will resolve domain via dns and add entries into reverse dns directly

    let set = {}

    // load other addresses from rdns, critical to apply instant blocking
    const addresses = await dnsTool.getIPsByDomain(domain).catch((err) => []);
    addresses.forEach((addr) => {
      set[addr] = 1
    })

    if (!options.exactMatch) {
      const patternAddresses = await dnsTool.getIPsByDomainPattern(domain).catch((err) => []);
      patternAddresses.forEach((addr) => {
        set[addr] = 1
      })
    }

    const existingAddresses = await domainIPTool.getMappedIPAddresses(domain, options);

    let existingSet = {}
    existingAddresses.forEach((addr) => {
      existingSet[addr] = 1
    })

    // only add new changed ip addresses, there is no need to remove any old ip addrs
    for (let addr in set) {
      if (!existingSet[addr]) {
        await rclient.saddAsync(key, addr);
        let blockSet = "blocked_domain_set";
        if (options.blockSet)
          blockSet = options.blockSet;
        await Block.block(addr, blockSet).catch((err) => undefined);
      }
    }
  }
  async blockCategory(category, options) {
    const domains = await this.getCategoryDomains(category);
    await dnsmasq.addPolicyCategoryFilterEntry(domains, options).catch((err) => undefined);
    sem.emitEvent({
      type: 'ReloadDNSRule',
      message: 'DNSMASQ filter rule is updated',
      toProcess: 'FireMain',
      suppressEventLogging: true
    })
  }

  async unblockCategory(category, options) {
    const domains = await this.getCategoryDomains(category);
    await dnsmasq.removePolicyCategoryFilterEntry(domains, options).catch((err) => undefined);
    sem.emitEvent({
      type: 'ReloadDNSRule',
      message: 'DNSMASQ filter rule is updated',
      toProcess: 'FireMain',
      suppressEventLogging: true,
    })
  }
  async updateCategoryBlock(category) {
    const domains = await this.getCategoryDomains(category);
    await dnsmasq.updatePolicyCategoryFilterEntry(domains, { category: category });
  }
  async getCategoryDomains(category) {
    const CategoryUpdater = require('./CategoryUpdater.js');
    const categoryUpdater = new CategoryUpdater();
    const domains = await categoryUpdater.getDomainsWithExpireTime(category);
    const excludedDomains = await categoryUpdater.getExcludedDomains(category);
    const defaultDomains = await categoryUpdater.getDefaultDomains(category);
    const includedDomains = await categoryUpdater.getIncludedDomains(category);
    const finalDomains = domains.filter((de) => {
      return !excludedDomains.includes(de.domain) && !defaultDomains.includes(de.domain)
    }).map((de) => { return de.domain }).concat(defaultDomains, includedDomains)

    function dedupAndPattern(arr) {
      const pattern = arr.filter((domain) => {
        return domain.startsWith("*.")
      }).map((domain) => domain.substring(2))
      return Array.from(new Set(arr.filter((domain) => {
        if (!domain.startsWith("*.") && pattern.includes(domain)) {
          return false;
        } else if (domain.startsWith("*.")) {
          return false;
        } else {
          return true;
        }
      }).concat(pattern)))
    }
    return dedupAndPattern(finalDomains)
  }
  patternDomain(domain) {
    domain = domain || "";
    if (domain.startsWith("*.")) {
      domain = domain.substring(2);
    }
    return domain;
  }
}

module.exports = () => new DomainBlock()
<commit_msg>comment out buggy setServers<commit_after>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict';

const log = require("../net2/logger.js")(__filename);

const rclient = require('../util/redis_manager.js').getRedisClient()

const DNSMASQ = require('../extension/dnsmasq/dnsmasq.js');
const dnsmasq = new DNSMASQ();

const Block = require('./Block.js');

const DNSTool = require('../net2/DNSTool.js')
const dnsTool = new DNSTool()

const dns = require('dns');
const util = require('util');
const resolver = new dns.Resolver();
let resolve4Async;
let resolve6Async;
const fc = require('../net2/config.js');
const dc = require('../extension/dnscrypt/dnscrypt');

const SysManager = require("../net2/SysManager.js")
const sysManager = new SysManager()

const sem = require('../sensor/SensorEventManager.js').getInstance()
const DomainUpdater = require('./DomainUpdater.js');
const domainUpdater = new DomainUpdater();
const DomainIPTool = require('./DomainIPTool.js');
const domainIPTool = new DomainIPTool();
class DomainBlock {

  constructor() {
    sem.once('IPTABLES_READY', async () => {
      sem.on('UPDATE_CATEGORY_DEFAULT_DOMAIN', async (event) => {
        if (event.category) {
          const PM2 = require('../alarm/PolicyManager2.js');
          const pm2 = new PM2();
          const policies = await pm2.loadActivePoliciesAsync();
          for (const policy of policies) {
            if (policy.type == "category" && policy.target == event.category && policy.dnsmasq_entry) {
              await pm2.tryPolicyEnforcement(policy, 'reenforce', policy)
            }
          }
        }
      })
    })
  }

  // a mapping from domain to ip is tracked in redis, so that we can apply block at ip level, which is more secure
  async blockDomain(domain, options) {
    options = options || {}
    log.info(`Implementing Block on ${domain}`);

    if (options.dnsmasq_entry) {
      await dnsmasq.addPolicyFilterEntry([domain], options).catch((err) => undefined);
      sem.emitEvent({
        type: 'ReloadDNSRule',
        message: 'DNSMASQ filter rule is updated',
        toProcess: 'FireMain',
        suppressEventLogging: true
      })
      return;
    }

    await this.syncDomainIPMapping(domain, options)
    domainUpdater.registerUpdate(domain, options);
    if (!options.ignoreApplyBlock) {
      await this.applyBlock(domain, options);
    }

    // setTimeout(() => {
    //   this.incrementalUpdateIPMapping(domain, options)
    // }, 60 * 1000) // reinforce in 60 seconds
  }

  async unblockDomain(domain, options) {
    if (options.dnsmasq_entry) {
      await dnsmasq.removePolicyFilterEntry([domain], options).catch((err) => undefined);
      sem.emitEvent({
        type: 'ReloadDNSRule',
        message: 'DNSMASQ filter rule is updated',
        toProcess: 'FireMain',
        suppressEventLogging: true,
      })
      return
    }
    if (!options.ignoreUnapplyBlock) {
      await this.unapplyBlock(domain, options);
    }

    if (!this.externalMapping) {
      await domainIPTool.removeDomainIPMapping(domain, options);
    }

    domainUpdater.unregisterUpdate(domain, options);
  }

  async applyBlock(domain, options) {
    const blockSet = options.blockSet || "blocked_domain_set"
    const addresses = await domainIPTool.getMappedIPAddresses(domain, options);
    if (addresses) {
      for (const addr of addresses) {
        try {
          await Block.block(addr, blockSet)
        } catch (err) { }
      }
    }
  }

  async unapplyBlock(domain, options) {
    const blockSet = options.blockSet || "blocked_domain_set"

    const addresses = await domainIPTool.getMappedIPAddresses(domain, options);
    if (addresses) {
      for (const addr of addresses) {
        try {
          Block.unblock(addr, blockSet)
        } catch (err) { }
      }
    }
  }

  resolve4WithTimeout(domain, timeout) {
    let callbackCalled = false
    return new Promise((resolve, reject) => {
      resolve4Async(domain).then((addresses) => {
        if (!callbackCalled) {
          callbackCalled = true
          resolve(addresses)
        }
      }).catch((err) => {
        if (!callbackCalled) {
          callbackCalled = true
          resolve([]) // return empty array in case any error
        }
      })
      setTimeout(() => {
        if (!callbackCalled) {
          callbackCalled = true
          resolve([]) // return empty array in case timeout
        }
      }, timeout)
    })
  }

  resolve6WithTimeout(domain, timeout) {
    let callbackCalled = false

    return new Promise((resolve, reject) => {
      resolve6Async(domain).then((addresses) => {
        if (!callbackCalled) {
          callbackCalled = true
          resolve(addresses)
        }
      }).catch((err) => {
        if (!callbackCalled) {
          callbackCalled = true
          resolve([]) // return empty array in case any error
        }
      })
      setTimeout(() => {
        if (!callbackCalled) {
          log.warn("Timeout when query domain", domain)
          callbackCalled = true
          resolve([]) // return empty array in case timeout
        }
      }, timeout)
    })
  }

  async resolveDomain(domain) {
    if (fc.isFeatureOn('doh')) {
      const server = `127.0.0.1:${dc.getLocalPort()}`;
 //     resolver.setServers([server]);
      resolve4Async = util.promisify(resolver.resolve4.bind(resolver));
      resolve6Async = util.promisify(resolver.resolve6.bind(resolver));
    } else {
      resolve4Async = util.promisify(dns.resolve4);
      resolve6Async = util.promisify(dns.resolve6);
    }
    const v4Addresses = await this.resolve4WithTimeout(domain, 3 * 1000).catch((err) => []); // 3 seconds for timeout
    await dnsTool.addReverseDns(domain, v4Addresses);

    const gateway6 = sysManager.myGateway6()
    if (gateway6) { // only query if ipv6 is supported
      const v6Addresses = await this.resolve6WithTimeout(domain, 3 * 1000).catch((err) => []);
      await dnsTool.addReverseDns(domain, v6Addresses);
      return v4Addresses.concat(v6Addresses)
    } else {
      return v4Addresses
    }
  }

  async syncDomainIPMapping(domain, options) {
    options = options || {}

    const key = domainIPTool.getDomainIPMappingKey(domain, options)

    await this.resolveDomain(domain); // this will resolve domain via dns and add entries into reverse dns directly

    let list = []

    // load other addresses from rdns, critical to apply instant blocking
    const addresses = await dnsTool.getIPsByDomain(domain).catch((err) => []);
    list.push.apply(list, addresses)  // concat arrays

    if (!options.exactMatch) {
      const patternAddresses = await dnsTool.getIPsByDomainPattern(domain).catch((err) => []);
      list.push.apply(list, patternAddresses)
    }

    return rclient.saddAsync(key, list)
  }

  // incremental update mapping to reinforce ip blocking
  // this function should be executed in a serial way with other policy enforcements to avoid race conditions
  async incrementalUpdateIPMapping(domain, options) {
    options = options || {}

    log.info("Incrementally updating blocking list for", domain)

    const key = domainIPTool.getDomainIPMappingKey(domain, options)

    const existing = await rclient.existsAsync(key);

    if (!existing) {
      return
    }

    await this.resolveDomain(domain); // this will resolve domain via dns and add entries into reverse dns directly

    let set = {}

    // load other addresses from rdns, critical to apply instant blocking
    const addresses = await dnsTool.getIPsByDomain(domain).catch((err) => []);
    addresses.forEach((addr) => {
      set[addr] = 1
    })

    if (!options.exactMatch) {
      const patternAddresses = await dnsTool.getIPsByDomainPattern(domain).catch((err) => []);
      patternAddresses.forEach((addr) => {
        set[addr] = 1
      })
    }

    const existingAddresses = await domainIPTool.getMappedIPAddresses(domain, options);

    let existingSet = {}
    existingAddresses.forEach((addr) => {
      existingSet[addr] = 1
    })

    // only add new changed ip addresses, there is no need to remove any old ip addrs
    for (let addr in set) {
      if (!existingSet[addr]) {
        await rclient.saddAsync(key, addr);
        let blockSet = "blocked_domain_set";
        if (options.blockSet)
          blockSet = options.blockSet;
        await Block.block(addr, blockSet).catch((err) => undefined);
      }
    }
  }
  async blockCategory(category, options) {
    const domains = await this.getCategoryDomains(category);
    await dnsmasq.addPolicyCategoryFilterEntry(domains, options).catch((err) => undefined);
    sem.emitEvent({
      type: 'ReloadDNSRule',
      message: 'DNSMASQ filter rule is updated',
      toProcess: 'FireMain',
      suppressEventLogging: true
    })
  }

  async unblockCategory(category, options) {
    const domains = await this.getCategoryDomains(category);
    await dnsmasq.removePolicyCategoryFilterEntry(domains, options).catch((err) => undefined);
    sem.emitEvent({
      type: 'ReloadDNSRule',
      message: 'DNSMASQ filter rule is updated',
      toProcess: 'FireMain',
      suppressEventLogging: true,
    })
  }
  async updateCategoryBlock(category) {
    const domains = await this.getCategoryDomains(category);
    await dnsmasq.updatePolicyCategoryFilterEntry(domains, { category: category });
  }
  async getCategoryDomains(category) {
    const CategoryUpdater = require('./CategoryUpdater.js');
    const categoryUpdater = new CategoryUpdater();
    const domains = await categoryUpdater.getDomainsWithExpireTime(category);
    const excludedDomains = await categoryUpdater.getExcludedDomains(category);
    const defaultDomains = await categoryUpdater.getDefaultDomains(category);
    const includedDomains = await categoryUpdater.getIncludedDomains(category);
    const finalDomains = domains.filter((de) => {
      return !excludedDomains.includes(de.domain) && !defaultDomains.includes(de.domain)
    }).map((de) => { return de.domain }).concat(defaultDomains, includedDomains)

    function dedupAndPattern(arr) {
      const pattern = arr.filter((domain) => {
        return domain.startsWith("*.")
      }).map((domain) => domain.substring(2))
      return Array.from(new Set(arr.filter((domain) => {
        if (!domain.startsWith("*.") && pattern.includes(domain)) {
          return false;
        } else if (domain.startsWith("*.")) {
          return false;
        } else {
          return true;
        }
      }).concat(pattern)))
    }
    return dedupAndPattern(finalDomains)
  }
  patternDomain(domain) {
    domain = domain || "";
    if (domain.startsWith("*.")) {
      domain = domain.substring(2);
    }
    return domain;
  }
}

module.exports = () => new DomainBlock()
<|endoftext|>


<commit_before>var wax = wax || {};
wax.tooltip = {};

wax.tooltip = function() {
    var _ct, // current tooltip
        popped = false,
        animate = false,
        t = {},
        parent;

    // Get the active tooltip for a layer or create a new one if no tooltip exists.
    // Hide any tooltips on layers underneath this one.
    function getTooltip(feature) {
        var tooltip = document.createElement('div');
        tooltip.className = 'wax-tooltip wax-tooltip-0';
        tooltip.innerHTML = feature;
        return tooltip;
    }

    // Hide a given tooltip.
    function hide() {
        if (!_ct) return;
        var event;

        function remove() {
            if (parentNode) parentNode.removeChild(this);
            _ct = null;
        }

        if (_ct.style['-webkit-transition'] !== undefined) {
            event = 'webkitTransitionEnd';
        } else if (_ct.style.MozTransition !== undefined) {
            event = 'transitionend';
        }

        if (animate && event) {
            // This code assumes that transform-supporting browsers
            // also support proper events. IE9 does both.
            bean.add(_ct, event, remove);
            _ct.className += ' ' + o.animationOut;
        } else {
            if (_ct.parentNode) _ct.parentNode.removeChild(_ct);
            _ct = null;
        }
    }

    function on(o) {
        var content;
        if ((o.e.type === 'mousemove' || !o.e.type) && !popped) {
            content = o.formatter({ format: 'teaser' }, o.data);
            if (!content) return;
            parent.style.cursor = 'pointer';
            _ct = parent.appendChild(getTooltip(content));
        } else {
            hide();
            content = o.formatter({ format: 'full' }, o.data);
            if (!content) return;
            _ct = parent.appendChild(getTooltip(content));
            _ct.className += ' wax-popup';

            var close = _ct.appendChild(document.createElement('a'));
            close.href = '#close';
            close.className = 'close';
            close.innerHTML = 'Close';
            popped = true;

            bean.add(close, 'click touchend', function closeClick(e) {
                e.stop();
                hide();
                popped = false;
            });
        }
    }

    function off() {
        parent.style.cursor = 'default';
        if (!popped && _ct) hide();
    }

    t.parent = function(x) {
        if (!arguments.length) return parent;
        parent = x;
        return t;
    };

    t.animate = function(x) {
        if (!arguments.lenght) return animate;
        animate = x;
        return t;
    };

    t.events = function() {
        return {
            on: on,
            off: off
        };
    };

    return t;
};
<commit_msg>Making tooltip eventing correct and faster<commit_after>var wax = wax || {};
wax.tooltip = {};

wax.tooltip = function() {
    var popped = false,
        animate = false,
        t = {},
        tooltips = [],
        parent;

    // Get the active tooltip for a layer or create a new one if no tooltip exists.
    // Hide any tooltips on layers underneath this one.
    function getTooltip(feature) {
        var tooltip = document.createElement('div');
        tooltip.className = 'wax-tooltip wax-tooltip-0';
        tooltip.innerHTML = feature;
        return tooltip;
    }

    // Hide a given tooltip.
    function hide() {
        var event;

        function remove() {
            if (this.parentNode) this.parentNode.removeChild(this);
        }

        if (document.body.style['-webkit-transition'] !== undefined) {
            event = 'webkitTransitionEnd';
        } else if (document.body.style.MozTransition !== undefined) {
            event = 'transitionend';
        }

        var _ct;
        while (_ct = tooltips.pop()) {
            if (animate && event) {
                // This code assumes that transform-supporting browsers
                // also support proper events. IE9 does both.
                  bean.add(_ct, event, remove);
                  _ct.className += ' wax-fade';
            } else {
                if (_ct.parentNode) _ct.parentNode.removeChild(_ct);
            }
        }
    }

    function on(o) {
        var content;
        hide();
        if ((o.e.type === 'mousemove' || !o.e.type) && !popped) {
            content = o.formatter({ format: 'teaser' }, o.data);
            if (!content) return;
            parent.style.cursor = 'pointer';
            tooltips.push(parent.appendChild(getTooltip(content)));
        } else {
            content = o.formatter({ format: 'full' }, o.data);
            if (!content) return;
            var tt = parent.appendChild(getTooltip(content));
            tt.className += ' wax-popup';

            var close = tt.appendChild(document.createElement('a'));
            close.href = '#close';
            close.className = 'close';
            close.innerHTML = 'Close';
            popped = true;

            tooltips.push(tt);

            bean.add(close, 'click touchend', function closeClick(e) {
                e.stop();
                hide();
                popped = false;
            });
        }
    }

    function off() {
        parent.style.cursor = 'default';
        if (!popped) hide();
    }

    t.parent = function(x) {
        if (!arguments.length) return parent;
        parent = x;
        return t;
    };

    t.animate = function(x) {
        if (!arguments.length) return animate;
        animate = x;
        return t;
    };

    t.events = function() {
        return {
            on: on,
            off: off
        };
    };

    return t;
};
<|endoftext|>


<commit_before>const child = require('child_process');

const forkCount =  parseInt(process.argv[2]);
const forkCalls =  parseInt(process.argv[3])
const intervalTime = parseInt(process.argv[4]);
const targetURI = 'www.google.com';

for (var i = 0 ; i < forkCount; i++){
	process.stdout.write(`Process: ${i} at work`);
	let childProcess = child.fork('get-request.js',[targetURI,forkCalls ,intervalTime]);

	childProcess.on('close', (code) => {`child process exited with code ${code}`})
}<commit_msg>Add tr.fuelx.com as the request uri<commit_after>const child = require('child_process');

const forkCount =  parseInt(process.argv[2]);
const forkCalls =  parseInt(process.argv[3])
const intervalTime = parseInt(process.argv[4]);
const targetURI = 'tr.fuelx.com';

for (var i = 0 ; i < forkCount; i++){
	process.stdout.write(`Process: ${i} at work`);
	let childProcess = child.fork('get-request.js',[targetURI,forkCalls ,intervalTime]);

	childProcess.on('close', (code) => {`child process exited with code ${code}`})
}<|endoftext|>


<commit_before>var phrases = ["Were you born in a barn?", "Get some work done", "Useless scrub", "Stop jacking off", "I'll bust your chops", "Are you born in a water park?", "Stop fapping around", "Are you born in a barn?", "Later, shizlord", "Oy!"];
var dialogs = ["WERE U BORN IN A BARN???", "GET SUM WERK DUN", "Useless scrub...", "Stop jacking off", "I'LL BUST YOUR CHOPS", "R U BORN IN A WATER PARK??", "Stop fapping around", "R U BORN IN A BARN???", "LATER, SHIZLORD", "OI!!"];

function androo(){
    var index = Math.round(Math.random()*(phrases.length-1));

    var ttsOptions = {
        lang: "en-US",
        gender: "male",
        rate: 0.7
    }

    chrome.tts.speak(phrases[index],ttsOptions);
    alert(dialogs[index]);

    setTimeout(androo,Math.random()*60*1000);
}

setTimeout(androo,20000);
<commit_msg>Update androo.js<commit_after>var phrases = ["Were you born in a barn?", "Get some work done", "Useless scrub", "Stop jacking off", "I'll bust your chops", "Are you born in a water park?", "Stop fapping around", "Are you born in a barn?", "Later, shizlord", "Oy!"];
var dialogs = ["WERE U BORN IN A BARN???", "GET SUM WERK DUN", "Useless scrub...", "Stop jacking off", "I'LL BUST YOUR CHOPS", "R U BORN IN A WATER PARK??", "Stop fapping around", "R U BORN IN A BARN???", "LATER, SHIZLORD", "OI!!"];

function androo(){
    var index = Math.round(Math.random()*(phrases.length-1));

    var ttsOptions = {
        gender: "male",
        rate: 0.7
    }

    chrome.tts.speak(phrases[index],ttsOptions);
    alert(dialogs[index]);

    setTimeout(androo,Math.random()*60*1000);
}

setTimeout(androo,20000);
<|endoftext|>


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

  // Inject the code from fn into the page, in an IIFE.
  function inject(fn) {
    var script = document.createElement('script');
    var parent = document.documentElement;
    script.textContent = '('+ fn +')();';
    parent.appendChild(script);
    parent.removeChild(script);
  }

  // Post a message whenever history.pushState is called. GitHub uses
  // pushState to implement page transitions without full page loads.
  // This needs to be injected because content scripts run in a sandbox.
  inject(function() {
    var pushState = history.pushState;
    history.pushState = function on_pushState() {
      window.postMessage('selfie:pageUpdated', '*');
      return pushState.apply(this, arguments);
    };
  });

  var allowedPaths = [
    // New issues
    /github.com\/[\w\-]+\/[\w\-]+\/issues\/new/,
    // Existing issues (comment)
    /github.com\/[\w\-]+\/[\w\-]+\/issues\/\d+/,
    // New pull request
    /github.com\/[\w\-]+\/[\w\-]+\/compare/,
    // Existing pull requests (comment)
    /github.com\/[\w\-]+\/[\w\-]+\/pull\/\d+/
  ];

  // Return true if predicate(item) returns true for any item in array.
  function any(array, predicate) {
    for (var i = 0; i < array.length; i++) {
      if (predicate(array[i])) {
        return true;
      }
    }
    return false;
  }

  function addSelfies() {
    if (!any(allowedPaths, (path) => path.test(window.location.href))) {
      // No selfies here!
      return;
    }
    new GitHubSelfies().setupSelfieStream();
  }

  // Add selfies when the extension is loaded into the page,
  // and whenever we push/pop new pages.
  window.addEventListener("message", function(event) {
    if (event.data === 'selfie:pageUpdated') {
      addSelfies();
    }
  });
  window.addEventListener("popstate", addSelfies);
  addSelfies();
})();
<commit_msg>Capture replaceState as well as pushState.<commit_after>(function() {
  "use strict";

  // Inject the code from fn into the page, in an IIFE.
  function inject(fn) {
    var script = document.createElement('script');
    var parent = document.documentElement;
    script.textContent = '('+ fn +')();';
    parent.appendChild(script);
    parent.removeChild(script);
  }

  // Post a message whenever history.pushState is called. GitHub uses
  // pushState to implement page transitions without full page loads.
  // This needs to be injected because content scripts run in a sandbox.
  inject(function() {
    var pushState = history.pushState;
    history.pushState = function on_pushState() {
      window.postMessage('selfie:pageUpdated', '*');
      return pushState.apply(this, arguments);
    };
    var replaceState = history.replaceState;
    history.replaceState = function on_replaceState() {
      window.postMessage('selfie:pageUpdated', '*');
      return replaceState.apply(this, arguments);
    };
  });

  var allowedPaths = [
    // New issues
    /github.com\/[\w\-]+\/[\w\-]+\/issues\/new/,
    // Existing issues (comment)
    /github.com\/[\w\-]+\/[\w\-]+\/issues\/\d+/,
    // New pull request
    /github.com\/[\w\-]+\/[\w\-]+\/compare/,
    // Existing pull requests (comment)
    /github.com\/[\w\-]+\/[\w\-]+\/pull\/\d+/
  ];

  // Return true if predicate(item) returns true for any item in array.
  function any(array, predicate) {
    for (var i = 0; i < array.length; i++) {
      if (predicate(array[i])) {
        return true;
      }
    }
    return false;
  }

  function addSelfies() {
    if (!any(allowedPaths, (path) => path.test(window.location.href))) {
      // No selfies here!
      return;
    }
    new GitHubSelfies().setupSelfieStream();
  }

  // Add selfies when the extension is loaded into the page,
  // and whenever we push/pop new pages.
  window.addEventListener("message", function(event) {
    if (event.data === 'selfie:pageUpdated') {
      addSelfies();
    }
  });
  window.addEventListener("popstate", addSelfies);
  addSelfies();
})();
<|endoftext|>


<commit_before>var db = require('../models');
exports.listar = function(request, reply){
  if (request.params.idEvento){
    db.Evento.findOne({_id: request.params.idEvento}, function(err, evento){
      if (err){
        reply({statusCode: 600, error: "Database", message:"Evento no encontrado"});
      } else if (evento){
        reply({statusCode:200,evento:evento});
      } else {
        reply({statusCode: 600, error: "Database", message:"Evento no encontrado"});
      }
    });
  } else {
    db.Evento.find(function(err, eventos){
      if (err){
        reply({statusCode: 600, error: "Database", message:"Evento no encontrado"});
      } else if (eventos){
        reply({statusCode:200,eventos:eventos});
      } else {
        reply({statusCode: 600, error: "Database", message:"Evento no encontrado"});
      }
    });
  }
};
exports.atletas = function(request, reply){
  db.AtletaEvento
  .populate("atleta evento")
  .find({evento: request.params.idEvento}, function(err, atletas){
    if (err){
      reply({statusCode: 600, error: "Database", message:"Equipo no encontrado"});
    } else if (atletas_eventos){
      reply({statusCode:200,atletas:atletas});
    } else {
      reply({statusCode: 600, error: "Database", message:"Equipo no encontrado"});
    }
  });
};
exports.create = function(request, reply){
  new db.Evento(request.payload).save(function(err, evento, numberAffected){
    if(err){
      return reply({statusCode: 600, error: "Database", message: "Error de Base de datos."});
    }
    return reply({statusCode: 200, _id: evento._id});
  });
}
exports.save = function(request, reply){
  var evento = request.payload;
  evento.modified = Date.now();
  db.Evento.update({_id:request.params.idEvento}, {$set: evento}, function(err, raw){
    if (err) {
      console.log("EVENTOS_SAVE err="+JSON.stringify(err));
      return reply({statusCode:600});
    }
    return reply({statusCode: 200});
  });
}
exports.delete = function(request, reply){
  db.Evento.remove({_id:request.params.idEvento}, function(err){
    if (err) {
      console.log("ATLETAS_DELETE err="+JSON.stringify(err));
      return reply({statusCode:600});
    }
    db.AtletaEvento.remove({evento:request.params.idEvento}, function(errAE){
      if (errAE) {
        console.log("ATLETA_EVENTOS_DELETE err="+JSON.stringify(errAE));
        return reply({statusCode:600});
      }
      return reply({statusCode: 200});
    });
  });
}
<commit_msg>Cambio en query mongoose<commit_after>var db = require('../models');
exports.listar = function(request, reply){
  if (request.params.idEvento){
    db.Evento.findOne({_id: request.params.idEvento}, function(err, evento){
      if (err){
        reply({statusCode: 600, error: "Database", message:"Evento no encontrado"});
      } else if (evento){
        reply({statusCode:200,evento:evento});
      } else {
        reply({statusCode: 600, error: "Database", message:"Evento no encontrado"});
      }
    });
  } else {
    db.Evento.find(function(err, eventos){
      if (err){
        reply({statusCode: 600, error: "Database", message:"Evento no encontrado"});
      } else if (eventos){
        reply({statusCode:200,eventos:eventos});
      } else {
        reply({statusCode: 600, error: "Database", message:"Evento no encontrado"});
      }
    });
  }
};
exports.atletas = function(request, reply){
  db.AtletaEvento
  .find({evento: request.params.idEvento})
  .populate("atleta evento")
  .exec(function(err, atletas){
    if (err){
      reply({statusCode: 600, error: "Database", message:"Equipo no encontrado"});
    } else if (atletas_eventos){
      reply({statusCode:200,atletas:atletas});
    } else {
      reply({statusCode: 600, error: "Database", message:"Equipo no encontrado"});
    }
  });
};
exports.create = function(request, reply){
  new db.Evento(request.payload).save(function(err, evento, numberAffected){
    if(err){
      return reply({statusCode: 600, error: "Database", message: "Error de Base de datos."});
    }
    return reply({statusCode: 200, _id: evento._id});
  });
}
exports.save = function(request, reply){
  var evento = request.payload;
  evento.modified = Date.now();
  db.Evento.update({_id:request.params.idEvento}, {$set: evento}, function(err, raw){
    if (err) {
      console.log("EVENTOS_SAVE err="+JSON.stringify(err));
      return reply({statusCode:600});
    }
    return reply({statusCode: 200});
  });
}
exports.delete = function(request, reply){
  db.Evento.remove({_id:request.params.idEvento}, function(err){
    if (err) {
      console.log("ATLETAS_DELETE err="+JSON.stringify(err));
      return reply({statusCode:600});
    }
    db.AtletaEvento.remove({evento:request.params.idEvento}, function(errAE){
      if (errAE) {
        console.log("ATLETA_EVENTOS_DELETE err="+JSON.stringify(errAE));
        return reply({statusCode:600});
      }
      return reply({statusCode: 200});
    });
  });
}
<|endoftext|>


<commit_before>;var CookiesCnilBanner;

(function(navigator, window, document){
	CookiesCnilBanner = function(launchFunction){
		if(!(this instanceof CookiesCnilBanner)){
	        return new CookiesCnilBanner(launchFunction);
		}

		this.cookieTimeout = 33696000000; // 13 months in milliseconds
		this.bots = /bot|googlebot|crawler|spider|robot|crawling/i;
		this.trackingCookiesNames = ["__utma","__utmb","__utmc","__utmt","__utmv","__utmz","_ga","_gat"];
		this.launchFunction = launchFunction;
		this.init();
	};

	CookiesCnilBanner.prototype = {
		init: function(){
			// Do nothing if it is a bot
			// If DoNotTrack is activated, do nothing too
			if(this.isBot() || !this.isToTrack() || this.hasConsent() === false){
				return false;
			}

			// User has already consent to use cookies to tracking
			if(this.hasConsent() === true){
				// Launch user custom function
				this.launchFunction();
				return true;
			}

			// If it's not a bot, no DoNotTrack and not already accept : show banner
			this.showBanner();

			// Accept cookies by default for the next page
			this.setCookie('hasConsent', true);
		},

		/*
		 * Show banner at the top of the page
		 */
		showBanner: function(){
			var _this = this,
				banner = document.getElementById("cookies-cnil-banner"),
				rejectButton = document.getElementById("cookies-cnil-reject")
				acceptButton = document.getElementById("cookies-cnil-accept")
				moreLink = document.getElementById("cookies-cnil-more");

			banner.style.display = "block";

			this.addEventListener(moreLink, "click", function(e){
				_this.deleteCookie('hasConsent');
			});

			this.addEventListener(acceptButton, "click", function(){
				banner.parentNode.removeChild(banner);
				_this.setCookie('hasConsent', true);
				_this.launchFunction();
			});

			this.addEventListener(rejectButton, "click", function(){
				banner.parentNode.removeChild(banner);
				_this.setCookie('hasConsent', false);
			});
		},

		/*
		 * Check if user already consent
		 */
		hasConsent: function(){
			if(document.cookie.indexOf("hasConsent=true") > -1){
				return true;
			} else if(document.cookie.indexOf("hasConsent=false") > -1){
				return false;
			}
			return undefined;
		},

		/*
		 * Detect if the visitor is a bot or not
		 * Prevent for search engine take the cookie
		 * alert message as main content of the page
		 */
		isBot: function(){
			return this.bots.test(navigator.userAgent);
		},

		/*
		 * Check if DoNotTrack is activated
		 */
	    isToTrack: function() {
	    	var dnt = navigator.doNotTrack || navigator.msDoNotTrack || window.doNotTrack;
	        return (dnt !== undefined) ? (dnt && dnt !== 'yes' && dnt !== 1 && dnt !== "1") : true;
	    },

	    /*
	     * Delete existants tracking cookies
	     */
	    deleteTrackingCookies: function(){
	    	var name;
	    	for(name in this.trackingCookiesNames){
	    		this.deleteCookie(name);
	    	}
	    },

	    /*
	     * Create/update cookie
	     */
	    setCookie: function(name, value){
		    var date = new Date();
		    date.setTime(date.getTime() + this.cookieTimeout);

	    	document.cookie = name + "=" + value + ";expires=" + date.toGMTString() + ";path=/";
	    },

	    /*
	     * Delete cookie by changing expire
	     */
	    deleteCookie: function(name){
	        var hostname = document.location.hostname;
	        if(hostname.indexOf("www.") === 0){
	            hostname = hostname.substring(4);
	        }
	        document.cookie = name + "=; domain=." + hostname + "; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/";
	        document.cookie = name + "=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/";
	    },

	    addEventListener: function(DOMElement, evnt, callback){
	    	if(document.addEventListener){ // For all major browsers, except IE 8 and earlier
			    DOMElement.addEventListener(evnt, callback);
			} else if(DOMElement.attachEvent){ // For IE 8 and earlier versions
			    DOMElement.attachEvent("on"+evnt, callback);
			}
	    }
	};

	/*
	 * Add CookieCnilBanner to jQuery.fn
	 */
	if(window.jQuery){
		jQuery.fn.cookieCnilBanner = function(launchFunction, prefixId){
			return new CookiesCnilBanner(launchFunction, prefixId);
		};
	}
})(navigator, window, document);<commit_msg>Remove incomplete jQuery support<commit_after>;var CookiesCnilBanner;

(function(navigator, window, document){
	CookiesCnilBanner = function(launchFunction){
		if(!(this instanceof CookiesCnilBanner)){
	        return new CookiesCnilBanner(launchFunction);
		}

		this.cookieTimeout = 33696000000; // 13 months in milliseconds
		this.bots = /bot|googlebot|crawler|spider|robot|crawling/i;
		this.trackingCookiesNames = ["__utma","__utmb","__utmc","__utmt","__utmv","__utmz","_ga","_gat"];
		this.launchFunction = launchFunction;
		this.init();
	};

	CookiesCnilBanner.prototype = {
		init: function(){
			// Do nothing if it is a bot
			// If DoNotTrack is activated, do nothing too
			if(this.isBot() || !this.isToTrack() || this.hasConsent() === false){
				return false;
			}

			// User has already consent to use cookies to tracking
			if(this.hasConsent() === true){
				// Launch user custom function
				this.launchFunction();
				return true;
			}

			// If it's not a bot, no DoNotTrack and not already accept : show banner
			this.showBanner();

			// Accept cookies by default for the next page
			this.setCookie('hasConsent', true);
		},

		/*
		 * Show banner at the top of the page
		 */
		showBanner: function(){
			var _this = this,
				banner = document.getElementById("cookies-cnil-banner"),
				rejectButton = document.getElementById("cookies-cnil-reject")
				acceptButton = document.getElementById("cookies-cnil-accept")
				moreLink = document.getElementById("cookies-cnil-more");

			banner.style.display = "block";

			this.addEventListener(moreLink, "click", function(e){
				_this.deleteCookie('hasConsent');
			});

			this.addEventListener(acceptButton, "click", function(){
				banner.parentNode.removeChild(banner);
				_this.setCookie('hasConsent', true);
				_this.launchFunction();
			});

			this.addEventListener(rejectButton, "click", function(){
				banner.parentNode.removeChild(banner);
				_this.setCookie('hasConsent', false);
			});
		},

		/*
		 * Check if user already consent
		 */
		hasConsent: function(){
			if(document.cookie.indexOf("hasConsent=true") > -1){
				return true;
			} else if(document.cookie.indexOf("hasConsent=false") > -1){
				return false;
			}
			return undefined;
		},

		/*
		 * Detect if the visitor is a bot or not
		 * Prevent for search engine take the cookie
		 * alert message as main content of the page
		 */
		isBot: function(){
			return this.bots.test(navigator.userAgent);
		},

		/*
		 * Check if DoNotTrack is activated
		 */
	    isToTrack: function() {
	    	var dnt = navigator.doNotTrack || navigator.msDoNotTrack || window.doNotTrack;
	        return (dnt !== undefined) ? (dnt && dnt !== 'yes' && dnt !== 1 && dnt !== "1") : true;
	    },

	    /*
	     * Delete existants tracking cookies
	     */
	    deleteTrackingCookies: function(){
	    	var name;
	    	for(name in this.trackingCookiesNames){
	    		this.deleteCookie(name);
	    	}
	    },

	    /*
	     * Create/update cookie
	     */
	    setCookie: function(name, value){
		    var date = new Date();
		    date.setTime(date.getTime() + this.cookieTimeout);

	    	document.cookie = name + "=" + value + ";expires=" + date.toGMTString() + ";path=/";
	    },

	    /*
	     * Delete cookie by changing expire
	     */
	    deleteCookie: function(name){
	        var hostname = document.location.hostname;
	        if(hostname.indexOf("www.") === 0){
	            hostname = hostname.substring(4);
	        }
	        document.cookie = name + "=; domain=." + hostname + "; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/";
	        document.cookie = name + "=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/";
	    },

	    addEventListener: function(DOMElement, evnt, callback){
	    	if(document.addEventListener){ // For all major browsers, except IE 8 and earlier
			    DOMElement.addEventListener(evnt, callback);
			} else if(DOMElement.attachEvent){ // For IE 8 and earlier versions
			    DOMElement.attachEvent("on"+evnt, callback);
			}
	    }
	};
})(navigator, window, document);<|endoftext|>


<commit_before>/*
 * patternlab-node - v1.2.0 - 2016
 *
 * Brian Muenzenmeyer, Geoffrey Pursell, and the web community.
 * Licensed under the MIT license.
 *
 * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.
 *
 */

"use strict";

var path = require('path');
var fs = require('fs-extra');
var of = require('./object_factory');

// PRIVATE FUNCTIONS

function addToPatternPaths(patternlab, bucketName, pattern) {
  //this is messy, could use a refactor.
  patternlab.patternPaths[bucketName][pattern.patternName] = pattern.subdir.replace(/\\/g, '/') + "/" + pattern.fileName;
}

//todo: refactor this as a method on the pattern object itself once we merge dev with pattern-engines branch
function isPatternExcluded(pattern) {
  // returns whether or not the first character of the pattern filename is an underscore, or excluded
  return pattern.fileName.charAt(0) === '_';
}

// Returns the array of patterns to be rendered in the styleguide view and
// linked to in the pattern navigation. Checks if patterns are excluded.
function assembleStyleguidePatterns(patternlab) {
  var styleguideExcludes = patternlab.config.styleGuideExcludes;
  var styleguidePatterns = [];

  if (styleguideExcludes && styleguideExcludes.length) {
    for (var i = 0; i < patternlab.patterns.length; i++) {

      // skip underscore-prefixed files
      if (isPatternExcluded(patternlab.patterns[i])) {
        if (patternlab.config.debug) {
          console.log('Omitting ' + patternlab.patterns[i].key + " from styleguide pattern exclusion.");
        }
        continue;
      }

      var key = patternlab.patterns[i].key;
      var typeKey = key.substring(0, key.indexOf('-'));
      var isExcluded = (styleguideExcludes.indexOf(typeKey) > -1);
      if (!isExcluded) {
        styleguidePatterns.push(patternlab.patterns[i]);
      }
    }
  } else {
    styleguidePatterns = patternlab.patterns;
  }

  return styleguidePatterns;
}

function buildNavigation(patternlab) {
  for (var i = 0; i < patternlab.patterns.length; i++) {

    var pattern = patternlab.patterns[i];
    var bucketName = pattern.name.replace(/\\/g, '-').split('-')[1];

    //check if the bucket already exists
    var bucketIndex = patternlab.bucketIndex.indexOf(bucketName);
    if (bucketIndex === -1) {

      // skip underscore-prefixed files. don't create a bucket on account of an underscored pattern
      if (isPatternExcluded(pattern)) {
        continue;
      }

      //add the bucket
      var bucket = new of.oBucket(bucketName);

      //add patternPath and viewAllPath
      patternlab.patternPaths[bucketName] = {};
      patternlab.viewAllPaths[bucketName] = {};

      //get the navItem
      var navItemName = pattern.subdir.split('/').pop();
      navItemName = navItemName.replace(/(\d).(-)/g, '');

      //get the navSubItem
      var navSubItemName = pattern.patternName.replace(/-/g, ' ');

      //test whether the pattern struture is flat or not - usually due to a template or page
      var flatPatternItem = false;
      if (navItemName === bucketName) {
        flatPatternItem = true;
      }

      //assume the navItem does not exist.
      var navItem = new of.oNavItem(navItemName);

      //assume the navSubItem does not exist.
      var navSubItem = new of.oNavSubItem(navSubItemName);
      navSubItem.patternPath = pattern.patternLink;
      navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name

      //add the patternState if it exists
      if (pattern.patternState) {
        navSubItem.patternState = pattern.patternState;
      }

      //if it is flat - we should not add the pattern to patternPaths
      if (flatPatternItem) {

        bucket.patternItems.push(navSubItem);

        //add to patternPaths
        addToPatternPaths(patternlab, bucketName, pattern);

      } else {

        bucket.navItems.push(navItem);
        bucket.navItemsIndex.push(navItemName);
        navItem.navSubItems.push(navSubItem);
        navItem.navSubItemsIndex.push(navSubItemName);

        //add to patternPaths
        addToPatternPaths(patternlab, bucketName, pattern);

        //add the navViewAllItem
        var navViewAllItem = new of.oNavSubItem("View All");
        navViewAllItem.patternPath = pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + "/index.html";
        navViewAllItem.patternPartial = "viewall-" + pattern.patternGroup;

        bucket.patternItems.push(navViewAllItem);
        patternlab.viewAllPaths[bucketName].viewall = pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length);

      }

      //add the bucket.
      patternlab.buckets.push(bucket);
      patternlab.bucketIndex.push(bucketName);

      //done

    } else {
      //find the bucket
      bucket = patternlab.buckets[bucketIndex];

      //get the navItem
      //if there is one or more slashes in the subdir, get everything after
      //the last slash. if no slash, get the whole subdir string and strip
      //any numeric + hyphen prefix
      navItemName = pattern.subdir.split('/').pop().replace(/^\d*\-/, '');

      //get the navSubItem
      navSubItemName = pattern.patternName.replace(/-/g, ' ');

      //assume the navSubItem does not exist.
      navSubItem = new of.oNavSubItem(navSubItemName);
      navSubItem.patternPath = pattern.patternLink;
      navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name

      //add the patternState if it exists
      if (pattern.patternState) {
        navSubItem.patternState = pattern.patternState;
      }

      //test whether the pattern struture is flat or not - usually due to a template or page
      flatPatternItem = false;
      if (navItemName === bucketName) {
        flatPatternItem = true;
      }

      //if it is flat - we should not add the pattern to patternPaths
      if (flatPatternItem) {

        // skip underscore-prefixed files
        if (isPatternExcluded(pattern)) {
          continue;
        }

        //add the navItem to patternItems
        bucket.patternItems.push(navSubItem);

        //add to patternPaths
        addToPatternPaths(patternlab, bucketName, pattern);

      } else {

        // only do this if pattern is included
        if (!isPatternExcluded(pattern)) {
          //check to see if navItem exists
          var navItemIndex = bucket.navItemsIndex.indexOf(navItemName);
          if (navItemIndex === -1) {
            navItem = new of.oNavItem(navItemName);

            //add the navItem and navSubItem
            navItem.navSubItems.push(navSubItem);
            navItem.navSubItemsIndex.push(navSubItemName);
            bucket.navItems.push(navItem);
            bucket.navItemsIndex.push(navItemName);

          } else {
            //add the navSubItem
            navItem = bucket.navItems[navItemIndex];
            navItem.navSubItems.push(navSubItem);
            navItem.navSubItemsIndex.push(navSubItemName);
          }
        }

        //check if we are moving to a new sub section in the next loop
        if (!patternlab.patterns[i + 1] || pattern.patternSubGroup !== patternlab.patterns[i + 1].patternSubGroup) {

          //add the navViewAllSubItem
          var navViewAllSubItem = new of.oNavSubItem("");
          navViewAllSubItem.patternName = "View All";
          navViewAllSubItem.patternPath = pattern.flatPatternPath + "/index.html";
          navViewAllSubItem.patternPartial = "viewall-" + pattern.patternGroup + "-" + pattern.patternSubGroup;

          navItem.navSubItems.push(navViewAllSubItem);
          navItem.navSubItemsIndex.push("View All");
        }

        // just add to patternPaths
        addToPatternPaths(patternlab, bucketName, pattern);
      }
    }

    patternlab.viewAllPaths[bucketName][pattern.patternSubGroup] = pattern.flatPatternPath;
  }
  return bucketIndex;
}

// MAIN BUILDER FUNCTION

function buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab) {
  var paths = patternlab.config.paths;
  var prevSubdir = '';
  var prevGroup = '';
  var i;

  for (i = 0; i < patternlab.patterns.length; i++) {
    // skip underscore-prefixed files
    if (isPatternExcluded(patternlab.patterns[i])) {
      if (patternlab.config.debug) {
        console.log('Omitting ' + patternlab.patterns[i].key + " from view all rendering.");
      }
      continue;
    }

    var pattern = patternlab.patterns[i];

    //create the view all for the section
    // check if the current section is different from the previous one
    if (pattern.patternGroup !== prevGroup) {
      prevGroup = pattern.patternGroup;

      var viewAllPatterns = [];
      var patternPartial = "viewall-" + pattern.patternGroup;
      var j;

      for (j = 0; j < patternlab.patterns.length; j++) {
        if (patternlab.patterns[j].patternGroup === pattern.patternGroup) {
          //again, skip any sibling patterns to the current one that may have underscores
          if (isPatternExcluded(patternlab.patterns[j])) {
            if (patternlab.config.debug) {
              console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering.");
            }
            continue;
          }

          viewAllPatterns.push(patternlab.patterns[j]);
        }
      }

      var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8');
      var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster });
      fs.outputFileSync(paths.public.patterns + pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + '/index.html', mainPageHead + viewAllHtml + mainPageFoot);
    }

    //create the view all for the subsection
    // check if the current sub section is different from the previous one
    if (pattern.subdir !== prevSubdir) {
      prevSubdir = pattern.subdir;

      viewAllPatterns = [];
      patternPartial = "viewall-" + pattern.patternGroup + "-" + pattern.patternSubGroup;

      for (j = 0; j < patternlab.patterns.length; j++) {
        if (patternlab.patterns[j].subdir === pattern.subdir) {
          //again, skip any sibling patterns to the current one that may have underscores
          if (isPatternExcluded(patternlab.patterns[j])) {
            if (patternlab.config.debug) {
              console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering.");
            }
            continue;
          }

          viewAllPatterns.push(patternlab.patterns[j]);
        }
      }

      var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8');
      var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster});
      fs.outputFileSync(paths.public.patterns + pattern.flatPatternPath + '/index.html', mainPageHeadHtml + viewAllHtml + mainPageFootHtml);
    }
  }
}

function buildFrontEnd(patternlab) {
  var pa = require('./pattern_assembler');
  var mh = require('./media_hunter');
  var pattern_assembler = new pa();
  var media_hunter = new mh();
  var styleguidePatterns = [];
  var paths = patternlab.config.paths;

  patternlab.buckets = [];
  patternlab.bucketIndex = [];
  patternlab.patternPaths = {};
  patternlab.viewAllPaths = {};

  //sort all patterns explicitly.
  patternlab.patterns = patternlab.patterns.sort(function (a, b) {
    if (a.name > b.name) {
      return 1;
    }
    if (a.name < b.name) {
      return -1;
    }

    // a must be equal to b
    return 0;
  });

  //find mediaQueries
  media_hunter.find_media_queries('./source/css', patternlab);

  // check if patterns are excluded, if not add them to styleguidePatterns
  styleguidePatterns = assembleStyleguidePatterns(patternlab);

  //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value
  patternlab.data.cacheBuster = patternlab.cacheBuster;

  //get the main page head and foot
  var mainPageHead = patternlab.userHead.extendedTemplate.replace('{% pattern-lab-head %}', patternlab.header);
  var mainPageHeadHtml = pattern_assembler.renderPattern(mainPageHead, patternlab.data);
  var mainPageFoot = patternlab.userFoot.extendedTemplate.replace('{% pattern-lab-foot %}', patternlab.footer);
  var mainPageFootHtml = pattern_assembler.renderPattern(mainPageFoot, patternlab.data);

  //build the styleguide
  var styleguideTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/styleguide.mustache'), 'utf8');
  var styleguideHtml = pattern_assembler.renderPattern(styleguideTemplate, {partials: styleguidePatterns, cacheBuster: patternlab.cacheBuster});

  fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), mainPageHeadHtml + styleguideHtml + mainPageFootHtml);

  //build the viewall pages
  buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab);

  //build the patternlab website
  var patternlabSiteTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/index.mustache'), 'utf8');

  //loop through all patterns.to build the navigation
  //todo: refactor this someday
  buildNavigation(patternlab);

  //the patternlab site requires a lot of partials to be rendered.
  //patternNav
  var patternNavTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/patternNav.mustache'), 'utf8');
  var patternNavPartialHtml = pattern_assembler.renderPattern(patternNavTemplate, patternlab);

  //ishControls
  var ishControlsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/ishControls.mustache'), 'utf8');
  patternlab.config.mqs = patternlab.mediaQueries;
  var ishControlsPartialHtml = pattern_assembler.renderPattern(ishControlsTemplate, patternlab.config);

  //patternPaths
  var patternPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/patternPaths.mustache'), 'utf8');
  var patternPathsPartialHtml = pattern_assembler.renderPattern(patternPathsTemplate, {'patternPaths': JSON.stringify(patternlab.patternPaths)});

  //viewAllPaths
  var viewAllPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/viewAllPaths.mustache'), 'utf8');
  var viewAllPathsPartialHtml = pattern_assembler.renderPattern(viewAllPathsTemplate, {'viewallpaths': JSON.stringify(patternlab.viewAllPaths)});

  //render the patternlab template, with all partials
  var patternlabSiteHtml = pattern_assembler.renderPattern(patternlabSiteTemplate, {
    defaultPattern: patternlab.config.defaultPattern || 'all',
    cacheBuster: patternlab.cacheBuster
  }, {
    'ishControls': ishControlsPartialHtml,
    'patternNav': patternNavPartialHtml,
    'patternPaths': patternPathsPartialHtml,
    'viewAllPaths': viewAllPathsPartialHtml
  });
  fs.outputFileSync(path.resolve(paths.public.root, 'index.html'), patternlabSiteHtml);
}

module.exports = buildFrontEnd;
<commit_msg>comment placement adjustment to not lie<commit_after>/*
 * patternlab-node - v1.2.0 - 2016
 *
 * Brian Muenzenmeyer, Geoffrey Pursell, and the web community.
 * Licensed under the MIT license.
 *
 * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.
 *
 */

"use strict";

var path = require('path');
var fs = require('fs-extra');
var of = require('./object_factory');

// PRIVATE FUNCTIONS

function addToPatternPaths(patternlab, bucketName, pattern) {
  //this is messy, could use a refactor.
  patternlab.patternPaths[bucketName][pattern.patternName] = pattern.subdir.replace(/\\/g, '/') + "/" + pattern.fileName;
}

//todo: refactor this as a method on the pattern object itself once we merge dev with pattern-engines branch
function isPatternExcluded(pattern) {
  // returns whether or not the first character of the pattern filename is an underscore, or excluded
  return pattern.fileName.charAt(0) === '_';
}

// Returns the array of patterns to be rendered in the styleguide view and
// linked to in the pattern navigation. Checks if patterns are excluded.
function assembleStyleguidePatterns(patternlab) {
  var styleguideExcludes = patternlab.config.styleGuideExcludes;
  var styleguidePatterns = [];

  if (styleguideExcludes && styleguideExcludes.length) {
    for (var i = 0; i < patternlab.patterns.length; i++) {

      // skip underscore-prefixed files
      if (isPatternExcluded(patternlab.patterns[i])) {
        if (patternlab.config.debug) {
          console.log('Omitting ' + patternlab.patterns[i].key + " from styleguide pattern exclusion.");
        }
        continue;
      }

      var key = patternlab.patterns[i].key;
      var typeKey = key.substring(0, key.indexOf('-'));
      var isExcluded = (styleguideExcludes.indexOf(typeKey) > -1);
      if (!isExcluded) {
        styleguidePatterns.push(patternlab.patterns[i]);
      }
    }
  } else {
    styleguidePatterns = patternlab.patterns;
  }

  return styleguidePatterns;
}

function buildNavigation(patternlab) {
  for (var i = 0; i < patternlab.patterns.length; i++) {

    var pattern = patternlab.patterns[i];
    var bucketName = pattern.name.replace(/\\/g, '-').split('-')[1];

    //check if the bucket already exists
    var bucketIndex = patternlab.bucketIndex.indexOf(bucketName);
    if (bucketIndex === -1) {

      // skip underscore-prefixed files. don't create a bucket on account of an underscored pattern
      if (isPatternExcluded(pattern)) {
        continue;
      }

      //add the bucket
      var bucket = new of.oBucket(bucketName);

      //add patternPath and viewAllPath
      patternlab.patternPaths[bucketName] = {};
      patternlab.viewAllPaths[bucketName] = {};

      //get the navItem
      var navItemName = pattern.subdir.split('/').pop();
      navItemName = navItemName.replace(/(\d).(-)/g, '');

      //get the navSubItem
      var navSubItemName = pattern.patternName.replace(/-/g, ' ');

      //test whether the pattern struture is flat or not - usually due to a template or page
      var flatPatternItem = false;
      if (navItemName === bucketName) {
        flatPatternItem = true;
      }

      //assume the navItem does not exist.
      var navItem = new of.oNavItem(navItemName);

      //assume the navSubItem does not exist.
      var navSubItem = new of.oNavSubItem(navSubItemName);
      navSubItem.patternPath = pattern.patternLink;
      navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name

      //add the patternState if it exists
      if (pattern.patternState) {
        navSubItem.patternState = pattern.patternState;
      }

      //if it is flat - we should not add the pattern to patternPaths
      if (flatPatternItem) {

        bucket.patternItems.push(navSubItem);

        //add to patternPaths
        addToPatternPaths(patternlab, bucketName, pattern);

      } else {

        bucket.navItems.push(navItem);
        bucket.navItemsIndex.push(navItemName);
        navItem.navSubItems.push(navSubItem);
        navItem.navSubItemsIndex.push(navSubItemName);

        //add to patternPaths
        addToPatternPaths(patternlab, bucketName, pattern);

        //add the navViewAllItem
        var navViewAllItem = new of.oNavSubItem("View All");
        navViewAllItem.patternPath = pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + "/index.html";
        navViewAllItem.patternPartial = "viewall-" + pattern.patternGroup;

        bucket.patternItems.push(navViewAllItem);
        patternlab.viewAllPaths[bucketName].viewall = pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length);

      }

      //add the bucket.
      patternlab.buckets.push(bucket);
      patternlab.bucketIndex.push(bucketName);

      //done

    } else {
      //find the bucket
      bucket = patternlab.buckets[bucketIndex];

      //get the navItem
      //if there is one or more slashes in the subdir, get everything after
      //the last slash. if no slash, get the whole subdir string and strip
      //any numeric + hyphen prefix
      navItemName = pattern.subdir.split('/').pop().replace(/^\d*\-/, '');

      //get the navSubItem
      navSubItemName = pattern.patternName.replace(/-/g, ' ');

      //assume the navSubItem does not exist.
      navSubItem = new of.oNavSubItem(navSubItemName);
      navSubItem.patternPath = pattern.patternLink;
      navSubItem.patternPartial = bucketName + "-" + pattern.patternName; //add the hyphenated name

      //add the patternState if it exists
      if (pattern.patternState) {
        navSubItem.patternState = pattern.patternState;
      }

      //test whether the pattern struture is flat or not - usually due to a template or page
      flatPatternItem = false;
      if (navItemName === bucketName) {
        flatPatternItem = true;
      }

      //if it is flat - we should not add the pattern to patternPaths
      if (flatPatternItem) {

        // skip underscore-prefixed files
        if (isPatternExcluded(pattern)) {
          continue;
        }

        //add the navItem to patternItems
        bucket.patternItems.push(navSubItem);

        //add to patternPaths
        addToPatternPaths(patternlab, bucketName, pattern);

      } else {

        // only do this if pattern is included
        if (!isPatternExcluded(pattern)) {
          //check to see if navItem exists
          var navItemIndex = bucket.navItemsIndex.indexOf(navItemName);
          if (navItemIndex === -1) {
            navItem = new of.oNavItem(navItemName);

            //add the navItem and navSubItem
            navItem.navSubItems.push(navSubItem);
            navItem.navSubItemsIndex.push(navSubItemName);
            bucket.navItems.push(navItem);
            bucket.navItemsIndex.push(navItemName);

          } else {
            //add the navSubItem
            navItem = bucket.navItems[navItemIndex];
            navItem.navSubItems.push(navSubItem);
            navItem.navSubItemsIndex.push(navSubItemName);
          }
        }

        //check if we are moving to a new sub section in the next loop
        if (!patternlab.patterns[i + 1] || pattern.patternSubGroup !== patternlab.patterns[i + 1].patternSubGroup) {

          //add the navViewAllSubItem
          var navViewAllSubItem = new of.oNavSubItem("");
          navViewAllSubItem.patternName = "View All";
          navViewAllSubItem.patternPath = pattern.flatPatternPath + "/index.html";
          navViewAllSubItem.patternPartial = "viewall-" + pattern.patternGroup + "-" + pattern.patternSubGroup;

          navItem.navSubItems.push(navViewAllSubItem);
          navItem.navSubItemsIndex.push("View All");
        }

        // just add to patternPaths
        addToPatternPaths(patternlab, bucketName, pattern);
      }
    }

    patternlab.viewAllPaths[bucketName][pattern.patternSubGroup] = pattern.flatPatternPath;
  }
  return bucketIndex;
}

function buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab) {
  var paths = patternlab.config.paths;
  var prevSubdir = '';
  var prevGroup = '';
  var i;

  for (i = 0; i < patternlab.patterns.length; i++) {
    // skip underscore-prefixed files
    if (isPatternExcluded(patternlab.patterns[i])) {
      if (patternlab.config.debug) {
        console.log('Omitting ' + patternlab.patterns[i].key + " from view all rendering.");
      }
      continue;
    }

    var pattern = patternlab.patterns[i];

    //create the view all for the section
    // check if the current section is different from the previous one
    if (pattern.patternGroup !== prevGroup) {
      prevGroup = pattern.patternGroup;

      var viewAllPatterns = [];
      var patternPartial = "viewall-" + pattern.patternGroup;
      var j;

      for (j = 0; j < patternlab.patterns.length; j++) {
        if (patternlab.patterns[j].patternGroup === pattern.patternGroup) {
          //again, skip any sibling patterns to the current one that may have underscores
          if (isPatternExcluded(patternlab.patterns[j])) {
            if (patternlab.config.debug) {
              console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering.");
            }
            continue;
          }

          viewAllPatterns.push(patternlab.patterns[j]);
        }
      }

      var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8');
      var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster });
      fs.outputFileSync(paths.public.patterns + pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length) + '/index.html', mainPageHead + viewAllHtml + mainPageFoot);
    }

    //create the view all for the subsection
    // check if the current sub section is different from the previous one
    if (pattern.subdir !== prevSubdir) {
      prevSubdir = pattern.subdir;

      viewAllPatterns = [];
      patternPartial = "viewall-" + pattern.patternGroup + "-" + pattern.patternSubGroup;

      for (j = 0; j < patternlab.patterns.length; j++) {
        if (patternlab.patterns[j].subdir === pattern.subdir) {
          //again, skip any sibling patterns to the current one that may have underscores
          if (isPatternExcluded(patternlab.patterns[j])) {
            if (patternlab.config.debug) {
              console.log('Omitting ' + patternlab.patterns[j].key + " from view all sibling rendering.");
            }
            continue;
          }

          viewAllPatterns.push(patternlab.patterns[j]);
        }
      }

      var viewAllTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/viewall.mustache'), 'utf8');
      var viewAllHtml = pattern_assembler.renderPattern(viewAllTemplate, {partials: viewAllPatterns, patternPartial: patternPartial, cacheBuster: patternlab.cacheBuster});
      fs.outputFileSync(paths.public.patterns + pattern.flatPatternPath + '/index.html', mainPageHeadHtml + viewAllHtml + mainPageFootHtml);
    }
  }
}

// MAIN BUILDER FUNCTION

function buildFrontEnd(patternlab) {
  var pa = require('./pattern_assembler');
  var mh = require('./media_hunter');
  var pattern_assembler = new pa();
  var media_hunter = new mh();
  var styleguidePatterns = [];
  var paths = patternlab.config.paths;

  patternlab.buckets = [];
  patternlab.bucketIndex = [];
  patternlab.patternPaths = {};
  patternlab.viewAllPaths = {};

  //sort all patterns explicitly.
  patternlab.patterns = patternlab.patterns.sort(function (a, b) {
    if (a.name > b.name) {
      return 1;
    }
    if (a.name < b.name) {
      return -1;
    }

    // a must be equal to b
    return 0;
  });

  //find mediaQueries
  media_hunter.find_media_queries('./source/css', patternlab);

  // check if patterns are excluded, if not add them to styleguidePatterns
  styleguidePatterns = assembleStyleguidePatterns(patternlab);

  //also add the cachebuster value. slight chance this could collide with a user that has defined cacheBuster as a value
  patternlab.data.cacheBuster = patternlab.cacheBuster;

  //get the main page head and foot
  var mainPageHead = patternlab.userHead.extendedTemplate.replace('{% pattern-lab-head %}', patternlab.header);
  var mainPageHeadHtml = pattern_assembler.renderPattern(mainPageHead, patternlab.data);
  var mainPageFoot = patternlab.userFoot.extendedTemplate.replace('{% pattern-lab-foot %}', patternlab.footer);
  var mainPageFootHtml = pattern_assembler.renderPattern(mainPageFoot, patternlab.data);

  //build the styleguide
  var styleguideTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/styleguide.mustache'), 'utf8');
  var styleguideHtml = pattern_assembler.renderPattern(styleguideTemplate, {partials: styleguidePatterns, cacheBuster: patternlab.cacheBuster});

  fs.outputFileSync(path.resolve(paths.public.styleguide, 'html/styleguide.html'), mainPageHeadHtml + styleguideHtml + mainPageFootHtml);

  //build the viewall pages
  buildViewAllPages(mainPageHead, mainPageFoot, mainPageHeadHtml, mainPageFootHtml, pattern_assembler, patternlab);

  //build the patternlab website
  var patternlabSiteTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/index.mustache'), 'utf8');

  //loop through all patterns.to build the navigation
  //todo: refactor this someday
  buildNavigation(patternlab);

  //the patternlab site requires a lot of partials to be rendered.
  //patternNav
  var patternNavTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/patternNav.mustache'), 'utf8');
  var patternNavPartialHtml = pattern_assembler.renderPattern(patternNavTemplate, patternlab);

  //ishControls
  var ishControlsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/ishControls.mustache'), 'utf8');
  patternlab.config.mqs = patternlab.mediaQueries;
  var ishControlsPartialHtml = pattern_assembler.renderPattern(ishControlsTemplate, patternlab.config);

  //patternPaths
  var patternPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/patternPaths.mustache'), 'utf8');
  var patternPathsPartialHtml = pattern_assembler.renderPattern(patternPathsTemplate, {'patternPaths': JSON.stringify(patternlab.patternPaths)});

  //viewAllPaths
  var viewAllPathsTemplate = fs.readFileSync(path.resolve(paths.source.patternlabFiles, 'templates/partials/viewAllPaths.mustache'), 'utf8');
  var viewAllPathsPartialHtml = pattern_assembler.renderPattern(viewAllPathsTemplate, {'viewallpaths': JSON.stringify(patternlab.viewAllPaths)});

  //render the patternlab template, with all partials
  var patternlabSiteHtml = pattern_assembler.renderPattern(patternlabSiteTemplate, {
    defaultPattern: patternlab.config.defaultPattern || 'all',
    cacheBuster: patternlab.cacheBuster
  }, {
    'ishControls': ishControlsPartialHtml,
    'patternNav': patternNavPartialHtml,
    'patternPaths': patternPathsPartialHtml,
    'viewAllPaths': viewAllPathsPartialHtml
  });
  fs.outputFileSync(path.resolve(paths.public.root, 'index.html'), patternlabSiteHtml);
}

module.exports = buildFrontEnd;
<|endoftext|>


<commit_before>function Proxy(queue, phantom, pollFunction) {

  this.queue = queue;
  this.phantom = phantom;
  this.pollFunction = pollFunction;
}

Proxy.prototype.createPage = function(cb) {
  var args = [0, 'createPage'];
  this.queue.push([args, makeSafeCallback(cb, this.pollFunction)]);
};

Proxy.prototype.injectJs = function(fileName, cb) {
  var args = [0, 'injectJs', fileName];
  this.queue.push([args, makeSafeCallback(cb, this.pollFunction)]);
};

Proxy.prototype.addCookie = function(cookie, cb) {
  var args = [0, 'addCookie', cookie];
  this.queue.push([args, makeSafeCallback(cb, this.pollFunction)]);
};

Proxy.prototype.clearCookies = function(cb) {
  var args = [0, 'clearCookies'];
  this.queue.push([args, makeSafeCallback(cb, this.pollFunction)]);
};

Proxy.prototype.deleteCookie = function(cookie, cb) {
  var args = [0, 'deleteCookie', cookie];
  this.queue.push([args, makeSafeCallback(cb, this.pollFunction)]);
};

Proxy.prototype.set = function(prop, val, cb) {
  var args = [0, 'setProperty', prop, val];
  this.queue.push([args, makeSafeCallback(cb, this.pollFunction)]);
};

Proxy.prototype.get = function(prop, cb) {
  var args = [0, 'getProperty', property];
  this.queue.push([args, makeSafeCallback(cb, this.pollFunction)]);
};

Proxy.prototype.exit = function(cb) {
  this.phantom.kill('SIGTERM');
  makeSafeCallback(cb)();
};

Proxy.prototype.on = function() {
  this.phantom.on.apply(this.phaneom, arguments);
};

module.exports = Proxy;
<commit_msg>Better proxy code<commit_after>/*
 * Proxy class
 */

// Methods to build into the prototype
// They map our method names to the remote method names
var methods = {
  'injectJs' : 'injectJs',
  'createPage': 'createPage',
  'addCookie': 'addCookie',
  'clearCookies': 'clearCookies',
  'deleteCookie': 'deleteCookie',
  'set': 'setProperty',
  'get': 'getProperty'
};

function Proxy(queue, phantom, pollFunction) {
  this.queue = queue;
  this.phantom = phantom;
  this.pollFunction = pollFunction;
}

function makeMethod(name) {
  return function() {
    var args = Array.prototype.slice.call(arguments);

    // Arguments to pass into the queue
    var qArgs = [0, name];

    // Append everything but the last argument (which is the callback)
    qArgs = qArgs.concat(args.slice(0, -1));

    // The callback is the last argument
    var cb = args.slice(-1);

    // Push call into the queue
    this.queue.push([qArgs, makeSafeCallback(cb, this.pollFunction)]);
  };
}

// Build prototype methods
for (key in methods) {
  Proxy.prototype[key] = makeMethod(methods[key]);
}

Proxy.prototype.exit = function(cb) {
  /* Kill the phantom process. */
  this.phantom.kill('SIGTERM');
  makeSafeCallback(cb)();
};

Proxy.prototype.on = function() {
  /* Pass down to phantom process. */
  this.phantom.on.apply(this.phantom, arguments);
};

module.exports = Proxy;
<|endoftext|>