<commit_before>/*jslint browser: true*/
/*global console,require*/

//-----------------------------------------------------------------------

var dataSource = 'berlin',
	dataURI = 'http://www.berlin.de/sen/wirtschaft/service/maerkte-feste/weihnachtsmaerkte/index.php/index.json?ipp=500',
	dataVec = [];

//-----------------------------------------------------------------------

function push_back(data) {
	'use strict';

	dataVec.push(data);
}

//-----------------------------------------------------------------------

function twoDigits(val) {
	'use strict';

	return val.toString().length < 2 ? '0' + val : val.toString();
}

//-----------------------------------------------------------------------

function analyseDataLine(data) {
	'use strict';

	var obj = {};

	function parseDates() {
		var currentDate, endDate;
		obj.begin = data.von;
		obj.end = data.bis;

		currentDate = new Date(new Date(obj.begin).getFullYear() + "-11-16");
		endDate = new Date((new Date(obj.begin).getFullYear() + 1) + "-01-07");

		for (currentDate; currentDate < endDate; currentDate.setDate(currentDate.getDate() + 1)) {
			obj[currentDate.getFullYear() + twoDigits(currentDate.getMonth() + 1) + twoDigits(currentDate.getDate())] = '';
		}

		obj.hours = data.oeffnungszeiten;
	}

	obj.name = data.name;
	parseDates();

	push_back(obj);

//	console.log(obj.name);
}

//-----------------------------------------------------------------------

function fine() {
	'use strict';

	console.log('');
}

//-----------------------------------------------------------------------

function saveAsJSFile(filepath, data) {
	'use strict';

	console.log('Saving ' + filepath);

	var fs = require('fs'),
		str = '';

	str += "define({ data:\n";
	str += JSON.stringify(data, null, '  ');
	str += "\n});\n";

	fs.writeFile(filepath, str, function (err) {
		if (err) {
			return console.log(err);
		}

		fine();
	});
}

//-----------------------------------------------------------------------

function analyseJSON(savepath, json) {
	'use strict';

	console.log('Analysing file');

	var data = json.index,
		i;

	for (i = 0; i < data.length; ++i) {
		analyseDataLine(data[i]);
	}

	saveAsJSFile(savepath, dataVec);
}

//-----------------------------------------------------------------------

function loadJSON(filepath, savepath) {
	'use strict';

	console.log('Loading ' + filepath);

	var fs = require('fs');

	fs.readFile(filepath, 'utf-8', function (err, json) {
		if (err) {
			console.error(err);
		} else {
			if (typeof json === 'string') {
				json = JSON.parse(json);
			}
			analyseJSON(savepath, json);
		}
	});
}

//-----------------------------------------------------------------------

function downloadFile(filepath, uri, savepath) {
	'use strict';

	console.log('Downloading ' + uri);

	var fs = require('fs'),
		http = require('http'),
		file = fs.createWriteStream(filepath);

	http.get(uri, function (response) {
		response.pipe(file);
		loadJSON(filepath, savepath);
	});
}

//-----------------------------------------------------------------------

function parseFolder(path) {
	'use strict';

	var fs = require('fs'),
		now = new Date(),
		filename = dataSource + '-' + now.getFullYear() + twoDigits(now.getMonth() + 1) + twoDigits(now.getDate()) + '.json',
		savename = dataSource + '-' + now.getFullYear() + twoDigits(now.getMonth() + 1) + twoDigits(now.getDate()) + '.js',
		filepath = path + '/' + filename,
		savepath = path + '/' + savename,
		found = false;

	fs.readdir(path, function (err, files) {
		files.forEach(function (file) {
			if (file === filename) {
				found = true;
				console.log('Use cached file ' + filepath);
				loadJSON(filepath, savepath);
			}
		});

		if (!found) {
			downloadFile(filepath, dataURI, savepath);
		}
	});
}

//-----------------------------------------------------------------------

function buildBerlin() {
	'use strict';

	parseFolder('.');
}

//-----------------------------------------------------------------------

try {
	console.log();
	buildBerlin();
} catch (e) {
	console.error(e);
}

//-----------------------------------------------------------------------
//eof
<commit_msg>parse opening hours<commit_after>/*jslint browser: true*/
/*global console,require*/

//-----------------------------------------------------------------------

var dataSource = 'berlin',
	dataURI = 'http://www.berlin.de/sen/wirtschaft/service/maerkte-feste/weihnachtsmaerkte/index.php/index/all.json?ipp=500',
	dataVec = [];

//-----------------------------------------------------------------------

function push_back(data) {
	'use strict';

	dataVec.push(data);
}

//-----------------------------------------------------------------------

function twoDigits(val) {
	'use strict';

	return val.toString().length < 2 ? '0' + val : val.toString();
}

//-----------------------------------------------------------------------

function parseOpeningHours(str) {
	'use strict';

	var arr = [],
		weekdaysName = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'],
		weekdaysNameDot = ['Mo.', 'Di.', 'Mi.', 'Do.', 'Fr.', 'Sa.', 'So.'],
		weekdays = ['', '', '', '', '', '', ''],
		days = [],
		daily = '',
		date,
		left,
		i,
		j,
		from,
		fromDot,
		to,
		res = [];

	arr = str.replace(/\r\n|\r|\n/g, '\n').split('\n');

	for (i = 0; i < arr.length; ++i) {
		if (arr[i].length > 0) {
			date = arr[i].trim().split(' ');
			if (date.length === 1) {
				// 10:00-20:00
				daily = date[0];
			} else if (date.length === 2) {
				left = date[0].split('-');
				if (left.length === 1) {
					from = weekdaysName.indexOf(left[0]);
					fromDot = weekdaysNameDot.indexOf(left[0]);
					if (from > -1) {
						// Mo 10:00-20:00
						weekdays[from] = date[1];
					} else if (fromDot > -1) {
						// Mo. 10:00-20:00
						weekdays[fromDot] = date[1];
					} else if ('täglich' === left[0]) {
						// täglich 10:00-20:00
						daily = date[1];
					} else {
						left = date[0].split('.');
						if (left.length === 3) {
							// 24.12. 10:00-20:00
							days.push(left[0] + '.' + left[1] + '. ' + date[1]);
						} else if ((left.length === 4) && (left[1][0] === '/')) {
							// 24./25.12. 10:00-20:00
							days.push(left[0] + '.' + left[2] + '. ' + date[1]);
							days.push(left[1].substr(1) + '.' + left[2] + '. ' + date[1]);
						} else if ((left.length === 5) && (left[1][0] !== '/') && (left[2][0] === '/')) {
							// 24.12/25.12. 10:00-20:00
							days.push(left[0] + '.' + left[1] + '. ' + date[1]);
							days.push(left[2].substr(1) + '.' + left[3] + '. ' + date[1]);
						}
					}
				} else if (left.length === 2) {
					from = weekdaysName.indexOf(left[0]);
					to = weekdaysName.indexOf(left[1]);
					if ((from > -1) && (to > -1)) {
						// Mo-So 10:00-20:00
						if (to < from) {
							to += 7;
						}
						for (j = from; j < (to + 1); ++j) {
							weekdays[j % 7] = date[1].replace(',', '');
						}
					}
				}
			} else if ((date.length === 3) && ('Fr,' === date[0]) && ('Sa' === date[1])) {
				weekdays[weekdaysName.indexOf(date[0].substr(0, 2))] = date[2];
				weekdays[weekdaysName.indexOf(date[1])] = date[2];
			} else if ((date.length === 3) && ('Sa,' === date[0]) && ('So' === date[1])) {
				weekdays[weekdaysName.indexOf(date[0].substr(0, 2))] = date[2];
				weekdays[weekdaysName.indexOf(date[1])] = date[2];
			} else if ((date.length === 5) && ('am' === date[0]) && ('und' === date[2])) {
				// am 24.12. und 25.12. 10:00-20:00
				days.push(date[1] + ' ' + date[4]);
				days.push(date[3] + ' ' + date[4]);
			} else if ((date.length === 6) && ('Do,' === date[0]) && ('Sa' === date[2]) && ('24.12.' === date[4]) && ('geschlossen' === date[5])) {
				// Do, Fr, Sa 14:00-22:00, 24.12. geschlossen
				weekdays[weekdaysName.indexOf(date[0].substr(0, 2))] = date[3].replace(',', '');
				weekdays[weekdaysName.indexOf(date[1].substr(0, 2))] = date[3].replace(',', '');
				weekdays[weekdaysName.indexOf(date[2])] = date[3].replace(',', '');
				days.push(date[4] + ' ' + date[5]);
			}
		}
	}

	if (daily.length > 0) {
		res.push(daily);
	}
	for (i = 0; i < weekdays.length; ++i) {
		if (weekdays[i] !== '') {
			res.push(weekdaysName[i] + ' ' + weekdays[i]);
		}
	}
	for (i = 0; i < days.length; ++i) {
		res.push(days[i]);
	}

	return res;
}

//-----------------------------------------------------------------------

function testOpeningHours(obj, data) {
	'use strict';

	var i, item, checkDate, checkTime, splitted,
		weekdaysName = ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'];

	if (0 === data.length) {
		console.log('- ' + obj.name + ' has no opening hours!');
	}

	for (i = 0; i < data.length; ++i) {
		item = data[i].split(' ');
		checkDate = '';
		checkTime = '';
		if (1 === item.length) {
			checkTime = item[0];
		} else if (2 === item.length) {
			checkDate = item[0];
			checkTime = item[1];
		} else {
			console.log('- ' + obj.name + ' has wrong opening hours: ' + data[i]);
		}

		if ('' !== checkDate) {
			if (-1 === weekdaysName.indexOf(checkDate)) {
				splitted = checkDate.split('.');
				if ((checkDate.length !== 6) || (splitted.length !== 3) || (parseInt(splitted[0], 10) > 31) || (parseInt(splitted[1], 10) > 12) || ('' !== splitted[2])) {
					console.log('- ' + obj.name + ' has wrong opening date: ' + checkDate);
				}
			}
		}
		if ('' !== checkTime) {
			splitted = checkTime.split('-');
			if ((checkTime.length !== 11) || (splitted.length !== 2) || (splitted[0].length !== 5) || (splitted[1].length !== 5)) {
				if ('geschlossen' !== checkTime) {
					console.log('- ' + obj.name + ' has wrong opening time: ' + checkTime);
				}
			} else {
				splitted = checkTime.split('-')[0].split(':');
				if ((splitted.length !== 2) || (parseInt(splitted[0], 10) > 24) || (parseInt(splitted[1], 10) > 60)) {
					console.log('- ' + obj.name + ' has wrong opening time: ' + checkTime);
				}
				splitted = checkTime.split('-')[1].split(':');
				if ((splitted.length !== 2) || (parseInt(splitted[0], 10) > 24) || (parseInt(splitted[1], 10) > 60)) {
					console.log('- ' + obj.name + ' has wrong opening time: ' + checkTime);
				}
			}
		}
	}
}

//-----------------------------------------------------------------------

function analyseDataLine(data) {
	'use strict';

	var obj = {};

	function parseDates() {
		var currentDate, endDate,
			hours = parseOpeningHours(data.oeffnungszeiten);
//		obj.begin = data.von;
//		obj.end = data.bis;

		testOpeningHours(obj, hours);

		currentDate = new Date(new Date(obj.begin).getFullYear() + "-11-16");
		endDate = new Date((new Date(obj.begin).getFullYear() + 1) + "-01-07");

//		for (currentDate; currentDate < endDate; currentDate.setDate(currentDate.getDate() + 1)) {
//			obj[currentDate.getFullYear() + twoDigits(currentDate.getMonth() + 1) + twoDigits(currentDate.getDate())] = '';
//		}

		obj.hours = hours.join('<br>');
		obj.oeffnungszeiten = data.oeffnungszeiten;
	}

	obj.name = data.name;
	parseDates();

	push_back(obj);

//	console.log(obj.name);
}

//-----------------------------------------------------------------------

function fine() {
	'use strict';

	console.log('');
}

//-----------------------------------------------------------------------

function saveAsJSFile(filepath, data) {
	'use strict';

	console.log('Saving ' + filepath);

	var fs = require('fs'),
		str = '';

	str += "define({ data:\n";
	str += JSON.stringify(data, null, '  ');
	str += "\n});\n";

	fs.writeFile(filepath, str, function (err) {
		if (err) {
			return console.log(err);
		}

		fine();
	});
}

//-----------------------------------------------------------------------

function analyseJSON(savepath, json) {
	'use strict';

	console.log('Analysing file');

	var data = json.index,
		i;

	for (i = 0; i < data.length; ++i) {
		analyseDataLine(data[i]);
	}

	saveAsJSFile(savepath, dataVec);
}

//-----------------------------------------------------------------------

function loadJSON(filepath, savepath) {
	'use strict';

	console.log('Loading ' + filepath);

	var fs = require('fs');

	fs.readFile(filepath, 'utf-8', function (err, json) {
		if (err) {
			console.error(err);
		} else {
			if (typeof json === 'string') {
				json = JSON.parse(json);
			}
			analyseJSON(savepath, json);
		}
	});
}

//-----------------------------------------------------------------------

function downloadFile(filepath, uri, savepath) {
	'use strict';

	console.log('Downloading ' + uri);

	var fs = require('fs'),
		http = require('http'),
		file = fs.createWriteStream(filepath);

	http.get(uri, function (response) {
		response.pipe(file);
		loadJSON(filepath, savepath);
	});
}

//-----------------------------------------------------------------------

function parseFolder(path) {
	'use strict';

	var fs = require('fs'),
		now = new Date(),
		filename = dataSource + '-' + now.getFullYear() + twoDigits(now.getMonth() + 1) + twoDigits(now.getDate()) + '.json',
		savename = dataSource + '-' + now.getFullYear() + twoDigits(now.getMonth() + 1) + twoDigits(now.getDate()) + '.js',
		filepath = path + '/' + filename,
		savepath = path + '/' + savename,
		found = false;

	fs.readdir(path, function (err, files) {
		files.forEach(function (file) {
			if (file === filename) {
				found = true;
				console.log('Use cached file ' + filepath);
				loadJSON(filepath, savepath);
			}
		});

		if (!found) {
			downloadFile(filepath, dataURI, savepath);
		}
	});
}

//-----------------------------------------------------------------------

function buildBerlin() {
	'use strict';

	parseFolder('.');
}

//-----------------------------------------------------------------------

try {
	console.log();
	buildBerlin();
} catch (e) {
	console.error(e);
}

//-----------------------------------------------------------------------
//eof
<|endoftext|>


<commit_before>define(['mac/hfs/BTreeNodeView'], function(BTreeNodeView) {

  'use strict';

  var BLOCK_BYTES = 512;

  function BTreeByteSink(byteSource) {
    this.byteSource = byteSource;
  }
  BTreeByteSink.prototype = {
    getRawNode: function(number) {
      return this.byteSource.slice(
        number * BLOCK_BYTES,
        (number + 1) * BLOCK_BYTES).getBytes();
    },
    getNode: function(number) {
      return this.getRawNode(number)
      .then(function(rawNode) {
        return new BTreeNodeView(rawNode.buffer, rawNode.byteOffset, rawNode.byteLength);
      });
    },
    getHeaderNode: function() {
      var promise = this.getNode(0)
      .then(function(node) {
        if (node.nodeType !== 'header') return Promise.reject('node zero is not a header node');
        return node;
      });
      this.getHeaderNode = function(){ return promise; };
      return promise;
    },
    getFirstLeafNode: function() {
      var self = this;
      var promise = this.getHeaderNode()
      .then(function(node) {
        return self.getNode(node.records[0].firstLeaf);
      });
      this.getFirstLeafNode = function(){ return promise; };
      return promise;
    },
    getRootNode: function() {
      var self = this;
      var promise = this.getHeaderNode()
      .then(function(node) {
        return self.getNode(node.records[0].rootNodeNumber);
      });
      this.getRootNode = function(){ return promise; };
      return promise;
    },
    findLeafForParentDirectoryID: function(parentDirectoryID) {
      var self = this;
      function onNode(node) {
        if (node.nodeType === 'leaf') return node;
        if (node.nodeType !== 'index') return Promise.reject('node is not a leaf or index');
        for (var i = node.records.length - 1; i >= 0; i--) {
          if (parentDirectoryID >= node.records[i].parentDirectoryID) {
            return self.getNode(records[i].nodeNumber).then(onNode);
          }
        }
        return Promise.reject('parent directory ID not found: ' + parentDirectoryID);
      }
      return this.getRootNode().then(onNode);
    },
  };

  return BTreeByteSink;

});
<commit_msg>Use word folder not directory<commit_after>define(['mac/hfs/BTreeNodeView'], function(BTreeNodeView) {

  'use strict';

  var BLOCK_BYTES = 512;

  function BTreeByteSink(byteSource) {
    this.byteSource = byteSource;
  }
  BTreeByteSink.prototype = {
    getRawNode: function(number) {
      return this.byteSource.slice(
        number * BLOCK_BYTES,
        (number + 1) * BLOCK_BYTES).getBytes();
    },
    getNode: function(number) {
      return this.getRawNode(number)
      .then(function(rawNode) {
        return new BTreeNodeView(rawNode.buffer, rawNode.byteOffset, rawNode.byteLength);
      });
    },
    getHeaderNode: function() {
      var promise = this.getNode(0)
      .then(function(node) {
        if (node.nodeType !== 'header') return Promise.reject('node zero is not a header node');
        return node;
      });
      this.getHeaderNode = function(){ return promise; };
      return promise;
    },
    getFirstLeafNode: function() {
      var self = this;
      var promise = this.getHeaderNode()
      .then(function(node) {
        return self.getNode(node.records[0].firstLeaf);
      });
      this.getFirstLeafNode = function(){ return promise; };
      return promise;
    },
    getRootNode: function() {
      var self = this;
      var promise = this.getHeaderNode()
      .then(function(node) {
        return self.getNode(node.records[0].rootNodeNumber);
      });
      this.getRootNode = function(){ return promise; };
      return promise;
    },
    findLeafForParentFolderID: function(parentFolderID) {
      var self = this;
      function onNode(node) {
        if (node.nodeType === 'leaf') return node;
        if (node.nodeType !== 'index') return Promise.reject('node is not a leaf or index');
        for (var i = node.records.length - 1; i >= 0; i--) {
          if (parentFolderID >= node.records[i].parentFolderID) {
            return self.getNode(records[i].nodeNumber).then(onNode);
          }
        }
        return Promise.reject('parent folder ID not found: ' + parentFolderID);
      }
      return this.getRootNode().then(onNode);
    },
  };

  return BTreeByteSink;

});
<|endoftext|>


<commit_before>/**
 * React Starter Kit (https://www.reactstarterkit.com/)
 *
 * Copyright © 2014-2016 Kriasoft, LLC. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

import path from 'path';
import gaze from 'gaze';
import Promise from 'bluebird';
import fs from './lib/fs';
import pkg from '../package.json';
/**
 * Copies static files such as robots.txt, favicon.ico to the
 * output (build) folder.
 */
async function copy({ watch } = {}) {
  const ncp = Promise.promisify(require('ncp'));

  await Promise.all([
    ncp('src/public', 'build/public'),
    ncp('src/content', 'build/content'),
  ]);

  await fs.writeFile('./build/package.json', JSON.stringify({
    private: true,
    engines: pkg.engines,
    dependencies: pkg.dependencies,
    scripts: {
      start: 'node server.js',
    },
  }, null, 2));

  if (watch) {
    const watcher = await new Promise((resolve, reject) => {
      gaze('src/content/**/*.*', (err, val) => err ? reject(err) : resolve(val));
    });

    const cp = async (file) => {
      const relPath = file.substr(path.join(__dirname, '../src/content/').length);
      await ncp(`src/content/${relPath}`, `build/content/${relPath}`);
    };

    watcher.on('changed', cp);
    watcher.on('added', cp);
  }
}

export default copy;
<commit_msg>Copy material.css and material.js to build/public<commit_after>/**
 * React Starter Kit (https://www.reactstarterkit.com/)
 *
 * Copyright © 2014-2016 Kriasoft, LLC. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

import path from 'path';
import gaze from 'gaze';
import Promise from 'bluebird';
import fs from './lib/fs';
import pkg from '../package.json';
/**
 * Copies static files such as robots.txt, favicon.ico to the
 * output (build) folder.
 */
async function copy({ watch } = {}) {
  const ncp = Promise.promisify(require('ncp'));

  await Promise.all([
    ncp('src/public', 'build/public'),
    ncp('src/content', 'build/content'),
    ncp('node_modules/react-mdl/extra/material.css', 'build/public/material.css'),
    ncp('node_modules/react-mdl/extra/material.js', 'build/public/material.js'),
  ]);

  await fs.writeFile('./build/package.json', JSON.stringify({
    private: true,
    engines: pkg.engines,
    dependencies: pkg.dependencies,
    scripts: {
      start: 'node server.js',
    },
  }, null, 2));

  if (watch) {
    const watcher = await new Promise((resolve, reject) => {
      gaze('src/content/**/*.*', (err, val) => err ? reject(err) : resolve(val));
    });

    const cp = async (file) => {
      const relPath = file.substr(path.join(__dirname, '../src/content/').length);
      await ncp(`src/content/${relPath}`, `build/content/${relPath}`);
    };

    watcher.on('changed', cp);
    watcher.on('added', cp);
  }
}

export default copy;
<|endoftext|>


<commit_before>/*global $, jQuery, alert, console, error, success, endless, ajax, templateHelper, Routing, appLocale, exports, module, require, define*/
/*jslint nomen: true */ /* Tolerate dangling _ in identifiers */
/*jslint vars: true */ /* Tolerate many var statements per function */
/*jslint white: true */
/*jslint browser: true */
/*jslint devel: true */ /* Assume console, alert, ... */
/*jslint windows: true */ /* Assume Windows */
/*jslint maxerr: 100 */ /* Maximum number of errors */

/*
 * Class dependencies:
 *      jquery > 1.8.3
 *      isotope
 *      jsrender
 *      jsviews
 * external dependencies:
 *      templateHelper
 *      base genericAction
 */

// fansWorld TV Class Module 1.1 (con galerias de profiles)
// 1.0

(function (root, factory) {
    "use strict";
    if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like enviroments that support module.exports,
        // like Node.
        module.exports = factory(require('Routing'), require('templateHelper'), require('ajax'), require('ExposeTranslation'));
    } else if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['jQuery', 'Routing', 'templateHelper', 'ajax', 'ExposeTranslation'], factory);
    } else {
        // Browser globals (root is window)
        root.TV = factory(root.jQuery, root.Routing, root.templateHelper, root.ajax, root.ExposeTranslation);
    }
}(this, function (jQuery, Routing, templateHelper, ajax, ExposeTranslation) {
    "use strict";
    var TV = (function() {
        function TV(filtersList, channelsList) {
            //////////////
            // Internal //
            //////////////
            var that = this;
            this.jQuery = jQuery;
            this.name = filtersList;
            this.channelsList = channelsList;
            this.channel = $('.filter-channels').closest('ul').find("li.active").attr("data-channel-id");
            this.filter = $('#list-filters ul').find('li.active').attr('data-list-filter-type');

            this.page = 1;

            this.contentContainer = $('body');
            this.isotopeContainer = $(this.contentContainer).find('.isotope_container').last();
            if(this.isotopeContainer.length <= 0) {
                return;
            }
            this.feedSource = $(this.isotopeContainer).attr('data-feed-source');
            if(typeof this.feedSource === 'undefined'){
                this.entityId   = $("[data-list]").attr('data-entity-id');
                this.entityType = $("[data-list]").attr('data-entity-type');
                this.dataList = $("[data-list]").attr('data-list');
                this.isProfile = true;
                console.log("in-profile");
                var feed = that.getProfileVideoFeed();
                console.log("filter: " + that.criteria + " feed: " + feed);
                var opts = {
                    'sort': that.criteria,
                    'page': that.page,
                    'entityId': that.entityId,
                    'entityType': that.entityType
                };
                $(this.isotopeContainer).attr('data-feed-source', feed);
                console.log(opts);

            } else {
                this.isTeve = true;
            }
            this.defaultTags = [
                {filter: 'day', title: ExposeTranslation.get('day')},
                {filter: 'week', title: ExposeTranslation.get('week')},
                {filter: 'month', title: ExposeTranslation.get('month')}
            ];

            $(this.isotopeContainer).empty();

            //////////////
            // Bindings //
            //////////////
            // modalPopup
            $('#montage-video-list a').modalPopup();
            // subscribe buttons
            $('[data-subscribe-channel]').click(function () {
                that.subscribe($(this));
            });
            // Handle channel list
            this.channelToggle();
            // Handle Filter tabs (popular, views, latest)
            this.filterToggle();
            this.filterToolbar();

            ////////////////////
            // New TV Gallery //
            ////////////////////
            // load isotope gallery
            if(this.isTeve) {
                this.profileGallery();
            } else {
                this.loadGallery();
            }
            // Tags
            this.myTags();
            // custom tags
            if(this.filter === 'views') {
                this.addCustomTags(this.defaultTags);
            }
        }
        TV.prototype.loadGallery = function() {
            var that = this;
            $(this.isotopeContainer).fwGalerizer({
                normalize: false,
                endless: true,
                feedfilter: {
                    'sort': that.criteria,
                    'page': that.page,
                    'entityId': that.entityId,
                    'entityType': that.entityType
                },
                onEndless: function( plugin ) {
                    plugin.options.feedfilter.page += 1;
                    return plugin.options.feedfilter;
                },
                onDataReady: function(videos) {
                    var i, outp = [];
                    var normalize = function(video) {
                        var href = Routing.generate(appLocale + '_video_show', {
                            'id': video.id,
                            'slug': video.slug
                        });
                        var hrefModal = Routing.generate(appLocale + '_modal_media', {
                            'id': video.id,
                            'type': 'video'
                        });
                        var authorUrl = Routing.generate(appLocale + '_user_land', {
                            'username': 'juan.perez'
                        });
                        return {
                                'type': 'video',
                                'date': video.createdAt,
                                'href': href,
                                'hrefModal': hrefModal,
                                'image': video.imgsrc,
                                'slug': video.slug,
                                'title': video.title,
                                'author': 'juan.perez',
                                'authorHref': authorUrl,
                                'authorImage': 'http://fansworld.dodici.local/uploads/media/default/0001/02/thumb_1000_default_small_square_81dfa380953b084fb7eefb0273ac602bdee11874.jpg'
                        };
                    };
                    for(i in videos.elements) {
                        if (videos.elements.hasOwnProperty(i)) {
                            outp.push(normalize(videos.elements[i]));
                        }
                    }
                    return outp;
                }
            });
        };
        TV.prototype.profileGallery = function() {
            this.channel = $('.filter-channels').closest('ul').find("li.active").attr("data-channel-id");
            this.filter = $('#list-filters ul').find('li.active').attr('data-list-filter-type');
            this.page  = 1;
            $(this.isotopeContainer).fwGalerizer({
                normalize: false,
                endless: true,
                feedfilter: {'channel': this.channel, 'filter': this.filter, 'page': this.page},
                onEndless: function( plugin ) {
                    plugin.options.feedfilter.page += 1;
                    console.log("loading video gallery for channel %s with filter %s page: %s", plugin.options.feedfilter.channel, plugin.options.feedfilter.filter, plugin.options.feedfilter.page);
                    return plugin.options.feedfilter;
                },
                onDataReady: function(videos) {
                    var i, outp = [];
                    var normalize = function(video) {
                        var href = Routing.generate(appLocale + '_video_show', {
                            'id': video.id,
                            'slug': video.slug
                        });
                        var hrefModal = Routing.generate(appLocale + '_modal_media', {
                            'id': video.id,
                            'type': 'video'
                        });
                        var authorUrl = Routing.generate(appLocale + '_user_land', {
                            'username': video.author.username
                        });
                        return {
                                'type': 'video',
                                'date': video.createdAt,
                                'href': href,
                                'hrefModal': hrefModal,
                                'image': video.image,
                                'slug': video.slug,
                                'title': video.title,
                                'author': video.author.username,
                                'authorHref': authorUrl,
                                'authorImage': video.author.image
                        };
                    };
                    for(i in videos.videos) {
                        if (videos.videos.hasOwnProperty(i)) {
                            outp.push(normalize(videos.videos[i]));
                        }
                    }
                    return outp;
                }
            });
            this.page += 1;
        };
        TV.prototype.channelToggle = function() {
            var that = this;
            $('.filter-channels').closest('ul').find("li").click(function(e){
                var i;
                var selectedChannel = $(this).first().attr('data-list-target');
                $(".channels-widget .content .active").removeClass('active');
                $('.filter-channels').closest('ul').find("li.active").removeClass('active');
                $(this).first().addClass('active');

                $(".channels-widget .content #" + selectedChannel).addClass('active');

                // Update channel
                that.channel = $('.filter-channels').closest('ul').find("li.active").attr("data-channel-id");
                // update tags
                that.myTags(that.channel, that.filter);
                // custom tags
                if(that.filter === 'views') {
                    that.addCustomTags(that.defaultTags);
                }
                // Destroy gallery items
                that.destroyGallery();
                // Load new gallery
                that.profileGallery();
            });
        };
        TV.prototype.customFilterToggler = function(element) {
            var that = this;
            element.click(function(e){
                $('[data-list-filter-type=' + that.filter + ']').removeClass();
                that.filter = $(this).attr('data-list-filter-type');
                // update tags
                that.myTags(that.channel, that.filter);
                // create custom UI filter elements
                that.addCustomTags(that.defaultTags);
                $('[data-list-filter-type=' + that.filter + ']').addClass('active');
                // Destroy gallery items
                that.destroyGallery();
                // Load new gallery
                that.loadGallery();
            });
        };
        TV.prototype.getMethodName = function() {
            var that = this;
            var criteria = '';
            switch($("[data-sort] .btn-group").find('.active').attr('data-type')){
                case "0":
                    criteria = "highlight";
                    break;
                case "1":
                    criteria = "most-visited";
                    break;
                case "2":
                    criteria = "popular";
                    break;
                case "3":
                    criteria = "most-visited-today";
                    break;
            }
            that.criteria = criteria;
            return criteria;
        };
        TV.prototype.getProfileVideoFeed = function() {
            var that = this;
            var type = $("[data-sort] .btn-group").find('.active').attr('data-type');
            if(typeof(type) === 'undefined'){
                type = 'popular';
            }
            var methodName = that.getMethodName();
            var opts = {
                'sort': that.criteria,
                'page': that.page,
                'entityId': that.entityId,
                'entityType': that.entityType
            };
            var route = '';
            switch(that.criteria){
                case 'popular':
                    route = that.dataList + "_popular";
                    break;
                case 'highlight':
                    route = that.dataList + "_highlighted";
                    break;
                case 'most-visited':
                    route = that.dataList + "_visited";
                    break;
                case 'most-visited-today':
                    route = that.dataList + "_visited";
                    opts.today = true;
                    break;
            }
            return route;
        };
        TV.prototype.filterToolbar = function($toolbar) {
            var that = this;
            var method = '';
            $("[data-sort] .btn-group .btn").on('click', function(){
                $(this).parent().find('.active').removeClass('active');
                $(this).addClass('active');
                switch($(this).attr('data-type')){
                    case "0":
                        that.criteria = "highlight";
                        break;
                    case "1":
                        that.criteria = "most-visited";
                        break;
                    case "2":
                        that.criteria = "popular";
                        break;
                    case "3":
                        that.criteria = "most-visited-today";
                        break;
                }
                var feed = that.getProfileVideoFeed();
                $(that.isotopeContainer).attr('data-feed-source', feed);
                console.log("filter: " + that.criteria + " feed: " + feed);
                var opts = {
                    'sort': that.criteria,
                    'page': that.page,
                    'entityId': that.entityId,
                    'entityType': that.entityType
                };
                console.log(opts);
                // Destroy gallery items
                that.destroyGallery();
                that.page = 1;  // reset page count
                // Load new gallery
                that.loadGallery();
            });
        };
        TV.prototype.filterToggle = function() {
            var that = this;
            $('#list-filters').find("li").click(function(e){
                var i;
                var selectedFilter = $(this).first().attr('data-list-filter-type');
                $('#list-filters').find("li.active").removeClass('active');
                $(this).first().addClass('active');

                that.filter = $('#list-filters ul').find('li.active').attr('data-list-filter-type');
                // update tags
                that.myTags(that.channel, that.filter);
                // custom tags
                if(that.filter === 'views') {
                    that.addCustomTags(that.defaultTags);
                }
                // Destroy gallery items
                that.destroyGallery();
                // Load new gallery
                that.profileGallery();
            });
        };
        TV.prototype.myTags = function(channel, filter) {
            var $tagList = $(".content-container").find(".tag-list-container ul");
            $tagList.empty();
            ajax.genericAction("tag_ajaxgetusedinvideos", {
                "channel": channel,
                "filter": filter
            }, function(r) {
                var i;
                for (i in r.tags) {
                    if (r.tags.hasOwnProperty(i)) {
                        var tagHref = Routing.generate(appLocale + "_teve_taggedvideos", {
                            term: r.tags[i].slug
                        });
                        //console.log(r.tags[i]);
                        $tagList.append("
" + r.tags[i].title + "
");
                    }
                }
            });
        };
        TV.prototype.addCustomTags = function(tags, options) {
            var that = this;
            var i;
            var $tagList = $(".content-container").find(".tag-list-container ul");
            for(i in tags) {
                if (tags.hasOwnProperty(i)) {
                    var $customFilter = $("
" + tags[i].title + "
");
                    that.customFilterToggler($customFilter);
                    $tagList.prepend($customFilter);
                }
            }
            return;
        };
        TV.prototype.destroyGallery = function() {
            $(this.isotopeContainer).data('fwGalerizer').destroy();
            return;
        };
        TV.prototype.subscribe = function ($button) {
            var channel = $button.attr('data-subscribe-channel');
            var params = {};

            if (!channel || channel === 'all') {
                return alert('Por favor elija un canal antes de suscribirse.');
            }
            params.channel = channel;

            $button.addClass('loading-small');

            ajax.genericAction('teve_channelsubscribe', params, function (response) {
                success(response.message);
                $button.text(response.buttontext);

                if (response.state === true) {
                    $button.prepend($('').attr('class', 'icon-remove').after(' '));
                } else if (response.state === false) {
                    $button.prepend($('').attr('class', 'icon-ok').after(' '));
                }
                $button.removeClass('loading-small');
            }, function (msg) {
                error(msg);
                $button.removeClass('loading-small');
            });
        };
        return TV;
    }());
    // Just return a value to define the module export.
    // This example returns an object, but the module
    // can return a function as the exported value.
    return TV;
}));

// implicit init that adds module to global scope
// TODO: refactor inside curl
$(document).ready(function () {
    "use strict";
    window.fansworld = window.fansworld || {};
    var defaultChannel = null; //
    var defaultFilter = 'popular';
    window.fansworld.tv = new window.TV(defaultChannel, defaultFilter);
    return;
});<commit_msg>revisado<commit_after>/*global $, jQuery, alert, console, error, success, endless, ajax, templateHelper, Routing, appLocale, exports, module, require, define*/
/*jslint nomen: true */ /* Tolerate dangling _ in identifiers */
/*jslint vars: true */ /* Tolerate many var statements per function */
/*jslint white: true */
/*jslint browser: true */
/*jslint devel: true */ /* Assume console, alert, ... */
/*jslint windows: true */ /* Assume Windows */
/*jslint maxerr: 100 */ /* Maximum number of errors */

/*
 * Class dependencies:
 *      jquery > 1.8.3
 *      isotope
 *      jsrender
 *      jsviews
 * external dependencies:
 *      templateHelper
 *      base genericAction
 */

// fansWorld TV Class Module 1.1 (con galerias de profiles)
// 1.0

(function (root, factory) {
    "use strict";
    if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like enviroments that support module.exports,
        // like Node.
        module.exports = factory(require('Routing'), require('templateHelper'), require('ajax'), require('ExposeTranslation'));
    } else if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['jQuery', 'Routing', 'templateHelper', 'ajax', 'ExposeTranslation'], factory);
    } else {
        // Browser globals (root is window)
        root.TV = factory(root.jQuery, root.Routing, root.templateHelper, root.ajax, root.ExposeTranslation);
    }
}(this, function (jQuery, Routing, templateHelper, ajax, ExposeTranslation) {
    "use strict";
    var TV = (function() {
        function TV(filtersList, channelsList) {
            //////////////
            // Internal //
            //////////////
            var that = this;
            this.jQuery = jQuery;
            this.name = filtersList;
            this.channelsList = channelsList;
            this.channel = $('.filter-channels').closest('ul').find("li.active").attr("data-channel-id");
            this.filter = $('#list-filters ul').find('li.active').attr('data-list-filter-type');

            this.page = 1;

            this.contentContainer = $('body');
            this.isotopeContainer = $(this.contentContainer).find('.isotope_container').last();
            if(this.isotopeContainer.length <= 0) {
                return;
            }
            this.feedSource = $(this.isotopeContainer).attr('data-feed-source');
            if(typeof this.feedSource === 'undefined' || this.feedSource.length == ''){
                this.entityId   = $("[data-list]").attr('data-entity-id');
                this.entityType = $("[data-list]").attr('data-entity-type');
                this.dataList = $("[data-list]").attr('data-list');
                this.isProfile = true;
                console.log("in-profile");
                var feed = that.getProfileVideoFeed();
                console.log("filter: " + that.criteria + " feed: " + feed);
                var opts = {
                    'sort': that.criteria,
                    'page': that.page,
                    'entityId': that.entityId,
                    'entityType': that.entityType
                };
                $(this.isotopeContainer).attr('data-feed-source', feed);
                console.log(opts);

            } else {
                this.isTeve = true;
            }
            this.defaultTags = [
                {filter: 'day', title: ExposeTranslation.get('day')},
                {filter: 'week', title: ExposeTranslation.get('week')},
                {filter: 'month', title: ExposeTranslation.get('month')}
            ];

            $(this.isotopeContainer).empty();

            //////////////
            // Bindings //
            //////////////
            // modalPopup
            $('#montage-video-list a').modalPopup();
            // subscribe buttons
            $('[data-subscribe-channel]').click(function () {
                that.subscribe($(this));
            });
            // Handle channel list
            this.channelToggle();
            // Handle Filter tabs (popular, views, latest)
            this.filterToggle();
            this.filterToolbar();

            ////////////////////
            // New TV Gallery //
            ////////////////////
            // load isotope gallery
            if(this.isTeve) {
                this.profileGallery();
            } else {
                this.loadGallery();
            }
            // Tags
            this.myTags();
            // custom tags
            if(this.filter === 'views') {
                this.addCustomTags(this.defaultTags);
            }
        }
        TV.prototype.loadGallery = function() {
            var that = this;
            $(this.isotopeContainer).fwGalerizer({
                normalize: false,
                endless: true,
                feedfilter: {
                    'sort': that.criteria,
                    'page': that.page,
                    'entityId': that.entityId,
                    'entityType': that.entityType
                },
                onEndless: function( plugin ) {
                    plugin.options.feedfilter.page += 1;
                    return plugin.options.feedfilter;
                },
                onDataReady: function(videos) {
                    var i, outp = [];
                    var normalize = function(video) {
                        var href = Routing.generate(appLocale + '_video_show', {
                            'id': video.id,
                            'slug': video.slug
                        });
                        var hrefModal = Routing.generate(appLocale + '_modal_media', {
                            'id': video.id,
                            'type': 'video'
                        });
                        var authorUrl = Routing.generate(appLocale + '_user_land', {
                            'username': 'juan.perez'
                        });
                        return {
                                'type': 'video',
                                'date': video.createdAt,
                                'href': href,
                                'hrefModal': hrefModal,
                                'image': video.imgsrc,
                                'slug': video.slug,
                                'title': video.title,
                                'author': 'juan.perez',
                                'authorHref': authorUrl,
                                'authorImage': 'http://fansworld.dodici.local/uploads/media/default/0001/02/thumb_1000_default_small_square_81dfa380953b084fb7eefb0273ac602bdee11874.jpg'
                        };
                    };
                    for(i in videos.elements) {
                        if (videos.elements.hasOwnProperty(i)) {
                            outp.push(normalize(videos.elements[i]));
                        }
                    }
                    return outp;
                }
            });
        };
        TV.prototype.profileGallery = function() {
            this.channel = $('.filter-channels').closest('ul').find("li.active").attr("data-channel-id");
            this.filter = $('#list-filters ul').find('li.active').attr('data-list-filter-type');
            this.page  = 1;
            $(this.isotopeContainer).fwGalerizer({
                normalize: false,
                endless: true,
                feedfilter: {'channel': this.channel, 'filter': this.filter, 'page': this.page},
                onEndless: function( plugin ) {
                    plugin.options.feedfilter.page += 1;
                    console.log("loading video gallery for channel %s with filter %s page: %s", plugin.options.feedfilter.channel, plugin.options.feedfilter.filter, plugin.options.feedfilter.page);
                    return plugin.options.feedfilter;
                },
                onDataReady: function(videos) {
                    var i, outp = [];
                    var normalize = function(video) {
                        var href = Routing.generate(appLocale + '_video_show', {
                            'id': video.id,
                            'slug': video.slug
                        });
                        var hrefModal = Routing.generate(appLocale + '_modal_media', {
                            'id': video.id,
                            'type': 'video'
                        });
                        var authorUrl = Routing.generate(appLocale + '_user_land', {
                            'username': video.author.username
                        });
                        return {
                                'type': 'video',
                                'date': video.createdAt,
                                'href': href,
                                'hrefModal': hrefModal,
                                'image': video.image,
                                'slug': video.slug,
                                'title': video.title,
                                'author': video.author.username,
                                'authorHref': authorUrl,
                                'authorImage': video.author.image
                        };
                    };
                    for(i in videos.videos) {
                        if (videos.videos.hasOwnProperty(i)) {
                            outp.push(normalize(videos.videos[i]));
                        }
                    }
                    return outp;
                }
            });
            this.page += 1;
        };
        TV.prototype.channelToggle = function() {
            var that = this;
            $('.filter-channels').closest('ul').find("li").click(function(e){
                var i;
                var selectedChannel = $(this).first().attr('data-list-target');
                $(".channels-widget .content .active").removeClass('active');
                $('.filter-channels').closest('ul').find("li.active").removeClass('active');
                $(this).first().addClass('active');

                $(".channels-widget .content #" + selectedChannel).addClass('active');

                // Update channel
                that.channel = $('.filter-channels').closest('ul').find("li.active").attr("data-channel-id");
                // update tags
                that.myTags(that.channel, that.filter);
                // custom tags
                if(that.filter === 'views') {
                    that.addCustomTags(that.defaultTags);
                }
                // Destroy gallery items
                that.destroyGallery();
                // Load new gallery
                that.profileGallery();
            });
        };
        TV.prototype.customFilterToggler = function(element) {
            var that = this;
            element.click(function(e){
                $('[data-list-filter-type=' + that.filter + ']').removeClass();
                that.filter = $(this).attr('data-list-filter-type');
                // update tags
                that.myTags(that.channel, that.filter);
                // create custom UI filter elements
                that.addCustomTags(that.defaultTags);
                $('[data-list-filter-type=' + that.filter + ']').addClass('active');
                // Destroy gallery items
                that.destroyGallery();
                // Load new gallery
                that.loadGallery();
            });
        };
        TV.prototype.getMethodName = function() {
            var that = this;
            var criteria = '';
            switch($("[data-sort] .btn-group").find('.active').attr('data-type')){
                case "0":
                    criteria = "highlight";
                    break;
                case "1":
                    criteria = "most-visited";
                    break;
                case "2":
                    criteria = "popular";
                    break;
                case "3":
                    criteria = "most-visited-today";
                    break;
            }
            that.criteria = criteria;
            return criteria;
        };
        TV.prototype.getProfileVideoFeed = function() {
            var that = this;
            var type = $("[data-sort] .btn-group").find('.active').attr('data-type');
            if(typeof(type) === 'undefined'){
                type = 'popular';
            }
            var methodName = that.getMethodName();
            var opts = {
                'sort': that.criteria,
                'page': that.page,
                'entityId': that.entityId,
                'entityType': that.entityType
            };
            var route = '';
            switch(that.criteria){
                case 'popular':
                    route = that.dataList + "_popular";
                    break;
                case 'highlight':
                    route = that.dataList + "_highlighted";
                    break;
                case 'most-visited':
                    route = that.dataList + "_visited";
                    break;
                case 'most-visited-today':
                    route = that.dataList + "_visited";
                    opts.today = true;
                    break;
            }
            return route;
        };
        TV.prototype.filterToolbar = function($toolbar) {
            var that = this;
            var method = '';
            $("[data-sort] .btn-group .btn").on('click', function(){
                $(this).parent().find('.active').removeClass('active');
                $(this).addClass('active');
                switch($(this).attr('data-type')){
                    case "0":
                        that.criteria = "highlight";
                        break;
                    case "1":
                        that.criteria = "most-visited";
                        break;
                    case "2":
                        that.criteria = "popular";
                        break;
                    case "3":
                        that.criteria = "most-visited-today";
                        break;
                }
                var feed = that.getProfileVideoFeed();
                $(that.isotopeContainer).attr('data-feed-source', feed);
                console.log("filter: " + that.criteria + " feed: " + feed);
                var opts = {
                    'sort': that.criteria,
                    'page': that.page,
                    'entityId': that.entityId,
                    'entityType': that.entityType
                };
                console.log(opts);
                // Destroy gallery items
                that.destroyGallery();
                that.page = 1;  // reset page count
                // Load new gallery
                that.loadGallery();
            });
        };
        TV.prototype.filterToggle = function() {
            var that = this;
            $('#list-filters').find("li").click(function(e){
                var i;
                var selectedFilter = $(this).first().attr('data-list-filter-type');
                $('#list-filters').find("li.active").removeClass('active');
                $(this).first().addClass('active');

                that.filter = $('#list-filters ul').find('li.active').attr('data-list-filter-type');
                // update tags
                that.myTags(that.channel, that.filter);
                // custom tags
                if(that.filter === 'views') {
                    that.addCustomTags(that.defaultTags);
                }
                // Destroy gallery items
                that.destroyGallery();
                // Load new gallery
                that.profileGallery();
            });
        };
        TV.prototype.myTags = function(channel, filter) {
            var $tagList = $(".content-container").find(".tag-list-container ul");
            $tagList.empty();
            ajax.genericAction("tag_ajaxgetusedinvideos", {
                "channel": channel,
                "filter": filter
            }, function(r) {
                var i;
                for (i in r.tags) {
                    if (r.tags.hasOwnProperty(i)) {
                        var tagHref = Routing.generate(appLocale + "_teve_taggedvideos", {
                            term: r.tags[i].slug
                        });
                        //console.log(r.tags[i]);
                        $tagList.append("
" + r.tags[i].title + "
");
                    }
                }
            });
        };
        TV.prototype.addCustomTags = function(tags, options) {
            var that = this;
            var i;
            var $tagList = $(".content-container").find(".tag-list-container ul");
            for(i in tags) {
                if (tags.hasOwnProperty(i)) {
                    var $customFilter = $("
" + tags[i].title + "
");
                    that.customFilterToggler($customFilter);
                    $tagList.prepend($customFilter);
                }
            }
            return;
        };
        TV.prototype.destroyGallery = function() {
            $(this.isotopeContainer).data('fwGalerizer').destroy();
            return;
        };
        TV.prototype.subscribe = function ($button) {
            var channel = $button.attr('data-subscribe-channel');
            var params = {};

            if (!channel || channel === 'all') {
                return alert('Por favor elija un canal antes de suscribirse.');
            }
            params.channel = channel;

            $button.addClass('loading-small');

            ajax.genericAction('teve_channelsubscribe', params, function (response) {
                success(response.message);
                $button.text(response.buttontext);

                if (response.state === true) {
                    $button.prepend($('').attr('class', 'icon-remove').after(' '));
                } else if (response.state === false) {
                    $button.prepend($('').attr('class', 'icon-ok').after(' '));
                }
                $button.removeClass('loading-small');
            }, function (msg) {
                error(msg);
                $button.removeClass('loading-small');
            });
        };
        return TV;
    }());
    // Just return a value to define the module export.
    // This example returns an object, but the module
    // can return a function as the exported value.
    return TV;
}));

// implicit init that adds module to global scope
// TODO: refactor inside curl
$(document).ready(function () {
    "use strict";
    window.fansworld = window.fansworld || {};
    var defaultChannel = null; //
    var defaultFilter = 'popular';
    window.fansworld.tv = new window.TV(defaultChannel, defaultFilter);
    return;
});<|endoftext|>


<commit_before>jQuery(function($) {
	var supportedTypes = ['image/gif', 'image/png', 'image/jpeg', 'image/bmp', 'image/x-icon', 'application/pdf', 'image/x-tiff', 'image/x-tiff', 'application/postscript', 'image/vnd.adobe.photoshop'];

	// Cloudinary Image
	$('.field.type-cloudinaryimage').each(function() {

		var $el = $(this),
			data = $el.data();

		var $action = $el.find('.field-action'),
			$upload = $el.find('.field-upload');

		var $uploadBtn = $el.find('.btn-upload-image'),
			$deleteBtn = $el.find('.btn-delete-image'),
			$cancelBtn = $el.find('.btn-cancel-image'),
			$undoBtn = $el.find('.btn-undo-image');

		var $uploadQueued = $el.find('.upload-queued'),
			$deleteQueued = $el.find('.delete-queued'),
			$selectQueued = $el.find('.select-queued');

		var $deletePending = $el.find('.delete-pending');

		var $image = $el.find('.image-container'),
			$imagePreview = $image.find('.image-preview.current'),
			$imageDetails = $image.find('.image-details'),
			$imageValues = $image.find('.image-values');

		var $select2Input = $el.find('.ui-select2-cloudinary');

		var action = false;

		var imageFieldHTML = '
' +
				'

'
			'
';

		var removeNewImage = function() {
			$el.find('.image-preview.new').remove();
		};

		var removeSelectImage = function() {
			$el.find('.image-preview.select').remove();
		};

		var clearSelect = function() {
			$select2Input.siblings('.select2-container').select2('val', '', true);
			// $select2Input.val('');
		};

		var checkExistingImage = function() {
			if (data.fieldValue) {
				// Show it
				$imagePreview.show();
				// If we've got a pending remove/delete
				if (action) {
					// Show the undo button
					$undoBtn.show();
					// Messages
					$deleteQueued.show();
				} else {
					// Make sure the undo button is hidden
					$undoBtn.hide();
					// Show delete button
					$deleteBtn.show();
					// Show image values
					$imageValues.show();
				}
			} else {
				// Otherwise if we aren't deleting anything yet
				if (!action) {
					// Hide the delete button
					$deleteBtn.hide();
				} else {
					// Or make sure it's visiboe
					$deleteBtn.show();
				}
				// Make sure upload button references no current image
				$uploadBtn.html('Upload Image');
			}
		};

		$upload.change(function(e) {
			var imageSelected = $(this).val() ? true : false;
			var renderPlaceholder = function() {
				// Cloud selection
				clearSelect();
				// Image
				$imagePreview.hide();
				$imageValues.hide();
				// Messages
				$uploadQueued[imageSelected ? 'show' : 'hide']();
				// Buttons
				$undoBtn.hide();
				$deleteBtn.hide();
				$cancelBtn.show();
				$uploadBtn.text(imageSelected ? 'Change Image' : 'Upload Image');
				// Preview
				removeNewImage();
				// Render HTML
				return $(imageFieldHTML).prependTo($image);
			};
			// Preview
			if (imageSelected) {
				if (window.FileReader) {
					var files = e.target.files;
					for (var i = 0, f; f = files[i]; i++) {
						if (!_.contains(supportedTypes, f.type)) {
							$upload.val('');
							alert("Unsupported file type. Supported formats are: GIF, PNG, JPG, BMP, ICO, PDF, TIFF, EPS, PSD");
							continue;
						}
						var fileReader = new FileReader();
						fileReader.onload = (function(file) {
							return function(e) {
								renderPlaceholder().find('.img-thumbnail .placeholder').prop('src', e.target.result).prop( 'title', escape(file.name) );
								$(window).trigger('redraw');
							};
						})(f);
						fileReader.readAsDataURL(f);
					}
				} else {
					return renderPlaceholder();
				}
			}
		});

		// Upload Image
		$uploadBtn.click(function() {
			$upload.click();
		});

		// Delete/Remove Image
		$deleteBtn.click(function(e) {
			e.preventDefault();
			// Action
			if (e.altKey) {
				$action.val($deleteBtn.data('alt-action'));
				action = $deleteBtn.data('alt-action') === 'delete' ? 'delete' : 'remove';
			} else {
				$action.val($deleteBtn.data('default-action'));
				action = $deleteBtn.data('default-action') === 'delete' ? 'delete' : 'remove';
			}
			// Details
			$imageValues.hide();
			// Image
			$imagePreview.addClass('removed');
			$deletePending.addClass(action == 'delete' ? 'ion-trash-a' : 'ion-close').show();
			// Buttons
			$deleteBtn.hide();
			$undoBtn.html('Undo ' + ( action == 'delete' ? 'Delete' : 'Remove')).show();
			$cancelBtn.hide();
			$uploadBtn.html('Upload Image');
			// Messages
			$deleteQueued.show();
			$deleteQueued.find('.alert').html('Image '+ ( action == 'delete' ? 'deleted' : 'removed') + ' - save to confirm');
			// Redraw
			$(window).trigger('redraw');
		});

		// Undo Delete/Remove
		$undoBtn.click(function(e) {
			e.preventDefault();
			// Action
			$action.val('');
			action = false;
			// Details
			$imageValues.show();
			// Image
			$imagePreview.removeClass('removed');
			$deletePending.removeClass('ion-close ion-trash-a').hide();
			// Buttons
			$undoBtn.hide();
			$cancelBtn.hide();
			$deleteBtn.show();
			$uploadBtn.html('Change Image');
			// Messages
			$deleteQueued.hide();
			// Redraw
			$(window).trigger('redraw');
		});

		// Cancel Upload
		$cancelBtn.click(function(e) {
			e.preventDefault();
			// Remove new image preview
			removeNewImage();
			// Erase selected image
			$upload.val('');
			// If we have an image already
			checkExistingImage();
			// Hide the cancel upload button
			$cancelBtn.hide();
			// Hide queued upload message
			$uploadQueued.hide();
			// Redraw
			$(window).trigger('redraw');
		});

		// Image popup
		if ( data.fieldValue ) {
			$imagePreview.find('a').fancybox({
				prevEffect: 'none',
				nextEffect: 'none',
				closeBtn: false,
				helpers: {
					title: {},
					buttons: {}
				}
			});
		}

		$select2Input.each(function(i, el) {

			el = $(el), query = '';

			var perPage = 10,
				args = {
					context: 'cloudinary',
					list: Keystone.list.path,
					field: el.attr('name'),
					prefix: el.data('prefix'),
				},
				cursors;

			if (Keystone.item) {
				args.item = Keystone.item.id;
			}

			el.select2({
				placeholder: 'Search for an image from Cloudinary ...',
				allowClear: true,
				multiple: false,
				width: "60%",
				loadMorePadding: 100,
				ajax: {
					url: '/keystone/api/cloudinary/autocomplete',
					dataType: 'json',
					quietMillis: 500,
					data: function(term, page) {
						query = term;

						if (page == 1) {
							cursors = [ null ]
						};

						return _.extend({
							q: term, //search term
							max: perPage, // page size
							page: page, // page number, tracked by select2, one-based
							next: cursors[page - 1]
						}, args);
					},
					results: function(data, page) {
						var more = !!data.next, items = [];
						if (more) {
							cursors.push(data.next);
						}

						$.each(data.items, function(){
							if(query.length == 0 || this.public_id.toLowerCase().indexOf(query.toLowerCase()) >= 0 ){
								items.push(this);
							}
						});

						return { results: items, more: more };
					}
				},
				id: function(item){ return item.public_id; },
				initSelection: function(element, callback) {
					var id = $(element).val();
					if (id !== '') {
						$.ajax('/keystone/api/cloudinary/get', {
							data: { id: id },
							dataType: 'json'
						}).done(function(result) {
							callback({
								id: result.id,
								text: result.id
							});
						});
					}
				},
				formatResult: function(item) { return item.public_id; },
				formatSelection: function(item) { return item.public_id; },
				escapeMarkup: function (m) { return m; } // we do not want to escape markup since we are displaying html in results
			});

			el.on('change', function(e) {
				var select2data, imageWrapper, $newImage;

				if (e.val === '') {
					removeSelectImage();
					$selectQueued.hide();
					checkExistingImage();
					return;
				}

				if ($el.find('.image-preview.current').length) {
					// Image
					$imagePreview.hide();
					$imageValues.hide();
					// Messages
					$uploadQueued.hide();
					// Buttons
					$undoBtn.hide();
					$deleteBtn.hide();
					$cancelBtn.hide();
				}

				if ($el.find('.image-preview.new').length) {
					// Image
					removeNewImage();
					// Data
					$upload.val('');
					// Messages
					$uploadQueued.hide();
					$cancelBtn.hide();
				}

				if ($el.find('.image-preview.select').length) {
					removeSelectImage();
				}

				select2data = el.select2('data');
				imageWrapper = '
' +
					'

' +
					'
';
				$newImage = $('').attr('src', select2data.url);

				$newImage.on('load', function() {
					$(imageWrapper).prependTo($image).find('.img-thumbnail').append($(this));
					$selectQueued.show();
				});

			});

		});

	});

});
<commit_msg>Cloudinary preview when select is true.<commit_after>jQuery(function($) {
	var supportedTypes = ['image/gif', 'image/png', 'image/jpeg', 'image/bmp', 'image/x-icon', 'application/pdf', 'image/x-tiff', 'image/x-tiff', 'application/postscript', 'image/vnd.adobe.photoshop'];

	// Cloudinary Image
	$('.field.type-cloudinaryimage').each(function() {

		var $el = $(this),
			data = $el.data();

		var $action = $el.find('.field-action'),
			$upload = $el.find('.field-upload');

		var $uploadBtn = $el.find('.btn-upload-image'),
			$deleteBtn = $el.find('.btn-delete-image'),
			$cancelBtn = $el.find('.btn-cancel-image'),
			$undoBtn = $el.find('.btn-undo-image');

		var $uploadQueued = $el.find('.upload-queued'),
			$deleteQueued = $el.find('.delete-queued'),
			$selectQueued = $el.find('.select-queued');

		var $deletePending = $el.find('.delete-pending');

		var $image = $el.find('.image-container'),
			$imagePreview = $image.find('.image-preview.current'),
			$imageDetails = $image.find('.image-details'),
			$imageValues = $image.find('.image-values');

		var $select2Input = $el.find('.ui-select2-cloudinary');

		var action = false;

		var imageFieldHTML = '
' +
				'

'
			'
';

		var removeNewImage = function() {
			$el.find('.image-preview.new').remove();
		};

		var removeSelectImage = function() {
			$el.find('.image-preview.select').remove();
		};

		var clearSelect = function() {
			$select2Input.siblings('.select2-container').select2('val', '', true);
			// $select2Input.val('');
		};

		var checkExistingImage = function() {
			if (data.fieldValue) {
				// Show it
				$imagePreview.show();
				// If we've got a pending remove/delete
				if (action) {
					// Show the undo button
					$undoBtn.show();
					// Messages
					$deleteQueued.show();
				} else {
					// Make sure the undo button is hidden
					$undoBtn.hide();
					// Show delete button
					$deleteBtn.show();
					// Show image values
					$imageValues.show();
				}
			} else {
				// Otherwise if we aren't deleting anything yet
				if (!action) {
					// Hide the delete button
					$deleteBtn.hide();
				} else {
					// Or make sure it's visiboe
					$deleteBtn.show();
				}
				// Make sure upload button references no current image
				$uploadBtn.html('Upload Image');
			}
		};

		$upload.change(function(e) {
			var imageSelected = $(this).val() ? true : false;
			var renderPlaceholder = function() {
				// Cloud selection
				clearSelect();
				// Image
				$imagePreview.hide();
				$imageValues.hide();
				// Messages
				$uploadQueued[imageSelected ? 'show' : 'hide']();
				// Buttons
				$undoBtn.hide();
				$deleteBtn.hide();
				$cancelBtn.show();
				$uploadBtn.text(imageSelected ? 'Change Image' : 'Upload Image');
				// Preview
				removeNewImage();
				// Render HTML
				return $(imageFieldHTML).prependTo($image);
			};
			// Preview
			if (imageSelected) {
				if (window.FileReader) {
					var files = e.target.files;
					for (var i = 0, f; f = files[i]; i++) {
						if (!_.contains(supportedTypes, f.type)) {
							$upload.val('');
							alert("Unsupported file type. Supported formats are: GIF, PNG, JPG, BMP, ICO, PDF, TIFF, EPS, PSD");
							continue;
						}
						var fileReader = new FileReader();
						fileReader.onload = (function(file) {
							return function(e) {
								renderPlaceholder().find('.img-thumbnail .placeholder').prop('src', e.target.result).prop( 'title', escape(file.name) );
								$(window).trigger('redraw');
							};
						})(f);
						fileReader.readAsDataURL(f);
					}
				} else {
					return renderPlaceholder();
				}
			}
		});

		// Upload Image
		$uploadBtn.click(function() {
			$upload.click();
		});

		// Delete/Remove Image
		$deleteBtn.click(function(e) {
			e.preventDefault();
			// Action
			if (e.altKey) {
				$action.val($deleteBtn.data('alt-action'));
				action = $deleteBtn.data('alt-action') === 'delete' ? 'delete' : 'remove';
			} else {
				$action.val($deleteBtn.data('default-action'));
				action = $deleteBtn.data('default-action') === 'delete' ? 'delete' : 'remove';
			}
			// Details
			$imageValues.hide();
			// Image
			$imagePreview.addClass('removed');
			$deletePending.addClass(action == 'delete' ? 'ion-trash-a' : 'ion-close').show();
			// Buttons
			$deleteBtn.hide();
			$undoBtn.html('Undo ' + ( action == 'delete' ? 'Delete' : 'Remove')).show();
			$cancelBtn.hide();
			$uploadBtn.html('Upload Image');
			// Messages
			$deleteQueued.show();
			$deleteQueued.find('.alert').html('Image '+ ( action == 'delete' ? 'deleted' : 'removed') + ' - save to confirm');
			// Redraw
			$(window).trigger('redraw');
		});

		// Undo Delete/Remove
		$undoBtn.click(function(e) {
			e.preventDefault();
			// Action
			$action.val('');
			action = false;
			// Details
			$imageValues.show();
			// Image
			$imagePreview.removeClass('removed');
			$deletePending.removeClass('ion-close ion-trash-a').hide();
			// Buttons
			$undoBtn.hide();
			$cancelBtn.hide();
			$deleteBtn.show();
			$uploadBtn.html('Change Image');
			// Messages
			$deleteQueued.hide();
			// Redraw
			$(window).trigger('redraw');
		});

		// Cancel Upload
		$cancelBtn.click(function(e) {
			e.preventDefault();
			// Remove new image preview
			removeNewImage();
			// Erase selected image
			$upload.val('');
			// If we have an image already
			checkExistingImage();
			// Hide the cancel upload button
			$cancelBtn.hide();
			// Hide queued upload message
			$uploadQueued.hide();
			// Redraw
			$(window).trigger('redraw');
		});

		// Image popup
		if ( data.fieldValue ) {
			$imagePreview.find('a').fancybox({
				prevEffect: 'none',
				nextEffect: 'none',
				closeBtn: false,
				helpers: {
					title: {},
					buttons: {}
				}
			});
		}

		$select2Input.each(function(i, el) {

			el = $(el), query = '';

			var perPage = 10,
				args = {
					context: 'cloudinary',
					list: Keystone.list.path,
					field: el.attr('name'),
					prefix: el.data('prefix'),
				},
				cursors;

			if (Keystone.item) {
				args.item = Keystone.item.id;
			}

			el.select2({
				placeholder: 'Search for an image from Cloudinary ...',
				allowClear: true,
				multiple: false,
				width: "60%",
				loadMorePadding: 100,
				ajax: {
					url: '/keystone/api/cloudinary/autocomplete',
					dataType: 'json',
					quietMillis: 500,
					data: function(term, page) {
						query = term;

						if (page == 1) {
							cursors = [ null ]
						};

						return _.extend({
							q: term, //search term
							max: perPage, // page size
							page: page, // page number, tracked by select2, one-based
							next: cursors[page - 1]
						}, args);
					},
					results: function(data, page) {
						var more = !!data.next, items = [];
						if (more) {
							cursors.push(data.next);
						}

						$.each(data.items, function(){
							if(query.length == 0 || this.public_id.toLowerCase().indexOf(query.toLowerCase()) >= 0 ){
								items.push(this);
							}
						});

						return { results: items, more: more };
					}
				},
				id: function(item){ return item.public_id; },
				initSelection: function(element, callback) {
					var id = $(element).val();
					if (id !== '') {
						$.ajax('/keystone/api/cloudinary/get', {
							data: { id: id },
							dataType: 'json'
						}).done(function(result) {
							callback({
								id: result.id,
								text: result.id
							});
						});
					}
				},
				formatResult: function(item) {return ' ' + item.public_id;},
				formatSelection: function(item) { return item.public_id; },
				escapeMarkup: function (m) { return m; } // we do not want to escape markup since we are displaying html in results
			});

			el.on('change', function(e) {
				var select2data, imageWrapper, $newImage;

				if (e.val === '') {
					removeSelectImage();
					$selectQueued.hide();
					checkExistingImage();
					return;
				}

				if ($el.find('.image-preview.current').length) {
					// Image
					$imagePreview.hide();
					$imageValues.hide();
					// Messages
					$uploadQueued.hide();
					// Buttons
					$undoBtn.hide();
					$deleteBtn.hide();
					$cancelBtn.hide();
				}

				if ($el.find('.image-preview.new').length) {
					// Image
					removeNewImage();
					// Data
					$upload.val('');
					// Messages
					$uploadQueued.hide();
					$cancelBtn.hide();
				}

				if ($el.find('.image-preview.select').length) {
					removeSelectImage();
				}

				select2data = el.select2('data');
				imageWrapper = '
' +
					'

' +
					'
';
				$newImage = $('').attr('src', select2data.url);

				$newImage.on('load', function() {
					$(imageWrapper).prependTo($image).find('.img-thumbnail').append($(this));
					$selectQueued.show();
				});

			});

		});

	});

});
<|endoftext|>


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

  // Can be overridden by granting different permission in manifest.json
  const defaultBaseURL = 'https://freeyourstuff.cc/';

  if (typeof chrome !== "undefined" && chrome.runtime.onMessage) {
    chrome.runtime.onMessage.addListener(displayHandler);
  } else {
    console.log('Chrome API not found. Loading outside of extension context with example data.');
    loadExample('yelp');
  }

  function getPermissions() {
    return new Promise(function(resolve) {
      chrome.permissions.getAll(permissions => {
        resolve(permissions);
      });
    });
  }

  function displayHandler(request) {
    if (request.action === 'display' && request.data && request.schema) {
      getPermissions().then(permissions => {

        let baseURL;

        // If we have a cross-origin permission defined in manifest.json,
        // we use it for the base URL, matching up to (and including) the
        // first slash.
        baseURL = permissions && permissions.origins && permissions.origins[0] ?
          permissions.origins[0].match(/.*\//)[0] : defaultBaseURL;
        showData(request.data, request.schema, baseURL);
        chrome.runtime.onMessage.removeListener(displayHandler);
      });
    }
  }

  function loadExample(scriptName) {
    let script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = `examples/${scriptName}.js`;
    script.onload = showExampleData;
    document.body.appendChild(script);
  }

  function makeRenderFunction(rowName) {
    return (val, type, row) => {
      if (row[rowName])
        return `<a href="${row[rowName]}">${val}</a>`;
      else
        return val;
    };
  }

  function showExampleData() {
    showData(exampleData, exampleSchema, defaultBaseURL);
  }

  // Message object properties:
  // text: 'text'
  // type: 'warning' | 'success' | 'error' (will be added as CSS class name)
  // retry: Whether we're showing the same message again (triggers animation)
  function showMessage(msg) {
    if (!msg.retry) {
      $('#messages').empty();
      $('#messages').append(`<div class="${msg.type} message">${msg.text}</div>`);
      $('#messages').show();
    } else {
      $('#messages').fadeOut().fadeIn();
    }
  }

  // retry: Whether this was user-triggered.
  function checkLoginStatus(retry, baseURL) {
    $.get(`${baseURL}api/loginstatus`).done(res => {
      // Hide previous warning messages
      $('#messages').hide();
      if (typeof res == 'object' && res.loggedIn) {
        let userLink = `<a href="${baseURL}user/${res.id}" target="_blank">${res.displayName}</a>`;
        $('#loginInfoLink').html(userLink);
        $('#loginInfo').show();
        $('#publish').show();
        $('#signedout').hide();
        clearInterval(window.interval);
      } else {
        $('#signedout').show();
        $('#publish').hide();
        $('#loginInfo').hide();
      }
    }).fail(err => {
      showMessage({
        text: `We can't reach freeyourstuff.cc right now, so you can't publish your data. Sorry! You can still download it or` +
          ` <a id="retry" href="#">retry connecting.</a>`,
        type: 'warning',
        retry
      }, true);
      $('#retry').off();
      $('#retry').click((e) => {
        e.preventDefault();
        checkLoginStatus(true, baseURL);
      });
    });
  }

  // Once the user clicks any of the login links (local, Google, Facebook, etc.),
  // we start pinging the site in the background so that once the user
  // is logged in, the "Publish" button automagically appears
  function getLinkOpener(url, baseURL) {
    return function() {
      $(this).prop('disabled', true);
      window.open(url);
      startPinging(baseURL);
    };
  }

  function startPinging(baseURL) {
    $('#pinging').show();
    window.interval = setInterval(() => {
      checkLoginStatus(false, baseURL);
    }, 1000);
  }

  function stopPinging() {
    $('#facebook,#google,#twitter,#local').prop('disabled', false);
    clearInterval(window.interval);
    $('#pinging').fadeOut();
  }

  function getPublishClickHandler(json, baseURL) {
    return function(e) {
      $('#publish').prop('disabled', true); // Prevent repeat submission
      $.ajax({
        type: 'POST',
        contentType: 'application/json',
        url: `${baseURL}api/siteset`,
        data: json,
        dataType: 'json'
      }).done(res => {
        $('#publish').hide();
        showMessage({
          text: 'Your data was successfully published! Thank you for contributing to the commons. :-)',
          type: 'success'
        });
      }).fail(err => {
        $('#publish').prop('disabled', false);

        let text = 'There was a problem publishing your data. Sorry! :-(';
        if (err.responseJSON.error) {
          text += ' We got the following error message:' +
            `<br><br><code>${err.responseJSON.error}</code>`;
        }
        text += '

You can help us out by ' +
          'filing a bug.';
        showMessage({
          text,
          type: 'error'
        });
      });
    };
  }

  function showData(data, schema, baseURL) {

    let json = JSON.stringify(data, null, 2);
    // We need to URI-encode it so we can stash it into the href attribute
    let encodedJSON = encodeURIComponent(json);
    $('#download').attr('href', `data:application/json;charset=utf-8,${encodedJSON}`);
    $('#download').attr('download', 'data.json');

    $('#publish').click(getPublishClickHandler(json, baseURL));
    $('#facebook').click(getLinkOpener(`${baseURL}auth/facebook`, baseURL));
    $('#twitter').click(getLinkOpener(`${baseURL}auth/twitter`, baseURL));
    $('#google').click(getLinkOpener(`${baseURL}auth/google`, baseURL));
    $('#local').click(getLinkOpener(`${baseURL}signin`, baseURL));
    $('#stop').click(stopPinging);

    // For testing/dev purposes, inform user if we're not publishing to prod
    if (defaultBaseURL != baseURL) {
      $('#nonStandardURL').text(baseURL);
      $('#nonStandardURLNotice').show();
    }

    checkLoginStatus(false, baseURL);

    if (data.schemaKey !== schema.schema.key) {
      throw new Error('Schemas do not match. Cannot process data.');
    }

    for (let setName in data) {
      // Exclude metadata
      if (setName == 'schemaKey' || setName == 'schemaVersion')
        continue;

      let columns = [];
      let fields = [];

      $('#results').append(`<h3>${schema[setName].label.en}</h3>`);

      // Show header information
      if (data[setName].head) {
        $('#results').append(`<table id="result_${setName}_header" class="headerTable"></table>`);
        for (let headerKey in data[setName].head) {
          let rowValue = data[setName].head[headerKey];
          if (schema[setName].head[headerKey].type == 'weburl')
            rowValue = `<a href="${rowValue}">${rowValue}</a>`;

          // Show the header field's description as title attribute if we have one
          let title = '';
          if (schema[setName].head[headerKey].description)
            title = `class="headerKey" title="${schema[setName].head[headerKey].description.en}"`;

          let row = `<tr><td class="headerCell">` +
            `<span ${title}>${schema[setName].head[headerKey].label.en}</span>` +
            `</td><td>${rowValue}</td></tr>`;
          $(`#result_${setName}_header`).append(row);
        }
      }

      // Loop through each data object in the set
      for (let dataObj of data[setName].data) {
        // Aggregate information from the schema as we go --
        // this way we only have metadata we have actual data for
        for (let prop in dataObj) {
          if (fields.indexOf(prop) == -1) {
            if (!schema[setName].data[prop].describes) {
              let colDef = {
                data: prop,
                title: schema[setName].data[prop].label.en,
                defaultContent: ''
              };
              if (schema[setName].data[prop].type == 'date')
                colDef.render = renderDate;
              if (schema[setName].data[prop].type == 'datetime')
                colDef.render = renderDateTime;
              columns.push(colDef);
              fields.push(prop);
            } else {
              // We're encountering data that "describes" other data, i.e. a URL
              // for some text elsewhere. Let's locate the relevant column and
              // add a render function if it doesn't already have one.
              for (let col of columns) {
                if (col.data == schema[setName].data[prop].describes) {
                  if (!col.render)
                    col.render = makeRenderFunction(prop);
                  break;
                }
              }
            }
          }
        }
      }
      if (Array.isArray(data[setName].data) && data[setName].data.length) {
        $('#results').append(`<table id="result_${setName}" class="table table-hover table-responsive">`);
        $(`#result_${setName}`).dataTable({
          "data": data[setName].data,
          "columns": columns
        });
      } else {
        $('#results').append('No data of this type included in the set.');
      }
    }
  }

  // For dates without times, we avoid time shifts by just using the
  // UTC date information and displaying it in a different format
  // (without time). We're defaulting to US-style for now.
  function renderDate(isoDateString) {
    let isoDate = new Date(isoDateString);
    return isoDate.toString() === 'Invalid Date' ? undefined :
      `${isoDate.getUTCMonth()+1}/${isoDate.getUTCDate()}/${isoDate.getUTCFullYear()}`;
  }

  function renderDateTime(isoDateTimeString) {
    let isoDateTime = new Date(isoDateTimeString);
    return isoDateTime.toString() === 'Invalid Date' ? undefined :
      isoDateTime.toLocaleString('en-US');
  }

})();
<commit_msg>Automagically close login tab once user is logged in<commit_after>(function() {
  'use strict';

  // Can be overridden by granting different permission in manifest.json
  const defaultBaseURL = 'https://freeyourstuff.cc/';

  if (typeof chrome !== "undefined" && chrome.runtime.onMessage) {
    chrome.runtime.onMessage.addListener(displayHandler);
  } else {
    console.log('Chrome API not found. Loading outside of extension context with example data.');
    loadExample('yelp');
  }

  function getPermissions() {
    return new Promise(function(resolve) {
      chrome.permissions.getAll(permissions => {
        resolve(permissions);
      });
    });
  }

  function displayHandler(request) {
    if (request.action === 'display' && request.data && request.schema) {
      getPermissions().then(permissions => {

        let baseURL;

        // If we have a cross-origin permission defined in manifest.json,
        // we use it for the base URL, matching up to (and including) the
        // first slash.
        baseURL = permissions && permissions.origins && permissions.origins[0] ?
          permissions.origins[0].match(/.*\//)[0] : defaultBaseURL;
        showData(request.data, request.schema, baseURL);
        chrome.runtime.onMessage.removeListener(displayHandler);
      });
    }
  }

  function loadExample(scriptName) {
    let script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = `examples/${scriptName}.js`;
    script.onload = showExampleData;
    document.body.appendChild(script);
  }

  function makeRenderFunction(rowName) {
    return (val, type, row) => {
      if (row[rowName])
        return `<a href="${row[rowName]}">${val}</a>`;
      else
        return val;
    };
  }

  function showExampleData() {
    showData(exampleData, exampleSchema, defaultBaseURL);
  }

  // Message object properties:
  // text: 'text'
  // type: 'warning' | 'success' | 'error' (will be added as CSS class name)
  // retry: Whether we're showing the same message again (triggers animation)
  function showMessage(msg) {
    if (!msg.retry) {
      $('#messages').empty();
      $('#messages').append(`<div class="${msg.type} message">${msg.text}</div>`);
      $('#messages').show();
    } else {
      $('#messages').fadeOut().fadeIn();
    }
  }

  // retry: Whether this was user-triggered.
  function checkLoginStatus(retry, baseURL, loginTab) {
    $.get(`${baseURL}api/loginstatus`).done(res => {

      // Hide previous warning messages
      $('#messages').hide();
      if (typeof res == 'object' && res.loggedIn) {
        let userLink = `<a href="${baseURL}user/${res.id}" target="_blank">${res.displayName}</a>`;
        $('#loginInfoLink').html(userLink);
        $('#loginInfo').show();
        $('#publish').show();
        $('#signedout').hide();
        clearInterval(window.interval);
        if (loginTab) {
          chrome.tabs.remove(loginTab.id, () => {
            // Reading the property suppresses error on console if tab has been closed
            if (chrome.runtime.lastError);
          });
        }
      } else {
        $('#signedout').show();
        $('#publish').hide();
        $('#loginInfo').hide();
      }
    }).fail(err => {
      showMessage({
        text: `We can't reach freeyourstuff.cc right now, so you can't publish your data. Sorry! You can still download it or` +
          ` <a id="retry" href="#">retry connecting.</a>`,
        type: 'warning',
        retry
      }, true);
      $('#retry').off();
      $('#retry').click((e) => {
        e.preventDefault();
        checkLoginStatus(true, baseURL);
      });
    });
  }

  // Once the user clicks any of the login links (local, Google, Facebook, etc.),
  // we start pinging the site in the background so that once the user
  // is logged in, the "Publish" button automagically appears
  function getLinkOpener(url, baseURL) {
    return function() {
      $(this).prop('disabled', true);
      chrome.tabs.create({ url }, (loginTab) => {
        startPinging(baseURL, loginTab);
      });
    };
  }

  function startPinging(baseURL, loginTab) {
    $('#pinging').show();
    window.interval = setInterval(() => {
      checkLoginStatus(false, baseURL, loginTab);
    }, 1000);
  }

  function stopPinging() {
    $('#facebook,#google,#twitter,#local').prop('disabled', false);
    clearInterval(window.interval);
    $('#pinging').fadeOut();
  }

  function getPublishClickHandler(json, baseURL) {
    return function(e) {
      $('#publish').prop('disabled', true); // Prevent repeat submission
      $.ajax({
        type: 'POST',
        contentType: 'application/json',
        url: `${baseURL}api/siteset`,
        data: json,
        dataType: 'json'
      }).done(res => {
        $('#publish').hide();
        showMessage({
          text: 'Your data was successfully published! Thank you for contributing to the commons. :-)',
          type: 'success'
        });
      }).fail(err => {
        $('#publish').prop('disabled', false);

        let text = 'There was a problem publishing your data. Sorry! :-(';
        if (err.responseJSON.error) {
          text += ' We got the following error message:' +
            `<br><br><code>${err.responseJSON.error}</code>`;
        }
        text += '

You can help us out by ' +
          'filing a bug.';
        showMessage({
          text,
          type: 'error'
        });
      });
    };
  }

  function showData(data, schema, baseURL) {

    let json = JSON.stringify(data, null, 2);
    // We need to URI-encode it so we can stash it into the href attribute
    let encodedJSON = encodeURIComponent(json);
    $('#download').attr('href', `data:application/json;charset=utf-8,${encodedJSON}`);
    $('#download').attr('download', 'data.json');

    $('#publish').click(getPublishClickHandler(json, baseURL));
    $('#facebook').click(getLinkOpener(`${baseURL}auth/facebook`, baseURL));
    $('#twitter').click(getLinkOpener(`${baseURL}auth/twitter`, baseURL));
    $('#google').click(getLinkOpener(`${baseURL}auth/google`, baseURL));
    $('#local').click(getLinkOpener(`${baseURL}signin`, baseURL));
    $('#stop').click(stopPinging);

    // For testing/dev purposes, inform user if we're not publishing to prod
    if (defaultBaseURL != baseURL) {
      $('#nonStandardURL').text(baseURL);
      $('#nonStandardURLNotice').show();
    }

    checkLoginStatus(false, baseURL);

    if (data.schemaKey !== schema.schema.key) {
      throw new Error('Schemas do not match. Cannot process data.');
    }

    for (let setName in data) {
      // Exclude metadata
      if (setName == 'schemaKey' || setName == 'schemaVersion')
        continue;

      let columns = [];
      let fields = [];

      $('#results').append(`<h3>${schema[setName].label.en}</h3>`);

      // Show header information
      if (data[setName].head) {
        $('#results').append(`<table id="result_${setName}_header" class="headerTable"></table>`);
        for (let headerKey in data[setName].head) {
          let rowValue = data[setName].head[headerKey];
          if (schema[setName].head[headerKey].type == 'weburl')
            rowValue = `<a href="${rowValue}">${rowValue}</a>`;

          // Show the header field's description as title attribute if we have one
          let title = '';
          if (schema[setName].head[headerKey].description)
            title = `class="headerKey" title="${schema[setName].head[headerKey].description.en}"`;

          let row = `<tr><td class="headerCell">` +
            `<span ${title}>${schema[setName].head[headerKey].label.en}</span>` +
            `</td><td>${rowValue}</td></tr>`;
          $(`#result_${setName}_header`).append(row);
        }
      }

      // Loop through each data object in the set
      for (let dataObj of data[setName].data) {
        // Aggregate information from the schema as we go --
        // this way we only have metadata we have actual data for
        for (let prop in dataObj) {
          if (fields.indexOf(prop) == -1) {
            if (!schema[setName].data[prop].describes) {
              let colDef = {
                data: prop,
                title: schema[setName].data[prop].label.en,
                defaultContent: ''
              };
              if (schema[setName].data[prop].type == 'date')
                colDef.render = renderDate;
              if (schema[setName].data[prop].type == 'datetime')
                colDef.render = renderDateTime;
              columns.push(colDef);
              fields.push(prop);
            } else {
              // We're encountering data that "describes" other data, i.e. a URL
              // for some text elsewhere. Let's locate the relevant column and
              // add a render function if it doesn't already have one.
              for (let col of columns) {
                if (col.data == schema[setName].data[prop].describes) {
                  if (!col.render)
                    col.render = makeRenderFunction(prop);
                  break;
                }
              }
            }
          }
        }
      }
      if (Array.isArray(data[setName].data) && data[setName].data.length) {
        $('#results').append(`<table id="result_${setName}" class="table table-hover table-responsive">`);
        $(`#result_${setName}`).dataTable({
          "data": data[setName].data,
          "columns": columns
        });
      } else {
        $('#results').append('No data of this type included in the set.');
      }
    }
  }

  // For dates without times, we avoid time shifts by just using the
  // UTC date information and displaying it in a different format
  // (without time). We're defaulting to US-style for now.
  function renderDate(isoDateString) {
    let isoDate = new Date(isoDateString);
    return isoDate.toString() === 'Invalid Date' ? undefined :
      `${isoDate.getUTCMonth()+1}/${isoDate.getUTCDate()}/${isoDate.getUTCFullYear()}`;
  }

  function renderDateTime(isoDateTimeString) {
    let isoDateTime = new Date(isoDateTimeString);
    return isoDateTime.toString() === 'Invalid Date' ? undefined :
      isoDateTime.toLocaleString('en-US');
  }

})();
<|endoftext|>


<commit_before>/* MONOGRAPH EXTENSION
	{
		"name": "animation",
		"description": "Fine grain animation controls",
		"author": "Xiaoji Chen (cxiaoji@gmail.com)",
		"target": [1.4, 1.49],
		"triggers": ["animate"],
		"actions": ["delay", "duration", "easing"]
	}
*/

(function() {

	var settings = {};

	proto.define(["delay", "duration", "easing"], function(evt) {

		var args = evt.args;
		var command = args[0],
			value = args[1],
			value2 = args[2];

		if (update(this)) {
			var elements = this.querySelectorAll("._");
			for (var i = 0; i < elements.length; i++) {
				update(elements[i]);
			}
		}

		function update(element) {
			var d = settings[element.id];
			if (!d) {
				d = settings[element.id] = [];
			}

			switch (command) {
				case "duration":
					if (d[0] != value) {
						d[0] = value;
						return true;
					}
					return false;
				case "delay":
					if (d[1] != value) {
						d[1] = value;
						return true;
					}
					return false;
				case "easing":
					var v = value2 ? value + " " + value2 : value;
					if (d[2] != v) {
						d[2] = v;
						return true;
					}
					return false;
			}
		}

	});

	var default_dur = proto.option("duration")(),
		default_ease = proto.option("easing")(),
		default_delay = proto.option("delay")();

	proto.option("duration", function(element) {
		proto.trigger(element, "animate");
		var d = settings[element.id],
			v = d && d[0];
		return v == undefined ? default_dur : v
	});
	proto.option("easing", function(element) {
		var d = settings[element.id],
			v = d && d[2];
		return v == undefined ? default_ease : v
	});
	proto.option("delay", function(element) {
		var d = settings[element.id],
			v = d && d[1];
		return v == undefined ? default_delay : v
	});

})();<commit_msg>add relative speed<commit_after>/* MONOGRAPH EXTENSION
	{
		"name": "animation",
		"description": "Fine grain animation controls",
		"author": "Xiaoji Chen (cxiaoji@gmail.com)",
		"target": [1.4, 1.49],
		"triggers": ["animate"],
		"actions": ["delay", "duration", "easing"]
	}
*/

(function() {

	var settings = {};

	proto.define(["delay", "duration", "easing"], function(evt) {

		var args = evt.args;
		var command = args[0],
			value = args[1],
			value2 = args[2];

		if (update(this)) {
			var elements = this.querySelectorAll("._");
			for (var i = 0; i < elements.length; i++) {
				update(elements[i]);
			}
		}

		function update(element) {
			var d = settings[element.id];
			if (!d) {
				d = settings[element.id] = [];
			}

			switch (command) {
				case "duration":
					if (d[0] != value) {
						d[0] = value;
						return true;
					}
					return false;
				case "delay":
					if (d[1] != value) {
						d[1] = value;
						return true;
					}
					return false;
				case "easing":
					var v = value2 ? value + " " + value2 : value;
					if (d[2] != v) {
						d[2] = v;
						return true;
					}
					return false;
			}
		}

	});

	var default_dur = proto.option("duration")(),
		default_ease = proto.option("easing")(),
		default_delay = proto.option("delay")();

	proto.option("duration", function(element) {
		proto.trigger(element, "animate");
		var d = settings[element.id],
			v = d && d[0];
		if(v == null) return default_dur;
		else if(v[v.length-1] == "x") return default_dur * v.substr(0, v.length-1);
		else return v;
	});
	proto.option("easing", function(element) {
		var d = settings[element.id],
			v = d && d[2];
		return v == undefined ? default_ease : v
	});
	proto.option("delay", function(element) {
		var d = settings[element.id],
			v = d && d[1];
		if(v == null) return default_delay;
		else if(v[v.length-1] == "x") return default_delay * v.substr(0, v.length-1);
		else return v;
	});

})();<|endoftext|>