<commit_before>/*
 *  Scrapedown - make a fist at turning a Web page into markdown
 */
function loadScript(src, callback, value) {
    var r = false;
    var js = document.createElement('script');
    js.type = 'text/javascript';
    js.src = scrapedown_location + src;
    js.onload = js.onreadystatechange = function() {
        if (!r && (!this.readyState || this.readyState == 'complete')) {
          r = true;
          callback(value);
        }
    };
    document.body.appendChild(js);
}

scrapedown_init();

/*
 *  convert selected text, or readability page
 */
function  scrapedown_init() {
    var html = getSelectionHtml();
    loadScript("readability.js", function () {
        readability.init(function (div) {
            if (!html) {
                html = div.innerHTML;
            }
            scrapedown_html(html);
        });
    });
}

/*
 *  convert to-markdown
 */
function scrapedown_html(html) {
    loadScript("to-markdown.js", function () {
        var text = toMarkdown(html);
        scrapedown_build_gui();
        document.getElementById('inputPane').value = text;

        loadScript("marked.js", function () {
            scrapedown_render();

            // polling for changes is a little clumsy, but most reliable ..
            window.setInterval(scrapedown_render, 500);
        });
    });
}

/*
 *  create gui
 */
function scrapedown_build_gui(text) {

    var gui = document.createElement("div");
    gui.id = "scrapedown";

    var left = document.createElement("div");
    left.id = "leftContainer";
    gui.appendChild(left);

    var textarea = document.createElement("textarea");
    textarea.id = "inputPane";
    textarea.setAttribute("class", "pane");
    textarea.setAttribute("cols", 80);
    textarea.setAttribute("rows", 20);
    left.appendChild(textarea);

    var right = document.createElement("div");
    right.id = "rightContainer";
    gui.appendChild(right);

    var preview = document.createElement("div");
    preview.setAttribute("class", "pane");
    preview.id = "previewPane";
    right.appendChild(preview);

    document.body.appendChild(gui);
}

/*
 *  render preview of markdown text
 */
var lastText;
var converter;

function scrapedown_render() {

    text = document.getElementById('inputPane').value;

    if (text === lastText) {
        return;
    }
    lastText = text;

    document.getElementById('previewPane').innerHTML = marked(text);
};

/*
 *  attempt to get the selected portion of the page as HTML
 */
function getSelectionHtml() {
    var html = "";
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            html = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            html = document.selection.createRange().htmlText;
        }
    }
    return html;
}
<commit_msg>Added polyfill for the Array.map function for IE<commit_after>/*
 *  Scrapedown - make a fist at turning a Web page into markdown
 */
function loadScript(src, callback, value) {
    var r = false;
    var js = document.createElement('script');
    js.type = 'text/javascript';
    js.src = scrapedown_location + src;
    js.onload = js.onreadystatechange = function() {
        if (!r && (!this.readyState || this.readyState == 'complete')) {
          r = true;
          callback(value);
        }
    };
    document.body.appendChild(js);
}

/*
 *  polyfill the Array.map function
 */
(function(fn){
    if (!fn.map) fn.map=function(f){var r=[];for(var i=0;i<this.length;i++)r.push(f(this[i]));return r}
    if (!fn.filter) fn.filter=function(f){var r=[];for(var i=0;i<this.length;i++)if(f(this[i]))r.push(this[i]);return r}
})(Array.prototype);

scrapedown_init();

/*
 *  convert selected text, or readability page
 */
function  scrapedown_init() {
    var html = getSelectionHtml();
    loadScript("readability.js", function () {
        readability.init(function (div) {
            if (!html) {
                html = div.innerHTML;
            }
            scrapedown_html(html);
        });
    });
}

/*
 *  convert to-markdown
 */
function scrapedown_html(html) {
    loadScript("to-markdown.js", function () {
        var text = toMarkdown(html);
        scrapedown_build_gui();
        document.getElementById('inputPane').value = text;

        loadScript("marked.js", function () {
            scrapedown_render();

            // polling for changes is a little clumsy, but most reliable ..
            window.setInterval(scrapedown_render, 500);
        });
    });
}

/*
 *  create gui
 */
function scrapedown_build_gui(text) {

    var gui = document.createElement("div");
    gui.id = "scrapedown";

    var left = document.createElement("div");
    left.id = "leftContainer";
    gui.appendChild(left);

    var textarea = document.createElement("textarea");
    textarea.id = "inputPane";
    textarea.setAttribute("class", "pane");
    textarea.setAttribute("cols", 80);
    textarea.setAttribute("rows", 20);
    left.appendChild(textarea);

    var right = document.createElement("div");
    right.id = "rightContainer";
    gui.appendChild(right);

    var preview = document.createElement("div");
    preview.setAttribute("class", "pane");
    preview.id = "previewPane";
    right.appendChild(preview);

    document.body.appendChild(gui);
}

/*
 *  render preview of markdown text
 */
var lastText;
var converter;

function scrapedown_render() {

    text = document.getElementById('inputPane').value;

    if (text === lastText) {
        return;
    }
    lastText = text;

    document.getElementById('previewPane').innerHTML = marked(text);
};

/*
 *  attempt to get the selected portion of the page as HTML
 */
function getSelectionHtml() {
    var html = "";
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            html = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            html = document.selection.createRange().htmlText;
        }
    }
    return html;
}
<|endoftext|>


<commit_before>import strip from "strip"
import sanitizeHtml from "sanitize-html"
import entities from "entities"
import moment from "moment"
import request from "request"
import normalize from "normalize-url"
import FeedParser from "feedparser"
import zlib from "zlib"
import podcastParser from "./podcast_parser_sax"

import Podcast from "../models/podcast" // eslint-disable-line
import Episode from "../models/episode"

import config from "../config" // eslint-disable-line
import logger from "../utils/logger"
import { getStatsDClient } from '../utils/statsd';

const WindsUserAgent = "Winds: Open Source RSS & Podcast app: https://getstream.io/winds/"
const AcceptHeader = "text/html,application/xhtml+xml,application/xml"
const statsd = getStatsDClient()

// sanitize cleans the html before returning it to the frontend
var sanitize = function(dirty) {
    return sanitizeHtml(dirty, {
        allowedAttributes: {
            img: ["src", "title", "alt"],
        },
        allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),
    })
}

function ParseFeed(feedUrl, callback) {
    let t0 = new Date()

    let req = request(feedUrl, {
        pool: false,
        timeout: 10000,
		gzip: true,
    })

    req.setMaxListeners(50)
    req.setHeader("User-Agent", WindsUserAgent)
    req.setHeader("Accept", AcceptHeader)

    let feedparser = new FeedParser()

    req.on("error", err => {
        callback(err, null)
    })

    req.on("response", res => {
		statsd.timing("winds.parsers.feed.ttfb", (new Date() - t0))
        if (res.statusCode !== 200) {
            return feedparser.emit("error", new Error("Bad status code"))
        }

        let encoding = res.headers["content-encoding"] || "identity"

        if (encoding.match(/\bdeflate\b/)) {
            res = res.pipe(zlib.createInflate())
        } else if (encoding.match(/\bgzip\b/)) {
            res = res.pipe(zlib.createGunzip())
        }
        res.pipe(feedparser)
    })

    feedparser.on("error", err => {
        callback(err, null)
    })

    let feedContents = { articles: [] }

    feedparser.on("end", () => {
        callback(null, feedContents)
    })

    feedparser.on("readable", () => {
		let t0 = new Date()
        let postBuffer
        while ((postBuffer = feedparser.read())) {
            let post = Object.assign({}, postBuffer)

            let description = strip(entities.decodeHTML(post.description)).substring(0, 280)

            let parsedArticle = {
                content: sanitize(post.summary),
                description: description,
                enclosures: post.enclosures,
                publicationDate:
                    moment(post.pubdate).toISOString() ||
                    moment()
                        .subtract(feedContents.articles.length, "minutes") // feedContents.articles only gets pushed to every time we parse an article, so it serves as a reasonable offset.
                        .toISOString(),
                title: strip(entities.decodeHTML(post.title)),
                url: normalize(post.link),
                // For some sites like XKCD the content from RSS is better than Mercury
                // note that we don't actually get the images, OG scraping is more reliable
            }

            // HNEWS
            if (post.comments) {
                parsedArticle.commentUrl = post.comments
            }

            // product hunt comments url
            if (post.link.indexOf("https://www.producthunt.com") === 0) {
                let matches = post.description.match(/(https:\/\/www.producthunt.com\/posts\/.*)"/)
                if (matches.length) {
                    parsedArticle.commentUrl = matches[1]
                }
            }

            // nice images for XKCD
            if (post.link.indexOf("https://xkcd") === 0) {
                let matches = post.description.match(/(https:\/\/imgs.xkcd.com\/comics\/.*?)"/)
                if (matches.length) {
                    parsedArticle.images = { og: matches[1] }
                }
            }

            feedContents.articles.push(parsedArticle)
            feedContents.title = post.meta.title
            feedContents.link = post.meta.link
            feedContents.image = post.meta.image
        }
		statsd.timing("winds.parsers.feed.parse", (new Date() - t0))
    })
}

function ParsePodcast(podcastUrl, callback) {
    logger.info(`Attempting to parse podcast ${podcastUrl}`)
    let opts = {
        headers: {
            Accept: AcceptHeader,
            "User-Agent": WindsUserAgent,
        },
        pool: false,
        timeout: 10000,
        url: podcastUrl,
    }

    let podcastContents = { episodes: [] }

    request(opts, (error, response, responseData) => {
        // easy way to detect charset or encoding issues
        // let partialBody = response.body.substring(0,500)
        //logger.debug(`${podcastUrl} response \n${partialBody}`)
        podcastParser(responseData, (err, data) => {
            if (err) {
                return callback(err, null)
            }

            // the podcast metadata we care about:
            podcastContents.title = data.title
            podcastContents.link = data.link
            podcastContents.image = data.image
            podcastContents.description = data.description ? data.description.long : ""

            let episodes = data.episodes ? data.episodes : data

            episodes.map(episode => {
                try {
                    let url = episode.link
                    if (!url) {
                        url = episode.enclosure ? episode.enclosure.url : episode.guid
                    }
                    var parsedEpisode = new Episode({
                        description: strip(episode.description).substring(0, 280),
                        duration: episode.duration,
                        enclosure: episode.enclosure && episode.enclosure.url,
                        images: { og: episode.image },
                        link: episode.link,
                        publicationDate:
                            moment(episode.published).toISOString() ||
                            moment()
                                .subtract(podcastContents.episodes.length, "minutes")
                                .toISOString(),
                        title: strip(episode.title),
                        url: normalize(url),
                    })
                } catch (e) {
                    logger.error("Failed to parse episode", e)
                }
                podcastContents.episodes.push(parsedEpisode)
            })
            callback(null, podcastContents)
        })
    })
}

exports.ParseFeed = ParseFeed
exports.ParsePodcast = ParsePodcast
<commit_msg>refactor parsing code with better instrumentation<commit_after>import strip from "strip"
import sanitizeHtml from "sanitize-html"
import entities from "entities"
import moment from "moment"
import request from "request"
import normalize from "normalize-url"
import FeedParser from "feedparser"
import podcastParser from "./podcast_parser_sax"

import Podcast from "../models/podcast" // eslint-disable-line
import Episode from "../models/episode"

import config from "../config" // eslint-disable-line
import logger from "../utils/logger"
import { getStatsDClient } from '../utils/statsd';

const WindsUserAgent = "Winds: Open Source RSS & Podcast app: https://getstream.io/winds/"
const AcceptHeader = "text/html,application/xhtml+xml,application/xml"
const statsd = getStatsDClient()

// sanitize cleans the html before returning it to the frontend
var sanitize = function(dirty) {
    return sanitizeHtml(dirty, {
        allowedAttributes: {
            img: ["src", "title", "alt"],
        },
        allowedTags: sanitizeHtml.defaults.allowedTags.concat(["img"]),
    })
}

function ParseFeed(feedUrl, callback) {
    let t0 = new Date()
    let t1 = null
    let t2 = null
    let req = request(feedUrl, {
        pool: false,
        timeout: 10000,
		gzip: true,
    }, (error, response, body) => {
        if (error) {
            return
        }
		if (response.statusCode !== 200) {
			return feedparser.emit("error", new Error("Bad status code"))
		}
		statsd.timing("winds.parsers.feed.transfer", (new Date() - t1))
		t2 = new Date()
		feedparser.end(body, ()=>{
			statsd.timing("winds.parsers.feed.write_to_parser_stream", (new Date() - t2))
            console.log(`body size: ${body.length}`)
		})
    })

    req.setMaxListeners(50)
    req.setHeader("User-Agent", WindsUserAgent)
    req.setHeader("Accept", AcceptHeader)

    let feedparser = new FeedParser()

    req.on("error", err => {
        callback(err, null)
    })

    req.on("response", res => {
		if (res.statusCode === 200) {
			t1 = new Date()
			statsd.timing("winds.parsers.feed.ttfb", (new Date() - t0))
		}
    })

    feedparser.on("error", err => {
        callback(err, null)
    })

    let feedContents = { articles: [] }

    feedparser.on("end", () => {
        if (t2 !== null){
			statsd.timing("winds.parsers.feed.finished_parsing", (new Date() - t2))
        }
        callback(null, feedContents)
    })

    feedparser.on("readable", () => {
        let postBuffer
        while ((postBuffer = feedparser.read())) {
            let post = Object.assign({}, postBuffer)

            let description = strip(entities.decodeHTML(post.description)).substring(0, 280)

            let parsedArticle = {
                content: sanitize(post.summary),
                description: description,
                enclosures: post.enclosures,
                publicationDate:
                    moment(post.pubdate).toISOString() ||
                    moment()
                        .subtract(feedContents.articles.length, "minutes") // feedContents.articles only gets pushed to every time we parse an article, so it serves as a reasonable offset.
                        .toISOString(),
                title: strip(entities.decodeHTML(post.title)),
                url: normalize(post.link),
                // For some sites like XKCD the content from RSS is better than Mercury
                // note that we don't actually get the images, OG scraping is more reliable
            }

            // HNEWS
            if (post.comments) {
                parsedArticle.commentUrl = post.comments
            }

            // product hunt comments url
            if (post.link.indexOf("https://www.producthunt.com") === 0) {
                let matches = post.description.match(/(https:\/\/www.producthunt.com\/posts\/.*)"/)
                if (matches.length) {
                    parsedArticle.commentUrl = matches[1]
                }
            }

            // nice images for XKCD
            if (post.link.indexOf("https://xkcd") === 0) {
                let matches = post.description.match(/(https:\/\/imgs.xkcd.com\/comics\/.*?)"/)
                if (matches.length) {
                    parsedArticle.images = { og: matches[1] }
                }
            }

            feedContents.articles.push(parsedArticle)
            feedContents.title = post.meta.title
            feedContents.link = post.meta.link
            feedContents.image = post.meta.image
        }
    })
}

function ParsePodcast(podcastUrl, callback) {
    logger.info(`Attempting to parse podcast ${podcastUrl}`)
    let opts = {
        headers: {
            Accept: AcceptHeader,
            "User-Agent": WindsUserAgent,
        },
        pool: false,
        timeout: 10000,
        url: podcastUrl,
    }

    let podcastContents = { episodes: [] }

    request(opts, (error, response, responseData) => {
        // easy way to detect charset or encoding issues
        // let partialBody = response.body.substring(0,500)
        //logger.debug(`${podcastUrl} response \n${partialBody}`)
        podcastParser(responseData, (err, data) => {
            if (err) {
                return callback(err, null)
            }

            // the podcast metadata we care about:
            podcastContents.title = data.title
            podcastContents.link = data.link
            podcastContents.image = data.image
            podcastContents.description = data.description ? data.description.long : ""

            let episodes = data.episodes ? data.episodes : data

            episodes.map(episode => {
                try {
                    let url = episode.link
                    if (!url) {
                        url = episode.enclosure ? episode.enclosure.url : episode.guid
                    }
                    var parsedEpisode = new Episode({
                        description: strip(episode.description).substring(0, 280),
                        duration: episode.duration,
                        enclosure: episode.enclosure && episode.enclosure.url,
                        images: { og: episode.image },
                        link: episode.link,
                        publicationDate:
                            moment(episode.published).toISOString() ||
                            moment()
                                .subtract(podcastContents.episodes.length, "minutes")
                                .toISOString(),
                        title: strip(episode.title),
                        url: normalize(url),
                    })
                } catch (e) {
                    logger.error("Failed to parse episode", e)
                }
                podcastContents.episodes.push(parsedEpisode)
            })
            callback(null, podcastContents)
        })
    })
}

exports.ParseFeed = ParseFeed
exports.ParsePodcast = ParsePodcast
<|endoftext|>


<commit_before>var parse = require('csv-parse/lib/sync'),
	csvstr = require('csv-stringify'),
	fs = require('fs'),
	promise = require('bluebird'),
	_ = require('lodash'),
	headers,
	qs = require('querystring'),
	config = JSON.parse(fs.readFileSync('./munge-config.json')),
	round_re = /ROUND\W+(\d+)/;

var load_transcript = (fname) => {
	var text = fs.readFileSync(fname).toString(),
		first_sep_match = text.match(round_re),
		fidx = first_sep_match && text.indexOf(first_sep_match[0]),
		rtext = fidx && text.slice(fidx).split('\n').filter((x) => x.length > 0),
		rounds = [],
		cur_r = first_sep_match && parseInt(first_sep_match[1]);

	if (!first_sep_match) {
		console.error("No separator found in ", fname, " skipping");
		return;
	}

	rtext.map((line) => {
		var rT = rounds[cur_r] || '',
			m = line.match(round_re);
		if (m) {
			// incr and skip
			cur_r = parseInt(m[1]);
			console.info('next round ', fname, ' r ', cur_r);
			return;
		}
		rounds[cur_r] = rT + line;
	});

	return rounds;
},
load_transcripts = () => {
	var srcdir = config.transcripts;
	return fs.readdirSync(srcdir)
		.filter((fname) => fname.indexOf('.txt') >= 0)
		.reduce((d,fname) =>
			{
				d[fname.slice(0,-'.txt'.length)] = load_transcript([srcdir,fname].join('/'));
				return d;
			}, {});
},
load_rounds = () => {
	// loads data files in batch
	var srcdir = config.rounds;
	return fs.readdirSync(srcdir)
		.filter((fname) => fname.indexOf('.json') >= 0)
		.reduce((d,fname) =>
			{
				var filen = [srcdir,fname].join('/'),
					filed = JSON.parse(fs.readFileSync(filen).toString()),
					pid = filed.participant,
					rounds = filed;

				if (pid !== fname.slice(0,-'.json'.length)) {
					console.warn('file doestn match participant id ', pid, fname);
				}
				d[pid] = rounds;
				return d;
			},
			{});
}, gen_out = (transcripts, rounds, fakeapps) => {
	// get fields x
	var field_names = [
		'id',
		'round',
		'participant',
		'condition',
		'domain',
		'app_a',
		'type_a',
		'app_b',
		'type_b',
		'chosen',
		'type_chosen',
		'elapsed_secs',
		'confidence',
		'thinkaloud'
	],
	field_values = [
		(rounds, r, ri) => [rounds.participant,''+ri].join('-'), // unique id
		(rounds, r, ri) => ri+1,
		(rounds, r, ri) => rounds.participant,
		(rounds, r, ri) => r.cond,
		(rounds, r, ri) => r.domain,
		(rounds, r, ri) => r.a,
		(rounds, r, ri) => fakeapps[r.a],
		(rounds, r, ri) => r.b,
		(rounds, r, ri) => fakeapps[r.b],
		(rounds, r, ri) => r.result.chosen,
		(rounds, r, ri) => fakeapps[r.result.chosen],
		(rounds, r, ri) => Math.round(r.result.elapsed/1000.0),
		(rounds, r, ri) => parseInt(r.result.confidence.slice('likert'.length+1)),
		(rounds, r, ri) => transcripts[rounds.participant] && transcripts[rounds.participant][ri] || '~'
	];

	var rows = [field_names].concat(_.flatten(_.keys(rounds).map((participant) => {
		var rdata = rounds[participant];
		return _(rdata.rounds).map((r,i) => field_values.map((f) => {
			console.info(rdata.participant, i, field_names[field_values.indexOf(f)], f(rdata,r,i));
			return f(rdata,r,i);
		})).value();
	})));

	return new Promise((acc, rej) => {
		csvstr(rows, (err, output) => {
			if (!err) { return acc(output); }
			console.error("Error ", err);
			rej(err);
		});
	});
}, loadCSV = (fname) => {
	var text = 	fs.readFileSync(fname).toString();
	console.log("Parsing file ", fname, "(", text.length, ")");
	var data = parse(text, {max_limit_on_data_read:9999999999});
	headers = data[0];
	data = data.slice(1);
	data = data.map((x) => _.zipObject(headers,x));
	return data;
}, app2type = (apparr) => {
	// simply takes array [ { "App type code":'', "fake name": .. } ]
	// -> { fake name : app type code }

	return apparr.reduce((d, app) => {
		d[app['fake name']] = app['App type code'];
		return d;
	}, {});
},
main = (mode) => {
	var ts = load_transcripts(),
		rs = load_rounds(),
		fakeapps = app2type(loadCSV(config.fakeapps)),
		fout = config.out;

	if (!fout) {
		console.error("No output directory specified, please set out_dir in qual-chop-config");
		return;
	}

	console.info('loaded ', _.keys(ts).length, ' transcripts', _.keys(ts));
	console.info('loaded ', _.keys(rs).length, ' rounds ', _.keys(rs));

	console.info('fake apps ', fakeapps);

	gen_out(ts, rs, fakeapps).then((output) => {
		console.info("Writing output ", fout, fout.length);
		fs.writeFileSync(fout, output);
		console.log('done.');
	}).catch((err) => {
		console.error("Error, terminating ", err);
	});
};

if (require.main === module) { main(); }<commit_msg>core features<commit_after>var parse = require('csv-parse/lib/sync'),
	csvstr = require('csv-stringify'),
	fs = require('fs'),
	promise = require('bluebird'),
	_ = require('lodash'),
	headers,
	qs = require('querystring'),
	config = JSON.parse(fs.readFileSync('./munge-config.json')),
	cutils = require('./client-utils'),
	round_re = /ROUND\W+(\d+)/;

var load_transcript = (fname) => {
	var text = fs.readFileSync(fname).toString(),
		first_sep_match = text.match(round_re),
		fidx = first_sep_match && text.indexOf(first_sep_match[0]),
		rtext = fidx && text.slice(fidx).split('\n').filter((x) => x.length > 0),
		rounds = [],
		cur_r = first_sep_match && parseInt(first_sep_match[1]);

	if (!first_sep_match) {
		console.error("No separator found in ", fname, " skipping");
		return;
	}

	rtext.map((line) => {
		var rT = rounds[cur_r] || '',
			m = line.match(round_re);
		if (m) {
			// incr and skip
			cur_r = parseInt(m[1]);
			console.info('next round ', fname, ' r ', cur_r);
			return;
		}
		rounds[cur_r] = rT + line;
	});

	return rounds;
},
load_transcripts = () => {
	var srcdir = config.transcripts;
	return fs.readdirSync(srcdir)
		.filter((fname) => fname.indexOf('.txt') >= 0)
		.reduce((d,fname) =>
			{
				d[fname.slice(0,-'.txt'.length)] = load_transcript([srcdir,fname].join('/'));
				return d;
			}, {});
},
load_client = () => {
	var pitypes = JSON.parse(fs.readFileSync('../mitm_out/pi_by_host.json')),
		hosts = JSON.parse(fs.readFileSync('../mitm_out/host_by_app.json')),
		details =  JSON.parse(fs.readFileSync('../mitm_out/company_details.json')),
		allData = JSON.parse(fs.readFileSync('../mitm_out/data_all.json')),
		getAppCompany = (app) => allData.filter((x) => x.app === app)[0].company;

	return {
		getHosts:(app) => {
			var data = allData.filter((x) => x.app === app),
				hTh = cutils.makeHTH(data),
				hu = _.uniq(_.keys(hosts[app]).map((h) => hTh[h]));
			return hu;
		},
		getCompanies:(app) => {
			var c2pi = cutils.makeCompany2pi(app, allData.filter((x) => x.app === app), hosts, pitypes, 0);
			return _.keys(c2pi);
		},
		getCategories:(app) => {
			var c2pi = cutils.makeCompany2pi(app, allData.filter((x) => x.app === app), hosts, pitypes, 0),
				appcompany = getAppCompany(app),
				cat2c2pi = cutils.makeCategories(appcompany, details, c2pi);
			return _.keys(cat2c2pi);
		},
		getPermissions:(app) => {
			var c2pi = cutils.makeCompany2pi(app, allData.filter((x) => x.app === app), hosts, pitypes, 0),
				appcompany = getAppCompany(app),
				cat2c2pi = cutils.makeCategories(appcompany, details, c2pi),
				pits =  _(c2pi).values().flatten().uniq().value(),
				pi2cat = pits.reduce((red, pit) => {
					var cats = _.keys(cat2c2pi).filter((cat) => {
						return _(cat2c2pi[cat]).values().flatten().value().indexOf(pit) >= 0;
					});
					red[pit] = cats;
					return red;
				}, {});
			return _.keys(pi2cat).filter((k) => pi2cat[k].length);
		},
		getUnique:(app) => {
		}
	};
},
load_rounds = () => {
	// loads data files in batch
	var srcdir = config.rounds;
	return fs.readdirSync(srcdir)
		.filter((fname) => fname.indexOf('.json') >= 0)
		.reduce((d,fname) =>
			{
				var filen = [srcdir,fname].join('/'),
					filed = JSON.parse(fs.readFileSync(filen).toString()),
					pid = filed.participant,
					rounds = filed;

				if (pid !== fname.slice(0,-'.json'.length)) {
					console.warn('file doestn match participant id ', pid, fname);
				}
				d[pid] = rounds;
				return d;
			},
			{});
}, gen_out = (transcripts, rounds, fakeapps) => {
	// get fields x
	var client = load_client(),
		field_names = [
			'id',
			'round',
			'participant',
			'pdciApps',
			'npdci',
			'condition',
			'domain',
			'app_a',
			'type_a',
			'app_b',
			'type_b',
			'chosen',
			'type_chosen',
			'elapsed_secs',
			'confidence',
			'hosts_a',
			'hosts_b',
			'companies_a',
			'companies_b',
			'categories_a',
			'categories_b',
			'perms_a',
			'perms_b',
			'thinkaloud'
		],
		field_values = [
			(rounds, r, ri) => [rounds.participant,''+ri].join('-'), // unique id
			(rounds, r, ri) => ri+1,
			(rounds, r, ri) => rounds.participant,
			(rounds, r, ri) => rounds.pdciApps.join(';'),
			(rounds, r, ri) => rounds.pdciApps.length,
			(rounds, r, ri) => r.cond,
			(rounds, r, ri) => r.domain,
			(rounds, r, ri) => r.a,
			(rounds, r, ri) => fakeapps[r.a],
			(rounds, r, ri) => r.b,
			(rounds, r, ri) => fakeapps[r.b],
			(rounds, r, ri) => r.result.chosen,
			(rounds, r, ri) => fakeapps[r.result.chosen],
			(rounds, r, ri) => Math.round(r.result.elapsed/1000.0),
			(rounds, r, ri) => parseInt(r.result.confidence.slice('likert'.length+1)),
			// now features
			(rounds, r, ri) => client.getHosts(r.a).join(';'),
			(rounds, r, ri) => client.getHosts(r.b).join(';'),
			(rounds, r, ri) => client.getCompanies(r.a).join(';'),
			(rounds, r, ri) => client.getCompanies(r.b).join(';'),
			(rounds, r, ri) => client.getCategories(r.a).join(';'),
			(rounds, r, ri) => client.getCategories(r.b).join(';'),
			(rounds, r, ri) => client.getPermissions(r.a).join(';'),
			(rounds, r, ri) => client.getPermissions(r.b).join(';'),
			(rounds, r, ri) => transcripts[rounds.participant] && transcripts[rounds.participant][ri] || '~'
		];

	var rows = [field_names].concat(_.flatten(_.keys(rounds).map((participant) => {
		var rdata = rounds[participant];
		return _(rdata.rounds).map((r,i) => field_values.map((f) => {
			console.info(rdata.participant, i, field_names[field_values.indexOf(f)], f(rdata,r,i));
			return f(rdata,r,i);
		})).value();
	})));

	return new Promise((acc, rej) => {
		csvstr(rows, (err, output) => {
			if (!err) { return acc(output); }
			console.error("Error ", err);
			rej(err);
		});
	});
}, loadCSV = (fname) => {
	var text = 	fs.readFileSync(fname).toString();
	console.log("Parsing file ", fname, "(", text.length, ")");
	var data = parse(text, {max_limit_on_data_read:9999999999});
	headers = data[0];
	data = data.slice(1);
	data = data.map((x) => _.zipObject(headers,x));
	return data;
}, app2type = (apparr) => {
	// simply takes array [ { "App type code":'', "fake name": .. } ]
	// -> { fake name : app type code }

	return apparr.reduce((d, app) => {
		d[app['fake name']] = app['App type code'];
		return d;
	}, {});
},
main = (mode) => {
	var ts = load_transcripts(),
		rs = load_rounds(),
		fakeapps = app2type(loadCSV(config.fakeapps)),
		fout = config.out;

	if (!fout) {
		console.error("No output directory specified, please set out_dir in qual-chop-config");
		return;
	}

	console.info('loaded ', _.keys(ts).length, ' transcripts', _.keys(ts));
	console.info('loaded ', _.keys(rs).length, ' rounds ', _.keys(rs));

	console.info('fake apps ', fakeapps);

	gen_out(ts, rs, fakeapps).then((output) => {
		console.info("Writing output ", fout, fout.length);
		fs.writeFileSync(fout, output);
		console.log('done.');
	}).catch((err) => {
		console.error("Error, terminating ", err);
	});
};

if (require.main === module) { main(); }<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var inherits = require('util').inherits;
var extend = require('xtend');

var TChannelPeersBase = require('./peers_base.js');
var TChannelPeer = require('./peer');
var TChannelSelfPeer = require('./self_peer');

function TChannelRootPeers(channel, options) {
    if (!(this instanceof TChannelRootPeers)) {
        return new TChannelRootPeers(channel, options);
    }

    var self = this;
    TChannelPeersBase.call(self, channel, options);

    self.allocPeerEvent = self.defineEvent('allocPeer');
    self.peerOptions = self.options.peerOptions || {};

    self.selfPeer = null;
}

inherits(TChannelRootPeers, TChannelPeersBase);

TChannelRootPeers.prototype.close = function close(callback) {
    var self = this;

    var peers = self.values();
    if (self.selfPeer) {
        peers.push(self.selfPeer);
    }
    TChannelPeersBase.prototype.close.call(self, peers, callback);
};

TChannelRootPeers.prototype.sanitySweep =
function sanitySweep(callback) {
    var self = this;

    if (self.selfPeer) {
        for (var i = 0; i < self.selfPeer.connections.length; i++) {
            var conn = self.selfPeer.connections[i];
            conn.ops.sanitySweep();
        }
    }

    TChannelPeersBase.prototype.sanitySweep.call(self, callback);
};

TChannelRootPeers.prototype.getSelfPeer = function getSelfPeer() {
    var self = this;

    if (!self.selfPeer) {
        self.selfPeer = TChannelSelfPeer(self.channel);
    }
    return self.selfPeer;
};

TChannelRootPeers.prototype.add = function add(hostPort, options) {
    /*eslint max-statements: [2, 25]*/
    var self = this;

    var peer = self._map[hostPort];
    if (peer) {
        return peer;
    }

    if (hostPort === self.channel.hostPort) {
        return self.getSelfPeer();
    }

    options = options || extend({}, self.peerOptions);
    options.preferConnectionDirection = self.preferConnectionDirection;
    peer = TChannelPeer(self.channel, hostPort, options);
    self.allocPeerEvent.emit(self, peer);

    self._map[hostPort] = peer;
    self._keys.push(hostPort);

    return peer;
};

TChannelRootPeers.prototype.clear = function clear() {
    var self = this;

    var names = Object.keys(self.channel.subChannels);
    for (var i = 0; i < names.length; i++) {
        var subChannel = self.channel.subChannels[names[i]];
        subChannel.peers.clear();
    }

    self._map = Object.create(null);
    self._keys = [];
};

TChannelRootPeers.prototype._delete = function _del(peer) {
    var self = this;

    var names = Object.keys(self.channel.subChannels);
    for (var i = 0; i < names.length; i++) {
        var subChannel = self.channel.subChannels[names[i]];
        subChannel.peers._delete(peer);
    }

    delete self._map[peer.hostPort];
    var index = self._keys.indexOf(peer.hostPort);
    popout(self._keys, index);
};

TChannelRootPeers.prototype.choosePeer = function choosePeer(req) {
    return null;
};

function popout(array, i) {
    if (!array.length) {
        return;
    }

    var j = array.length - 1;
    if (i !== j) {
        var tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
    array.pop();
}

module.exports = TChannelRootPeers;
<commit_msg>root_peers: return early for common sanitySweep case<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var inherits = require('util').inherits;
var extend = require('xtend');

var TChannelPeersBase = require('./peers_base.js');
var TChannelPeer = require('./peer');
var TChannelSelfPeer = require('./self_peer');

function TChannelRootPeers(channel, options) {
    if (!(this instanceof TChannelRootPeers)) {
        return new TChannelRootPeers(channel, options);
    }

    var self = this;
    TChannelPeersBase.call(self, channel, options);

    self.allocPeerEvent = self.defineEvent('allocPeer');
    self.peerOptions = self.options.peerOptions || {};

    self.selfPeer = null;
}

inherits(TChannelRootPeers, TChannelPeersBase);

TChannelRootPeers.prototype.close = function close(callback) {
    var self = this;

    var peers = self.values();
    if (self.selfPeer) {
        peers.push(self.selfPeer);
    }
    TChannelPeersBase.prototype.close.call(self, peers, callback);
};

TChannelRootPeers.prototype.sanitySweep =
function sanitySweep(callback) {
    var self = this;

    if (!self.selfPeer) {
        TChannelPeersBase.prototype.sanitySweep.call(self, callback);
        return;
    }

    for (var i = 0; i < self.selfPeer.connections.length; i++) {
        var conn = self.selfPeer.connections[i];
        conn.ops.sanitySweep();
    }

    TChannelPeersBase.prototype.sanitySweep.call(self, callback);
};

TChannelRootPeers.prototype.getSelfPeer = function getSelfPeer() {
    var self = this;

    if (!self.selfPeer) {
        self.selfPeer = TChannelSelfPeer(self.channel);
    }
    return self.selfPeer;
};

TChannelRootPeers.prototype.add = function add(hostPort, options) {
    /*eslint max-statements: [2, 25]*/
    var self = this;

    var peer = self._map[hostPort];
    if (peer) {
        return peer;
    }

    if (hostPort === self.channel.hostPort) {
        return self.getSelfPeer();
    }

    options = options || extend({}, self.peerOptions);
    options.preferConnectionDirection = self.preferConnectionDirection;
    peer = TChannelPeer(self.channel, hostPort, options);
    self.allocPeerEvent.emit(self, peer);

    self._map[hostPort] = peer;
    self._keys.push(hostPort);

    return peer;
};

TChannelRootPeers.prototype.clear = function clear() {
    var self = this;

    var names = Object.keys(self.channel.subChannels);
    for (var i = 0; i < names.length; i++) {
        var subChannel = self.channel.subChannels[names[i]];
        subChannel.peers.clear();
    }

    self._map = Object.create(null);
    self._keys = [];
};

TChannelRootPeers.prototype._delete = function _del(peer) {
    var self = this;

    var names = Object.keys(self.channel.subChannels);
    for (var i = 0; i < names.length; i++) {
        var subChannel = self.channel.subChannels[names[i]];
        subChannel.peers._delete(peer);
    }

    delete self._map[peer.hostPort];
    var index = self._keys.indexOf(peer.hostPort);
    popout(self._keys, index);
};

TChannelRootPeers.prototype.choosePeer = function choosePeer(req) {
    return null;
};

function popout(array, i) {
    if (!array.length) {
        return;
    }

    var j = array.length - 1;
    if (i !== j) {
        var tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
    array.pop();
}

module.exports = TChannelRootPeers;
<|endoftext|>


<commit_before>/**
 * This file is part of the DreamFactory Services Platform(tm) (DSP)
 *
 * DreamFactory Services Platform(tm) <http://github.com/dreamfactorysoftware/dsp-core>
 * Copyright 2012-2014 DreamFactory Software, Inc. <support@dreamfactory.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';
var loginFrame = $("#login-frame");
var loginPage = $("#login-page");
var container = $("#container");

/**
 * Angular module declaration
 */
angular.module("AdminApp", [
	"ngRoute",
	"ngResource",
	"ngGrid",
	"AdminApp.controllers",
	"AdminApp.apisdk"
])
	.config([
		'$routeProvider',
		'$locationProvider',
		'$httpProvider',
		function ($routeProvider, $locationProvider, $httpProvider) {

			$routeProvider.when('/', {
				controller:  QuickStartCtrl,
				templateUrl: 'quick-start.html'
			});
			$routeProvider.when('/app', {
				controller:  AppCtrl,
				templateUrl: 'applications.html'
			});
			$routeProvider.when('/user', {
				controller:  UserCtrl,
				templateUrl: 'users.html'
			});
			$routeProvider.when('/role', {
				controller:  RoleCtrl,
				templateUrl: 'roles.html'
			});
			$routeProvider.when('/group', {
				controller:  GroupCtrl,
				templateUrl: 'groups.html'
			});
			$routeProvider.when('/schema', {
				controller:  SchemaCtrl,
				templateUrl: 'schema.html'
			});
			$routeProvider.when('/service', {
				controller:  ServiceCtrl,
				templateUrl: 'services.html'
			});
			$routeProvider.when('/import', {
				controller:  FileCtrl,
				templateUrl: 'import.html'
			});
			$routeProvider.when('/file', {
				controller:  FileCtrl,
				templateUrl: 'files.html'
			});
			$routeProvider.when('/package', {
				controller:  PackageCtrl,
				templateUrl: 'package.html'
			});
			$routeProvider.when('/config', {
				controller:  ConfigCtrl,
				templateUrl: 'config.html'
			});
			$routeProvider.when('/data', {
				controller:  DataCtrl,
				templateUrl: 'data.html'
			});
			$routeProvider.when('/scripts', {
				controller:  ScriptCtrl,
				templateUrl: 'scripts.html'
			});
			$routeProvider.when('/api', {
				controller:  'ApiSDKCtrl',
				templateUrl: 'apisdk.html'
			});

			var interceptor = ['$location', '$q', '$rootScope',
				function ($location, $q, $rootScope) {
					function success(response) {

						return response;
					}

					function error(response) {

						if (response.status === 401) {
							if (response.config.method === "GET") {
								$rootScope.$broadcast("error:401", function () {
									window.location.reload(true);
								});
							} else {
								$rootScope.$broadcast("error:401", null);
							}

							return $q.reject(response);
						} else {
							$.pnotify({
								title: "Error",
								type:  'error',
								text:  response.data.error[0].message
							});
							return $q.reject(response);
						}
					}

					return function (promise) {
						return promise.then(success, error);
					}
				}
			];

			$httpProvider.responseInterceptors.push(interceptor);
		}

	])
	.factory('AppsRelated', function ($resource) {
		return $resource('/rest/system/app/:id/?app_name=admin&fields=*&related=roles', {}, {
			update: {
				method: 'PUT'
			},
			query:  {
				method:  'GET',
				isArray: false
			}
		});
	})
	.factory('AppsRelatedToService', function ($resource) {
		return $resource('/rest/system/app/:id/?app_name=admin&fields=*&related=app_service_relations', {}, {
			update: {
				method: 'PUT'
			},
			query:  {
				method:  'GET',
				isArray: false
			}
		});
	})
	.factory('App', function ($resource) {
		return $resource('/rest/system/app/:id/?app_name=admin&fields=*', {}, {
			update: {
				method: 'PUT'
			},
			query:  {
				method:  'GET',
				isArray: false
			}
		});
	})
	.factory('User', function ($resource) {
		return $resource('/rest/system/user/:id/?app_name=admin&fields=*&related=lookup_keys&order=display_name%20ASC', {
			send_invite: false
		}, {
			update: {
				method: 'PUT'
			},
			query:  {
				method:  'GET',
				isArray: false
			}
		});
	})
	.factory('Role', function ($resource) {
		return $resource('/rest/system/role/:id/?app_name=admin&fields=*', {}, {
			update: {
				method: 'PUT'
			},
			query:  {
				method:  'GET',
				isArray: false
			}
		})
	})
	.factory('RolesRelated', function ($resource) {
		return $resource('/rest/system/role/:id/?app_name=admin&fields=*&related=users,apps,role_service_accesses,role_system_accesses,lookup_keys', {}, {
			update: {
				method: 'PUT'
			},
			query:  {
				method:  'GET',
				isArray: false
			}
		});
	})
	.factory('Service', function ($resource) {
		return $resource('/rest/system/service/:id/?app_name=admin&fields=*', {}, {
			update: {
				method: 'PUT'
			},
			query:  {
				method:  'GET',
				isArray: false
			}
		});
	})
	.factory('Schema', function ($resource) {
		return $resource('/rest/schema/:name/?app_name=admin&fields=*', {}, {
			update: {
				method: 'PUT'
			},
			query:  {
				method:  'GET',
				isArray: false
			}
		});
	})
	.factory('DB', function ($resource) {
		return $resource('/rest/db/:name/?app_name=admin&fields=*&include_schema=true', {}, {
			update: {
				method: 'PUT'
			},
			query:  {
				method:  'GET',
				isArray: false
			}
		});
	})
	.factory('Group', function ($resource) {
		return $resource('/rest/system/app_group/:id/?app_name=admin&fields=*&related=apps', {}, {
			update: {
				method: 'PUT'
			},
			query:  {
				method:  'GET',
				isArray: false
			}
		});
	})
	.factory('Config', function ($resource) {
		return $resource('/rest/system/config/?app_name=admin', {}, {
			update: {
				method: 'PUT'
			},
			query:  {
				method:  'GET',
				isArray: false
			}
		});
	})
	.factory('Event', function ($resource) {
		return $resource('/rest/system/event/?app_name=admin', {}, {
			update: {
				method: 'PUT'
			},
			query:  {
				method:  'GET',
				isArray: false
			}
		});
	})
	.factory('EmailTemplates', function ($resource) {
		return $resource('/rest/system/email_template/:id/?app_name=admin&fields=*', {}, {
			update: {
				method: 'PUT'
			}
		});
	})
	.run(function ($rootScope) {
		$rootScope.$on("error:401", function (message, data) {
			$rootScope.showLogin();
			$rootScope.onReturn = function () {

				if (data) {
					data();
				}
			};

		});
		$rootScope.showLogin = function () {
			container.hide();
			loginFrame.attr("src", "");
			loginFrame.attr("src", "../web/login");
			loginFrame.load(function () {
				$rootScope.checkLogin();
			});
			loginPage.show();
		}
		$rootScope.hideLogin = function () {
			container.show();
			loginPage.hide();
			$rootScope.onReturn();

		};
		$rootScope.checkLogin = function () {
			var loginLocation = document.getElementById("login-frame").contentWindow.location;
			loginLocation = loginLocation.toString();
			if (loginLocation.indexOf("launchpad") != -1) {
				$rootScope.hideLogin();
			}
		};

	});

var setCurrentApp = function (currentApp) {
	$('.active').removeClass('active');
	$("#nav_" + currentApp).addClass("active");
};

var showFileManager = function () {
	$('#root-file-manager').find('iframe').css('height', $(window).height() - 60).attr('src', CurrentServer + '/filemanager/').show();
};

window.onresize = resize;
window.onload = resize;

function resize() {
	$("#grid-table").css('height', $(window).height() - 60);
}<commit_msg>Restoring File<commit_after>/**
 * This file is part of the DreamFactory Services Platform(tm) (DSP)
 *
 * DreamFactory Services Platform(tm) <http://github.com/dreamfactorysoftware/dsp-core>
 * Copyright 2012-2014 DreamFactory Software, Inc. <support@dreamfactory.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';
var loginFrame = $("#login-frame");
var loginPage = $("#login-page");
var container = $("#container");

/**
 * Angular module declaration
 */
angular.module("AdminApp", [
        "ngRoute",
        "ngResource",
        "ngGrid",
        "AdminApp.controllers",
        "AdminApp.apisdk"
    ])
    .config([
        '$routeProvider',
        '$locationProvider',
        '$httpProvider',
        function ($routeProvider, $locationProvider, $httpProvider) {

            $routeProvider.when('/', {
                controller: QuickStartCtrl,
                templateUrl: 'quick-start.html'
            });
            $routeProvider.when('/app', {
                controller: AppCtrl,
                templateUrl: 'applications.html'
            });
            $routeProvider.when('/user', {
                controller: UserCtrl,
                templateUrl: 'users.html'
            });
            $routeProvider.when('/role', {
                controller: RoleCtrl,
                templateUrl: 'roles.html'
            });
            $routeProvider.when('/group', {
                controller: GroupCtrl,
                templateUrl: 'groups.html'
            });
            $routeProvider.when('/schema', {
                controller: SchemaCtrl,
                templateUrl: 'schema.html'
            });
            $routeProvider.when('/service', {
                controller: ServiceCtrl,
                templateUrl: 'services.html'
            });
            $routeProvider.when('/import', {
                controller: FileCtrl,
                templateUrl: 'import.html'
            });
            $routeProvider.when('/file', {
                controller: FileCtrl,
                templateUrl: 'files.html'
            });
            $routeProvider.when('/package', {
                controller: PackageCtrl,
                templateUrl: 'package.html'
            });
            $routeProvider.when('/config', {
                controller: ConfigCtrl,
                templateUrl: 'config.html'
            });
            $routeProvider.when('/data', {
                controller: DataCtrl,
                templateUrl: 'data.html'
            });
            $routeProvider.when('/scripts', {
                controller: ScriptCtrl,
                templateUrl: 'scripts.html'
            });
            $routeProvider.when('/api', {
                controller: 'ApiSDKCtrl',
                templateUrl: 'apisdk.html'
            });

            var interceptor = ['$location', '$q', '$rootScope',
                function ($location, $q, $rootScope) {
                    function success(response) {

                        return response;
                    }

                    function error(response) {

                        if (response.status === 401 || response.status === 403) {
                            if (response.config.method === "GET") {
                                $rootScope.$broadcast("error:401", function () {
                                    window.location.reload(true);
                                });
                            } else {
                                $rootScope.$broadcast("error:401", null);
                            }

                            return $q.reject(response);
                        }else if(response.status = 404){
                            return $q.reject(response);
                        } else {
                            $.pnotify({
                                title: "Error",
                                type: 'error',
                                text: getErrorString(response)
                            });
                            return $q.reject(response);
                        }
                    }

                    return function (promise) {
                        return promise.then(success, error);
                    }
                }
            ];

            $httpProvider.responseInterceptors.push(interceptor);
        }

    ])
    .factory('AppsRelated', function ($resource) {
        return $resource('/rest/system/app/:id/?app_name=admin&fields=*&related=roles', {}, {
            update: {
                method: 'PUT'
            },
            query: {
                method: 'GET',
                isArray: false
            }
        });
    })
    .factory('AppsRelatedToService', function ($resource) {
        return $resource('/rest/system/app/:id/?app_name=admin&fields=*&related=app_service_relations', {}, {
            update: {
                method: 'PUT'
            },
            query: {
                method: 'GET',
                isArray: false
            }
        });
    })
    .factory('App', function ($resource) {
        return $resource('/rest/system/app/:id/?app_name=admin&fields=*', {}, {
            update: {
                method: 'PUT'
            },
            query: {
                method: 'GET',
                isArray: false
            }
        });
    })
    .factory('User', function ($resource) {
        return $resource('/rest/system/user/:id/?app_name=admin&fields=*&related=lookup_keys&order=display_name%20ASC', {
            send_invite: false
        }, {
            update: {
                method: 'PUT'
            },
            query: {
                method: 'GET',
                isArray: false
            }
        });
    })
    .factory('Role', function ($resource) {
        return $resource('/rest/system/role/:id/?app_name=admin&fields=*', {}, {
            update: {
                method: 'PUT'
            },
            query: {
                method: 'GET',
                isArray: false
            }
        })
    })
    .factory('RolesRelated', function ($resource) {
        return $resource('/rest/system/role/:id/?app_name=admin&fields=*&related=users,apps,role_service_accesses,role_system_accesses,lookup_keys', {}, {
            update: {
                method: 'PUT'
            },
            query: {
                method: 'GET',
                isArray: false
            }
        });
    })
    .factory('Service', function ($resource) {
        return $resource('/rest/system/service/:id/?app_name=admin&fields=*', {}, {
            update: {
                method: 'PUT'
            },
            query: {
                method: 'GET',
                isArray: false
            }
        });
    })
    .factory('Schema', function ($resource) {
        return $resource('/rest/schema/:name/?app_name=admin&fields=*', {}, {
            update: {
                method: 'PUT'
            },
            query: {
                method: 'GET',
                isArray: false
            }
        });
    })
    .factory('DB', function ($resource) {
        return $resource('/rest/db/:name/?app_name=admin&fields=*&include_schema=true', {}, {
            update: {
                method: 'PUT'
            },
            query: {
                method: 'GET',
                isArray: false
            }
        });
    })
    .factory('Group', function ($resource) {
        return $resource('/rest/system/app_group/:id/?app_name=admin&fields=*&related=apps', {}, {
            update: {
                method: 'PUT'
            },
            query: {
                method: 'GET',
                isArray: false
            }
        });
    })
    .factory('Config', function ($resource) {
        return $resource('/rest/system/config/?app_name=admin', {}, {
            update: {
                method: 'PUT'
            },
            query: {
                method: 'GET',
                isArray: false
            }
        });
    })
    .factory('Event', function ($resource) {
        return $resource('/rest/system/event/?app_name=admin', {}, {
            update: {
                method: 'PUT'
            },
            query: {
                method: 'GET',
                isArray: false
            }
        });
    })
    .factory('Script', function ($resource) {
        return $resource('/rest/system/script/:script_id/?app_name=admin', {}, {
            update: {
                method: 'PUT'
            },
            query: {
                method: 'GET',
                isArray: false
            }
        });
    })
    .factory('EmailTemplates', function ($resource) {
        return $resource('/rest/system/email_template/:id/?app_name=admin&fields=*', {}, {
            update: {
                method: 'PUT'
            }
        });
    })
    .run(function ($rootScope) {
        $rootScope.$on("error:401", function (message, data) {
            $rootScope.showLogin();
            $rootScope.onReturn = function () {

                if (data) data();
            };

        });
        $rootScope.showLogin = function () {
            container.hide();
            loginFrame.attr("src", "");
            loginFrame.attr("src", "../web/login");
            loginFrame.load(function () {
                $rootScope.checkLogin();
            });
            loginPage.show();
        }
        $rootScope.hideLogin = function () {
            container.show();
            loginPage.hide();
            $rootScope.onReturn();

        };
        $rootScope.checkLogin = function () {
            var loginLocation = document.getElementById("login-frame").contentWindow.location;
            loginLocation = loginLocation.toString();
            if (loginLocation.indexOf("launchpad") != -1) {
                $rootScope.hideLogin();
            }
        };

    });

var setCurrentApp = function (currentApp) {
    $('.active').removeClass('active');
    $("#nav_" + currentApp).addClass("active");
};

var showFileManager = function () {
    $("#root-file-manager iframe").css('height', $(window).height() - 200).attr("src", CurrentServer + '/filemanager/').show();

};

window.onresize = resize;
window.onload = resize;

function resize() {
    $("#grid-table").css('height', $(window).height() - 60);
}<|endoftext|>


<commit_before>window.cfail = window.cfail || {};
cfail.reporting = (function () {
  var random = function () {
    function K() {
      return(((1 + Math.random()) * 65536) | 0).toString(16).substring(1)
    }

    return(K() + K() + "-" + K() + "-" + K() + "-" + K() + "-" + K() + K() + K())
  };
  var defaults = {id: null, processInterval: 4, daysToStore: 7, onBeforeStore: null, appfailApiRoot: "http://cfail.herokuapp.com"};
  var requestData = {RequestUrl: "", HttpVerb: "", ReferrerUrl: document.referrer, OccurrenceTimeUtc: null, User: "Anonymous", PostValuePairs: [], QueryValuePairs: [], Cookies: [], UniqueId: null, UserAgent: navigator.userAgent, HttpStatus: null, Exceptions: [], PageCorrelationId: random(), IsXHRFailure: false, XHRRequestURL: null, ConnectionStatus: "online", IsStandalone: false, TimeOnPage: 0};
  var defaultException = {ExceptionType: "Javascript Error", ExceptionMessage: "", StackTrace: ""};
  var config = {};
  var exceptionQueue = [];
  var m;
  var hasOfflineEvents = ("ononline" in window && "onoffline" in window) ? true : false;

  function hasJSON() {
    return"JSON" in window && window.JSON
  }

  var hasLocalStorage = ("localStorage" in window && window.localStorage) ? true : false;
  var y = new Date();
  var J = false;
  var RequestUrl = null;
  var logEnabled = false;
  var D = "cfail/reporting.js";
  var JOSN2_URL = "http://cdn.staticfile.org/json2/20130526/json2.min.js";
  var hasOnlineBool = J ? false : (typeof navigator.onLine === "boolean") ? true : false;
  var clone = function (L) {
    var M = !L ? null : (L instanceof Array ? [] : {});
    for (var K in L) {
      if (typeof(L[K]) === "object") {
        M[K] = clone(L[K])
      } else {
        M[K] = L[K]
      }
    }
    return M
  };
  var extend = function (O, N) {
    var L = {};
    for (var prop in O) {
      if (O.hasOwnProperty(prop)) {
        L[prop] = O[prop]
      }
    }
    for (var K in N) {
      if (N.hasOwnProperty(K)) {
        L[K] = N[K]
      }
    }
    return L
  };
  var log = function (message) {
    if (logEnabled && typeof console === "object") {
      console.log(message)
    }
  };
  var addEventListener = function (element, eventName, eventListener) {
    if (element.addEventListener) {
      element.addEventListener(eventName.replace(/^on/, ""), eventListener, false)
    } else {
      if (element[eventName]) {
        var K = element[eventName];
        element[eventName] = function (O) {
          K.apply(null, arguments);
          eventListener.apply(null, arguments);
        }
      } else {
        element[eventName] = function (O) {
          eventListener.apply(null, arguments);
        }
      }
    }
  };
  (function (L) {
    var M = L.prototype.send;
    L.prototype.send = function (Q) {
      var O = this;
      var P;
      var N = function () {
        if (O.readyState === 4) {
          log(O);
          var R = O.appfailData;
          if (O.status && O.status >= 400) {
            catchXhrError({ReadyState: O.readyState, Status: O.status, StatusText: O.statusText, Method: R ? R.method : null, Url: R ? R.url : null})
          }
        }
        if (P) {
          P()
        }
      };
      if (this.addEventListener) {
        this.addEventListener("readystatechange", N, false)
      } else {
        P = this.onreadystatechange;
        this.onreadystatechange = N
      }
      M.call(this, Q)
    };
    var K = L.prototype.open;
    L.prototype.open = function (P, N, O) {
      this.appfailData = {method: P, url: N};
      K.call(this, P, N, O)
    }
  })(XMLHttpRequest);

  var bootstrap = function () {
    addEventListener(window, "onerror", function (M, L, K) {
      catchError(M, L, K);
      return true
    });
    m = window.setInterval(function () {
      if (exceptionQueue.length) {
        processQueue()
      }
    }, config.processInterval * 1000);
    if (hasOfflineEvents) {
      addEventListener(window, "ononline", function () {
        loadStoredErrors();
        processQueue()
      })
    }
  };

  var b = function () {
    return(new Date() - y)
  };
  var query = [];
  (function () {
    var K, M = /\+/g, L = /([^&=]+)=?([^&]*)/g, O = function (P) {
      return decodeURIComponent(P.replace(M, " "))
    }, N = window.location.search.substring(1);
    K = L.exec(N);
    while (K) {
      query.push([O(K[1]), O(K[2])]);
      K = L.exec(N)
    }
  })();
  var populateFailOccurrence = function (error) {
    error.RequestUrl = RequestUrl ? RequestUrl : document.location.href;
    if (!error.OccurrenceTimeUtc) {
      error.OccurrenceTimeUtc = new Date().getTime()
    }
    error.UniqueId = random();
    error.TimeOnPage = b();
    error.UserAgent = navigator.userAgent;
    error.Cookies = [];
    error.ReferrerUrl = document.referrer;
    error.QueryValuePairs = query;
  };
  var catchError = function (message, url, linenumber) {
    log(message, url, linenumber);

    if (typeof message === 'string') {
        message = {message: message};
        message.filename = '';
        message.lineno = linenumber;
    }

    var failOccurrence = clone(requestData);
    failOccurrence.OccurrenceTimeUtc = (message && message.timeStamp) ? new Date(message.timeStamp).getTime() : null;
    var exception = clone(defaultException);
    exception.ExceptionMessage = message.message;
    exception.StackTrace = message.filename + " --- line " + message.lineno;
    failOccurrence.Exceptions.push(exception);
    populateFailOccurrence(failOccurrence);
    if (config.onBeforeStore) {
      config.onBeforeStore(failOccurrence)
    }
    exceptionQueue.push(failOccurrence)
  };
  var catchXhrError = function (xhr) {
    log(xhr);
    if (!xhr.Url) {
      return
    }
    var failOccurrence = clone(requestData);
    failOccurrence.XHRRequestURL = xhr.Url;
    failOccurrence.IsXHRFailure = true;
    failOccurrence.HttpStatus = xhr.Status;
    failOccurrence.HttpVerb = xhr.Method;
    populateFailOccurrence(failOccurrence);
    if (config.onBeforeStore) {
      config.onBeforeStore(failOccurrence)
    }
    exceptionQueue.push(failOccurrence)
  };
  var catchManual = function (err) {
    log(err);
    var failOccurrence = clone(requestData);
    var exception = clone(defaultException);
    exception.StackTrace = err.stack || "";
    if (err.type) {
      exception.ExceptionType = err.type
    }
    exception.ExceptionMessage = err.message;
    failOccurrence.Exceptions.push(exception);
    populateFailOccurrence(failOccurrence);
    if (config.onBeforeStore) {
      config.onBeforeStore(failOccurrence)
    }
    exceptionQueue.push(failOccurrence)
  };
  var processQueue = function () {
    if (exceptionQueue.length && ((hasOnlineBool && !navigator.onLine) || !hasJSON())) {
      if (!hasJSON()) {
        error("JSON parser has not yet loaded. Stored failure reports to local storage.")
      } else {
        error("No connection found, stored failure reports to local storage")
      }
      storeQueue();
      exceptionQueue = [];
      return
    }
    var M = {ID: config.id, ModuleVersion: "1.0.0.0", ApplicationType: "Javascript", FailOccurrences: []};
    while (exceptionQueue.length) {
      var L = exceptionQueue.shift();
      M.FailOccurrences.push(L)
    }
    exceptionQueue.length = 0;

    var img = new Image();
    img.src = config.appfailApiRoot + "/jsFail/v1?json=" + encodeURIComponent(JSON.stringify(M))
  };
  var storeQueue = function () {
    if (hasJSON() && hasLocalStorage) {
      var N = window.localStorage.getItem("cfail-errors");
      if (N !== "" && N !== null) {
        var L = JSON.parse(N);
        for (var M = 0, K = L.length; M < K; M++) {
          exceptionQueue.push(L[M])
        }
      }
      window.localStorage.setItem("cfail-errors", JSON.stringify(exceptionQueue))
    }
  };
  var loadStoredErrors = function () {
    if (!hasLocalStorage) {
      return
    }
    var exceptions;
    var Q = window.localStorage.getItem("cfail-errors");
    if (Q === "" || Q === null) {
      return
    }
    exceptions = JSON.parse(Q);
    var now = +new Date();
    var L = 86400000;
    var R = config.daysToStore * L;
    var M = [];
    for (var O = 0, K = exceptions.length; O < K; O++) {
      if (now - R > exceptions[O].OccurrenceTimeUtc) {
        error("Dropping an old error")
      } else {
        M.push(exceptions[O])
      }
    }
    exceptionQueue = M;
    window.localStorage.removeItem("cfail-errors")
  };
  var mergeConfigFromScript = function () {
    if (cfail.config) {
      config = extend(defaults, cfail.config);
      return
    }
    var scripts = document.getElementsByTagName("script");
    var cfailScript;
    for (var i = 0, l = scripts.length; i < l; i++) {
      if (scripts[i].src.indexOf(D) > -1) {
        cfailScript = scripts[i];
        break
      }
    }
    if (cfailScript.src.indexOf("?") === -1) {
      return
    }
    var L = cfailScript.src.split("?")[1];
    var M = L.split("&");
    var N = {};
    for (var P = 0, T = M.length; P < T; P++) {
      var Q = M[P].split("=");
      N[Q[0]] = Q[1]
    }
    config = extend(defaults, N)
  };

  function hasConfigFromQuery(str) {
    var result = new RegExp("[?&]" + str + "=([^&]*)").exec(window.location.search);
    return result && decodeURIComponent(result[1].replace(/\+/g, " "))
  }

  function loadJSON() {
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = JOSN2_URL;
    document.body.appendChild(script)
  }

  (function () {
    if (!hasJSON()) {
      loadJSON()
    }
    mergeConfigFromScript();
    if (!config.id) {
      error("No application id was found.");
      return
    }
    if (hasOnlineBool && navigator.onLine) {
      loadStoredErrors()
    }

    bootstrap();

    if (hasConfigFromQuery("cfail-report-test-exception")) {
      try {
        throw new Error("This is an Appfail test exception. Congratulations, your web-site is successfully reporting javascript errors to Appfail")
      } catch (err) {
        catchManual(err)
      }
    }
  })();
  var error = function (message) {
    if (console && console.error) {
      console.error("cfail: " + message)
    }
  };
  var runTests = function () {
    log("hasOnlineBool: ", hasOnlineBool);
    log("hasOfflineEvents: ", hasOfflineEvents);
    log("hasJSON: ", hasJSON());
    log("hasLocalStorage: ", hasLocalStorage)
  };
  return{catchManual: catchManual, processQueue: processQueue, storeQueue: storeQueue, loadStoredErrors: loadStoredErrors, runTests: runTests}
})();
<commit_msg>Updated reporting.js<commit_after>window.cfail = window.cfail || {};
cfail.reporting = (function () {
  var random = function () {
    function K() {
      return(((1 + Math.random()) * 65536) | 0).toString(16).substring(1)
    }

    return(K() + K() + "-" + K() + "-" + K() + "-" + K() + "-" + K() + K() + K())
  };
  var defaults = {id: null, processInterval: 4, daysToStore: 7, onBeforeStore: null, appfailApiRoot: "http://cfail.herokuapp.com"};
  var requestData = {RequestUrl: "", HttpVerb: "", ReferrerUrl: document.referrer, OccurrenceTimeUtc: null, User: "Anonymous", PostValuePairs: [], QueryValuePairs: [], Cookies: [], UniqueId: null, UserAgent: navigator.userAgent, HttpStatus: null, Exceptions: [], PageCorrelationId: random(), IsXHRFailure: false, XHRRequestURL: null, ConnectionStatus: "online", IsStandalone: false, TimeOnPage: 0};
  var defaultException = {ExceptionType: "Javascript Error", ExceptionMessage: "", StackTrace: ""};
  var config = {};
  var exceptionQueue = [];
  var m;
  var hasOfflineEvents = ("ononline" in window && "onoffline" in window) ? true : false;

  function hasJSON() {
    return"JSON" in window && window.JSON
  }

  var hasLocalStorage = ("localStorage" in window && window.localStorage) ? true : false;
  var y = new Date();
  var J = false;
  var RequestUrl = null;
  var logEnabled = false;
  var D = "cfail/reporting.js";
  var JOSN2_URL = "http://cdn.staticfile.org/json2/20130526/json2.min.js";
  var hasOnlineBool = J ? false : (typeof navigator.onLine === "boolean") ? true : false;
  var clone = function (L) {
    var M = !L ? null : (L instanceof Array ? [] : {});
    for (var K in L) {
      if (typeof(L[K]) === "object") {
        M[K] = clone(L[K])
      } else {
        M[K] = L[K]
      }
    }
    return M
  };
  var extend = function (O, N) {
    var L = {};
    for (var prop in O) {
      if (O.hasOwnProperty(prop)) {
        L[prop] = O[prop]
      }
    }
    for (var K in N) {
      if (N.hasOwnProperty(K)) {
        L[K] = N[K]
      }
    }
    return L
  };
  var log = function (message) {
    if (logEnabled && typeof console === "object") {
      console.log(message)
    }
  };
  var addEventListener = function (element, eventName, eventListener) {
    if (element.addEventListener) {
      element.addEventListener(eventName.replace(/^on/, ""), eventListener, false)
    } else {
      if (element[eventName]) {
        var K = element[eventName];
        element[eventName] = function (O) {
          K.apply(null, arguments);
          eventListener.apply(null, arguments);
        }
      } else {
        element[eventName] = function (O) {
          eventListener.apply(null, arguments);
        }
      }
    }
  };
  (function (L) {
    var M = L.prototype.send;
    L.prototype.send = function (Q) {
      var O = this;
      var P;
      var N = function () {
        if (O.readyState === 4) {
          log(O);
          var R = O.appfailData;
          if (O.status && O.status >= 400) {
            catchXhrError({ReadyState: O.readyState, Status: O.status, StatusText: O.statusText, Method: R ? R.method : null, Url: R ? R.url : null})
          }
        }
        if (P) {
          P()
        }
      };
      if (this.addEventListener) {
        this.addEventListener("readystatechange", N, false)
      } else {
        P = this.onreadystatechange;
        this.onreadystatechange = N
      }
      M.call(this, Q)
    };
    var K = L.prototype.open;
    L.prototype.open = function (P, N, O) {
      this.appfailData = {method: P, url: N};
      K.call(this, P, N, O)
    }
  })(XMLHttpRequest);

  var bootstrap = function () {
    addEventListener(window, "onerror", function (M, L, K) {
      catchError(M, L, K);
      return true
    });
    m = window.setInterval(function () {
      if (exceptionQueue.length) {
        processQueue()
      }
    }, config.processInterval * 1000);
    if (hasOfflineEvents) {
      addEventListener(window, "ononline", function () {
        loadStoredErrors();
        processQueue()
      })
    }
  };

  var b = function () {
    return(new Date() - y)
  };
  var query = [];
  (function () {
    var K, M = /\+/g, L = /([^&=]+)=?([^&]*)/g, O = function (P) {
      return decodeURIComponent(P.replace(M, " "))
    }, N = window.location.search.substring(1);
    K = L.exec(N);
    while (K) {
      query.push([O(K[1]), O(K[2])]);
      K = L.exec(N)
    }
  })();
  var populateFailOccurrence = function (error) {
    error.RequestUrl = RequestUrl ? RequestUrl : document.location.href;
    if (!error.OccurrenceTimeUtc) {
      error.OccurrenceTimeUtc = new Date().getTime()
    }
    error.UniqueId = random();
    error.TimeOnPage = b();
    error.UserAgent = navigator.userAgent;
    error.Cookies = [];
    error.ReferrerUrl = document.referrer;
    error.QueryValuePairs = query;
  };
  var catchError = function (message, url, linenumber) {
    log(message, url, linenumber);

    if (typeof message === 'string') {
        message = {message: message};
        message.filename = url;
        message.lineno = linenumber;
    }

    var failOccurrence = clone(requestData);
    failOccurrence.OccurrenceTimeUtc = (message && message.timeStamp) ? new Date(message.timeStamp).getTime() : null;
    var exception = clone(defaultException);
    exception.ExceptionMessage = message.message;
    exception.StackTrace = message.filename + " --- line " + message.lineno;
    failOccurrence.Exceptions.push(exception);
    populateFailOccurrence(failOccurrence);
    if (config.onBeforeStore) {
      config.onBeforeStore(failOccurrence)
    }
    exceptionQueue.push(failOccurrence)
  };
  var catchXhrError = function (xhr) {
    log(xhr);
    if (!xhr.Url) {
      return
    }
    var failOccurrence = clone(requestData);
    failOccurrence.XHRRequestURL = xhr.Url;
    failOccurrence.IsXHRFailure = true;
    failOccurrence.HttpStatus = xhr.Status;
    failOccurrence.HttpVerb = xhr.Method;
    populateFailOccurrence(failOccurrence);
    if (config.onBeforeStore) {
      config.onBeforeStore(failOccurrence)
    }
    exceptionQueue.push(failOccurrence)
  };
  var catchManual = function (err) {
    log(err);
    var failOccurrence = clone(requestData);
    var exception = clone(defaultException);
    exception.StackTrace = err.stack || "";
    if (err.type) {
      exception.ExceptionType = err.type
    }
    exception.ExceptionMessage = err.message;
    failOccurrence.Exceptions.push(exception);
    populateFailOccurrence(failOccurrence);
    if (config.onBeforeStore) {
      config.onBeforeStore(failOccurrence)
    }
    exceptionQueue.push(failOccurrence)
  };
  var processQueue = function () {
    if (exceptionQueue.length && ((hasOnlineBool && !navigator.onLine) || !hasJSON())) {
      if (!hasJSON()) {
        error("JSON parser has not yet loaded. Stored failure reports to local storage.")
      } else {
        error("No connection found, stored failure reports to local storage")
      }
      storeQueue();
      exceptionQueue = [];
      return
    }
    var M = {ID: config.id, ModuleVersion: "1.0.0.0", ApplicationType: "Javascript", FailOccurrences: []};
    while (exceptionQueue.length) {
      var L = exceptionQueue.shift();
      M.FailOccurrences.push(L)
    }
    exceptionQueue.length = 0;

    var img = new Image();
    img.src = config.appfailApiRoot + "/jsFail/v1?json=" + encodeURIComponent(JSON.stringify(M))
  };
  var storeQueue = function () {
    if (hasJSON() && hasLocalStorage) {
      var N = window.localStorage.getItem("cfail-errors");
      if (N !== "" && N !== null) {
        var L = JSON.parse(N);
        for (var M = 0, K = L.length; M < K; M++) {
          exceptionQueue.push(L[M])
        }
      }
      window.localStorage.setItem("cfail-errors", JSON.stringify(exceptionQueue))
    }
  };
  var loadStoredErrors = function () {
    if (!hasLocalStorage) {
      return
    }
    var exceptions;
    var Q = window.localStorage.getItem("cfail-errors");
    if (Q === "" || Q === null) {
      return
    }
    exceptions = JSON.parse(Q);
    var now = +new Date();
    var L = 86400000;
    var R = config.daysToStore * L;
    var M = [];
    for (var O = 0, K = exceptions.length; O < K; O++) {
      if (now - R > exceptions[O].OccurrenceTimeUtc) {
        error("Dropping an old error")
      } else {
        M.push(exceptions[O])
      }
    }
    exceptionQueue = M;
    window.localStorage.removeItem("cfail-errors")
  };
  var mergeConfigFromScript = function () {
    if (cfail.config) {
      config = extend(defaults, cfail.config);
      return
    }
    var scripts = document.getElementsByTagName("script");
    var cfailScript;
    for (var i = 0, l = scripts.length; i < l; i++) {
      if (scripts[i].src.indexOf(D) > -1) {
        cfailScript = scripts[i];
        break
      }
    }
    if (cfailScript.src.indexOf("?") === -1) {
      return
    }
    var L = cfailScript.src.split("?")[1];
    var M = L.split("&");
    var N = {};
    for (var P = 0, T = M.length; P < T; P++) {
      var Q = M[P].split("=");
      N[Q[0]] = Q[1]
    }
    config = extend(defaults, N)
  };

  function hasConfigFromQuery(str) {
    var result = new RegExp("[?&]" + str + "=([^&]*)").exec(window.location.search);
    return result && decodeURIComponent(result[1].replace(/\+/g, " "))
  }

  function loadJSON() {
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = JOSN2_URL;
    document.body.appendChild(script)
  }

  (function () {
    if (!hasJSON()) {
      loadJSON()
    }
    mergeConfigFromScript();
    if (!config.id) {
      error("No application id was found.");
      return
    }
    if (hasOnlineBool && navigator.onLine) {
      loadStoredErrors()
    }

    bootstrap();

    if (hasConfigFromQuery("cfail-report-test-exception")) {
      try {
        throw new Error("This is an Appfail test exception. Congratulations, your web-site is successfully reporting javascript errors to Appfail")
      } catch (err) {
        catchManual(err)
      }
    }
  })();
  var error = function (message) {
    if (console && console.error) {
      console.error("cfail: " + message)
    }
  };
  var runTests = function () {
    log("hasOnlineBool: ", hasOnlineBool);
    log("hasOfflineEvents: ", hasOfflineEvents);
    log("hasJSON: ", hasJSON());
    log("hasLocalStorage: ", hasLocalStorage)
  };
  return{catchManual: catchManual, processQueue: processQueue, storeQueue: storeQueue, loadStoredErrors: loadStoredErrors, runTests: runTests}
})();
<|endoftext|>


<commit_before>import React from 'react';

import GreetingMaster from './GreetingMaster';
import GreetingDetail from './GreetingDetail';

const BACKEND_URL = 'http://localhost:7000/greetings';
const MODE_MASTER = 'MODE_MASTER';
const MODE_DETAIL = 'MODE_DETAIL';

export default class GreetingController extends React.Component {
    render() {
        const {mode, greetings} = this.state;
        return (

                {mode === MODE_MASTER ?
                    <GreetingMaster greetings={greetings}
                                    onAdd={() => this.setState({mode: MODE_DETAIL})}
                    /> :
                    <GreetingDetail onSave={(greeting) => this.saveGreeting(greeting)}/>
                }

);
    }

    constructor(props) {
        super(props);
        this.state = {
            greetings: [],
            mode: MODE_MASTER
        };
    }

    componentDidMount() {
        this.loadGreetings();
    }

    loadGreetings() {
        (async () => {
            try {
                const response = await fetch(BACKEND_URL);
                const json = await response.json();
                this.setState({greetings: json});
            } catch (err) {
                console.error('LOADING GREETINGS FAILED:', err);
            }
        })();
    }

    // should work, but cause error in browser

    // async loadGreetings() {
    //     try {
    //         const response = await fetch(BACKEND_URL);
    //         const json = await response.json();
    //         this.setState({greetings: json});
    //         return json;
    //     } catch (err) {
    //         console.error('LOADING GREETINGS FAILED:', err);
    //     }
    // }

    saveGreeting(greetingToBeAdded) {
        (async () => {
            try {
                const response = await fetch(BACKEND_URL, {
                    method: 'POST',
                    headers: {
                        'Accept': 'application/json',
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(greetingToBeAdded)
                });
                if (response.status !== 201) {
                    throw new Error('Invalid status code: ' + response.status);
                }
                const json = await response.json();
                // the server responded with the id of the new Greeting
                const newGreetingId = json.id;
                // create a new Greeting object that contains the received id
                // (create a new object for immutability)
                const newGreeting = {...greetingToBeAdded, id: newGreetingId};
                // add the new greetings to the list of all greetings
                // (create a new array for immutability)
                const newGreetings = [...this.state.greetings, newGreeting];

                // set the new list of greetings as our new state
                // also set 'MODE_MASTER' to make sure the master-View is
                // displayed now
                this.setState({
                    greetings: newGreetings,
                    mode: MODE_MASTER
                });
            } catch (err) {
                console.error('LOADING GREETINGS FAILED:', err);
            }
        })();
    }
}

<commit_msg>Make "better" async example work<commit_after>require("babel-polyfill");

import React from 'react';
import GreetingMaster from './GreetingMaster';
import GreetingDetail from './GreetingDetail';

const BACKEND_URL = 'http://localhost:7000/greetings';
const MODE_MASTER = 'MODE_MASTER';
const MODE_DETAIL = 'MODE_DETAIL';

export default class GreetingController extends React.Component {
    render() {
        const {mode, greetings} = this.state;
        return (

                {mode === MODE_MASTER ?
                    <GreetingMaster greetings={greetings}
                                    onAdd={() => this.setState({mode: MODE_DETAIL})}
                    /> :
                    <GreetingDetail onSave={(greeting) => this.saveGreeting(greeting)}/>
                }

);
    }

    constructor(props) {
        super(props);
        this.state = {
            greetings: [],
            mode: MODE_MASTER
        };
    }

    componentDidMount() {
        this.loadGreetings();
    }

     async loadGreetings() {
         try {
             const response = await fetch(BACKEND_URL);
             const json = await response.json();
             this.setState({greetings: json});
             return json;
         } catch (err) {
             console.error('LOADING GREETINGS FAILED:', err);
         }
     }

    saveGreeting(greetingToBeAdded) {
        (async () => {
            try {
                const response = await fetch(BACKEND_URL, {
                    method: 'POST',
                    headers: {
                        'Accept': 'application/json',
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(greetingToBeAdded)
                });
                if (response.status !== 201) {
                    throw new Error('Invalid status code: ' + response.status);
                }
                const json = await response.json();
                // the server responded with the id of the new Greeting
                const newGreetingId = json.id;
                // create a new Greeting object that contains the received id
                // (create a new object for immutability)
                const newGreeting = {...greetingToBeAdded, id: newGreetingId};
                // add the new greetings to the list of all greetings
                // (create a new array for immutability)
                const newGreetings = [...this.state.greetings, newGreeting];

                // set the new list of greetings as our new state
                // also set 'MODE_MASTER' to make sure the master-View is
                // displayed now
                this.setState({
                    greetings: newGreetings,
                    mode: MODE_MASTER
                });
            } catch (err) {
                console.error('LOADING GREETINGS FAILED:', err);
            }
        })();
    }
}

<|endoftext|>


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

router.get('/get_food/:food', function(req, res, next) {
  var food = req.params.food;
  var return_data = {};
  var data = null;

  request('http://api.nal.usda.gov/ndb/search/?format=json&q=' + food + '&sort=r&offset=0&api_key=DEMO_KEY', function (error, res1, body) {
    if (!error && res1.statusCode == 200) {
      data = JSON.parse(res1.body);
      for (var item in data.list.item) {
        return_data[data.list.item[item]["name"]] = data.list.item[item]["ndbno"];
      }
      res.send(return_data);
    }
    else {
      res.send("Got error");
    }
  });
});

router.get('/get_nutrition/:food_id', function(req, res, next) {
  //console.log("getting food nutrition");
  var food = req.params.food_id;

  var interested = ["Energy", "Sugars, total", "Total lipid (fat)", "Carboydrate, by difference", "Fiber, total dietary"];
  var return_data = {};

  request('http://api.nal.usda.gov/ndb/reports/?ndbno=' + food + '&type=b&format=json&api_key=DEMO_KEY', function(error, res2, body) {
    if (!error && res2.statusCode == 200) {
      data = JSON.parse(res2.body);
      var nutrients = data.report.food["nutrients"];
      return_data["name"] = data.report.food.name;
      for (var item in nutrients) {
        if (interested.indexOf(nutrients[item]["name"]) != -1) {
          return_data[nutrients[item]["name"]] = nutrients[item]["value"];
        }
      }

      res.send(return_data);
    }
  });
});

router.get('/get_list/:list', function(req, res, next) {
  var list_name = req.params.list;
  res.send('gets a users list');
});

router.get('/update_list/:list', function(req, res, next) {
  var list = req.params.list;
  res.send('updates a users list');
});

router.get('/del_list/:list', function(req, res, next) {
  var list = req.params.list;
  res.send('deletes a users list');
});

module.exports = router;
<commit_msg>added add_list route<commit_after>var express = require('express');
var router = express.Router();
var request = require('request');

router.get('/get_food/:food', function(req, res, next) {
  var food = req.params.food;
  var return_data = {};
  var data = null;

  request('http://api.nal.usda.gov/ndb/search/?format=json&q=' + food + '&sort=r&offset=0&api_key=DEMO_KEY', function (error, res1, body) {
    if (!error && res1.statusCode == 200) {
      data = JSON.parse(res1.body);
      for (var item in data.list.item) {
        return_data[data.list.item[item]["name"]] = data.list.item[item]["ndbno"];
      }
      res.send(return_data);
    }
    else {
      res.send("Got error");
    }
  });
});

router.get('/get_nutrition/:food_id', function(req, res, next) {
  //console.log("getting food nutrition");
  var food = req.params.food_id;

  var interested = ["Energy", "Sugars, total", "Total lipid (fat)", "Carboydrate, by difference", "Fiber, total dietary"];
  var return_data = {};

  request('http://api.nal.usda.gov/ndb/reports/?ndbno=' + food + '&type=b&format=json&api_key=DEMO_KEY', function(error, res2, body) {
    if (!error && res2.statusCode == 200) {
      data = JSON.parse(res2.body);
      var nutrients = data.report.food["nutrients"];
      return_data["name"] = data.report.food.name;
      for (var item in nutrients) {
        if (interested.indexOf(nutrients[item]["name"]) != -1) {
          return_data[nutrients[item]["name"]] = nutrients[item]["value"];
        }
      }

      res.send(return_data);
    }
  });
});

router.get('/add_list/:food', function(req, res, next) {
  var list_name = req.params.list;
  res.send('adds a food to the users list');
});

router.get('/get_list/:list', function(req, res, next) {
  var list_name = req.params.list;
  res.send('gets a users list');
});

router.get('/update_list/:list', function(req, res, next) {
  var list = req.params.list;
  res.send('updates a users list');
});

router.get('/del_list/:list', function(req, res, next) {
  var list = req.params.list;
  res.send('deletes a users list');
});

module.exports = router;
<|endoftext|>