<commit_before>/*=====
// this file is in place as a quick way to give summaries to all available dojox projects.

dojox = {
	// summary:
	//	DojoX: the home for Dojo eXtensions
	//
	// description:
	//	DojoX is a collection of subprojects provided by Dojo committers and subject to
	//	the generous licensing and policies of the [Dojo CLA](http://dojotoolkit.org/cla)
	//	Each subproject in DojoX has its own top-level directory and a README file with
	//	status information and project status and a stability rating (experimental, beta, stable)
	//
	//	Projects may or may not depend on other top-level Dojo projects, like Dojo or Dijit.
	//	Unlike Dojo and Dijit, code is not subject to i18n and a11y restrictions and may vary
	//	in quality (experimental code is encouraged in DojoX, but currently prohibited in Dojo
	//	and Dijit)
	//
	//	DojoX projects may mature to a stable state and stay in DojoX, or on occasion
	//	after proving themselves may migrate to Dojo Core or Dijit.  Dojo and Dijit projects
	//	are constrained both by development resources as well as design goals, so DojoX is
	//	a natural place to provide enhanced behavior or extend Dojo Core or Dijit primitives.
	//	DojoX can also be an incubator for entirely new projects.
}

dojox.analytics = {
	// summary: TODOC
};

dojox.atom = {
	// summary: TODOC
};

dojox.av = {
	// summary: TODOC
};

dojox.charting = {
	// summary: Vector graphic, data-driven graphs and charts
};

dojox.collections = {
	// summary: A set of lists and hashes for easy use within your applications.
};

dojox.color = {
	// summary: Advanced color methods, including HSV, HSL, and CMYK conversion, a color generator and advanced colorspace calculations.
};

dojox.cometd = {
	// summary: A cometd client written in Dojo
};

dojox.data = {
	// summary: Additional dojo.data data stores and demos
};

dojox.date = {
	// summary: Additional date manipulation functions
};

dojox.drawing = {
	// summary: A vector drawing program
};

dojox.dtl = {
	// summary: Django Templating Language implementation
};

dojox.editor = {
	// summary: Extensions for dijit.Editor
};

dojox.encoding = {
	// summary: Various encoding algorithms, including crypto and digests.
};

dojox.flash = {
	// summary: Utilities to embed and communicate with Flash-based objects
};

dojox.form = {
	// summary: Form-related widgets
};

dojox.fx = {
	// summary: Extension animations to the core dojo FX project
	//
	// description:
	//	A package of animations, and FX-related code, extending Dojo Core fx.
	//	Including this package includes all the Base and Core fx packages.
	//

	style: { // summary: Module to provide CSS animations
	},

	scroll: { // summary: Module to provide scroll-related FX
	}
};
dojox.fx["ext-dojo"] = {
	// summary: Direct extensions to dojo.fx namespace
	NodeList: {
		// summary: module to include to support dojox.fx animations in dojo.query()
	}
};

dojox.gfx = {
	// summary: Cross-browser vector graphics API
	// description:
	//
	//	dojox.gfx is an advanced API providing normalized vector drawing
	//	in a variety of browsers. It has individual renderers for SVG, VML,
	//	Canvas, and Silverlight.
};

dojox.gfx3d = {
	// summary: A 3d API for dojox.gfx
};

dojox.grid = {
	// summary: An advanced Grid widget with virtual scrolling, cell editing, and much more
};

dojox.help = {
	// summary: TODOC
};

dojox.highlight = {
	// summary: A client-side syntax highlighting engine.
	// description:
	//	This project parses pre > code nodes, and applies syntax highlighting for
	//	a wide variety of languages. Simply dojo.require() in all the
	//	dojox.highlight.languages you wish to include in your highlighingting,
	//	and customize colors in the highlight.css.
	//
	//	It is provided as a dojo package, contributed under CLA
	//	by Ivan Sagalaev and is available originally from:
	// 	http://softwaremaniacs.org/soft/highlight/en/
	//
};

dojox.html = {
	// summary: TODOC
};

dojox.image = {
	// summary: A collection of image related widgets
};

dojox.io = {
	// summary: Extensions to the Core dojo.io transports
};

dojox.jq = {
	// summary: A JQuery compatibility layer
};

dojox.jsonPath = {
	// summary: A query system for JavaScript objects
};

dojox.lang = {
	// summary: Language specific extensions
	functional: {
		// summary: Functional language constructs, including currying and lambda.
	}
};

dojox.layout = {
	// summary: A collection of layout related Widgets
};

dojox.math = {
	// summary: A collection of various advanced math functions.
};

dojox.robot = {
	// summary: TODOC
};

dojox.rpc = {
	// summary: TODOC
};

dojox.secure = {
	// summary: TODOC
};

dojox.sketch = {
	// summary: TODOC
};

dojox.sql = {
	// summary: objects to support Dojo Offline (dojox.off)  DEPRECATED
};

dojox.storage = {
	// summary: Objects for mass storage within the browser.  For when cookies just aren't enough.
};

dojox.string = {
	// summary: A collection of various objects for advanced string manipulation, including a Builder and a tokenizer.
};

dojox.testing = {
	// summary: TODOC
};

dojox.timing = {
	// summary: A set of objects to perform advanced time-based tasks, including a basic Timer.
};

dojox.uuid = {
	// summary: Universally Unique Identifier (UUID) implementations, including an implementation of UUID 2
};

dojox.validate = {
	// summary: Additional input validation methods
	ca : {
		// summary: Methods specific to the Canadian provinces
	},
	creditCard : {
		// summary: Validate various credit card types
	}
};

dojox.widget = {
	// summary: A collection of un-categorized widgets, or code not requiring its own package.
	//
	// description:
	// 	These are standalone widgets with varying levels of stability. Some are useful,
	//	some were created for demonstration purposes, and learning tools. The each maintain
	//	their own .css file (typically dojox/widget/WidgetName/WidgetName.css)
};

dojox.wire = {
	// summary:
	//	Declarative data binding and action tags for simplified MVC
};

dojox.xml = {
	// summary: XML utilities.  Currently only includes a DomParser, which returns a psuedo-XML document in JSON-like form.
};

dojox.xmpp = {
	// summary: TODOC
};
=====*/
<commit_msg>more dojox summaries<commit_after>/*=====
// this file is in place as a quick way to give summaries to all available dojox projects.

dojox = {
	// summary:
	//	DojoX: the home for Dojo eXtensions
	//
	// description:
	//	DojoX is a collection of subprojects provided by Dojo committers and subject to
	//	the generous licensing and policies of the [Dojo CLA](http://dojotoolkit.org/cla)
	//	Each subproject in DojoX has its own top-level directory and a README file with
	//	status information and project status and a stability rating (experimental, beta, stable)
	//
	//	Projects may or may not depend on other top-level Dojo projects, like Dojo or Dijit.
	//	Unlike Dojo and Dijit, code is not subject to i18n and a11y restrictions and may vary
	//	in quality (experimental code is encouraged in DojoX, but currently prohibited in Dojo
	//	and Dijit)
	//
	//	DojoX projects may mature to a stable state and stay in DojoX, or on occasion
	//	after proving themselves may migrate to Dojo Core or Dijit.  Dojo and Dijit projects
	//	are constrained both by development resources as well as design goals, so DojoX is
	//	a natural place to provide enhanced behavior or extend Dojo Core or Dijit primitives.
	//	DojoX can also be an incubator for entirely new projects.
}

dojox.analytics = {
	// summary: Website analytics and client monitoring system
};

dojox.atom = {
	// summary: Implements the Atom Syndication Format and Atom Publishing Protocol
};

dojox.av = {
	// summary: Provides Audio/Video capabilities
};

dojox.charting = {
	// summary: Vector graphic, data-driven graphs and charts
};

dojox.collections = {
	// summary: A set of lists and hashes for easy use within your applications.
};

dojox.color = {
	// summary: Advanced color methods, including HSV, HSL, and CMYK conversion, a color generator and advanced colorspace calculations.
};

dojox.cometd = {
	// summary: A cometd client written in Dojo
};

dojox.data = {
	// summary: Additional dojo.data data stores and demos
};

dojox.date = {
	// summary: Additional date manipulation functions
};

dojox.drawing = {
	// summary: A vector drawing program
};

dojox.dtl = {
	// summary: Django Templating Language implementation
};

dojox.editor = {
	// summary: Extensions for dijit.Editor
};

dojox.embed = {
	// summary: Base code for embedding for external objects like Flash, Quicktime
};

dojox.encoding = {
	// summary: Various encoding algorithms, including crypto and digests.
};

dojox.flash = {
	// summary: Utilities to embed and communicate with Flash-based objects
};

dojox.form = {
	// summary: Form-related widgets
};

dojox.fx = {
	// summary: Extension animations to the core dojo FX project
	//
	// description:
	//	A package of animations, and FX-related code, extending Dojo Core fx.
	//	Including this package includes all the Base and Core fx packages.
	//

	style: { // summary: Module to provide CSS animations
	},

	scroll: { // summary: Module to provide scroll-related FX
	}
};
dojox.fx["ext-dojo"] = {
	// summary: Direct extensions to dojo.fx namespace
	NodeList: {
		// summary: module to include to support dojox.fx animations in dojo.query()
	}
};

dojox.gfx = {
	// summary: Cross-browser vector graphics API
	// description:
	//
	//	dojox.gfx is an advanced API providing normalized vector drawing
	//	in a variety of browsers. It has individual renderers for SVG, VML,
	//	Canvas, and Silverlight.
};

dojox.gfx3d = {
	// summary: A 3d API for dojox.gfx
};

dojox.grid = {
	// summary: An advanced Grid widget with virtual scrolling, cell editing, and much more
};

dojox.help = {
	// summary: TODOC
};

dojox.highlight = {
	// summary: A client-side syntax highlighting engine.
	// description:
	//	This project parses pre > code nodes, and applies syntax highlighting for
	//	a wide variety of languages. Simply dojo.require() in all the
	//	dojox.highlight.languages you wish to include in your highlighingting,
	//	and customize colors in the highlight.css.
	//
	//	It is provided as a dojo package, contributed under CLA
	//	by Ivan Sagalaev and is available originally from:
	// 	http://softwaremaniacs.org/soft/highlight/en/
	//
};

dojox.html = {
	// summary: TODOC
};

dojox.image = {
	// summary: A collection of image related widgets
};

dojox.io = {
	// summary: Extensions to the Core dojo.io transports
};

dojox.jq = {
	// summary: A JQuery compatibility layer
};

dojox.jsonPath = {
	// summary: A query system for JavaScript objects
};

dojox.lang = {
	// summary: Language specific extensions
	functional: {
		// summary: Functional language constructs, including currying and lambda.
	}
};

dojox.layout = {
	// summary: A collection of layout related Widgets
};

dojox.math = {
	// summary: A collection of various advanced math functions.
};

dojox.robot = {
	// summary: TODOC
};

dojox.rpc = {
	// summary: TODOC
};

dojox.secure = {
	// summary: TODOC
};

dojox.sketch = {
	// summary: TODOC
};

dojox.sql = {
	// summary: objects to support Dojo Offline (dojox.off)  DEPRECATED
};

dojox.storage = {
	// summary: Objects for mass storage within the browser.  For when cookies just aren't enough.
};

dojox.string = {
	// summary: A collection of various objects for advanced string manipulation, including a Builder and a tokenizer.
};

dojox.testing = {
	// summary: TODOC
};

dojox.timing = {
	// summary: A set of objects to perform advanced time-based tasks, including a basic Timer.
};

dojox.uuid = {
	// summary: Universally Unique Identifier (UUID) implementations, including an implementation of UUID 2
};

dojox.validate = {
	// summary: Additional input validation methods
	ca : {
		// summary: Methods specific to the Canadian provinces
	},
	creditCard : {
		// summary: Validate various credit card types
	}
};

dojox.widget = {
	// summary: A collection of un-categorized widgets, or code not requiring its own package.
	//
	// description:
	// 	These are standalone widgets with varying levels of stability. Some are useful,
	//	some were created for demonstration purposes, and learning tools. The each maintain
	//	their own .css file (typically dojox/widget/WidgetName/WidgetName.css)
};

dojox.wire = {
	// summary:
	//	Declarative data binding and action tags for simplified MVC
};

dojox.xml = {
	// summary: XML utilities.  Currently only includes a DomParser, which returns a psuedo-XML document in JSON-like form.
};

dojox.xmpp = {
	// summary: TODOC
};
=====*/
<|endoftext|>


<commit_before>const express = require('express')
const config = require('../config')
const bodyParser = require('body-parser')
const router = express.Router({ strict: true, mergeParams: true })
const httpParams = require('../middleware/http-params')
const { httpRequest } = require('../util/http')
const debug = require('debug')('p3api-server:route/summary')
const apicache = require('apicache')
const redis = require('redis')
const redisOptions = config.get('redis')

const cacheWithRedis = apicache.options({ redisClient: redis.createClient(redisOptions) }).middleware
const onlyStatus200 = (req, res) => res.statusCode === 200

router.use(httpParams)

async function subQuery (dataType, query, opts) {
  return httpRequest({
    port: config.get('http_port'),
    headers: {
      'Content-Type': 'application/solrquery+x-www-form-urlencoded',
      Accept: opts.accept || 'application/json',
      Authorization: ''
    },
    method: 'POST',
    path: `/${dataType}`
  }, query)
    .then((body) => {
      return JSON.parse(body)
    })
}

router.get('/summary_by_taxon/:taxon_id', [
  cacheWithRedis('1 hour', onlyStatus200),
  bodyParser.json({ extended: true }),
  function (req, res, next) {
    const defs = []
    res.results = {}

    debug('summary_by_taxon:', req.params.taxon_id)

    defs.push(
      subQuery(
        'genome',
        `q=*:*&fq=taxon_lineage_ids:${req.params.taxon_id}&rows=0&json.facet={unique_family:"unique(family)",unique_genus:"unique(genus)",unique_species:"unique(species)",unique_strain:"unique(strain)"}`,
        {
          accept: 'application/solr+json'
        }
      ).then((results) => {
        res.results = Object.assign(res.results, results.facets)
      })
    )
    defs.push(
      subQuery(
        'genome_feature',
        `q=*:*&fq=feature_type:(CDS OR mat_peptide)&fq={!join fromIndex=genome from=genome_id to=genome_id v=taxon_lineage_ids:${req.params.taxon_id}}&rows=0&facet=true&facet.field=feature_type&facet.mincount=1&json.nl=map`,
        {
          accept: 'application/solr+json'
        }
      ).then((results) => {
        const feature_type_count = results.facet_counts.facet_fields.feature_type
        res.results = Object.assign(res.results, feature_type_count)
      })
    )
    defs.push(
      subQuery(
        'protein_structure',
        `q=*:*&fq=taxon_lineage_ids:${req.params.taxon_id}&rows=0`,
        {
          accept: 'application/solr+json'
        }
      ).then((results) => {
        const counts = {
          'PDB': results.response.numFound
        }
        res.results = Object.assign(res.results, counts)
      })
    )

    Promise.all(defs).then(() => {
      next()
    }, (err) => {
      next(err)
    })
  },
  function (req, res, next) {
    res.set('content-type', 'application/json')
    res.end(JSON.stringify(res.results))
  }
])
const allowed = {
  'genome': ['host_group', 'host_name', 'host_common_name', 'geographic_group', 'isolation_country'],
  'genome_feature': ['feature_type'],
  'sp_gene': ['property', 'source', 'evidence'],
  'protein_feature': ['source'],
  'protein_structure': ['method'],
  'surveillance': ['pathogen_test_type', 'pathogen_test_result', 'subtype', 'host_group', 'host_common_name', 'host_species', 'geographic_group', 'collection_country'],
  'serology': ['test_type', 'test_result', 'serotype', 'host_type', 'host_common_name', 'host_species', 'geographic_group', 'collection_country']
}

router.get('/distinct/:collection/:field', [
  bodyParser.json({ extended: true }),
  (req, res, next) => {
    const collection = req.params.collection
    const field = req.params.field
    if (allowed.hasOwnProperty(collection) && allowed[collection].includes(field)) {
      next()
    } else {
      res.set('content-type', 'application/json')
      res.end(JSON.stringify({ status: 405, message: `/distinct/${collection}/${field} is not allowed` }))
    }
  },
  cacheWithRedis('1 hour', onlyStatus200),
  (req, res, next) => {
    const collection = req.params.collection
    const field = req.params.field

    subQuery(collection, `q=*:*&rows=0&facet=true&facet.field=${field}&facet.mincount=1&facet.limit=-1&json.nl=map`, {
      accept: 'application/solr+json'
    })
      .then((body) => {
        if (body && body.facet_counts) {
          // debug(body.facet_counts.facet_fields[field])
          res.results = body.facet_counts.facet_fields[field]
          next()
        } else {
          next({ 'status': body.status, 'message': body.error.msg })
        }
      })
  },
  (req, res) => {
    res.set('content-type', 'application/json')
    res.end(JSON.stringify(res.results))
  }
])

module.exports = router
<commit_msg>increase cache duration, add more fields<commit_after>const express = require('express')
const config = require('../config')
const bodyParser = require('body-parser')
const router = express.Router({ strict: true, mergeParams: true })
const httpParams = require('../middleware/http-params')
const { httpRequest } = require('../util/http')
const debug = require('debug')('p3api-server:route/summary')
const apicache = require('apicache')
const redis = require('redis')
const redisOptions = config.get('redis')

const cacheWithRedis = apicache.options({ redisClient: redis.createClient(redisOptions) }).middleware
const onlyStatus200 = (req, res) => res.statusCode === 200

router.use(httpParams)

async function subQuery (dataType, query, opts) {
  return httpRequest({
    port: config.get('http_port'),
    headers: {
      'Content-Type': 'application/solrquery+x-www-form-urlencoded',
      Accept: opts.accept || 'application/json',
      Authorization: ''
    },
    method: 'POST',
    path: `/${dataType}`
  }, query)
    .then((body) => {
      return JSON.parse(body)
    })
}

router.get('/summary_by_taxon/:taxon_id', [
  cacheWithRedis('1 day', onlyStatus200),
  bodyParser.json({ extended: true }),
  function (req, res, next) {
    const defs = []
    res.results = {}

    debug('summary_by_taxon:', req.params.taxon_id)

    defs.push(
      subQuery(
        'genome',
        `q=*:*&fq=taxon_lineage_ids:${req.params.taxon_id}&rows=0&json.facet={unique_family:"unique(family)",unique_genus:"unique(genus)",unique_species:"unique(species)",unique_strain:"unique(strain)"}`,
        {
          accept: 'application/solr+json'
        }
      ).then((results) => {
        res.results = Object.assign(res.results, results.facets)
      })
    )
    defs.push(
      subQuery(
        'genome_feature',
        `q=*:*&fq=feature_type:(CDS OR mat_peptide)&fq={!join fromIndex=genome from=genome_id to=genome_id v=taxon_lineage_ids:${req.params.taxon_id}}&rows=0&facet=true&facet.field=feature_type&facet.mincount=1&json.nl=map`,
        {
          accept: 'application/solr+json'
        }
      ).then((results) => {
        const feature_type_count = results.facet_counts.facet_fields.feature_type
        res.results = Object.assign(res.results, feature_type_count)
      })
    )
    defs.push(
      subQuery(
        'protein_structure',
        `q=*:*&fq=taxon_lineage_ids:${req.params.taxon_id}&rows=0`,
        {
          accept: 'application/solr+json'
        }
      ).then((results) => {
        const counts = {
          'PDB': results.response.numFound
        }
        res.results = Object.assign(res.results, counts)
      })
    )

    Promise.all(defs).then(() => {
      next()
    }, (err) => {
      next(err)
    })
  },
  function (req, res, next) {
    res.set('content-type', 'application/json')
    res.end(JSON.stringify(res.results))
  }
])
const allowed = {
  'genome': ['host_group', 'host_name', 'host_common_name', 'geographic_group', 'isolation_country'],
  'genome_feature': ['feature_type'],
  'sp_gene': ['property', 'source', 'evidence'],
  'pathway_ref': ['pathway_name', 'pathway_class'],
  'subsystem_ref': ['subsystem_id', 'subsystem_name'],
  'protein_feature': ['source'],
  'protein_structure': ['method'],
  'surveillance': ['pathogen_test_type', 'pathogen_test_result', 'subtype', 'host_group', 'host_common_name', 'host_species', 'geographic_group', 'collection_country'],
  'serology': ['test_type', 'test_result', 'serotype', 'host_type', 'host_common_name', 'host_species', 'geographic_group', 'collection_country']
}

router.get('/distinct/:collection/:field', [
  bodyParser.json({ extended: true }),
  (req, res, next) => {
    const collection = req.params.collection
    const field = req.params.field
    if (allowed.hasOwnProperty(collection) && allowed[collection].includes(field)) {
      next()
    } else {
      res.set('content-type', 'application/json')
      res.end(JSON.stringify({ status: 405, message: `/distinct/${collection}/${field} is not allowed` }))
    }
  },
  cacheWithRedis('1 month', onlyStatus200),
  (req, res, next) => {
    const collection = req.params.collection
    const field = req.params.field

    subQuery(collection, `q=*:*&rows=0&facet=true&facet.field=${field}&facet.mincount=1&facet.limit=-1&json.nl=map`, {
      accept: 'application/solr+json'
    })
      .then((body) => {
        if (body && body.facet_counts) {
          // debug(body.facet_counts.facet_fields[field])
          res.results = body.facet_counts.facet_fields[field]
          next()
        } else {
          next({ 'status': body.status, 'message': body.error.msg })
        }
      })
  },
  (req, res) => {
    res.set('content-type', 'application/json')
    res.end(JSON.stringify(res.results))
  }
])

module.exports = router
<|endoftext|>


<commit_before>"use strict"

// SteamCommunity URL's
const SC  = 'http://steamcommunity.com/';
const SCM = SC + 'market/';
/**
 * This is solely here because of SteamApis.com,
 * it helps our ProxyAPI identify if the loaded page was indeed valid.
 * Feel free to ignore this.
 */
const Contains = {
    web: 'g_steamID',
    json: '"success"'
};

// Available endpoints
module.exports = {
    /**
     * Search page
     */
    'search': function(object) {
        let parameters = '';

        if(typeof object === 'object') {
            parameters = Object.keys(object).map((key) => {
                return `${key}=${object[key]}`;
            }).join('&');
        }

        return {
            contains: Contains.web,
            url: `${SCM}search?${parameters}&l=english`
        };
    },
    /**
     * Search render API
     */
    'searchRender': function(object) {
        let parameters = '';

        // Default search params if object was not set.
        if( ! object) {
            object = {
                query: "",
                start: 0,
                count: 10,
                search_descriptions: 0,
                sort_column: "popular",
                sort_dir: "desc"
            }
        }

        if(typeof object === 'object') {
            parameters = Object.keys(object).map((key) => {
                return `${key}=${object[key]}`;
            }).join('&');
        }

        return {
            contains: Contains.json,
            url: `${SCM}search/render?${parameters}`
        };
    },
    /**
     * Gets the popular listings
     */
    'popular': function(start, count) {
        return {
            contains: Contains.json,
            url: `${SCM}popular?language=english&currency=1&start=${start}&count=${count}`
        };
    },
    /**
     * Gets the recently created listings
     */
    'recent': function() {
        return {
            contans: Contans.json,
            url: `${SCM}recent?country=US&language=english&currency=1`
        };
    },
    /**
     * Gets the recently completed/sold listings
     */
    'recentcompleted': function() {
        return {
            contains: Contains.json,
            url: `${SCM}recentcompleted`
        };
    },
    /**
     * Gets the listings page using appID and marketHashName
     */
    'listings': function(appID, marketHashName) {
        // Return as a function bcus of Base64 and I want to use this.url m8
        return new function() {
            this.contains = Contains.web;
            this.url = `${SCM}listings/${appID}/${encodeURIComponent(marketHashName)}?l=english`;
            this.base64 = new Buffer(this.url).toString('base64');
        };
    },
    /**
     * Gets the item activity on the listings page
     */
    'itemordersactivity': function(nameID) {
        return {
            contains: Contains.json,
            url: `${SCM}itemordersactivity?language=english&currency=1&item_nameid=${nameID}`
        };
    },
    /**
     * Gets the item sale history on the listings page
     */
    'itemordershistogram': function(nameID) {
        return {
            contains: Contains.json,
            url: `${SCM}itemordershistogram?language=english&currency=1&item_nameid=${nameID}`
        };
    }
};
<commit_msg>Change all return objects to functions in Endpoint<commit_after>"use strict"

// SteamCommunity URL's
const SC  = 'http://steamcommunity.com/';
const SCM = SC + 'market/';
/**
 * This is solely here because of SteamApis.com,
 * it helps our ProxyAPI identify if the loaded page was indeed valid.
 * Feel free to ignore this.
 */
const Contains = {
    web: 'g_steamID',
    json: '"success"'
};

// Available endpoints
module.exports = {
    /**
     * Search page
     */
    'search': function(object) {
        let parameters = '';

        if(typeof object === 'object') {
            parameters = Object.keys(object).map((key) => {
                return `${key}=${object[key]}`;
            }).join('&');
        }

        return new function() {
            this.contains = Contains.web;
            this.url = `${SCM}search?${parameters}&l=english`;
            this.base64 = new Buffer(this.url).toString('base64');
        };
    },
    /**
     * Search render API
     */
    'searchRender': function(object) {
        let parameters = '';

        // Default search params if object was not set.
        if( ! object) {
            object = {
                query: "",
                start: 0,
                count: 10,
                search_descriptions: 0,
                sort_column: "popular",
                sort_dir: "desc"
            }
        }

        if(typeof object === 'object') {
            parameters = Object.keys(object).map((key) => {
                return `${key}=${object[key]}`;
            }).join('&');
        }

        return new function() {
            this.contains = Contains.json;
            this.url = `${SCM}search/render?${parameters}`;
            this.base64 = new Buffer(this.url).toString('base64');
        };
    },
    /**
     * Gets the popular listings
     */
    'popular': function(start, count) {
        return new function() {
            this.contains = Contains.json;
            this.url = `${SCM}popular?language=english&currency=1&start=${start}&count=${count}`;
            this.base64 = new Buffer(this.url).toString('base64');
        };
    },
    /**
     * Gets the recently created listings
     */
    'recent': function() {
        return new function() {
            this.contans = Contans.json;
            this.url = `${SCM}recent?country=US&language=english&currency=1`;
            this.base64 = new Buffer(this.url).toString('base64');
        };
    },
    /**
     * Gets the recently completed/sold listings
     */
    'recentcompleted': function() {
        return new function() {
            this.contains = Contains.json;
            this.url = `${SCM}recentcompleted`;
        };
    },
    /**
     * Gets the listings page using appID and marketHashName
     */
    'listings': function(appID, marketHashName) {
        return new function() {
            this.contains = Contains.web;
            this.url = `${SCM}listings/${appID}/${encodeURIComponent(marketHashName)}?l=english`;
            this.base64 = new Buffer(this.url).toString('base64');
        };
    },
    /**
     * Gets the item activity on the listings page
     */
    'itemordersactivity': function(nameID) {
        return new function() {
            this.contains = Contains.json;
            this.url = `${SCM}itemordersactivity?language=english&currency=1&item_nameid=${nameID}`;
            this.base64 = new Buffer(this.url).toString('base64');
        };
    },
    /**
     * Gets the item sale history on the listings page
     */
    'itemordershistogram': function(nameID) {
        return new function() {
            this.contains = Contains.json;
            this.url = `${SCM}itemordershistogram?language=english&currency=1&item_nameid=${nameID}`;
            this.base64 = new Buffer(this.url).toString('base64');
        };
    }
};
<|endoftext|>


<commit_before>var canyonvistadata = require("../canyonvistadata.json");
var can1 = require("../canyonvistadata.json");
var can2 = require("../canyonvistadata.json");
exports.view = function(req, res){
	res.render('foodfinder', canyonvistadata, can1);
};<commit_msg>Fixed foodfinder.js<commit_after>var canyonvistadata = require("../canyonvistadata.json");
var can1 = require("../canyonvistadata.json");
var can2 = require("../canyonvistadata.json");
exports.view = function(req, res){
	res.render('foodfinder', {"can1" : can1, "can2" : can2, "canyonData" : canyonvistadata});
};

<|endoftext|>


<commit_before>var express = require('express'),
	router = express.Router(),
	mongoose = require('mongoose'),
	bodyParser = require('body-parser'),
	methodOverride = require('method-override'),
	async = require('async'),
	nconf = require('nconf'),
	AWS = require('aws-sdk');

nconf.file('creds.json');
var S3accessKeyId = nconf.get('S3accessKeyId'),
    S3secretAccessKey = nconf.get('S3secretAccessKey'),
    S3endpoint = nconf.get('S3endpoint'),
    S3url = nconf.get('S3url');

String.prototype.capitalizeFirstLetter = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
}

router.use(bodyParser.urlencoded({ extended: true }))
router.use(methodOverride(function(req, res){
  	if (req.body && typeof req.body === 'object' && '_method' in req.body) {
    	// look in urlencoded POST bodies and delete it
    	var method = req.body._method
    	delete req.body._method
    	return method
  	}
}))

router.route('/')
	.get(function(req, res, next) {
		mongoose.model('Infophoto').find({}, null, {sort: {lname: 1}}, function (err, infophotos) {
		  	if (err) {
		  		return console.error(err);
		  	} else {
		  		var totalinfophotos = 0;
		  		var totalpictures = 0;
		  		var subscribers = 0;
		  		async.each(infophotos, function(infophoto, done){
		  			totalinfophotos +=1;
		  			console.log(infophoto);
		  			if(infophoto.newsletter == true){
		  				subscribers += 1;
		  			}
		  			if(infophoto.photos.length > 0){
		  				totalpictures += 4;
		  			}
		  			done();
		  		}, function(err){
				    // if any of the file processing produced an error, err would equal that error
				    if( err ) {
				      // One of the iterations produced an error.
				      // All processing will now stop.
				      console.log('A file failed to process');
				    } else {
					    res.format({
							html: function(){
						    	res.render('infophotos/index', {
						  			title: "Everyone's Info",
						  			"infophotos" : infophotos,
						  			"totalinfophotos" : totalinfophotos,
						  			"totalpictures" : totalpictures,
						  			"subscribers" : subscribers
					  			});
							},
							json: function(){
						    	res.json(infophotos);
							}
						});
				    }
		  		});
		  	}
		});
	})
	.post(function(req, res) {
	    // Get our form values. These rely on the "name" attributes
	    var fname = req.body.fname;
	    var lname = req.body.lname;
	    var email = req.body.email;
	    var twitter = req.body.twitter;
	    var company = req.body.company;
	    var title = req.body.title;
	    var newsletter = req.body.newsletter;
	    var interests = req.body.interests;
	    var favoritedemo = req.body.favoritedemo;

	    var uniqueurlIterator = 0;
	    var uniqueurl = fname.toLowerCase() + lname.toLowerCase() + uniqueurlIterator.toString();
	    //need to find in mongo by uniqueurl. if exists then add 1 to fname+lname
	    var goodurl = false;

	    async.until(
	    	function (){ return goodurl == true },
	    	function(done){
	    		uniqueurl = fname.toLowerCase() + lname.toLowerCase() + uniqueurlIterator.toString();
	    		fname = fname.capitalizeFirstLetter();
	    		lname = lname.capitalizeFirstLetter();
	    		console.log('Trying: ' + uniqueurl);
	    		mongoose.model('Infophoto').findOne({ uniqueurl: uniqueurl}, function (err, infophoto) {
		    		if (err) {
		    			console.log(err);
		    		} else {
		    			if (infophoto == null){
		    				goodurl = true;
		    				mongoose.model('Infophoto').create({
						    	fname : fname,
						    	lname : lname,
						    	email : email,
						    	twitter : twitter,
						    	company : company,
						    	title : title,
						    	newsletter : newsletter,
						    	interests : interests,
						    	favoritedemo : favoritedemo,
						    	uniqueurl : uniqueurl
						    }, function (err, infophoto) {
							  	if (err) {
							  		console.log(err);
							  		//return handleError(err);
							  		res.send("There was a problem adding the information to the database.");
							  	} else {
							  		console.log('POST creating new infophoto: ' + infophoto);
							  		res.format({
										html: function(){
											res.render('infophotos/thanks', {
										   		title: "Photobooth Registration Success"
									  		});
											/* If it worked, set the header so the address bar doesn't still say /adduser
									    	res.location("Photobooth Registration Success");
									    	// And forward to success page
						            		res.redirect("../");*/
										},
										json: function(){
									    	res.json(infophoto);
										}
									});
						      	}
							})
		    			} else {
		    				uniqueurlIterator += 1;
		    				done();
		    			}
		    		}
		    	});
	    	}, function(err){}
	    )
	});

/* GET New Infophoto page. */
router.get('/new', function(req, res) {
    res.render('infophotos/new', { title: 'Photobooth Registration' });
});

/* GET List of Pictures to be taken */
router.get('/list', function(req, res) {
    mongoose.model('Infophoto').find({photos : []}, null, {sort: {lname: 1}}, function (err, infophotos) {
		if (err) {
			console.log('GET Error: There was a problem retrieving: ' + err);
		} else {
			//console.log('GET Retrieving all empty infophotos: ' + infophotos);
			res.format({
				html: function(){
				   	res.render('infophotos/list', {
				   		title: "Waiting to Take Photos",
				  		"infophotos" : infophotos
			  		});
			 	},
				json: function(){
			   		res.json(infophoto);
			 	}
			});
		}
	});
});

/* GET Take Pictures */
router.get('/takepic/:uniqueurl', function(req, res) {
    mongoose.model('Infophoto').findOne({uniqueurl : req.params.uniqueurl}, function (err, infophoto) {
		if (err) {
			console.log('GET Error: There was a problem retrieving: ' + err);
		} else {
			//console.log('GET Retrieving all empty infophotos: ' + infophotos);
			res.format({
				html: function(){
				   	res.render('infophotos/takepic', {
				   		title: "Photobooth",
				  		"infophoto" : infophoto
			  		});
			 	}
			});
		}
	});
});

/* GET Take Pictures */
router.post('/addpic/:uniqueurl', function(req, res) {
	buf = new Buffer(req.body.photo.replace(/^data:image\/\w+;base64,/, ""),'base64')
    var s3 = new AWS.S3({accessKeyId: S3accessKeyId, secretAccessKey: S3secretAccessKey});
    var params = {
		Bucket: 'emcphotobooth', /* required */
		Key: req.params.uniqueurl + '/' + req.body.number + '.png', /* required */
		ACL: 'public-read',
		Body: buf,
		ContentType:  'image/png',
		ContentEncoding: 'base64'
	};
	s3.putObject(params, function(err, data) {
		if (err) console.log(err, err.stack); // an error occurred
		else     console.log(data);           // successful response
	});

	mongoose.model('Infophoto').findOneAndUpdate({uniqueurl : req.params.uniqueurl},
			{$push: {'photos': 'https://' + S3url + '/emcphotobooth/' + req.params.uniqueurl + '/' + req.body.number + '.png'}},
		    {safe: true, upsert: true},
		    function(err, model) {
		        //console.log(err);
		        //console.log(model);
		    }
	);

	res.format({
		text: function(){
			res.send('success');
	 	},
		json: function(){
	   		res.json({message : 'success'});
	 	}
	});

});

// route middleware to validate :uniqueurl
router.param('uniqueurl', function(req, res, next, uniqueurl) {
    //console.log('validating ' + uniqueurl + ' exists');
    mongoose.model('Infophoto').findOne({uniqueurl: uniqueurl}, function (err, infophoto) {
		if (err) {
			console.log(uniqueurl + ' was not found');
			res.status(404)
			var err = new Error('Not Found');
			err.status = 404;
			res.format({
				html: function(){
					next(err);
			 	},
				json: function(){
			   		res.json({message : err.status  + ' ' + err});
			 	}
			});
		} else if (infophoto === null) {
			console.log(uniqueurl + ' was not found');
			res.status(404)
			var err = new Error('Not Found');
			err.status = 404;
			res.format({
				html: function(){
					next(err);
			 	},
				json: function(){
			   		res.json({message : err.status  + ' ' + err});
			 	}
			});
		} else {
			//console.log(infophoto);
			// once validation is done save the new item in the req
			req.uniqueurl = uniqueurl;
			// go to the next thing
    		next();
		}
	});
});

router.route('/:uniqueurl')
	.get(function(req, res) {
		mongoose.model('Infophoto').findOne({uniqueurl : req.params.uniqueurl}, function (err, infophoto) {
			if (err) {
				console.log('GET Error: There was a problem retrieving: ' + err);
			} else {
				console.log('GET Retrieving uniqueurl: ' + infophoto.uniqueurl);
				res.format({
					html: function(){
					   	res.render('infophotos/show', {
					   		title: "Photobooth for " + infophoto.fname,
					  		"infophoto" : infophoto
				  		});
				 	},
					json: function(){
				   		res.json(infophoto);
				 	}
				});
			}
		});
	});

router.route('/:uniqueurl/edit')
	.get(function(req, res) {
		mongoose.model('Infophoto').findOne({uniqueurl : req.params.uniqueurl}, function (err, infophoto) {
			if (err) {
				console.log('GET Error: There was a problem retrieving: ' + err);
			} else {
				console.log('GET Retrieving uniqueurl: ' + infophoto.uniqueurl);
				res.format({
					html: function(){
					   	res.render('infophotos/edit', {
					   		title: "Edit Info for " + infophoto.fname,
					  		"infophoto" : infophoto
				  		});
				 	},
					json: function(){
				   		res.json(infophoto);
				 	}
				});
			}
		});
	})
	.put(function(req, res) {
		// Get our form values. These rely on the "name" attributes
	    var fname = req.body.fname;
	    var lname = req.body.lname;
	    var twitter = req.body.twitter;
	    var company = req.body.company;
	    var title = req.body.title;
	    var newsletter = req.body.newsletter;
	    var interests = req.body.interests;
	    var favoritedemo = req.body.favoritedemo;

	    //find the document by uniqueurl and then update it
		mongoose.model('Infophoto').findOne({uniqueurl : req.params.uniqueurl}, function (err, infophoto) {
			infophoto.update({
		    	fname : fname,
		    	lname : lname,
		    	twitter : twitter,
		    	company : company,
		    	title : title,
		    	newsletter : newsletter,
		    	interests : interests,
		    	favoritedemo : favoritedemo
		    }, function (err, infophotoID) {
			  if (err) {
			  	//return handleError(err);
			  	res.send("There was a problem updating the information to the database: " + err);
			  }
			  else {
			  		//console.log('PUT updating uniqueurl: ' + infophoto.uniqueurl);
			  		res.format({
			  			html: function(){
						   	res.redirect("/infophotos/" + infophoto.uniqueurl);
					 	},
						json: function(){
					   		res.json(infophoto);
					 	}
			  		});
		       }
			})
		});
	})
	.delete(function (req, res){
		mongoose.model('Infophoto').findOne({uniqueurl : req.params.uniqueurl}, function (err, infophoto) {
			if (err) {
				return console.error(err);
			} else {
				infophoto.remove(function (err, infophoto) {
					if (err) {
						return console.error(err);
					} else {
						console.log('DELETE removing uniqueurl: ' + infophoto.uniqueurl);
						res.format({
				  			html: function(){
							   	res.redirect("/infophotos");
						 	},
							json: function(){
						   		res.json({message : 'deleted',
						   			item : infophoto
						   		});
						 	}
				  		});
					}
				});
			}
		});
	});

module.exports = router;
<commit_msg>remove console<commit_after>var express = require('express'),
	router = express.Router(),
	mongoose = require('mongoose'),
	bodyParser = require('body-parser'),
	methodOverride = require('method-override'),
	async = require('async'),
	nconf = require('nconf'),
	AWS = require('aws-sdk');

nconf.file('creds.json');
var S3accessKeyId = nconf.get('S3accessKeyId'),
    S3secretAccessKey = nconf.get('S3secretAccessKey'),
    S3endpoint = nconf.get('S3endpoint'),
    S3url = nconf.get('S3url');

String.prototype.capitalizeFirstLetter = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
}

router.use(bodyParser.urlencoded({ extended: true }))
router.use(methodOverride(function(req, res){
  	if (req.body && typeof req.body === 'object' && '_method' in req.body) {
    	// look in urlencoded POST bodies and delete it
    	var method = req.body._method
    	delete req.body._method
    	return method
  	}
}))

router.route('/')
	.get(function(req, res, next) {
		mongoose.model('Infophoto').find({}, null, {sort: {lname: 1}}, function (err, infophotos) {
		  	if (err) {
		  		return console.error(err);
		  	} else {
		  		var totalinfophotos = 0;
		  		var totalpictures = 0;
		  		var subscribers = 0;
		  		async.each(infophotos, function(infophoto, done){
		  			totalinfophotos +=1;
		  			if(infophoto.newsletter == true){
		  				subscribers += 1;
		  			}
		  			if(infophoto.photos.length > 0){
		  				totalpictures += 4;
		  			}
		  			done();
		  		}, function(err){
				    // if any of the file processing produced an error, err would equal that error
				    if( err ) {
				      // One of the iterations produced an error.
				      // All processing will now stop.
				      console.log('A file failed to process');
				    } else {
					    res.format({
							html: function(){
						    	res.render('infophotos/index', {
						  			title: "Everyone's Info",
						  			"infophotos" : infophotos,
						  			"totalinfophotos" : totalinfophotos,
						  			"totalpictures" : totalpictures,
						  			"subscribers" : subscribers
					  			});
							},
							json: function(){
						    	res.json(infophotos);
							}
						});
				    }
		  		});
		  	}
		});
	})
	.post(function(req, res) {
	    // Get our form values. These rely on the "name" attributes
	    var fname = req.body.fname;
	    var lname = req.body.lname;
	    var email = req.body.email;
	    var twitter = req.body.twitter;
	    var company = req.body.company;
	    var title = req.body.title;
	    var newsletter = req.body.newsletter;
	    var interests = req.body.interests;
	    var favoritedemo = req.body.favoritedemo;

	    var uniqueurlIterator = 0;
	    var uniqueurl = fname.toLowerCase() + lname.toLowerCase() + uniqueurlIterator.toString();
	    //need to find in mongo by uniqueurl. if exists then add 1 to fname+lname
	    var goodurl = false;

	    async.until(
	    	function (){ return goodurl == true },
	    	function(done){
	    		uniqueurl = fname.toLowerCase() + lname.toLowerCase() + uniqueurlIterator.toString();
	    		fname = fname.capitalizeFirstLetter();
	    		lname = lname.capitalizeFirstLetter();
	    		console.log('Trying: ' + uniqueurl);
	    		mongoose.model('Infophoto').findOne({ uniqueurl: uniqueurl}, function (err, infophoto) {
		    		if (err) {
		    			console.log(err);
		    		} else {
		    			if (infophoto == null){
		    				goodurl = true;
		    				mongoose.model('Infophoto').create({
						    	fname : fname,
						    	lname : lname,
						    	email : email,
						    	twitter : twitter,
						    	company : company,
						    	title : title,
						    	newsletter : newsletter,
						    	interests : interests,
						    	favoritedemo : favoritedemo,
						    	uniqueurl : uniqueurl
						    }, function (err, infophoto) {
							  	if (err) {
							  		console.log(err);
							  		//return handleError(err);
							  		res.send("There was a problem adding the information to the database.");
							  	} else {
							  		console.log('POST creating new infophoto: ' + infophoto);
							  		res.format({
										html: function(){
											res.render('infophotos/thanks', {
										   		title: "Photobooth Registration Success"
									  		});
											/* If it worked, set the header so the address bar doesn't still say /adduser
									    	res.location("Photobooth Registration Success");
									    	// And forward to success page
						            		res.redirect("../");*/
										},
										json: function(){
									    	res.json(infophoto);
										}
									});
						      	}
							})
		    			} else {
		    				uniqueurlIterator += 1;
		    				done();
		    			}
		    		}
		    	});
	    	}, function(err){}
	    )
	});

/* GET New Infophoto page. */
router.get('/new', function(req, res) {
    res.render('infophotos/new', { title: 'Photobooth Registration' });
});

/* GET List of Pictures to be taken */
router.get('/list', function(req, res) {
    mongoose.model('Infophoto').find({photos : []}, null, {sort: {lname: 1}}, function (err, infophotos) {
		if (err) {
			console.log('GET Error: There was a problem retrieving: ' + err);
		} else {
			//console.log('GET Retrieving all empty infophotos: ' + infophotos);
			res.format({
				html: function(){
				   	res.render('infophotos/list', {
				   		title: "Waiting to Take Photos",
				  		"infophotos" : infophotos
			  		});
			 	},
				json: function(){
			   		res.json(infophoto);
			 	}
			});
		}
	});
});

/* GET Take Pictures */
router.get('/takepic/:uniqueurl', function(req, res) {
    mongoose.model('Infophoto').findOne({uniqueurl : req.params.uniqueurl}, function (err, infophoto) {
		if (err) {
			console.log('GET Error: There was a problem retrieving: ' + err);
		} else {
			//console.log('GET Retrieving all empty infophotos: ' + infophotos);
			res.format({
				html: function(){
				   	res.render('infophotos/takepic', {
				   		title: "Photobooth",
				  		"infophoto" : infophoto
			  		});
			 	}
			});
		}
	});
});

/* GET Take Pictures */
router.post('/addpic/:uniqueurl', function(req, res) {
	buf = new Buffer(req.body.photo.replace(/^data:image\/\w+;base64,/, ""),'base64')
    var s3 = new AWS.S3({accessKeyId: S3accessKeyId, secretAccessKey: S3secretAccessKey});
    var params = {
		Bucket: 'emcphotobooth', /* required */
		Key: req.params.uniqueurl + '/' + req.body.number + '.png', /* required */
		ACL: 'public-read',
		Body: buf,
		ContentType:  'image/png',
		ContentEncoding: 'base64'
	};
	s3.putObject(params, function(err, data) {
		if (err) console.log(err, err.stack); // an error occurred
		else     console.log(data);           // successful response
	});

	mongoose.model('Infophoto').findOneAndUpdate({uniqueurl : req.params.uniqueurl},
			{$push: {'photos': 'https://' + S3url + '/emcphotobooth/' + req.params.uniqueurl + '/' + req.body.number + '.png'}},
		    {safe: true, upsert: true},
		    function(err, model) {
		        //console.log(err);
		        //console.log(model);
		    }
	);

	res.format({
		text: function(){
			res.send('success');
	 	},
		json: function(){
	   		res.json({message : 'success'});
	 	}
	});

});

// route middleware to validate :uniqueurl
router.param('uniqueurl', function(req, res, next, uniqueurl) {
    //console.log('validating ' + uniqueurl + ' exists');
    mongoose.model('Infophoto').findOne({uniqueurl: uniqueurl}, function (err, infophoto) {
		if (err) {
			console.log(uniqueurl + ' was not found');
			res.status(404)
			var err = new Error('Not Found');
			err.status = 404;
			res.format({
				html: function(){
					next(err);
			 	},
				json: function(){
			   		res.json({message : err.status  + ' ' + err});
			 	}
			});
		} else if (infophoto === null) {
			console.log(uniqueurl + ' was not found');
			res.status(404)
			var err = new Error('Not Found');
			err.status = 404;
			res.format({
				html: function(){
					next(err);
			 	},
				json: function(){
			   		res.json({message : err.status  + ' ' + err});
			 	}
			});
		} else {
			//console.log(infophoto);
			// once validation is done save the new item in the req
			req.uniqueurl = uniqueurl;
			// go to the next thing
    		next();
		}
	});
});

router.route('/:uniqueurl')
	.get(function(req, res) {
		mongoose.model('Infophoto').findOne({uniqueurl : req.params.uniqueurl}, function (err, infophoto) {
			if (err) {
				console.log('GET Error: There was a problem retrieving: ' + err);
			} else {
				console.log('GET Retrieving uniqueurl: ' + infophoto.uniqueurl);
				res.format({
					html: function(){
					   	res.render('infophotos/show', {
					   		title: "Photobooth for " + infophoto.fname,
					  		"infophoto" : infophoto
				  		});
				 	},
					json: function(){
				   		res.json(infophoto);
				 	}
				});
			}
		});
	});

router.route('/:uniqueurl/edit')
	.get(function(req, res) {
		mongoose.model('Infophoto').findOne({uniqueurl : req.params.uniqueurl}, function (err, infophoto) {
			if (err) {
				console.log('GET Error: There was a problem retrieving: ' + err);
			} else {
				console.log('GET Retrieving uniqueurl: ' + infophoto.uniqueurl);
				res.format({
					html: function(){
					   	res.render('infophotos/edit', {
					   		title: "Edit Info for " + infophoto.fname,
					  		"infophoto" : infophoto
				  		});
				 	},
					json: function(){
				   		res.json(infophoto);
				 	}
				});
			}
		});
	})
	.put(function(req, res) {
		// Get our form values. These rely on the "name" attributes
	    var fname = req.body.fname;
	    var lname = req.body.lname;
	    var twitter = req.body.twitter;
	    var company = req.body.company;
	    var title = req.body.title;
	    var newsletter = req.body.newsletter;
	    var interests = req.body.interests;
	    var favoritedemo = req.body.favoritedemo;

	    //find the document by uniqueurl and then update it
		mongoose.model('Infophoto').findOne({uniqueurl : req.params.uniqueurl}, function (err, infophoto) {
			infophoto.update({
		    	fname : fname,
		    	lname : lname,
		    	twitter : twitter,
		    	company : company,
		    	title : title,
		    	newsletter : newsletter,
		    	interests : interests,
		    	favoritedemo : favoritedemo
		    }, function (err, infophotoID) {
			  if (err) {
			  	//return handleError(err);
			  	res.send("There was a problem updating the information to the database: " + err);
			  }
			  else {
			  		//console.log('PUT updating uniqueurl: ' + infophoto.uniqueurl);
			  		res.format({
			  			html: function(){
						   	res.redirect("/infophotos/" + infophoto.uniqueurl);
					 	},
						json: function(){
					   		res.json(infophoto);
					 	}
			  		});
		       }
			})
		});
	})
	.delete(function (req, res){
		mongoose.model('Infophoto').findOne({uniqueurl : req.params.uniqueurl}, function (err, infophoto) {
			if (err) {
				return console.error(err);
			} else {
				infophoto.remove(function (err, infophoto) {
					if (err) {
						return console.error(err);
					} else {
						console.log('DELETE removing uniqueurl: ' + infophoto.uniqueurl);
						res.format({
				  			html: function(){
							   	res.redirect("/infophotos");
						 	},
							json: function(){
						   		res.json({message : 'deleted',
						   			item : infophoto
						   		});
						 	}
				  		});
					}
				});
			}
		});
	});

module.exports = router;
<|endoftext|>


<commit_before>// StyleDocco JavaScript for preview iframes
// =========================================

(function () {

'use strict';

// Helper functions
// ================
// Using `Array.prototype` to make them work on Array like objects.
var filter = function(arr, it) { return Array.prototype.filter.call(arr, it); };
var map = function(arr, it) { return Array.prototype.map.call(arr, it); };

var bodyEl = document.getElementsByTagName('body')[0];

// Get bottom-most point in document with an element.
// `offsetHeight`/`scrollHeight` will not work with absolute or fixed elements.
var getContentHeight = (function() {
  var bodyStyle = window.getComputedStyle(bodyEl, null);
  return function() {
    if (bodyEl.childElementCount === 0) return bodyEl.offsetHeight;
    var els = bodyEl.getElementsByTagName('*');
    var elHeights = [];
    for (var i = 0, l = els.length; i < l; i++) {
      elHeights.push(els[i].offsetTop + els[i].offsetHeight);
    }
    var height = Math.max.apply(Math, elHeights);
    height += parseInt(bodyStyle.getPropertyValue('padding-bottom'));
    return Math.max(height, bodyEl.offsetHeight)
  }
})();

// Scans your stylesheet for pseudo classes and adds a class with the same name.
// Compile regular expression.
var pseudos = [ 'link', 'visited', 'hover', 'active', 'focus', 'target',
                'enabled', 'disabled', 'checked' ];
var pseudoRe = new RegExp(":((" + pseudos.join(")|(") + "))", "gi");
var processedPseudoClasses = map(
  filter(document.styleSheets, function(ss) { return !(ss.href != null); }),
  function(ss) {
    return map(
      filter(ss.cssRules, function(rule) {
        // Keep only rules with pseudo classes.
        return rule.selectorText && rule.selectorText.match(pseudoRe);
      }), function(rule) {
       // Replace : with . and encoded :
       return rule.cssText.replace(pseudoRe, ".\\3A $1");
      }).join('');
  }).join('');
if (processedPseudoClasses.length) {
  // Add a new style element with the processed pseudo class styles.
  var styleEl = document.createElement('style');
  styleEl.innerText = processedPseudoClasses;
  document.getElementsByTagName('head')[0].appendChild(styleEl);
}

var callbacks = {
  getHeight: function() {
    window.parent.postMessage({ height: getContentHeight() }, '*');
  }
};

window.addEventListener('message', function (ev) {
  if (ev.data == null) return;
  if (typeof ev.data === 'string') callbacks[ev.data]();
}, false);

}());
<commit_msg>Preview script refactoring<commit_after>// StyleDocco JavaScript for preview iframes
// =========================================
(function () {

'use strict';

// Helper functions
// ================
var toArray = function(obj) { return Array.prototype.slice.call(obj); };

var bodyEl = document.getElementsByTagName('body')[0];

// Pseudo classes
// ==============
// Scans your stylesheet for pseudo classes and adds a class with the same name.
// Compile regular expression.
var pseudos = [ 'link', 'visited', 'hover', 'active', 'focus', 'target',
                'enabled', 'disabled', 'checked' ];
var pseudoRe = new RegExp(":((" + pseudos.join(")|(") + "))", "gi");
var processedPseudoClasses = toArray(document.styleSheets)
  .map(function(ss) {
    return toArray(ss.cssRules)
      .filter(function(rule) {
        // Keep only rules with pseudo classes.
        return rule.selectorText && rule.selectorText.match(pseudoRe);
      })
      .map(function(rule) {
        // Replace : with . and encoded :
        return rule.cssText.replace(pseudoRe, ".\\3A $1");
      })
      .join('');
  })
  .join('');
if (processedPseudoClasses.length) {
  // Add a new style element with the processed pseudo class styles.
  var styleEl = document.createElement('style');
  styleEl.innerText = processedPseudoClasses;
  document.getElementsByTagName('head')[0].appendChild(styleEl);
}

// Resizing
// ========
// Get bottom-most point in document with an element.
// `offsetHeight`/`scrollHeight` will not work with absolute or fixed elements.
var getContentHeight = (function() {
  var bodyStyle = window.getComputedStyle(bodyEl, null);
  return function() {
    if (bodyEl.childElementCount === 0) return bodyEl.offsetHeight;
    var els = bodyEl.getElementsByTagName('*');
    var elHeights = [];
    for (var i = 0, l = els.length; i < l; i++) {
      elHeights.push(els[i].offsetTop + els[i].offsetHeight);
    }
    var height = Math.max.apply(Math, elHeights);
    height += parseInt(bodyStyle.getPropertyValue('padding-bottom'));
    return Math.max(height, bodyEl.offsetHeight)
  }
})();

var callbacks = {
  getHeight: function() {
    window.parent.postMessage({ height: getContentHeight() }, '*');
  }
};
window.addEventListener('message', function (ev) {
  if (ev.data == null) return;
  if (typeof ev.data === 'string') callbacks[ev.data]();
}, false);

}());
<|endoftext|>


<commit_before>//It's called basilisk.js, but this is all for /game

var scrolled_ew = 0;
var scrolled_ns = 0; //up is -
var stones_clickable = 0;
var space_clickable = 0; //up is -

var selectedNode;
var selectedNode_original_cell;
var Caleb; //var selectedNode_replacement_cell = too long. so Caleb.

var cell_swap_set_up = 0;
function setup_cell_swap_if_need_be(){
   if (cell_swap_set_up==1){return;} //only do this once
   cell_swap_set_up==1;

   var my_stone_img = document.createElement("img");
   my_stone_img.setAttribute('src', img_base + '/' + side + "m.gif");

   Caleb = document.createElement('td');
      Caleb.setAttribute('id', 'caleb_the_ripper');
      Caleb.appendChild(my_stone_img);
}
function retire_caleb_clone(){
   if (selectedNode_original_cell){
      var caleb_clone = document.getElementById ('caleb_clone');
      caleb_clone.parentNode.replaceChild (selectedNode_original_cell, caleb_clone);
      selectedNode_original_cell = null;
   }
}

function select(node){
   setup_cell_swap_if_need_be();
   retire_caleb_clone();

   var cell = document.getElementById ('cell ' + node);
   selectedNode_original_cell = cell.cloneNode(true);
   var caleb_clone = Caleb.cloneNode(true);
   caleb_clone.setAttribute('id', 'caleb_clone');
   cell.parentNode.replaceChild (caleb_clone, cell);

   //set form element for submission
   selectedNode = node; //string, such as '4-2'
   var submit_form = document.getElementById ('move_submit_form');
   submit_form.setAttribute ('action', url_base +'/game/' + gameid + '/move/'+ selectedNode);
   document.getElementById ('mv_subm_but').style.display='';
   document.getElementById ('mv_subm_but').value= 'Submit move';
}

$(document).ready(function() {
   if (!gameid) {return;}
   //TODO: make these work.
   //document.getElementById ('resign_button').onClick = "select_resign();return false;";
   //document.getElementById ('pass_button').onClick = "select_pass();return false;";
});
function select_resign(){ //prepares same submit button as submit()
   retire_caleb_clone();
   var submit_form = document.getElementById ('move_submit_form');
   submit_form.setAttribute ('action', url_base +'/game/' + gameid + '/resign');
   document.getElementById ('mv_subm_but').style.display= '';
   document.getElementById ('mv_subm_but').value= 'Submit resignation';
}
function select_pass(){ //prepares same submit button as submit()
   retire_caleb_clone();
   var submit_form = document.getElementById ('move_submit_form');
   submit_form.setAttribute ('action', url_base +'/game/' + gameid + '/pass');
   document.getElementById ('mv_subm_but').style.display= '';
   document.getElementById ('mv_subm_but').value= 'Submit pass';
}

var groups_loaded = false;
var groups; //array of arrays of nodestrings
var group_side; //object: 1stnode=>char
var group_selected; //object: 1stnode=>bool
var group_of_node; //object: nodestring=>1stnode

function select_group(node){
   if (!groups_loaded) return null;
   var group = group_of_node[node];
   if (group==null)
   group_selected[group] = group_selected[group] ? 0 : 1; //flip selected

   //replace images
   var img = img_base + '/' + group_side[group] +  group_selected[group] ? 'd.gif' : '.gif';
   for (n in groups[group]){
      var img = document.getElementById('img ' + n);
      img.setAttribute('src', img);
   }
   //adjust action for submit form:
   var action = "";
   for (g in groups){
      if (!groups_selected[g]) continue;
      if (!action=='') action += '_'; //separator
      action += g[0];
   }
   var submit_form = document.getElementById ('move_submit_form');
   submit_form.setAttribute ('action', url_base +'/game/' + gameid + '/think/' + action);
   document.getElementById ('mv_subm_but').style.display= '';
   document.getElementById ('mv_subm_but').value= 'Submit selection';
}

function scroll (direction){
   var board = document.getElementById('board');
   if (direction=='up'){
      scrolled_ns --;
      scrolled_ns += (w*2);
      scrolled_ns %= (w*2);
      if (twist_ns) render_board();
      else {
         var row = board.rows[h];
         row.parentNode.insertBefore (row, board.rows[1]);
      }
   }
   else if (direction=='down'){
      scrolled_ns ++;
      scrolled_ns %= (w*2);
      if (twist_ns) render_board();
      else {
         var row = board.rows[1];
         row.parentNode.insertBefore (row, board.rows[h+1]);
      }
   }
   else {
      if (direction=='left'){
         scrolled_ew += w-1;
         scrolled_ew %= w;
      }
      else{ //right
         scrolled_ew ++;
         scrolled_ew %= w;
      }
      for(var i = 0; i < h+2; i++){ //shift each row l or r
         var row = board.rows[i];
         if (direction=='left'){
            var cell = row.cells[w];
            cell.parentNode.insertBefore (cell, row.cells[1]);
         }
         else{ //right
            var cell = row.cells[1];
            cell.parentNode.insertBefore(cell, row.cells[w+1]);
         }
      }
   }
}

//delay until
//var tomato=setTimeout ('render_board()', 50);
//render_board();

//replacement board renderer. redraw after every scroll,
//using h,w,wraps_(..),twist_(..),scrolled_(..)
function render_board(){
   if (typeof (w) == "undefined") return;
   var board_table = document.getElementById ('board');
   if (!board_table) return;
   //clearTimeout(tomato);

   var old_tbody = document.getElementById ('board_tbody');
   if (old_tbody)  board_table.removeChild (old_tbody);

   var new_tbody = document.createElement ('tbody');
   new_tbody.setAttribute ('id', 'board_tbody');

   new_tbody.appendChild (board_letter_row('forwards'));
   var i=0;
   while (i<h){
      var r = (i + scrolled_ns);
      r %= (h*2);
      var row;
      if ((r >= h) && twist_ns)
         row = board_row (r, 'reverse');
      else
         row = board_row (r, 'forward');
      new_tbody.appendChild (row);
      i++
   }
   new_tbody.appendChild (board_letter_row (twist_ns ?'reverse' : 'forward'));
   board_table.appendChild(new_tbody);
}

function board_row (r, direction){
   r %= h;
   var row = document.createElement ('tr');
   var num = h - r;
   row.appendChild (board_cell ('c'+num+'.gif',null, false));

   var i=0;
   while (i<w) {
      var c = i + scrolled_ew;
      c %= w;
      if (direction=='reverse')
         c = w-c-1;
      var stone = board_position[r][c];
      var img;

      clickable = stones_clickable;
      if (stone == 0){
         img = 'e.gif';
         img = select_empty_img(r,c);
         clickable = space_clickable;
      }
      else
         img = stone + '.gif';
      var node = r +'-'+ c;
      row.appendChild (board_cell (img,node, clickable));
      i ++;
   }
   row.appendChild (board_cell ('c'+num+'.gif',null, false));
   return row;
}

//find dgs-style filename for empty cells
function select_empty_img(row,col){
   var Ektah;
   if (wrap_ns || twist_ns){
      Ektah = 'e';
   }
   else {
      if (row==0) {Ektah = 'u'}
      else if (row==h-1) {Ektah = 'd'}
      else {Ektah = 'e'}
   }
   if (!wrap_ew){ // && !twist_ew -- only twist ns for now
      if (col==0) {Ektah += 'l'}
      else if (col==w-1) {Ektah += 'r'}
   }
   return Ektah + '.gif';
}

//skip i
var letters = ['a','b','c','d','e','f','g','h','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];

function board_letter_row (direction){
   var row = document.createElement ('tr');

   var blank_cell = board_cell ('blank.gif',null, false);
   blank_cell.firstChild.setAttribute ('height', 25);
   blank_cell.firstChild.setAttribute ('width', 31);
   row.appendChild (blank_cell);

   var i=0;
   while (i<w) {
      var col = i + scrolled_ew;
      col %= w;
      if (direction=='reverse')
         col = w-col-1;
      row.appendChild (board_cell ('c'+letters[col]+'.gif',null, false));
      i ++;
   }

   row.appendChild (blank_cell.cloneNode(true));
   return row;
}
function board_cell (img_src, node, clickable){
   var cell  = document.createElement ('td');
   var img = document.createElement ('img');
   img.setAttribute ('src', img_base + "/" + img_src);
   cell.appendChild(img);
   if (node){
      cell.setAttribute('id', 'cell '+node);
      img.setAttribute('id', 'img '+node);
   }
   if (clickable)
      cell.setAttribute('onClick', "select('" + node + "')");
   return cell;
}

// populate comments
function render_comment_table(data){
   var c_table = document.getElementById("comments_table");
   var comment_tbody = document.createElement("tbody");
   if (data.length == 0) {
      comment_tbody.innerHTML = "
 No comments.
";
   }
   else{
      var head_row = document.createElement("tr");
      var cell = document.createElement("td");
      //head_row.innerHTML = "#	comment	";
      cell.innerHTML = '#';
      head_row.appendChild(cell);cell = document.createElement("td");
      cell.innerHTML = 'comment';
      head_row.appendChild(cell);
      head_row.setAttribute('class', 'headrow');
      comment_tbody.appendChild (head_row);
      for (i in data){
         var c_row = document.createElement("tr");
         cell = document.createElement("td");
         cell.innerHTML = data[i].movenum;
         c_row.appendChild(cell);
         cell = document.createElement("td");
         cell.innerHTML = ""+ data[i].commentator +': ' + data[i].comment;
         c_row.appendChild(cell);
         comment_tbody.appendChild (c_row);
      }
   }
   c_table.replaceChild (comment_tbody, c_table.tBodies[0]);
   if (logged_in){
      //clear comment textfield, msg on successful comment
      var comment_field = document.getElementById("Leocorno");
      comment_field.value= "";
      var comment_badness = document.getElementById("cBadness");
      comment_badness.innerHTML = "";
   }
}

//appends moves to empty <select>, and highlights latest move.
function render_moves_list (moves){
   var moves_select = document.getElementById('moves_select');
   for (i in moves){
      //var move    = moves[i].move;
      var move    = moves[i].pretty_node;
      var side    = moves[i].side;
      var movenum = moves[i].movenum;
      var option = new Option (movenum +": "+ side +', '+ move, movenum);
      moves_select.add (option, null);
   }
}

function highlight_node (move){
   var node_pattern = /^\{([^{}]+)\}$/;
   var match_node = node_pattern.exec(move.move);
   if (!match_node) return; //something like 'pass' or 'resign', i guess

   var img = document.getElementById ('img ' + match_node[1]);
   if (!img) return; //something wrong
   var special_src = img_base +'/'+ move.side + 'm.gif';
   img.setAttribute('src', special_src);
}

$(document).ready(function() {
   if (!gameid) {return}//something wrong

   stones_clickable = 0;
   space_clickable = board_clickable;
   render_board();

   //dl & display comments
   $.getJSON (
      url_base +"/comments/"+ gameid,
      function (data) {render_comment_table(data[1])}
      //data is ['success', game_comments]
   );

   //dl & display move list
   $.getJSON ( url_base +"/game/"+ gameid +"/allmoves",
      function (data) {
         if (data[0] == 'success'){
            var moves = data[1];
            if (moves.length){
               render_moves_list (moves);
               highlight_node (moves[moves.length-1]);
               document.getElementById('moves_pecan').style.display= '';
            }
            else{
               document.getElementById('moves_pecan').style.display= 'none';
            }
         }
         else
            alert (data[0]);
      }
      //data is ['success', game_moves]
   );

   //set up comment submission form
   //by binding 'new_comment' form and provide a simple callback function
   $('#new_comment').ajaxForm(function(json, success, object) {
      var msg_plus_data = eval ('('+json+')');
      var msg = msg_plus_data [0];
      if (msg == 'success'){
         var comments_data = msg_plus_data[1];
         render_comment_table (comments_data);
         return;
      }
      //failure
      var comment_badness = document.getElementById("cBadness");
      comment_badness.innerHTML = msg;
   });
});

<commit_msg>scrolling up&down with twist_ns is fast again<commit_after>//It's called basilisk.js, but this is all for /game

var scrolled_ew = 0;
var scrolled_ns = 0; //up is -
var stones_clickable = 0;
var space_clickable = 0; //up is -

var selectedNode;
var selectedNode_original_cell;
var Caleb; //var selectedNode_replacement_cell = too long. so Caleb.

var cell_swap_set_up = 0;
function setup_cell_swap_if_need_be(){
   if (cell_swap_set_up==1){return;} //only do this once
   cell_swap_set_up==1;

   var my_stone_img = document.createElement("img");
   my_stone_img.setAttribute('src', img_base + '/' + side + "m.gif");

   Caleb = document.createElement('td');
      Caleb.setAttribute('id', 'caleb_the_ripper');
      Caleb.appendChild(my_stone_img);
}
function retire_caleb_clone(){
   if (selectedNode_original_cell){
      var caleb_clone = document.getElementById ('caleb_clone');
      caleb_clone.parentNode.replaceChild (selectedNode_original_cell, caleb_clone);
      selectedNode_original_cell = null;
   }
}

function select(node){
   setup_cell_swap_if_need_be();
   retire_caleb_clone();

   var cell = document.getElementById ('cell ' + node);
   selectedNode_original_cell = cell.cloneNode(true);
   var caleb_clone = Caleb.cloneNode(true);
   caleb_clone.setAttribute('id', 'caleb_clone');
   cell.parentNode.replaceChild (caleb_clone, cell);

   //set form element for submission
   selectedNode = node; //string, such as '4-2'
   var submit_form = document.getElementById ('move_submit_form');
   submit_form.setAttribute ('action', url_base +'/game/' + gameid + '/move/'+ selectedNode);
   document.getElementById ('mv_subm_but').style.display='';
   document.getElementById ('mv_subm_but').value= 'Submit move';
}

$(document).ready(function() {
   if (!gameid) {return;}
   //TODO: make these work.
   //document.getElementById ('resign_button').onClick = "select_resign();return false;";
   //document.getElementById ('pass_button').onClick = "select_pass();return false;";
});
function select_resign(){ //prepares same submit button as submit()
   retire_caleb_clone();
   var submit_form = document.getElementById ('move_submit_form');
   submit_form.setAttribute ('action', url_base +'/game/' + gameid + '/resign');
   document.getElementById ('mv_subm_but').style.display= '';
   document.getElementById ('mv_subm_but').value= 'Submit resignation';
}
function select_pass(){ //prepares same submit button as submit()
   retire_caleb_clone();
   var submit_form = document.getElementById ('move_submit_form');
   submit_form.setAttribute ('action', url_base +'/game/' + gameid + '/pass');
   document.getElementById ('mv_subm_but').style.display= '';
   document.getElementById ('mv_subm_but').value= 'Submit pass';
}

var groups_loaded = false;
var groups; //array of arrays of nodestrings
var group_side; //object: 1stnode=>char
var group_selected; //object: 1stnode=>bool
var group_of_node; //object: nodestring=>1stnode

function select_group(node){
   if (!groups_loaded) return null;
   var group = group_of_node[node];
   if (group==null)
   group_selected[group] = group_selected[group] ? 0 : 1; //flip selected

   //replace images
   var img = img_base + '/' + group_side[group] +  group_selected[group] ? 'd.gif' : '.gif';
   for (n in groups[group]){
      var img = document.getElementById('img ' + n);
      img.setAttribute('src', img);
   }
   //adjust action for submit form:
   var action = "";
   for (g in groups){
      if (!groups_selected[g]) continue;
      if (!action=='') action += '_'; //separator
      action += g[0];
   }
   var submit_form = document.getElementById ('move_submit_form');
   submit_form.setAttribute ('action', url_base +'/game/' + gameid + '/think/' + action);
   document.getElementById ('mv_subm_but').style.display= '';
   document.getElementById ('mv_subm_but').value= 'Submit selection';
}

function scroll (direction){
   var board = document.getElementById('board');
   var tbody = board.tBodies[0];
   if (direction=='up'){
      scrolled_ns += (w*2)-1;
      scrolled_ns %= (w*2);
      var row = board.rows[h];
      row.parentNode.removeChild (row);
      if (twist_ns){
         var i=0;
         var r = (i + scrolled_ns);
         r %= (h*2);
         if ((r >= h) && twist_ns)
            row = board_row (r, 'reverse');
         else
            row = board_row (r, 'forward');
      }
      tbody.insertBefore (row, board.rows[1]);
   }
   else if (direction=='down'){
      scrolled_ns ++;
      scrolled_ns %= (w*2);
      var row = board.rows[1];
      row.parentNode.removeChild (row);
      if (twist_ns){
         var i=w-1;
         var r = (i + scrolled_ns);
         r %= (h*2);
         if ((r >= h) && twist_ns)
            row = board_row (r, 'reverse');
         else
            row = board_row (r, 'forward');
      }
      tbody.insertBefore (row, board.rows[h]);
   }
   else {
      if (direction=='left'){
         scrolled_ew += w-1;
         scrolled_ew %= w;
      }
      else{ //right
         scrolled_ew ++;
         scrolled_ew %= w;
      }
      for(var i = 0; i < h+2; i++){ //shift each row l or r
         var row = board.rows[i];
         if (direction=='left'){
            var cell = row.cells[w];
            cell.parentNode.insertBefore (cell, row.cells[1]);
         }
         else{ //right
            var cell = row.cells[1];
            cell.parentNode.insertBefore(cell, row.cells[w+1]);
         }
      }
   }
}

//delay until
//var tomato=setTimeout ('render_board()', 50);
//render_board();

//replacement board renderer. redraw after every scroll,
//using h,w,wraps_(..),twist_(..),scrolled_(..)
function render_board(){
   if (typeof (w) == "undefined") return;
   var board_table = document.getElementById ('board');
   if (!board_table) return;
   //clearTimeout(tomato);

   var old_tbody = document.getElementById ('board_tbody');
   if (old_tbody)  board_table.removeChild (old_tbody);

   var new_tbody = document.createElement ('tbody');
   new_tbody.setAttribute ('id', 'board_tbody');

   new_tbody.appendChild (board_letter_row('forwards'));
   var i=0;
   while (i<h){
      var r = (i + scrolled_ns);
      r %= (h*2);
      var row;
      if ((r >= h) && twist_ns)
         row = board_row (r, 'reverse');
      else
         row = board_row (r, 'forward');
      new_tbody.appendChild (row);
      i++
   }
   new_tbody.appendChild (board_letter_row (twist_ns ?'reverse' : 'forward'));
   board_table.appendChild(new_tbody);
}

function board_row (r, direction){
   r %= h;
   var row = document.createElement ('tr');
   var num = h - r;
   row.appendChild (board_cell ('c'+num+'.gif',null, false));

   var i=0;
   while (i<w) {
      var c = i + scrolled_ew;
      c %= w;
      if (direction=='reverse')
         c = w-c-1;
      var stone = board_position[r][c];
      var img;

      clickable = stones_clickable;
      if (stone == 0){
         img = 'e.gif';
         img = select_empty_img(r,c);
         clickable = space_clickable;
      }
      else
         img = stone + '.gif';
      var node = r +'-'+ c;
      row.appendChild (board_cell (img,node, clickable));
      i ++;
   }
   row.appendChild (board_cell ('c'+num+'.gif',null, false));
   return row;
}

//find dgs-style filename for empty cells
function select_empty_img(row,col){
   var Ektah;
   if (wrap_ns || twist_ns){
      Ektah = 'e';
   }
   else {
      if (row==0) {Ektah = 'u'}
      else if (row==h-1) {Ektah = 'd'}
      else {Ektah = 'e'}
   }
   if (!wrap_ew){ // && !twist_ew -- only twist ns for now
      if (col==0) {Ektah += 'l'}
      else if (col==w-1) {Ektah += 'r'}
   }
   return Ektah + '.gif';
}

//skip i
var letters = ['a','b','c','d','e','f','g','h','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];

function board_letter_row (direction){
   var row = document.createElement ('tr');

   var blank_cell = board_cell ('blank.gif',null, false);
   blank_cell.firstChild.setAttribute ('height', 25);
   blank_cell.firstChild.setAttribute ('width', 31);
   row.appendChild (blank_cell);

   var i=0;
   while (i<w) {
      var col = i + scrolled_ew;
      col %= w;
      if (direction=='reverse')
         col = w-col-1;
      row.appendChild (board_cell ('c'+letters[col]+'.gif',null, false));
      i ++;
   }

   row.appendChild (blank_cell.cloneNode(true));
   return row;
}
function board_cell (img_src, node, clickable){
   var cell  = document.createElement ('td');
   var img = document.createElement ('img');
   img.setAttribute ('src', img_base + "/" + img_src);
   cell.appendChild(img);
   if (node){
      cell.setAttribute('id', 'cell '+node);
      img.setAttribute('id', 'img '+node);
   }
   if (clickable)
      cell.setAttribute('onClick', "select('" + node + "')");
   return cell;
}

// populate comments
function render_comment_table(data){
   var c_table = document.getElementById("comments_table");
   var comment_tbody = document.createElement("tbody");
   if (data.length == 0) {
      comment_tbody.innerHTML = "
 No comments.
";
   }
   else{
      var head_row = document.createElement("tr");
      var cell = document.createElement("td");
      //head_row.innerHTML = "#	comment	";
      cell.innerHTML = '#';
      head_row.appendChild(cell);cell = document.createElement("td");
      cell.innerHTML = 'comment';
      head_row.appendChild(cell);
      head_row.setAttribute('class', 'headrow');
      comment_tbody.appendChild (head_row);
      for (i in data){
         var c_row = document.createElement("tr");
         cell = document.createElement("td");
         cell.innerHTML = data[i].movenum;
         c_row.appendChild(cell);
         cell = document.createElement("td");
         cell.innerHTML = ""+ data[i].commentator +': ' + data[i].comment;
         c_row.appendChild(cell);
         comment_tbody.appendChild (c_row);
      }
   }
   c_table.replaceChild (comment_tbody, c_table.tBodies[0]);
   if (logged_in){
      //clear comment textfield, msg on successful comment
      var comment_field = document.getElementById("Leocorno");
      comment_field.value= "";
      var comment_badness = document.getElementById("cBadness");
      comment_badness.innerHTML = "";
   }
}

//appends moves to empty <select>, and highlights latest move.
function render_moves_list (moves){
   var moves_select = document.getElementById('moves_select');
   for (i in moves){
      //var move    = moves[i].move;
      var move    = moves[i].pretty_node;
      var side    = moves[i].side;
      var movenum = moves[i].movenum;
      var option = new Option (movenum +": "+ side +', '+ move, movenum);
      moves_select.add (option, null);
   }
}

function highlight_node (move){
   var node_pattern = /^\{([^{}]+)\}$/;
   var match_node = node_pattern.exec(move.move);
   if (!match_node) return; //something like 'pass' or 'resign', i guess

   var img = document.getElementById ('img ' + match_node[1]);
   if (!img) return; //something wrong
   var special_src = img_base +'/'+ move.side + 'm.gif';
   img.setAttribute('src', special_src);
}

$(document).ready(function() {
   if (!gameid) {return}//something wrong

   stones_clickable = 0;
   space_clickable = board_clickable;
   render_board();

   //dl & display comments
   $.getJSON (
      url_base +"/comments/"+ gameid,
      function (data) {render_comment_table(data[1])}
      //data is ['success', game_comments]
   );

   //dl & display move list
   $.getJSON ( url_base +"/game/"+ gameid +"/allmoves",
      function (data) {
         if (data[0] == 'success'){
            var moves = data[1];
            if (moves.length){
               render_moves_list (moves);
               highlight_node (moves[moves.length-1]);
               document.getElementById('moves_pecan').style.display= '';
            }
            else{
               document.getElementById('moves_pecan').style.display= 'none';
            }
         }
         else
            alert (data[0]);
      }
      //data is ['success', game_moves]
   );

   //set up comment submission form
   //by binding 'new_comment' form and provide a simple callback function
   $('#new_comment').ajaxForm(function(json, success, object) {
      var msg_plus_data = eval ('('+json+')');
      var msg = msg_plus_data [0];
      if (msg == 'success'){
         var comments_data = msg_plus_data[1];
         render_comment_table (comments_data);
         return;
      }
      //failure
      var comment_badness = document.getElementById("cBadness");
      comment_badness.innerHTML = msg;
   });
});

<|endoftext|>


<commit_before>!function(n){function e(i){if(t[i])return t[i].exports;var r=t[i]={exports:{},id:i,loaded:!1};return n[i].call(r.exports,r,r.exports,e),r.loaded=!0,r.exports}var t={};return e.m=n,e.c=t,e.p="",e(0)}([function(n,e){!function(n){"use strict";var e=function(e){return{restrict:"E",scope:{config:"=funMetisConfig",events:"=funMetisEvents"},link:function(t,i){var r=i.find("> nav > ul");r.addClass("metismenu");var u=t.config||{},o=t.events||{};e(function(){var e=r.metisMenu(u);n.forEach(o,function(n){e.on(n.type,n.callback)})})}}};n.module("funMetisMenu",[]).directive("funMetisMenu",["$timeout",e])}(angular)}]);<commit_msg>delete dist dir<commit_after><|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();

router.get('/', global.apiCall, function(req, res, next) {
	res.json({
		status: "ok",
		version: "1"
	});
});

router.get('/announcements/get/:date', global.apiCall, function(req, res, next) {
	if (req.params.date == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid date parameter!"
		});
		return;
	}
	global.knex.select('*').from('planner_announcements').limit(1).where({
		date: req.params.date
	}).then(function (data) {
		if (data.length == 0) {
			res.json({
				status: "ok",
				announcement: null
			});
		} else {
			res.json({
				status: "ok",
				announcement: data[0]
			});
		}
	}).catch(function(error) {
		console.error("DB ERROR!");
		console.error(error);
		res.json({
			status: "error",
			error: "Database error"
		});
	});
});

router.get('/fridays/get/:date', global.apiCall, function(req, res, next) {
	if (req.params.date == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid date parameter!"
		});
		return;
	}
	global.knex.select('*').from('planner_fridays').limit(1).where({
		date: req.params.date
	}).then(function (data) {
		if (data.length == 0) {
			res.json({
				status: "ok",
				friday: null
			});
		} else {
			res.json({
				status: "ok",
				friday: data[0]
			});
		}
	}).catch(function(error) {
		console.error("DB ERROR!");
		console.error(error);
		res.json({
			status: "error",
			error: "Database error"
		});
	});
});

router.get('/events/get/:date/:section_index', global.apiCall, global.requireUser, global.getUserRecord, function(req, res, next) {
	if (req.params.date == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid date parameter!"
		});
		return;
	}
	if (req.params.section_index == undefined || parseInt(req.params.section_index) == NaN) {
		res.json({
			status: "error",
			error: "Missing or invalid section index parameter!"
		});
		return;
	}
	knex("planner_events").select("*").where({
		userId: res.locals.user.id,
		date: req.params.date,
		sectionIndex: req.params.section_index
	}).then(function(obj) {
		res.json({
			status: "ok",
			date: req.params.date,
			events: obj
		});
	}).catch(function() {
		res.json({
			status: "error",
			date: req.params.date,
			error: "Unknown database error"
		});
	});
});

router.post('/events/post/', global.apiCall, global.requireUser, global.getUserRecord, function(req, res, next) {
	if (req.body.date == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid date parameter!"
		});
		return;
	}
	if (req.body.subjectIndex == undefined || parseInt(req.body.subjectIndex) == NaN) {
		res.json({
			status: "error",
			error: "Missing or invalid section index parameter!"
		});
		return;
	}
	if (req.body.text == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid text parameter!"
		});
		return;
	}
	if (req.body.done == undefined || parseInt(req.body.done) == NaN || (parseInt(req.body.done) != 0 && parseInt(req.body.done) != 1)) {
		res.json({
			status: "error",
			error: "Missing or invalid done parameter!"
		});
		return;
	}
	knex("planner_events").select("*").where({
		userId: res.locals.user.id,
		date: req.body.date,
		sectionIndex: req.body.subjectIndex
	}).then(function(obj) {
		if (obj.length == 0) {
			// no event, insert it
			knex("planner_events").insert({
				sectionIndex: req.body.subjectIndex,
				userId: res.locals.user.id,
				date: req.body.date,
				text: req.body.text,
				done: req.body.done
			}).then(function() {
				res.json({
					status: "ok"
				});
			});/*.catch(function() {
				res.json({
					status: "error",
					error: "Database error"
				});
			});*/
		} else {
			// an event! update it
			knex("planner_events").where({ eventId: obj[0].eventId }).update({
				text: req.body.text,
				done: req.body.done
			}).then(function() {
				res.json({
					status: "ok"
				});
			});/*.catch(function() {
				res.json({
					status: "error",
					error: "Database error"
				});
			});*/
		}
	});/*.catch(function() {
		res.json({
			status: "error",
			error: "Unknown database error"
		});
	});*/
});

router.get('/sections/get/', global.apiCall, global.requireUser, global.getUserRecord, function(req, res, next) {
	knex("planner_sections").select("*").where({
		userId: res.locals.user.id
	}).then(function(obj) {
		res.json({
			status: "ok",
			sections: obj
		});
	});
});

router.post('/sections/add', global.apiCall, global.requireUser, global.getUserRecord, function(req, res, next) {
	if (req.body.sectionName == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid section name parameter!"
		});
		return;
	}
	knex("planner_sections").select("*").where({
		userId: res.locals.user.id
	}).then(function(obj) {
		knex("planner_sections").insert({
			sectionIndex: obj.length,
			name: req.body.sectionName,
			userId: res.locals.user.id
		}).then(function() {
			res.json({
				status: "ok",
				newIndex: obj.length
			});
		}).catch(function() {
			res.json({
				status: "error",
				error: "Unknown database error."
			});
		});
	}).catch(function() {
		res.json({
			status: "error",
			error: "Unknown database error."
		});
	});
});

router.post('/sections/remove', global.apiCall, global.requireUser, global.getUserRecord, function(req, res, next) {
	if (req.body.sectionIndex == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid section index parameter!"
		});
		return;
	}
	// use a transaction for consistency
	knex.transaction(function(trx) {
		return trx("planner_sections").select("*").where({
			userId: res.locals.user.id,
			sectionIndex: req.body.sectionIndex
		}).then(function(obj) {
			var itm = obj[0];
			return trx("planner_sections").where({
				sectionGid: itm.sectionGid
			}).update({
				sectionIndex: itm.sectionIndex * -1, // TODO: change this to del after beta and code path is tested
				userId: itm.userId * -1
			}).then(function() {
				return trx("planner_events").where({
					sectionIndex: itm.sectionIndex, // TODO: see above comment
					userId: itm.userId
				}).update({
					sectionIndex: itm.sectionIndex * -1,
					userId: itm.userId * -1
				});
			});
		});
	}).then(function() {
		res.json({
			status: "ok"
		});
	}).catch(function() {
		res.json({
			status: "error",
			error: "Unknown database error."
		});
	});
});

module.exports = router;<commit_msg>Fix adding sections after deleting one<commit_after>var express = require('express');
var router = express.Router();

router.get('/', global.apiCall, function(req, res, next) {
	res.json({
		status: "ok",
		version: "1"
	});
});

router.get('/announcements/get/:date', global.apiCall, function(req, res, next) {
	if (req.params.date == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid date parameter!"
		});
		return;
	}
	global.knex.select('*').from('planner_announcements').limit(1).where({
		date: req.params.date
	}).then(function (data) {
		if (data.length == 0) {
			res.json({
				status: "ok",
				announcement: null
			});
		} else {
			res.json({
				status: "ok",
				announcement: data[0]
			});
		}
	}).catch(function(error) {
		console.error("DB ERROR!");
		console.error(error);
		res.json({
			status: "error",
			error: "Database error"
		});
	});
});

router.get('/fridays/get/:date', global.apiCall, function(req, res, next) {
	if (req.params.date == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid date parameter!"
		});
		return;
	}
	global.knex.select('*').from('planner_fridays').limit(1).where({
		date: req.params.date
	}).then(function (data) {
		if (data.length == 0) {
			res.json({
				status: "ok",
				friday: null
			});
		} else {
			res.json({
				status: "ok",
				friday: data[0]
			});
		}
	}).catch(function(error) {
		console.error("DB ERROR!");
		console.error(error);
		res.json({
			status: "error",
			error: "Database error"
		});
	});
});

router.get('/events/get/:date/:section_index', global.apiCall, global.requireUser, global.getUserRecord, function(req, res, next) {
	if (req.params.date == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid date parameter!"
		});
		return;
	}
	if (req.params.section_index == undefined || parseInt(req.params.section_index) == NaN) {
		res.json({
			status: "error",
			error: "Missing or invalid section index parameter!"
		});
		return;
	}
	knex("planner_events").select("*").where({
		userId: res.locals.user.id,
		date: req.params.date,
		sectionIndex: req.params.section_index
	}).then(function(obj) {
		res.json({
			status: "ok",
			date: req.params.date,
			events: obj
		});
	}).catch(function() {
		res.json({
			status: "error",
			date: req.params.date,
			error: "Unknown database error"
		});
	});
});

router.post('/events/post/', global.apiCall, global.requireUser, global.getUserRecord, function(req, res, next) {
	if (req.body.date == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid date parameter!"
		});
		return;
	}
	if (req.body.subjectIndex == undefined || parseInt(req.body.subjectIndex) == NaN) {
		res.json({
			status: "error",
			error: "Missing or invalid section index parameter!"
		});
		return;
	}
	if (req.body.text == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid text parameter!"
		});
		return;
	}
	if (req.body.done == undefined || parseInt(req.body.done) == NaN || (parseInt(req.body.done) != 0 && parseInt(req.body.done) != 1)) {
		res.json({
			status: "error",
			error: "Missing or invalid done parameter!"
		});
		return;
	}
	knex("planner_events").select("*").where({
		userId: res.locals.user.id,
		date: req.body.date,
		sectionIndex: req.body.subjectIndex
	}).then(function(obj) {
		if (obj.length == 0) {
			// no event, insert it
			knex("planner_events").insert({
				sectionIndex: req.body.subjectIndex,
				userId: res.locals.user.id,
				date: req.body.date,
				text: req.body.text,
				done: req.body.done
			}).then(function() {
				res.json({
					status: "ok"
				});
			});/*.catch(function() {
				res.json({
					status: "error",
					error: "Database error"
				});
			});*/
		} else {
			// an event! update it
			knex("planner_events").where({ eventId: obj[0].eventId }).update({
				text: req.body.text,
				done: req.body.done
			}).then(function() {
				res.json({
					status: "ok"
				});
			});/*.catch(function() {
				res.json({
					status: "error",
					error: "Database error"
				});
			});*/
		}
	});/*.catch(function() {
		res.json({
			status: "error",
			error: "Unknown database error"
		});
	});*/
});

router.get('/sections/get/', global.apiCall, global.requireUser, global.getUserRecord, function(req, res, next) {
	knex("planner_sections").select("*").where({
		userId: res.locals.user.id
	}).then(function(obj) {
		res.json({
			status: "ok",
			sections: obj
		});
	});
});

router.post('/sections/add', global.apiCall, global.requireUser, global.getUserRecord, function(req, res, next) {
	if (req.body.sectionName == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid section name parameter!"
		});
		return;
	}
	knex("planner_sections").select("*").where({
		userId: res.locals.user.id
	}).then(function(obj) {
		knex("planner_sections").insert({
			sectionIndex: obj[obj.length - 1].sectionIndex,
			name: req.body.sectionName,
			userId: res.locals.user.id
		}).then(function() {
			res.json({
				status: "ok",
				newIndex: obj.length
			});
		}).catch(function() {
			res.json({
				status: "error",
				error: "Unknown database error."
			});
		});
	}).catch(function() {
		res.json({
			status: "error",
			error: "Unknown database error."
		});
	});
});

router.post('/sections/remove', global.apiCall, global.requireUser, global.getUserRecord, function(req, res, next) {
	if (req.body.sectionIndex == undefined) {
		res.json({
			status: "error",
			error: "Missing or invalid section index parameter!"
		});
		return;
	}
	// use a transaction for consistency
	knex.transaction(function(trx) {
		return trx("planner_sections").select("*").where({
			userId: res.locals.user.id,
			sectionIndex: req.body.sectionIndex
		}).then(function(obj) {
			var itm = obj[0];
			return trx("planner_sections").where({
				sectionGid: itm.sectionGid
			}).update({
				sectionIndex: itm.sectionIndex * -1, // TODO: change this to del after beta and code path is tested
				userId: itm.userId * -1
			}).then(function() {
				return trx("planner_events").where({
					sectionIndex: itm.sectionIndex, // TODO: see above comment
					userId: itm.userId
				}).update({
					sectionIndex: itm.sectionIndex * -1,
					userId: itm.userId * -1
				});
			});
		});
	}).then(function() {
		res.json({
			status: "ok"
		});
	}).catch(function() {
		res.json({
			status: "error",
			error: "Unknown database error."
		});
	});
});

module.exports = router;<|endoftext|>