<commit_before>/* jshint browser: true */
/* jshint unused: false */
/* global Backbone, $, localStorage, window, arangoHelper, templateEngine, JSONEditor */
/* global document, _ */

(function () {
  'use strict';

  var createDocumentLink = function (id) {
    var split = id.split('/');
    return 'collection/' +
      encodeURIComponent(split[0]) + '/' +
      encodeURIComponent(split[1]);
  };

  window.DocumentView = Backbone.View.extend({
    el: '#content',
    readOnly: false,
    colid: 0,
    docid: 0,

    customView: false,
    defaultMode: 'tree',

    template: templateEngine.createTemplate('documentView.ejs'),

    events: {
      'click #saveDocumentButton': 'saveDocument',
      'click #deleteDocumentButton': 'deleteDocumentModal',
      'click #confirmDeleteDocument': 'deleteDocument',
      'click #document-from': 'navigateToDocument',
      'click #document-to': 'navigateToDocument',
      'keydown #documentEditor .ace_editor': 'keyPress',
      'keyup .jsoneditor .search input': 'checkSearchBox',
      'click .jsoneditor .modes': 'storeMode',
      'click #addDocument': 'addDocument'
    },

    remove: function () {
      this.$el.empty().off(); /* off to unbind the events */
      this.stopListening();
      this.unbind();
      delete this.el;
      return this;
    },

    checkSearchBox: function (e) {
      if ($(e.currentTarget).val() === '') {
        this.editor.expandAll();
      }
    },

    initialize: function () {
      var mode = localStorage.getItem('JSONEditorMode');
      if (mode) {
        this.defaultMode = mode;
      }
    },

    addDocument: function () {
      if (!this.readOnly) {
        window.App.documentsView.addDocumentModal();
      }
    },

    storeMode: function () {
      var self = this;

      $('.type-modes').on('click', function (elem) {
        var mode = $(elem.currentTarget).text().toLowerCase();
        localStorage.setItem('JSONEditorMode', mode);
        self.defaultMode = mode;
      });
    },

    keyPress: function (e) {
      if (e.ctrlKey && e.keyCode === 13) {
        e.preventDefault();
        this.saveDocument();
      } else if (e.metaKey && e.keyCode === 13) {
        e.preventDefault();
        this.saveDocument();
      }
    },

    editor: 0,

    setType: function () {
      var callback = function (error, data, type) {
        if (error) {
          arangoHelper.arangoError('Error', 'Could not fetch data.');
        } else {
          this.type = type;
          this.breadcrumb();
          this.fillInfo();
          this.fillEditor();
          arangoHelper.checkCollectionPermissions(this.colid, this.changeViewToReadOnly.bind(this));
        }
      }.bind(this);

      this.collection.getDocument(this.colid, this.docid, callback);
    },

    deleteDocumentModal: function () {
      if (!this.readOnly) {
        var buttons = []; var tableContent = [];
        tableContent.push(
          window.modalView.createReadOnlyEntry(
            'doc-delete-button',
            'Confirm delete, document id is',
            this.type._id,
            undefined,
            undefined,
            false,
            /[<>&'"]/
          )
        );
        buttons.push(
          window.modalView.createDeleteButton('Delete', this.deleteDocument.bind(this))
        );
        window.modalView.show('modalTable.ejs', 'Delete Document', buttons, tableContent);
      }
    },

    deleteDocument: function () {
      var successFunction = function () {
        if (this.customView) {
          this.customDeleteFunction();
        } else {
          var navigateTo = 'collection/' + encodeURIComponent(this.colid) + '/documents/1';
          window.modalView.hide();
          window.App.navigate(navigateTo, {trigger: true});
        }
      }.bind(this);

      if (this.type._from && this.type._to) {
        var callbackEdge = function (error) {
          if (error) {
            arangoHelper.arangoError('Edge error', 'Could not delete edge');
          } else {
            successFunction();
          }
        };
        this.collection.deleteEdge(this.colid, this.docid, callbackEdge);
      } else {
        var callbackDoc = function (error) {
          if (error) {
            arangoHelper.arangoError('Error', 'Could not delete document');
          } else {
            successFunction();
          }
        };
        this.collection.deleteDocument(this.colid, this.docid, callbackDoc);
      }
    },

    navigateToDocument: function (e) {
      var navigateTo = $(e.target).attr('documentLink');
      if (navigateTo) {
        window.App.navigate(navigateTo, {trigger: true});
      }
    },

    fillInfo: function () {
      var mod = this.collection.first();
      var _id = mod.get('_id');
      var _key = mod.get('_key');
      var _rev = mod.get('_rev');
      var _from = mod.get('_from');
      var _to = mod.get('_to');

      $('#document-type').css('margin-left', '10px');
      $('#document-type').text('_id:');
      $('#document-id').css('margin-left', '0');
      $('#document-id').text(_id);
      $('#document-key').text(_key);
      $('#document-rev').text(_rev);

      if (_from && _to) {
        var hrefFrom = createDocumentLink(_from);
        var hrefTo = createDocumentLink(_to);
        $('#document-from').text(_from);
        $('#document-from').attr('documentLink', hrefFrom);
        $('#document-to').text(_to);
        $('#document-to').attr('documentLink', hrefTo);
      } else {
        $('.edge-info-container').hide();
      }
    },

    fillEditor: function () {
      var toFill = this.removeReadonlyKeys(this.collection.first().attributes);
      $('.disabledBread').last().text(this.collection.first().get('_key'));
      this.editor.set(toFill);
      $('.ace_content').attr('font-size', '11pt');
    },

    jsonContentChanged: function () {
      this.enableSaveButton();
    },

    resize: function () {
      $('#documentEditor').height($('.centralRow').height() - 300);
    },

    render: function () {
      $(this.el).html(this.template.render({}));

      $('#documentEditor').height($('.centralRow').height() - 300);
      this.disableSaveButton();

      var self = this;

      var container = document.getElementById('documentEditor');
      var options = {
        onChange: function () {
          self.jsonContentChanged();
        },
        search: true,
        mode: 'tree',
        modes: ['tree', 'code'],
        ace: window.ace
        // iconlib: 'fontawesome4'
      };

      this.editor = new JSONEditor(container, options);
      if (this.defaultMode) {
        this.editor.setMode(this.defaultMode);
      }

      return this;
    },

    changeViewToReadOnly: function () {
      this.readOnly = true;
      // breadcrumb
      $('.breadcrumb').find('a').html($('.breadcrumb').find('a').html() + ' (read-only)');
      // editor read only mode
      this.editor.setMode('view');
      $('.jsoneditor-modes').hide();
      // bottom buttons
      $('.bottomButtonBar button').addClass('disabled');
      $('.bottomButtonBar button').unbind('click');
      // top add document button
      $('#addDocument').addClass('disabled');
    },

    cleanupEditor: function () {
      if (this.editor) {
        this.editor.destroy();
      }
    },

    removeReadonlyKeys: function (object) {
      return _.omit(object, ['_key', '_id', '_from', '_to', '_rev']);
    },

    saveDocument: function () {
      if ($('#saveDocumentButton').attr('disabled') === undefined) {
        if (this.collection.first().attributes._id.substr(0, 1) === '_') {
          var buttons = []; var tableContent = [];
          tableContent.push(
            window.modalView.createReadOnlyEntry(
              'doc-save-system-button',
              'Caution',
              'You are modifying a system collection. Really continue?',
              undefined,
              undefined,
              false,
              /[<>&'"]/
            )
          );
          buttons.push(
            window.modalView.createSuccessButton('Save', this.confirmSaveDocument.bind(this))
          );
          window.modalView.show('modalTable.ejs', 'Modify System Collection', buttons, tableContent);
        } else {
          this.confirmSaveDocument();
        }
      }
    },

    confirmSaveDocument: function () {
      window.modalView.hide();

      var model;

      try {
        model = this.editor.get();
      } catch (e) {
        this.errorConfirmation(e);
        this.disableSaveButton();
        return;
      }

      model = JSON.stringify(model);

      if (this.type === 'edge' || this.type._from) {
        var callbackE = function (error, data) {
          if (error) {
            arangoHelper.arangoError('Error', data.responseJSON.errorMessage);
          } else {
            this.successConfirmation();
            this.disableSaveButton();
          }
        }.bind(this);

        this.collection.saveEdge(this.colid, this.docid, $('#document-from').html(), $('#document-to').html(), model, callbackE);
      } else {
        var callback = function (error, data) {
          if (error) {
            arangoHelper.arangoError('Error', data.responseJSON.errorMessage);
          } else {
            this.successConfirmation();
            this.disableSaveButton();
          }
        }.bind(this);

        this.collection.saveDocument(this.colid, this.docid, model, callback);
      }
    },

    successConfirmation: function () {
      arangoHelper.arangoNotification('Document saved.');
    },

    errorConfirmation: function (e) {
      arangoHelper.arangoError('Document editor: ', e);
    },

    enableSaveButton: function () {
      $('#saveDocumentButton').prop('disabled', false);
      $('#saveDocumentButton').addClass('button-success');
      $('#saveDocumentButton').removeClass('button-close');
    },

    disableSaveButton: function () {
      $('#saveDocumentButton').prop('disabled', true);
      $('#saveDocumentButton').addClass('button-close');
      $('#saveDocumentButton').removeClass('button-success');
    },

    breadcrumb: function () {
      var name = window.location.hash.split('/');
      $('#subNavigationBar .breadcrumb').html(
        'Collection: ' + name[1] + '' +
        '' +
        this.type.charAt(0).toUpperCase() + this.type.slice(1) + ': ' + name[2]
      );
    },

    escaped: function (value) {
      return value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
        .replace(/"/g, '"').replace(/'/g, ''');
    }
  });
}());
<commit_msg>fixed the create new document button in documents view (#2826)<commit_after>/* jshint browser: true */
/* jshint unused: false */
/* global Backbone, $, localStorage, window, arangoHelper, templateEngine, JSONEditor */
/* global document, _ */

(function () {
  'use strict';

  var createDocumentLink = function (id) {
    var split = id.split('/');
    return 'collection/' +
      encodeURIComponent(split[0]) + '/' +
      encodeURIComponent(split[1]);
  };

  window.DocumentView = Backbone.View.extend({
    el: '#content',
    readOnly: false,
    colid: 0,
    docid: 0,

    customView: false,
    defaultMode: 'tree',

    template: templateEngine.createTemplate('documentView.ejs'),

    events: {
      'click #saveDocumentButton': 'saveDocument',
      'click #deleteDocumentButton': 'deleteDocumentModal',
      'click #confirmDeleteDocument': 'deleteDocument',
      'click #document-from': 'navigateToDocument',
      'click #document-to': 'navigateToDocument',
      'keydown #documentEditor .ace_editor': 'keyPress',
      'keyup .jsoneditor .search input': 'checkSearchBox',
      'click .jsoneditor .modes': 'storeMode',
      'click #addDocument': 'addDocument'
    },

    remove: function () {
      this.$el.empty().off(); /* off to unbind the events */
      this.stopListening();
      this.unbind();
      delete this.el;
      return this;
    },

    checkSearchBox: function (e) {
      if ($(e.currentTarget).val() === '') {
        this.editor.expandAll();
      }
    },

    initialize: function () {
      var mode = localStorage.getItem('JSONEditorMode');
      if (mode) {
        this.defaultMode = mode;
      }
    },

    addDocument: function (e) {
      if (!this.readOnly) {
        window.App.documentsView.addDocumentModal(e);
      }
    },

    storeMode: function () {
      var self = this;

      $('.type-modes').on('click', function (elem) {
        var mode = $(elem.currentTarget).text().toLowerCase();
        localStorage.setItem('JSONEditorMode', mode);
        self.defaultMode = mode;
      });
    },

    keyPress: function (e) {
      if (e.ctrlKey && e.keyCode === 13) {
        e.preventDefault();
        this.saveDocument();
      } else if (e.metaKey && e.keyCode === 13) {
        e.preventDefault();
        this.saveDocument();
      }
    },

    editor: 0,

    setType: function () {
      var callback = function (error, data, type) {
        if (error) {
          arangoHelper.arangoError('Error', 'Could not fetch data.');
        } else {
          this.type = type;
          this.breadcrumb();
          this.fillInfo();
          this.fillEditor();
          arangoHelper.checkCollectionPermissions(this.colid, this.changeViewToReadOnly.bind(this));
        }
      }.bind(this);

      this.collection.getDocument(this.colid, this.docid, callback);
    },

    deleteDocumentModal: function () {
      if (!this.readOnly) {
        var buttons = []; var tableContent = [];
        tableContent.push(
          window.modalView.createReadOnlyEntry(
            'doc-delete-button',
            'Confirm delete, document id is',
            this.type._id,
            undefined,
            undefined,
            false,
            /[<>&'"]/
          )
        );
        buttons.push(
          window.modalView.createDeleteButton('Delete', this.deleteDocument.bind(this))
        );
        window.modalView.show('modalTable.ejs', 'Delete Document', buttons, tableContent);
      }
    },

    deleteDocument: function () {
      var successFunction = function () {
        if (this.customView) {
          this.customDeleteFunction();
        } else {
          var navigateTo = 'collection/' + encodeURIComponent(this.colid) + '/documents/1';
          window.modalView.hide();
          window.App.navigate(navigateTo, {trigger: true});
        }
      }.bind(this);

      if (this.type._from && this.type._to) {
        var callbackEdge = function (error) {
          if (error) {
            arangoHelper.arangoError('Edge error', 'Could not delete edge');
          } else {
            successFunction();
          }
        };
        this.collection.deleteEdge(this.colid, this.docid, callbackEdge);
      } else {
        var callbackDoc = function (error) {
          if (error) {
            arangoHelper.arangoError('Error', 'Could not delete document');
          } else {
            successFunction();
          }
        };
        this.collection.deleteDocument(this.colid, this.docid, callbackDoc);
      }
    },

    navigateToDocument: function (e) {
      var navigateTo = $(e.target).attr('documentLink');
      if (navigateTo) {
        window.App.navigate(navigateTo, {trigger: true});
      }
    },

    fillInfo: function () {
      var mod = this.collection.first();
      var _id = mod.get('_id');
      var _key = mod.get('_key');
      var _rev = mod.get('_rev');
      var _from = mod.get('_from');
      var _to = mod.get('_to');

      $('#document-type').css('margin-left', '10px');
      $('#document-type').text('_id:');
      $('#document-id').css('margin-left', '0');
      $('#document-id').text(_id);
      $('#document-key').text(_key);
      $('#document-rev').text(_rev);

      if (_from && _to) {
        var hrefFrom = createDocumentLink(_from);
        var hrefTo = createDocumentLink(_to);
        $('#document-from').text(_from);
        $('#document-from').attr('documentLink', hrefFrom);
        $('#document-to').text(_to);
        $('#document-to').attr('documentLink', hrefTo);
      } else {
        $('.edge-info-container').hide();
      }
    },

    fillEditor: function () {
      var toFill = this.removeReadonlyKeys(this.collection.first().attributes);
      $('.disabledBread').last().text(this.collection.first().get('_key'));
      this.editor.set(toFill);
      $('.ace_content').attr('font-size', '11pt');
    },

    jsonContentChanged: function () {
      this.enableSaveButton();
    },

    resize: function () {
      $('#documentEditor').height($('.centralRow').height() - 300);
    },

    render: function () {
      $(this.el).html(this.template.render({}));

      $('#documentEditor').height($('.centralRow').height() - 300);
      this.disableSaveButton();

      var self = this;

      var container = document.getElementById('documentEditor');
      var options = {
        onChange: function () {
          self.jsonContentChanged();
        },
        search: true,
        mode: 'tree',
        modes: ['tree', 'code'],
        ace: window.ace
        // iconlib: 'fontawesome4'
      };

      this.editor = new JSONEditor(container, options);
      if (this.defaultMode) {
        this.editor.setMode(this.defaultMode);
      }

      return this;
    },

    changeViewToReadOnly: function () {
      this.readOnly = true;
      // breadcrumb
      $('.breadcrumb').find('a').html($('.breadcrumb').find('a').html() + ' (read-only)');
      // editor read only mode
      this.editor.setMode('view');
      $('.jsoneditor-modes').hide();
      // bottom buttons
      $('.bottomButtonBar button').addClass('disabled');
      $('.bottomButtonBar button').unbind('click');
      // top add document button
      $('#addDocument').addClass('disabled');
    },

    cleanupEditor: function () {
      if (this.editor) {
        this.editor.destroy();
      }
    },

    removeReadonlyKeys: function (object) {
      return _.omit(object, ['_key', '_id', '_from', '_to', '_rev']);
    },

    saveDocument: function () {
      if ($('#saveDocumentButton').attr('disabled') === undefined) {
        if (this.collection.first().attributes._id.substr(0, 1) === '_') {
          var buttons = []; var tableContent = [];
          tableContent.push(
            window.modalView.createReadOnlyEntry(
              'doc-save-system-button',
              'Caution',
              'You are modifying a system collection. Really continue?',
              undefined,
              undefined,
              false,
              /[<>&'"]/
            )
          );
          buttons.push(
            window.modalView.createSuccessButton('Save', this.confirmSaveDocument.bind(this))
          );
          window.modalView.show('modalTable.ejs', 'Modify System Collection', buttons, tableContent);
        } else {
          this.confirmSaveDocument();
        }
      }
    },

    confirmSaveDocument: function () {
      window.modalView.hide();

      var model;

      try {
        model = this.editor.get();
      } catch (e) {
        this.errorConfirmation(e);
        this.disableSaveButton();
        return;
      }

      model = JSON.stringify(model);

      if (this.type === 'edge' || this.type._from) {
        var callbackE = function (error, data) {
          if (error) {
            arangoHelper.arangoError('Error', data.responseJSON.errorMessage);
          } else {
            this.successConfirmation();
            this.disableSaveButton();
          }
        }.bind(this);

        this.collection.saveEdge(this.colid, this.docid, $('#document-from').html(), $('#document-to').html(), model, callbackE);
      } else {
        var callback = function (error, data) {
          if (error) {
            arangoHelper.arangoError('Error', data.responseJSON.errorMessage);
          } else {
            this.successConfirmation();
            this.disableSaveButton();
          }
        }.bind(this);

        this.collection.saveDocument(this.colid, this.docid, model, callback);
      }
    },

    successConfirmation: function () {
      arangoHelper.arangoNotification('Document saved.');
    },

    errorConfirmation: function (e) {
      arangoHelper.arangoError('Document editor: ', e);
    },

    enableSaveButton: function () {
      $('#saveDocumentButton').prop('disabled', false);
      $('#saveDocumentButton').addClass('button-success');
      $('#saveDocumentButton').removeClass('button-close');
    },

    disableSaveButton: function () {
      $('#saveDocumentButton').prop('disabled', true);
      $('#saveDocumentButton').addClass('button-close');
      $('#saveDocumentButton').removeClass('button-success');
    },

    breadcrumb: function () {
      var name = window.location.hash.split('/');
      $('#subNavigationBar .breadcrumb').html(
        'Collection: ' + name[1] + '' +
        '' +
        this.type.charAt(0).toUpperCase() + this.type.slice(1) + ': ' + name[2]
      );
    },

    escaped: function (value) {
      return value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')
        .replace(/"/g, '"').replace(/'/g, ''');
    }
  });
}());
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies
 */

// Node.js core.
const path = require('path');

// Public node modules.
const _ = require('lodash');
const fs = require('fs');

module.exports = {

  /**
   * Upload files.
   *
   * @param part   File extracted from the request body.
   * @param ctx
   * @returns {*}
   */

  upload: function * (part, ctx) {

    // Init the promise.
    let deferred = Promise.defer();

    // Init and format variables.
    const promises = [];
    const defaultUploadFolder = 'public/upload';
    let stream;
    ctx = ctx || {};

    // Set the filename.
    const filename = Date.now().toString() + '-' + (_.kebabCase(part.fileName) || Math.floor(Math.random() * 1000000).toString());

    // Start uploading.
    stream = fs.createWriteStream(path.join(process.cwd(), strapi.config.upload.folder || defaultUploadFolder, filename));
    part.pipe(stream);

    // Register the data of the file in the database.
    promises.push(File.create(_.merge(part, {
      user: ctx.user && ctx.user.id,
      originalFilenameFormatted: _.kebabCase(part.fileName),
      originalFilename: part.fileName || '',
      filename: filename
    })));

    try {
      let files = yield promises;
      deferred.resolve(files);
    } catch (err) {
      strapi.log.error(err);
      deferred.reject(err);
    }

    return deferred.promise;
  }
};
<commit_msg>Move fs dependency in core dependencies<commit_after>'use strict';

/**
 * Module dependencies
 */

// Node.js core.
const path = require('path');
const fs = require('fs');

// Public node modules.
const _ = require('lodash');

module.exports = {

  /**
   * Upload files.
   *
   * @param part   File extracted from the request body.
   * @param ctx
   * @returns {*}
   */

  upload: function * (part, ctx) {

    // Init the promise.
    let deferred = Promise.defer();

    // Init and format variables.
    const promises = [];
    const defaultUploadFolder = 'public/upload';
    let stream;
    ctx = ctx || {};

    // Set the filename.
    const filename = Date.now().toString() + '-' + (_.kebabCase(part.fileName) || Math.floor(Math.random() * 1000000).toString());

    // Start uploading.
    stream = fs.createWriteStream(path.join(process.cwd(), strapi.config.upload.folder || defaultUploadFolder, filename));
    part.pipe(stream);

    // Register the data of the file in the database.
    promises.push(File.create(_.merge(part, {
      user: ctx.user && ctx.user.id,
      originalFilenameFormatted: _.kebabCase(part.fileName),
      originalFilename: part.fileName || '',
      filename: filename
    })));

    try {
      let files = yield promises;
      deferred.resolve(files);
    } catch (err) {
      strapi.log.error(err);
      deferred.reject(err);
    }

    return deferred.promise;
  }
};
<|endoftext|>


<commit_before>import { Router } from 'meteor/iron:router';
import { Session } from 'meteor/session';
import { Template } from 'meteor/templating';
import { $ } from 'meteor/jquery';

import ScssVars from '/imports/ui/lib/scss-vars.js';

import './faq.de.md';
import './faq.en.md';
import './faq.html';

Template.FAQ.onCreated(function() {
	this.headerTag = 'h3';
	this.contentTags = 'p, ul';

	this.scrollTo = id => {
		const idSelector = "#" + decodeURIComponent(id);
		const targetTitle = this.$(idSelector);
		if (targetTitle.length) {
			Meteor.defer(() => {
				targetTitle.nextUntil(this.headerTag).show();
				$(window).scrollTop(targetTitle.position().top - ScssVars.navbarHeight);
			});
		}
	};
});

Template.FAQ.onRendered(function() {
	// in order to create nice IDs for the questions also for non-english
	// alphabets we make our own ones
	this.$(this.headerTag).each(function() {
		const title = $(this);
		const id =
			title
			.text()
			.trim()
			.toLowerCase()
			.replace(/[_+.,!?@#$%^&*();\\\/|<>"'=]/g, "")
			.replace(/[ ]/g, "-");

		title.attr('id', id);
	});

	this.$('a').attr('target', '_blank');

	const hash = Router.current().params.hash;
	if (hash) this.scrollTo(hash);
});

Template.FAQ.helpers({
	localizedFAQ() {
		const templatePrefix = 'FAQ_';
		const templateNotFound = locale => !Template[templatePrefix + locale];

		// if the FAQ  doesn't exist with the specific locale fall back to the
		// more general one
		let locale = Session.get('locale');
		if (templateNotFound(locale)) locale = locale.slice(0, 2);

		// if this still doesn't work, use english locale
		if (templateNotFound(locale)) locale = 'en';

		return templatePrefix + locale;
	}
});

Template.FAQ.events({
	'click h3'(event, instance) {
		const title = $(event.currentTarget);
		title.nextUntil(instance.headerTag, instance.contentTags).toggle();
		title.toggleClass('active');
	},

	'click a[href^="#"]'(event, instance) {
		event.preventDefault();
		const href = $(event.currentTarget).attr('href');
		const id = href.substring(1); // Drop the hash-char
		instance.scrollTo(id);
	}
});
<commit_msg>don't _blank same-page links<commit_after>import { Router } from 'meteor/iron:router';
import { Session } from 'meteor/session';
import { Template } from 'meteor/templating';
import { $ } from 'meteor/jquery';

import ScssVars from '/imports/ui/lib/scss-vars.js';

import './faq.de.md';
import './faq.en.md';
import './faq.html';

Template.FAQ.onCreated(function() {
	this.headerTag = 'h3';
	this.contentTags = 'p, ul';

	this.scrollTo = id => {
		const idSelector = "#" + decodeURIComponent(id);
		const targetTitle = this.$(idSelector);
		if (targetTitle.length) {
			Meteor.defer(() => {
				targetTitle.nextUntil(this.headerTag).show();
				$(window).scrollTop(targetTitle.position().top - ScssVars.navbarHeight);
			});
		}
	};
});

Template.FAQ.onRendered(function() {
	// in order to create nice IDs for the questions also for non-english
	// alphabets we make our own ones
	this.$(this.headerTag).each(function() {
		const title = $(this);
		const id =
			title
			.text()
			.trim()
			.toLowerCase()
			.replace(/[_+.,!?@#$%^&*();\\\/|<>"'=]/g, "")
			.replace(/[ ]/g, "-");

		title.attr('id', id);
	});

	this.$('a').not('[href^="#"]').attr('target', '_blank');

	const hash = Router.current().params.hash;
	if (hash) this.scrollTo(hash);
});

Template.FAQ.helpers({
	localizedFAQ() {
		const templatePrefix = 'FAQ_';
		const templateNotFound = locale => !Template[templatePrefix + locale];

		// if the FAQ  doesn't exist with the specific locale fall back to the
		// more general one
		let locale = Session.get('locale');
		if (templateNotFound(locale)) locale = locale.slice(0, 2);

		// if this still doesn't work, use english locale
		if (templateNotFound(locale)) locale = 'en';

		return templatePrefix + locale;
	}
});

Template.FAQ.events({
	'click h3'(event, instance) {
		const title = $(event.currentTarget);
		title.nextUntil(instance.headerTag, instance.contentTags).toggle();
		title.toggleClass('active');
	},

	'click a[href^="#"]'(event, instance) {
		event.preventDefault();
		const href = $(event.currentTarget).attr('href');
		const id = href.substring(1); // Drop the hash-char
		instance.scrollTo(id);
	}
});
<|endoftext|>


<commit_before>Chloe = function (options) {
  options = options || {};
  options.host = options.host || 'localhost';
  options.port = options.port || 8901;

  var transports = [Chloe.WebSocketTransport,
                    Chloe.XhrTransport,
                    Chloe.JsonpTransport ];

  for (var i = 0, l = transports.length; i < l; i++) {
    if (transports[i].isEnabled()) {
      this.transport = new transports[i](options);
      break;
    }
  }

  this.channelSubscriptions = {};
};

Chloe.extend = function (source, obj) {
  for (var prop in source) obj[prop] = source[prop];
  return obj;
};

Chloe.prototype = {
  // Public API
  connect: function (callback) {
    var self = this;
    this.transport.connect(function (data) {
      self.sessionId = data.sessionId;
      callback();
    });
    this.transport.onmessage(function (message) {
      self.handleMessage(Chloe.Message.unpack(message));
    });
  },
  onmessage: function (callback) {
    var self = this;
    this.onmessageCallback = callback;
  },
  onclose: function (callback) {
    this.transport.onclose(callback);
  },
  send: function (data) {
    var message = Chloe.Message.pack(data, this.sessionId);
    message.send(this.transport);
  },
  subscribe: function (channel, callback) {
    var message = Chloe.Message.channelSubscribe(channel, this);
    this.channelSubscriptions[channel] = callback;
    message.send(this.transport);
  },

  // Internal functions
  handleMessage: function (message) {
    var callback = this.channelSubscriptions[message.channel];
    if (callback) {
      callback(message.data);
    } else if (this.onmessageCallback) {
      this.onmessageCallback(message.data);
    }
  }
};
<commit_msg>Allow override of transports<commit_after>Chloe = function (options) {
  options = options || {};
  options.host = options.host || 'localhost';
  options.port = options.port || 8901;

  var transports = options.transports ||
                   [Chloe.WebSocketTransport,
                    Chloe.XhrTransport,
                    Chloe.JsonpTransport];

  for (var i = 0, l = transports.length; i < l; i++) {
    if (transports[i].isEnabled()) {
      this.transport = new transports[i](options);
      break;
    }
  }

  this.channelSubscriptions = {};
};

Chloe.extend = function (source, obj) {
  for (var prop in source) obj[prop] = source[prop];
  return obj;
};

Chloe.prototype = {
  // Public API
  connect: function (callback) {
    var self = this;
    this.transport.connect(function (data) {
      self.sessionId = data.sessionId;
      callback();
    });
    this.transport.onmessage(function (message) {
      self.handleMessage(Chloe.Message.unpack(message));
    });
  },
  onmessage: function (callback) {
    var self = this;
    this.onmessageCallback = callback;
  },
  onclose: function (callback) {
    this.transport.onclose(callback);
  },
  send: function (data) {
    var message = Chloe.Message.pack(data, this.sessionId);
    message.send(this.transport);
  },
  subscribe: function (channel, callback) {
    var message = Chloe.Message.channelSubscribe(channel, this);
    this.channelSubscriptions[channel] = callback;
    message.send(this.transport);
  },

  // Internal functions
  handleMessage: function (message) {
    var callback = this.channelSubscriptions[message.channel];
    if (callback) {
      callback(message.data);
    } else if (this.onmessageCallback) {
      this.onmessageCallback(message.data);
    }
  }
};
<|endoftext|>


<commit_before>var myCharacteristic;

async function onStartButtonClick() {
  let serviceUuid = document.querySelector('#service').value;
  if (serviceUuid.startsWith('0x')) {
    serviceUuid = parseInt(serviceUuid);
  }

  let characteristicUuid = document.querySelector('#characteristic').value;
  if (characteristicUuid.startsWith('0x')) {
    characteristicUuid = parseInt(characteristicUuid);
  }

  serviceUuid = '0000ffe0-0000-1000-8000-00805f9b34fb';
  characteristicUuid = '0000ffe1-0000-1000-8000-00805f9b34fb';

  try {
    log('Requesting Bluetooth Device...');
    const device = await navigator.bluetooth.requestDevice({
        filters: [{services: [serviceUuid]}]});

    log('Connecting to GATT Server...');
    const server = await device.gatt.connect();

    log('Getting Service...');
    const service = await server.getPrimaryService(serviceUuid);

    log('Getting Characteristic...');
    myCharacteristic = await service.getCharacteristic(characteristicUuid);

    await myCharacteristic.startNotifications();

    log('> Notifications started');
    myCharacteristic.addEventListener('characteristicvaluechanged',
        handleNotifications);
  } catch(error) {
    log('Argh! ' + error);
  }
}

async function onStopButtonClick() {
  if (myCharacteristic) {
    try {
      await myCharacteristic.stopNotifications();
      log('> Notifications stopped');
      myCharacteristic.removeEventListener('characteristicvaluechanged',
          handleNotifications);
    } catch(error) {
      log('Argh! ' + error);
    }
  }
}

function userInfo() {

    var u = {
    "users": [
        { "name":"Tony", "userid":0, "height":160, "sex":1, "bod":"1948/12/19"  },
         { "name":"Y", "userid":1, "height":165, "sex":1, "bod":"1948/12/19"   },
         { "name":"Amy", "userid":2, "height":160, "sex":0, "bod":"1948/12/19"   }
    ]
    };

    let userId = document.querySelector('#userId').value;
    var buffer = new ArrayBuffer(5);
    var dv = new DataView(buffer);

    if (userId == 4) {

        let height = document.querySelector('#height').value;
        let age = document.querySelector('#age').value;
        let sex = document.querySelector('#sex').value;

    } else {

        var b = new Date(u.users[userId].bod);
        var c = new Date();
        var age = Math.floor((c-b)/31557600000);
        var height = u.users[userId].height;
        var sex = u.users[userId].sex;

    }

    dv.setUint8(0, 0xc0);
    dv.setUint8(1, 0x09);
    dv.setUint8(2, height);
    dv.setUint8(3, age);
    dv.setUint8(4, sex);

    return dv;

}

function handleNotifications(event) {

  try {
  let value = event.target.value;
  let a = [];
  // Convert raw data bytes to hex values just for the sake of showing something.
  // In the "real" world, you'd use data.getUint8, data.getUint16 or even
  // TextDecoder to process raw data bytes.
  for (let i = 0; i < value.byteLength; i++) {
    a.push('0x' + ('00' + value.getUint8(i).toString(16)).slice(-2));
  }
  log('> ' + a.join(' '));

  var result = '';
  var v;

  for (var i = 0; i < value.byteLength; i++) {
    v = value.getUint8(i).toString(16);
    if (v.length === 1) result += '0';
    result += v;
  }

var characteristic = myCharacteristic;

  if (result == "f8") {

      var d = ( Date.now() / 1000) - 946656000;
      var b = new ArrayBuffer(4);
      var dv = new DataView(b);
      dv.setUint32(0, d);
      let array = new Uint8Array([0xfa,0xf8,dv.getUint8(3),dv.getUint8(2),dv.getUint8(1),dv.getUint8(0)]);
    //  let array = new Uint8Array([0xfa,0xf8,0xae,0x15,0x26,0x21]);
      return characteristic.writeValue(array).then(() => {
            log('< faf8ae152621');});
  } else if (result == "fbf8") {
      let array = new Uint8Array([0xa1,0x5a]);
      return characteristic.writeValue(array).then(() => {
            log('< a15a');});
  } else if (result.substring(0,2) == "d2") {
      let array = new Uint8Array([0xc0,0x09,0x82,0x29,0x01]);
      return characteristic.writeValue(array).then(() => {
            log('< c009822901');});
  } else if (result.substring(0,6) == "d00201") {
      var d         = new Date((value.getUint32(0,1) + 946656000)*1000);
      var weight    = value.getUint16(8) / 10.0;
      var fat       = value.getUint16(10) / 10.0;
      var water     = value.getUint16(12) / 10.0;
      log("checkdate:"+d.toSting);
      log("checkdate:"+d.toISOSting);
      log("checkdate:"+d.valueof());
      log("weight:"+weight);
      log("fat:"+fat);
      log("water:"+water);
      let array = new Uint8Array([0xfa,0xd0,0x02,0x01]);
      return characteristic.writeValue(array).then(() => {
            log('< fad00201');});
  } else if (result.substring(0,6) == "d00202") {
      var muscle    = value.getUint16(4) / 10.0;
      var bone      = value.getUint16(6) / 10.0;
      var metabolism= value.getUint16(8);
      var skinfat   = value.getUint16(10) / 10.0;
      var offalfat  = value.getUint8(12) / 10.0;
      var bodyage   = value.getUint8(13) / 10.0;
      log("muscle:"+muscle);
      log("bone:"+bone);
      log("metabolism:"+metabolism);
      log("skinfat:"+skinfat);
      log("offalfat:"+ofaalfat);
      log("bodyage:"+bodyage);
            let array = new Uint8Array([0xfa,0xd0,0x02,0x02]);
            return characteristic.writeValue(array).then(() => {
                  log('< fad00202');});
   }
  } catch (error) {
      log('Argh! ' + error);
    }

}
<commit_msg>Update notifications-async-await.js<commit_after>var myCharacteristic;

async function onStartButtonClick() {
  let serviceUuid = document.querySelector('#service').value;
  if (serviceUuid.startsWith('0x')) {
    serviceUuid = parseInt(serviceUuid);
  }

  let characteristicUuid = document.querySelector('#characteristic').value;
  if (characteristicUuid.startsWith('0x')) {
    characteristicUuid = parseInt(characteristicUuid);
  }

  serviceUuid = '0000ffe0-0000-1000-8000-00805f9b34fb';
  characteristicUuid = '0000ffe1-0000-1000-8000-00805f9b34fb';

  try {
    log('Requesting Bluetooth Device...');
    const device = await navigator.bluetooth.requestDevice({
        filters: [{services: [serviceUuid]}]});

    log('Connecting to GATT Server...');
    const server = await device.gatt.connect();

    log('Getting Service...');
    const service = await server.getPrimaryService(serviceUuid);

    log('Getting Characteristic...');
    myCharacteristic = await service.getCharacteristic(characteristicUuid);

    await myCharacteristic.startNotifications();

    log('> Notifications started');
    myCharacteristic.addEventListener('characteristicvaluechanged',
        handleNotifications);
  } catch(error) {
    log('Argh! ' + error);
  }
}

async function onStopButtonClick() {
  if (myCharacteristic) {
    try {
      await myCharacteristic.stopNotifications();
      log('> Notifications stopped');
      myCharacteristic.removeEventListener('characteristicvaluechanged',
          handleNotifications);
    } catch(error) {
      log('Argh! ' + error);
    }
  }
}

function userInfo() {

    var u = {
    "users": [
        { "name":"Tony", "userid":0, "height":160, "sex":1, "bod":"1948/12/19"  },
         { "name":"Y", "userid":1, "height":165, "sex":1, "bod":"1948/12/19"   },
         { "name":"Amy", "userid":2, "height":160, "sex":0, "bod":"1948/12/19"   }
    ]
    };

    let userId = document.querySelector('#userId').value;
    var buffer = new ArrayBuffer(5);
    var dv = new DataView(buffer);

    if (userId == 4) {

        let height = document.querySelector('#height').value;
        let age = document.querySelector('#age').value;
        let sex = document.querySelector('#sex').value;

    } else {

        var b = new Date(u.users[userId].bod);
        var c = new Date();
        var age = Math.floor((c-b)/31557600000);
        var height = u.users[userId].height;
        var sex = u.users[userId].sex;

    }

    dv.setUint8(0, 0xc0);
    dv.setUint8(1, 0x09);
    dv.setUint8(2, height);
    dv.setUint8(3, age);
    dv.setUint8(4, sex);

    return dv;

}

function handleNotifications(event) {

  let value = event.target.value;
  let a = [];
  // Convert raw data bytes to hex values just for the sake of showing something.
  // In the "real" world, you'd use data.getUint8, data.getUint16 or even
  // TextDecoder to process raw data bytes.
  for (let i = 0; i < value.byteLength; i++) {
    a.push('0x' + ('00' + value.getUint8(i).toString(16)).slice(-2));
  }
  log('> ' + a.join(' '));

  try {
  var result = '';
  var v;

  for (var i = 0; i < value.byteLength; i++) {
    v = value.getUint8(i).toString(16);
    if (v.length === 1) result += '0';
    result += v;
  }

var characteristic = myCharacteristic;

  if (result == "f8") {

      var d = ( Date.now() / 1000) - 946656000;
      var b = new ArrayBuffer(4);
      var dv = new DataView(b);
      dv.setUint32(0, d);
      let array = new Uint8Array([0xfa,0xf8,dv.getUint8(3),dv.getUint8(2),dv.getUint8(1),dv.getUint8(0)]);
    //  let array = new Uint8Array([0xfa,0xf8,0xae,0x15,0x26,0x21]);
      return characteristic.writeValue(array).then(() => {
            log('< faf8ae152621');});
  } else if (result == "fbf8") {
      let array = new Uint8Array([0xa1,0x5a]);
      return characteristic.writeValue(array).then(() => {
            log('< a15a');});
  } else if (result.substring(0,2) == "d2") {
      let array = new Uint8Array([0xc0,0x09,0x82,0x29,0x01]);
      return characteristic.writeValue(array).then(() => {
            log('< c009822901');});
  } else if (result.substring(0,6) == "d00201") {
      var d         = new Date((value.getUint32(0,1) + 946656000)*1000);
      var weight    = value.getUint16(8) / 10.0;
      var fat       = value.getUint16(10) / 10.0;
      var water     = value.getUint16(12) / 10.0;
      log("checkdate:"+d.toSting);
      log("checkdate:"+d.toISOSting);
      log("checkdate:"+d.valueof());
      log("weight:"+weight);
      log("fat:"+fat);
      log("water:"+water);
      let array = new Uint8Array([0xfa,0xd0,0x02,0x01]);
      return characteristic.writeValue(array).then(() => {
            log('< fad00201');});
  } else if (result.substring(0,6) == "d00202") {
      var muscle    = value.getUint16(4) / 10.0;
      var bone      = value.getUint16(6) / 10.0;
      var metabolism= value.getUint16(8);
      var skinfat   = value.getUint16(10) / 10.0;
      var offalfat  = value.getUint8(12) / 10.0;
      var bodyage   = value.getUint8(13) / 10.0;
      log("muscle:"+muscle);
      log("bone:"+bone);
      log("metabolism:"+metabolism);
      log("skinfat:"+skinfat);
      log("offalfat:"+ofaalfat);
      log("bodyage:"+bodyage);
            let array = new Uint8Array([0xfa,0xd0,0x02,0x02]);
            return characteristic.writeValue(array).then(() => {
                  log('< fad00202');});
   }
  } catch (error) {
      log('Argh! ' + error);
    }

}
<|endoftext|>


<commit_before>
function connect(name) {
  if (!window.docReady) window.docReady = makeDoc();
  window.docReady.then(function(doc) {startService(name, doc)});
}

function startService(name, doc) {
  var port = chrome.runtime.connect({name: name});
  port.onMessage.addListener(dispatch.bind(null, {
    raGetInfo: getInfo,
    raGetCurrentIndex: getCurrentIndex,
    raGetTexts: getTexts,
  }))

  function dispatch(handlers, message) {
    var request = message.request;
    if (handlers[request.method]) {
      var result = handlers[request.method](request);
      Promise.resolve(result).then(function(response) {
        port.postMessage({id: message.id, response: response});
      });
    }
  }

  function getInfo(request) {
    var lang = document.documentElement.lang || $("html").attr("xml:lang");
    if (lang == "en") lang = null;    //foreign language pages often erronenously declare lang="en"
    return {
      isPdf: doc.isPdf,
      canSeek: doc.canSeek,
      url: location.href,
      title: document.title,
      lang: lang
    }
  }

  function getCurrentIndex(request) {
    if (getSelectedText()) return -100;
    else return doc.getCurrentIndex();
  }

  function getTexts(request) {
    if (request.index < 0) {
      if (request.index == -100) return getSelectedText().split(/(?:\r?\n){2,}/);
      else return null;
    }
    else {
      return Promise.resolve(doc.getTexts(request.index))
        .then(function(texts) {
          if (texts) {
            texts = texts.map(removeLinks);
            console.log(texts.join("\n\n"));
          }
          return texts;
        })
    }
  }

  function getSelectedText() {
    return window.getSelection().toString().trim();
  }
}

function makeDoc() {
  return domReady()
    .then(createDoc)
    .then(function(doc) {
      return Promise.resolve(doc.ready).then(function() {return doc});
    })

  function domReady() {
    return new Promise(function(fulfill) {
      $(fulfill);
    })
  }

  function createDoc() {
    if (location.hostname == "docs.google.com") {
      if ($(".kix-appview-editor").length) return new GoogleDoc();
      else if ($(".drive-viewer-paginated-scrollable").length) return new GDriveDoc();
      else return new HtmlDoc();
    }
    else if (location.hostname == "drive.google.com") return new GDriveDoc();
    else if (location.hostname == "read.amazon.com") return new KindleBook();
    else if (location.pathname.match(/\.pdf$/)) return new PdfDoc(location.href);
    else if ($("embed[type='application/pdf']").length) return new PdfDoc($("embed[type='application/pdf']").attr("src"));
    else return new HtmlDoc();
  }
}

function GoogleDoc() {
  var viewport = $(".kix-appview-editor").get(0);
  var pages = $(".kix-page");

  this.getCurrentIndex = function() {
    for (var i=0; i<pages.length; i++) if (pages.eq(i).position().top > viewport.scrollTop+$(viewport).height()/2) break;
    return i-1;
  }

  this.getTexts = function(index) {
    var page = pages.get(index);
    if (page) {
      viewport.scrollTop = $(page).position().top;
      return tryGetTexts(getTexts.bind(page), 2000);
    }
    else return null;
  }

  function getTexts() {
    return $(".kix-paragraphrenderer", this).get().map(getText).filter(isNotEmpty);
  }
}

function GDriveDoc() {
  var viewport = $(".drive-viewer-paginated-scrollable").get(0);
  var pages = $(".drive-viewer-paginated-page");

  this.getCurrentIndex = function() {
    for (var i=0; i<pages.length; i++) if (pages.eq(i).position().top > viewport.scrollTop+$(viewport).height()/2) break;
    return i-1;
  }

  this.getTexts = function(index) {
    var page = pages.get(index);
    if (page) {
      viewport.scrollTop = $(page).position().top;
      return tryGetTexts(getTexts.bind(page), 3000);
    }
    else return null;
  }

  function getTexts() {
    var texts = $("p", this).get().map(getText).filter(isNotEmpty);
    return fixParagraphs(texts);
  }
}

function KindleBook() {
  var mainDoc = document.getElementById("KindleReaderIFrame").contentDocument;
  var btnNext = mainDoc.getElementById("kindleReader_pageTurnAreaRight");
  var btnPrev = mainDoc.getElementById("kindleReader_pageTurnAreaLeft");
  var contentFrames = [
    mainDoc.getElementById("column_0_frame_0"),
    mainDoc.getElementById("column_0_frame_1"),
    mainDoc.getElementById("column_1_frame_0"),
    mainDoc.getElementById("column_1_frame_1")
  ];
  var currentIndex = 0;
  var lastText;

  this.getCurrentIndex = function() {
    return currentIndex = 0;
  }

  this.getTexts = function(index) {
    for (; currentIndex<index; currentIndex++) $(btnNext).click();
    for (; currentIndex>index; currentIndex--) $(btnPrev).click();
    return tryGetTexts(getTexts, 4000);
  }

  function getTexts() {
    var texts = [];
    contentFrames.filter(function(frame) {
      return frame.style.visibility != "hidden";
    })
    .forEach(function(frame) {
      var frameHeight = $(frame).height();
      $("h1, h2, h3, h4, h5, h6, .was-a-p", frame.contentDocument).each(function() {
        var top = $(this).offset().top;
        var bottom = top + $(this).height();
        if (top >= 0 && top < frameHeight) texts.push($(this).text());
      })
    })
    var out = [];
    for (var i=0; i<texts.length; i++) {
      if (texts[i] != (out.length ? out[out.length-1] : lastText)) out.push(texts[i]);
    }
    lastText = out[out.length-1];
    return out;
  }
}

function PdfDoc(url) {
  var pdf;
  this.isPdf = true;
  this.canSeek = true;

  this.getCurrentIndex = function() {
    return 0;
  }

  this.getTexts = function(index) {
    if (/^file:/.test(url)) {
      showUploadDialog();
      return Promise.resolve(null);
    }
    return ready().then(function() {
      if (index < pdf.numPages) return pdf.getPage(index+1).then(getPageTexts);
      else return null;
    })
  }

  function getPageTexts(page) {
    return page.getTextContent()
      .then(function(content) {
        var lines = [];
        for (var i=0; i<content.items.length; i++) {
          if (lines.length == 0 || i > 0 && content.items[i-1].transform[5] != content.items[i].transform[5]) lines.push("");
          lines[lines.length-1] += content.items[i].str;
        }
        return lines.map(function(line) {return line.trim()});
      })
      .then(fixParagraphs)
  }

  function ready() {
    if (pdf) return Promise.resolve();
    else {
      PDFJS.workerSrc = chrome.runtime.getURL("/js/pdf.worker.js");
      return PDFJS.getDocument(url).promise.then(function(result) {pdf = result});
    }
  }

  function showUploadDialog() {
    if ($(".pdf-upload-dialog:visible").length) return;

    var div = $("
")
      .addClass("pdf-upload-dialog");
    $("
")
      .text(formatMessage({code: "uploadpdf_message1", extension_name: chrome.i18n.getMessage("extension_short_name")}))
      .css("color", "blue")
      .appendTo(div);
    $("
")
      .text(formatMessage({code: "uploadpdf_message2", extension_name: chrome.i18n.getMessage("extension_short_name")}))
      .appendTo(div);
    var form = $("<form>")
      .attr("action", "https://support2.lsdsoftware.com/dropmeafile-readaloud/upload")
      .attr("method", "POST")
      .attr("enctype", "multipart/form-data")
      .on("submit", function() {
        btnSubmit.prop("disabled", true);
      })
      .appendTo(div);
    $("<input>")
      .attr("type", "file")
      .attr("name", "fileToUpload")
      .attr("accept", "application/pdf")
      .on("change", function() {
        btnSubmit.prop("disabled", !$(this).val())
      })
      .appendTo(form);
    $("
")
      .appendTo(form);
    $("
")
      .appendTo(form);
    var btnSubmit = $("<input>")
      .attr("type", "submit")
      .attr("value", chrome.i18n.getMessage("uploadpdf_submit_button"))
      .prop("disabled", true)
      .appendTo(form);

    div.appendTo(document.body)
      .dialog({
        title: chrome.i18n.getMessage("extension_short_name"),
        width: 400,
        modal: true
      })
  }

  function formatMessage(msg) {
    var message = chrome.i18n.getMessage(msg.code);
    if (message) message = message.replace(/{(\w+)}/g, function(m, p1) {return msg[p1]});
    return message;
  }
}

function HtmlDoc() {
  var headingTags = ["H1", "H2", "H3", "H4", "H5", "H6"];
  var paragraphTags = ["P", "BLOCKQUOTE", "PRE"];
  var listTags = ["OL", "UL"];

  this.getCurrentIndex = function() {
    return 0;
  }

  this.getTexts = function(index) {
    if (index == 0) return parse();
    else return null;
  }

  function parse() {
    //clear markers
    $(".read-aloud").removeClass("read-aloud");

    //find text blocks with at least 1 paragraphs
    var textBlocks = $("p").not("blockquote > p").parent().get();
    $.uniqueSort(textBlocks);

    //visible only
    textBlocks = $(textBlocks).filter(":visible").filter(notOutOfView).get();

    if (textBlocks.length) {
      //remove any block less than 1/7 the length of the longest block
      var lengths = textBlocks.map(function(block) {
        return $(block).children(paragraphTags.join(", ")).text().length;
      });
      var longest = Math.max.apply(null, lengths);
      textBlocks = textBlocks.filter(function(block, index) {
        return lengths[index] > longest/7;
      });

      //mark the elements to be read
      textBlocks.forEach(function(block) {
        $(findHeadingsFor(block)).addClass("read-aloud");
        $(block).children(headingTags.concat(paragraphTags).join(", ")).addClass("read-aloud");
        $(block).children(listTags.join(", ")).children("li").addClass("read-aloud");
      });
    }
    else {
      //if no text blocks found, read all headings
      $(headingTags.concat(paragraphTags).join(", ")).filter(":visible").addClass("read-aloud");
    }

    //extract texts
    var texts = $(".read-aloud").get().map(getText).filter(isNotEmpty);
    return texts;
  }

  function findHeadingsFor(block) {
    var result = [];
    var firstInnerElem = $(block).children(headingTags.concat(paragraphTags).join(", ")).get(0);
    var currentLevel = getHeadingLevel(firstInnerElem);
    var node = previousNode(firstInnerElem, true);
    while (node && !$(node).hasClass("read-aloud")) {
      if (node.nodeType == 1) {
        var level = getHeadingLevel(node);
        if (level < currentLevel) {
          result.push(node);
          currentLevel = level;
        }
      }
      node = previousNode(node);
    }
    return result.reverse();
  }

  function getHeadingLevel(elem) {
    var index = elem ? headingTags.indexOf(elem.tagName) : -1;
    return index == -1 ? 100 : index + 1;
  }

  function previousNode(node, skipChildren) {
    if (node == document.body) return null;
    if (node.nodeType == 1 && !skipChildren && node.lastChild) return node.lastChild;
    if (node.previousSibling) return node.previousSibling;
    return previousNode(node.parentNode, true);
  }
}

function notOutOfView() {
  return $(this).offset().left >= 0;
}

function getText(elem) {
  $(elem).find("sup").hide();
  $(elem).find("*").filter(function() {return this.style && this.style.position == 'absolute'}).hide();
  var text = elem.innerText.trim();
  if (elem.tagName == "LI") return ($(elem).index() + 1) + ". " + text;
  else return text;
}

function isNotEmpty(text) {
  return text;
}

function removeLinks(text) {
  return text.replace(/https?:\/\/\S+/g, "this URL.");
}

function waitMillis(millis) {
  return new Promise(function(fulfill) {
    setTimeout(fulfill, millis);
  });
}

function fixParagraphs(texts) {
  var out = [];
  var para = "";
  for (var i=0; i<texts.length; i++) {
    if (!texts[i]) {
      if (para) {
        out.push(para);
        para = "";
      }
      continue;
    }
    if (para) {
      if (/-$/.test(para)) para = para.substr(0, para.length-1);
      else para += " ";
    }
    para += texts[i].replace(/-\r?\n/g, "");
    if (texts[i].match(/[.!?:)"'\u2019\u201d]$/)) {
      out.push(para);
      para = "";
    }
  }
  if (para) out.push(para);
  return out;
}

function tryGetTexts(getTexts, millis) {
  return waitMillis(500)
    .then(getTexts)
    .then(function(texts) {
      if (texts && !texts.length && millis-500 > 0) return tryGetTexts(getTexts, millis-500);
      else return texts;
    })
}
<commit_msg>Quora support<commit_after>
function connect(name) {
  if (!window.docReady) window.docReady = makeDoc();
  window.docReady.then(function(doc) {startService(name, doc)});
}

function startService(name, doc) {
  var port = chrome.runtime.connect({name: name});
  port.onMessage.addListener(dispatch.bind(null, {
    raGetInfo: getInfo,
    raGetCurrentIndex: getCurrentIndex,
    raGetTexts: getTexts,
  }))

  function dispatch(handlers, message) {
    var request = message.request;
    if (handlers[request.method]) {
      var result = handlers[request.method](request);
      Promise.resolve(result).then(function(response) {
        port.postMessage({id: message.id, response: response});
      });
    }
  }

  function getInfo(request) {
    var lang = document.documentElement.lang || $("html").attr("xml:lang");
    if (lang == "en") lang = null;    //foreign language pages often erronenously declare lang="en"
    return {
      isPdf: doc.isPdf,
      canSeek: doc.canSeek,
      url: location.href,
      title: document.title,
      lang: lang
    }
  }

  function getCurrentIndex(request) {
    if (getSelectedText()) return -100;
    else return doc.getCurrentIndex();
  }

  function getTexts(request) {
    if (request.index < 0) {
      if (request.index == -100) return getSelectedText().split(/(?:\r?\n){2,}/);
      else return null;
    }
    else {
      return Promise.resolve(doc.getTexts(request.index))
        .then(function(texts) {
          if (texts) {
            texts = texts.map(removeLinks);
            console.log(texts.join("\n\n"));
          }
          return texts;
        })
    }
  }

  function getSelectedText() {
    return window.getSelection().toString().trim();
  }

  function removeLinks(text) {
    return text.replace(/https?:\/\/\S+/g, "this URL.");
  }
}

function makeDoc() {
  return domReady()
    .then(createDoc)
    .then(function(doc) {
      return Promise.resolve(doc.ready).then(function() {return doc});
    })

  function domReady() {
    return new Promise(function(fulfill) {
      $(fulfill);
    })
  }

  function createDoc() {
    if (location.hostname == "docs.google.com") {
      if ($(".kix-appview-editor").length) return new GoogleDoc();
      else if ($(".drive-viewer-paginated-scrollable").length) return new GDriveDoc();
      else return new HtmlDoc();
    }
    else if (location.hostname == "drive.google.com") return new GDriveDoc();
    else if (location.hostname == "read.amazon.com") return new KindleBook();
    else if (location.hostname == "www.quora.com") return new QuoraPage();
    else if (location.pathname.match(/\.pdf$/)) return new PdfDoc(location.href);
    else if ($("embed[type='application/pdf']").length) return new PdfDoc($("embed[type='application/pdf']").attr("src"));
    else return new HtmlDoc();
  }
}

function GoogleDoc() {
  var viewport = $(".kix-appview-editor").get(0);
  var pages = $(".kix-page");

  this.getCurrentIndex = function() {
    for (var i=0; i<pages.length; i++) if (pages.eq(i).position().top > viewport.scrollTop+$(viewport).height()/2) break;
    return i-1;
  }

  this.getTexts = function(index) {
    var page = pages.get(index);
    if (page) {
      viewport.scrollTop = $(page).position().top;
      return tryGetTexts(getTexts.bind(page), 2000);
    }
    else return null;
  }

  function getTexts() {
    return $(".kix-paragraphrenderer", this).get().map(getText).filter(isNotEmpty);
  }
}

function GDriveDoc() {
  var viewport = $(".drive-viewer-paginated-scrollable").get(0);
  var pages = $(".drive-viewer-paginated-page");

  this.getCurrentIndex = function() {
    for (var i=0; i<pages.length; i++) if (pages.eq(i).position().top > viewport.scrollTop+$(viewport).height()/2) break;
    return i-1;
  }

  this.getTexts = function(index) {
    var page = pages.get(index);
    if (page) {
      viewport.scrollTop = $(page).position().top;
      return tryGetTexts(getTexts.bind(page), 3000);
    }
    else return null;
  }

  function getTexts() {
    var texts = $("p", this).get().map(getText).filter(isNotEmpty);
    return fixParagraphs(texts);
  }
}

function KindleBook() {
  var mainDoc = document.getElementById("KindleReaderIFrame").contentDocument;
  var btnNext = mainDoc.getElementById("kindleReader_pageTurnAreaRight");
  var btnPrev = mainDoc.getElementById("kindleReader_pageTurnAreaLeft");
  var contentFrames = [
    mainDoc.getElementById("column_0_frame_0"),
    mainDoc.getElementById("column_0_frame_1"),
    mainDoc.getElementById("column_1_frame_0"),
    mainDoc.getElementById("column_1_frame_1")
  ];
  var currentIndex = 0;
  var lastText;

  this.getCurrentIndex = function() {
    return currentIndex = 0;
  }

  this.getTexts = function(index) {
    for (; currentIndex<index; currentIndex++) $(btnNext).click();
    for (; currentIndex>index; currentIndex--) $(btnPrev).click();
    return tryGetTexts(getTexts, 4000);
  }

  function getTexts() {
    var texts = [];
    contentFrames.filter(function(frame) {
      return frame.style.visibility != "hidden";
    })
    .forEach(function(frame) {
      var frameHeight = $(frame).height();
      $("h1, h2, h3, h4, h5, h6, .was-a-p", frame.contentDocument).each(function() {
        var top = $(this).offset().top;
        var bottom = top + $(this).height();
        if (top >= 0 && top < frameHeight) texts.push($(this).text());
      })
    })
    var out = [];
    for (var i=0; i<texts.length; i++) {
      if (texts[i] != (out.length ? out[out.length-1] : lastText)) out.push(texts[i]);
    }
    lastText = out[out.length-1];
    return out;
  }
}

function PdfDoc(url) {
  var pdf;
  this.isPdf = true;
  this.canSeek = true;

  this.getCurrentIndex = function() {
    return 0;
  }

  this.getTexts = function(index) {
    if (/^file:/.test(url)) {
      showUploadDialog();
      return Promise.resolve(null);
    }
    return ready().then(function() {
      if (index < pdf.numPages) return pdf.getPage(index+1).then(getPageTexts);
      else return null;
    })
  }

  function getPageTexts(page) {
    return page.getTextContent()
      .then(function(content) {
        var lines = [];
        for (var i=0; i<content.items.length; i++) {
          if (lines.length == 0 || i > 0 && content.items[i-1].transform[5] != content.items[i].transform[5]) lines.push("");
          lines[lines.length-1] += content.items[i].str;
        }
        return lines.map(function(line) {return line.trim()});
      })
      .then(fixParagraphs)
  }

  function ready() {
    if (pdf) return Promise.resolve();
    else {
      PDFJS.workerSrc = chrome.runtime.getURL("/js/pdf.worker.js");
      return PDFJS.getDocument(url).promise.then(function(result) {pdf = result});
    }
  }

  function showUploadDialog() {
    if ($(".pdf-upload-dialog:visible").length) return;

    var div = $("
")
      .addClass("pdf-upload-dialog");
    $("
")
      .text(formatMessage({code: "uploadpdf_message1", extension_name: chrome.i18n.getMessage("extension_short_name")}))
      .css("color", "blue")
      .appendTo(div);
    $("
")
      .text(formatMessage({code: "uploadpdf_message2", extension_name: chrome.i18n.getMessage("extension_short_name")}))
      .appendTo(div);
    var form = $("<form>")
      .attr("action", "https://support2.lsdsoftware.com/dropmeafile-readaloud/upload")
      .attr("method", "POST")
      .attr("enctype", "multipart/form-data")
      .on("submit", function() {
        btnSubmit.prop("disabled", true);
      })
      .appendTo(div);
    $("<input>")
      .attr("type", "file")
      .attr("name", "fileToUpload")
      .attr("accept", "application/pdf")
      .on("change", function() {
        btnSubmit.prop("disabled", !$(this).val())
      })
      .appendTo(form);
    $("
")
      .appendTo(form);
    $("
")
      .appendTo(form);
    var btnSubmit = $("<input>")
      .attr("type", "submit")
      .attr("value", chrome.i18n.getMessage("uploadpdf_submit_button"))
      .prop("disabled", true)
      .appendTo(form);

    div.appendTo(document.body)
      .dialog({
        title: chrome.i18n.getMessage("extension_short_name"),
        width: 400,
        modal: true
      })
  }

  function formatMessage(msg) {
    var message = chrome.i18n.getMessage(msg.code);
    if (message) message = message.replace(/{(\w+)}/g, function(m, p1) {return msg[p1]});
    return message;
  }
}

function QuoraPage() {
  this.getCurrentIndex = function() {
    return 0;
  }

  this.getTexts = function(index) {
    if (index == 0) return parse();
    else return null;
  }

  function parse() {
    var texts = [$(".QuestionArea .question_qtext").get(0).innerText];
    $(".AnswerBase")
      .each(function() {
        texts.push("Answer by " + $(this).find(".feed_item_answer_user .user").get(0).innerText);
        texts.push.apply(texts, $(this).find(".rendered_qtext").get(0).innerText.split(/\n\n+/));
        texts.push($(this).find(".AnswerFooter").get(0).innerText);
      })
    return texts;
  }
}

function HtmlDoc() {
  var headingTags = ["H1", "H2", "H3", "H4", "H5", "H6"];
  var paragraphTags = ["P", "BLOCKQUOTE", "PRE"];
  var listTags = ["OL", "UL"];

  this.getCurrentIndex = function() {
    return 0;
  }

  this.getTexts = function(index) {
    if (index == 0) return parse();
    else return null;
  }

  function parse() {
    //clear markers
    $(".read-aloud").removeClass("read-aloud");

    //find text blocks with at least 1 paragraphs
    var textBlocks = $("p").not("blockquote > p").parent().get();
    $.uniqueSort(textBlocks);

    //visible only
    textBlocks = $(textBlocks).filter(":visible").filter(notOutOfView).get();

    if (textBlocks.length) {
      //remove any block less than 1/7 the length of the longest block
      var lengths = textBlocks.map(function(block) {
        return $(block).children(paragraphTags.join(", ")).text().length;
      });
      var longest = Math.max.apply(null, lengths);
      textBlocks = textBlocks.filter(function(block, index) {
        return lengths[index] > longest/7;
      });

      //mark the elements to be read
      textBlocks.forEach(function(block) {
        $(findHeadingsFor(block)).addClass("read-aloud");
        $(block).children(headingTags.concat(paragraphTags).join(", ")).addClass("read-aloud");
        $(block).children(listTags.join(", ")).children("li").addClass("read-aloud");
      });
    }
    else {
      //if no text blocks found, read all headings
      $(headingTags.concat(paragraphTags).join(", ")).filter(":visible").addClass("read-aloud");
    }

    //extract texts
    var texts = $(".read-aloud").get().map(getText).filter(isNotEmpty);
    return texts;
  }

  function findHeadingsFor(block) {
    var result = [];
    var firstInnerElem = $(block).children(headingTags.concat(paragraphTags).join(", ")).get(0);
    var currentLevel = getHeadingLevel(firstInnerElem);
    var node = previousNode(firstInnerElem, true);
    while (node && !$(node).hasClass("read-aloud")) {
      if (node.nodeType == 1) {
        var level = getHeadingLevel(node);
        if (level < currentLevel) {
          result.push(node);
          currentLevel = level;
        }
      }
      node = previousNode(node);
    }
    return result.reverse();
  }

  function getHeadingLevel(elem) {
    var index = elem ? headingTags.indexOf(elem.tagName) : -1;
    return index == -1 ? 100 : index + 1;
  }

  function previousNode(node, skipChildren) {
    if (node == document.body) return null;
    if (node.nodeType == 1 && !skipChildren && node.lastChild) return node.lastChild;
    if (node.previousSibling) return node.previousSibling;
    return previousNode(node.parentNode, true);
  }

  function notOutOfView() {
    return $(this).offset().left >= 0;
  }
}

//helpers --------------------------

function getText(elem) {
  $(elem).find("sup").hide();
  $(elem).find("*").filter(function() {return this.style && this.style.position == 'absolute'}).hide();
  var text = elem.innerText.trim();
  if (elem.tagName == "LI") return ($(elem).index() + 1) + ". " + text;
  else return text;
}

function isNotEmpty(text) {
  return text;
}

function fixParagraphs(texts) {
  var out = [];
  var para = "";
  for (var i=0; i<texts.length; i++) {
    if (!texts[i]) {
      if (para) {
        out.push(para);
        para = "";
      }
      continue;
    }
    if (para) {
      if (/-$/.test(para)) para = para.substr(0, para.length-1);
      else para += " ";
    }
    para += texts[i].replace(/-\r?\n/g, "");
    if (texts[i].match(/[.!?:)"'\u2019\u201d]$/)) {
      out.push(para);
      para = "";
    }
  }
  if (para) out.push(para);
  return out;
}

function tryGetTexts(getTexts, millis) {
  return waitMillis(500)
    .then(getTexts)
    .then(function(texts) {
      if (texts && !texts.length && millis-500 > 0) return tryGetTexts(getTexts, millis-500);
      else return texts;
    })

  function waitMillis(millis) {
    return new Promise(function(fulfill) {
      setTimeout(fulfill, millis);
    });
  }
}
<|endoftext|>


<commit_before>var fs = require("fs");
var path = require("path");

var FICSClient = require("fics");

var SocketHandler = function(connection) {
  this.connection = connection;

  var self = this;
  this.connection.on("data", function(rawMessage) {
    var message = JSON.parse(rawMessage);

    self[message.operation](message.params);
  });

  this.connection.on("close", function() {
    if (self.client) {
      self.client.end();
    }
  });
};

SocketHandler.prototype.sendMessage = function(operation, data) {
  this.connection.write(JSON.stringify({ operation: operation, data: data }));
};

SocketHandler.prototype.passthrough = function(clientFn, responseMessage) {
  var self = this;
  this.client[clientFn]().then(function(data) {
    self.sendMessage(responseMessage, data);
  });
};

SocketHandler.prototype.channelList = function() {
  this.passthrough("channelList", "channelList");
};

SocketHandler.prototype.subscribedChannelList = function() {
  this.passthrough("channels", "subscribedChannelList");
};

SocketHandler.prototype.gameList = function() {
  this.passthrough("games", "gameList");
};

SocketHandler.prototype.userList = function() {
  this.passthrough("who", "userList");
};

SocketHandler.prototype.soughtList = function() {
  this.passthrough("sought", "soughtList");
};

SocketHandler.prototype.login = function(params) {
  this.client = new FICSClient();

  var self = this

  if (process.env.NODE_ENV === "development") {
    var sessionLog = fs.createWriteStream(path.join(process.cwd(), "log", "session.log"), {
     flags: "a"
    });

    this.client.getStream().pipe(sessionLog);

    this.client.lines(function(line) {
      self.sendMessage("raw", line);
    });
  }

  this.client.on("close", this.login.bind(this, params));

  this.client.chat().progress(function(data) {
    self.sendMessage("chatMessage", data);
  });

  this.client.login(params)
    .then(function(userData) {
      self.sendMessage("login", userData);
    })
    .fail(function() {
      self.sendMessage("loginFailure");
      self.client.close();
    });
};

SocketHandler.prototype.shout = function(messageData) {
  this.client.shout(messageData.message, messageData.it);
};

SocketHandler.prototype.tell = function(messageData) {
  this.client.tell(messageData.recipient, messageData.message);
};

SocketHandler.prototype.joinChannel = function(channelData) {
  this.client.joinChannel(channelData.number);
};

SocketHandler.prototype.leaveChannel = function(channelData) {
  this.client.leaveChannel(channelData.number);
};

SocketHandler.prototype.observe = function(gameData) {
  var gameNumber = gameData.number;

  var self = this;
  this.client.observe(gameNumber).progress(function(gameData) {
    self.sendMessage("observeUpdate", { number: gameNumber, update: gameData });
  });
};

SocketHandler.prototype.moveList = function(gameData) {
  var self = this;
  this.client.moves(gameData.number).then(function(moves) {
    self.sendMessage("moveList", { number: gameData.number, moves: moves });
  });
};

SocketHandler.prototype.observerList = function(gameData) {
  var self = this;
  this.client.observers(gameData.number).then(function(observers) {
    self.sendMessage("observerList", { number: gameData.number, observers: observers });
  });
};

SocketHandler.prototype.kibitz = function(gameData) {
  this.client.kibitz(gameData.number, gameData.message);
};

SocketHandler.prototype.whisper = function(gameData) {
  this.client.whisper(gameData.number, gameData.message);
};

SocketHandler.prototype.unobserve = function(gameData) {
  this.client.unobserve(gameData.number);
};

module.exports = SocketHandler;
<commit_msg>log socket disconnects<commit_after>var fs = require("fs");
var path = require("path");

var FICSClient = require("fics");

var log = require("./logger");

var SocketHandler = function(connection) {
  this.connection = connection;

  var self = this;
  this.connection.on("data", function(rawMessage) {
    var message = JSON.parse(rawMessage);

    self[message.operation](message.params);
  });

  this.connection.on("close", function() {
    if (self.client) {
      self.client.end();
    }
  });
};

SocketHandler.prototype.sendMessage = function(operation, data) {
  this.connection.write(JSON.stringify({ operation: operation, data: data }));
};

SocketHandler.prototype.passthrough = function(clientFn, responseMessage) {
  var self = this;
  this.client[clientFn]().then(function(data) {
    self.sendMessage(responseMessage, data);
  });
};

SocketHandler.prototype.channelList = function() {
  this.passthrough("channelList", "channelList");
};

SocketHandler.prototype.subscribedChannelList = function() {
  this.passthrough("channels", "subscribedChannelList");
};

SocketHandler.prototype.gameList = function() {
  this.passthrough("games", "gameList");
};

SocketHandler.prototype.userList = function() {
  this.passthrough("who", "userList");
};

SocketHandler.prototype.soughtList = function() {
  this.passthrough("sought", "soughtList");
};

SocketHandler.prototype.login = function(params) {
  this.client = new FICSClient();

  var self = this

  if (process.env.NODE_ENV === "development") {
    var sessionLog = fs.createWriteStream(path.join(process.cwd(), "log", "session.log"), {
     flags: "a"
    });

    this.client.getStream().pipe(sessionLog);

    this.client.lines(function(line) {
      self.sendMessage("raw", line);
    });
  }

  this.client.on("close", _.wrap(this.login.bind(this, params), function(callback) {
    var message = "Socket closed - re-logging user for websocket: " + this.connection;

    if (process.env.NODE_ENV === "development") {
      console.log(message);
    }

    logger.info(message);

    callback();
  }));

  this.client.chat().progress(function(data) {
    self.sendMessage("chatMessage", data);
  });

  this.client.login(params)
    .then(function(userData) {
      self.sendMessage("login", userData);
    })
    .fail(function() {
      self.sendMessage("loginFailure");
      self.client.close();
    });
};

SocketHandler.prototype.shout = function(messageData) {
  this.client.shout(messageData.message, messageData.it);
};

SocketHandler.prototype.tell = function(messageData) {
  this.client.tell(messageData.recipient, messageData.message);
};

SocketHandler.prototype.joinChannel = function(channelData) {
  this.client.joinChannel(channelData.number);
};

SocketHandler.prototype.leaveChannel = function(channelData) {
  this.client.leaveChannel(channelData.number);
};

SocketHandler.prototype.observe = function(gameData) {
  var gameNumber = gameData.number;

  var self = this;
  this.client.observe(gameNumber).progress(function(gameData) {
    self.sendMessage("observeUpdate", { number: gameNumber, update: gameData });
  });
};

SocketHandler.prototype.moveList = function(gameData) {
  var self = this;
  this.client.moves(gameData.number).then(function(moves) {
    self.sendMessage("moveList", { number: gameData.number, moves: moves });
  });
};

SocketHandler.prototype.observerList = function(gameData) {
  var self = this;
  this.client.observers(gameData.number).then(function(observers) {
    self.sendMessage("observerList", { number: gameData.number, observers: observers });
  });
};

SocketHandler.prototype.kibitz = function(gameData) {
  this.client.kibitz(gameData.number, gameData.message);
};

SocketHandler.prototype.whisper = function(gameData) {
  this.client.whisper(gameData.number, gameData.message);
};

SocketHandler.prototype.unobserve = function(gameData) {
  this.client.unobserve(gameData.number);
};

module.exports = SocketHandler;
<|endoftext|>


<commit_before>import { Router } from 'express';
import Boom from 'boom';
import Joi from 'joi';
import celebrate from 'celebrate';
import { ObjectID as objectId } from 'mongodb';
import pick from 'lodash/pick';
import {
  wrapHandler,
  idValidator as mongoIdValidator,
  toBSON,
} from './helpers';

export default ({
  router = Router(),
  repository,
  idValidator = mongoIdValidator,
}) => {
  router.param('id', async (req, res, next, rawId) => {
    const { error, value } = Joi.validate(rawId, idValidator);

    if (error) {
      return next(error);
    }

    const id = objectId(value);

    try {
      const entity = await repository.findById(id);

      if (!entity) {
        return next(Boom.notFound(`Unable to find entity with id ${rawId}`));
      }

      req.entity = entity;
    } catch (err) {
      return next(err);
    }

    return next();
  });

  router
    .route('/')
    .get(
      celebrate({
        query: {
          query: Joi.object().default({}),
          offset: Joi.number(),
          limit: Joi.number(),
          orderBy: Joi.object().default({}),
          fields: Joi.object().default({}),
        },
      }),
      wrapHandler(req => {
        const params = pick(req.query, ['fields', 'orderBy']);
        params.query = toBSON(req.query.query);

        if (req.query.offset !== undefined) {
          params.skip = parseInt(req.query.offset, 10);
        }

        if (req.query.limit !== undefined) {
          params.limit = parseInt(req.query.limit, 10);
        }

        return repository.findMany(params).toArray();
      }),
    )
    .post(wrapHandler(req => repository.createOne(toBSON(req.body))));

  router.get(
    '/count',
    celebrate({
      query: {
        query: Joi.object().default({}),
      },
    }),
    wrapHandler(req => repository.count({ query: toBSON(req.query.query) })),
  );

  router.delete(
    '/deleteOne',
    celebrate({
      query: Joi.object().required(),
    }),
    wrapHandler(req =>
      repository.deleteOne({ query: toBSON(req.query.query) }),
    ),
  );

  router
    .route('/:id')
    .get((req, res) => res.json(req.entity))
    .put(
      wrapHandler(req =>
        repository.replaceOne({
          ...req.entity,
          ...toBSON(req.body),
        }),
      ),
    )
    .patch(
      wrapHandler(async req => {
        await repository.validate({
          ...req.entity,
          ...req.body,
        });

        return repository.updateOne({
          query: {
            _id: req.entity._id,
          },
          update: {
            $set: req.body,
          },
        });
      }),
    )
    .delete(
      wrapHandler(req =>
        repository.deleteOne({ query: { _id: req.entity._id } }),
      ),
    );

  router.get(
    '/findOne',
    celebrate({
      query: {
        query: Joi.object().default({}),
      },
    }),
    wrapHandler(async req => {
      const query = toBSON(req.query.query);
      const entity = await repository.findOne({ query });

      if (!entity) {
        throw Boom.notFound('Unable to find entity.');
      }

      return entity;
    }),
  );

  return router;
};
<commit_msg>[makeen-router] bugfixes<commit_after>import { Router } from 'express';
import Boom from 'boom';
import Joi from 'joi';
import celebrate from 'celebrate';
import { ObjectID as objectId } from 'mongodb';
import pick from 'lodash/pick';
import {
  wrapHandler,
  idValidator as mongoIdValidator,
  toBSON,
} from './helpers';

export default ({
  router = Router(),
  repository,
  idValidator = mongoIdValidator,
}) => {
  router.param('id', async (req, res, next, rawId) => {
    const { error, value } = Joi.validate(rawId, idValidator);

    if (error) {
      return next(error);
    }

    const id = objectId(value);

    try {
      const entity = await repository.findById(id);

      if (!entity) {
        return next(Boom.notFound(`Unable to find entity with id ${rawId}`));
      }

      req.entity = entity;
    } catch (err) {
      return next(err);
    }

    return next();
  });

  router
    .route('/')
    .get(
      celebrate({
        query: {
          query: Joi.object().default({}),
          offset: Joi.number(),
          limit: Joi.number(),
          orderBy: Joi.object().default({}),
          fields: Joi.object().default({}),
        },
      }),
      wrapHandler(async req => {
        const params = pick(req.query, ['fields', 'orderBy']);
        params.query = toBSON(req.query.query);

        if (req.query.offset !== undefined) {
          params.skip = parseInt(req.query.offset, 10);
        }

        if (req.query.limit !== undefined) {
          params.limit = parseInt(req.query.limit, 10);
        }

        const cursor = await repository.findMany(params);

        return cursor.toArray();
      }),
    )
    .post(wrapHandler(req => repository.createOne(toBSON(req.body))));

  router.get(
    '/count',
    celebrate({
      query: {
        query: Joi.object().default({}),
      },
    }),
    wrapHandler(req => repository.count({ query: toBSON(req.query.query) })),
  );

  router.delete(
    '/deleteOne',
    celebrate({
      query: Joi.object().required(),
    }),
    wrapHandler(req =>
      repository.deleteOne({ query: toBSON(req.query.query) }),
    ),
  );

  router
    .route('/:id')
    .get((req, res) => res.json(req.entity))
    .put(
      wrapHandler(req =>
        repository.replaceOne({
          ...req.entity,
          ...toBSON(req.body),
        }),
      ),
    )
    .patch(
      wrapHandler(async req => {
        await repository.validate({
          ...req.entity,
          ...req.body,
        });

        return repository.updateOne({
          query: {
            _id: req.entity._id,
          },
          update: {
            $set: req.body,
          },
        });
      }),
    )
    .delete(
      wrapHandler(req =>
        repository.deleteOne({ query: { _id: req.entity._id } }),
      ),
    );

  router.get(
    '/findOne',
    celebrate({
      query: {
        query: Joi.object().default({}),
      },
    }),
    wrapHandler(async req => {
      const query = toBSON(req.query.query);
      const entity = await repository.findOne({ query });

      if (!entity) {
        throw Boom.notFound('Unable to find entity.');
      }

      return entity;
    }),
  );

  return router;
};
<|endoftext|>


<commit_before>
  function ExplanationWindow() {
    this.create();
  }

  ExplanationWindow.prototype = {};

  ExplanationWindow.prototype.create = function() {
    var me = this;
    this.div = document.createElement('div');
    this.div.setAttribute('id','appInfo');
    this.div.innerHTML =
      ''+
      '
'+
        ''+
        '
¿DE DÓNDE SALEN LOS DATOS?
'+
        '
Datos electorales
'+
        '
'+
          '
Resultados electorales
'+
        '
'+
        '
Datos demográficos
'+
        '
'+
          '
Edad media
'+
          '
Envejecimiento
'+
          '
Porcentaje de inmigración
'+
          '
Saldo vegetativo
'+
        '
'+
        '
Datos económicos
'+
        '
'+
          '
Tasa de paro
'+
          '
Parados larga duración
'+
          '
Jóvenes parados larga duración
'+
          '
PIB per cápita
'+
          '
Salario medio
'+
          '
Matriculaciones
'+
        '
'+
        '
Datos sociológicos
'+
        '
'+
          '
Estudios superiores
'+
          '
Consumo de TV
'+
          '
Consumo de prensa
'+
          '
Penetración de internet
'+
          '
Detenidos
'+
        '
'+

      '
'+
      '

';

    $('body').append(this.div);
    $(this.div).children('a.close_info').click(function(ev){ev.stopPropagation();ev.preventDefault();me.hide();});

    $(this.div).find('h4').click(function(ev){
      ev.stopPropagation(); ev.preventDefault();
			$(this).parent().find('ul').hide("slow");
			var theList = $(this).next("ul");
			theList.toggle("slow");
		});

    $(this.div).find('li').children('a').click(function(ev){

      ev.stopPropagation(); ev.preventDefault();

      if (!$(this).parent().hasClass('selected')) {

	      $('div#appInfo ul li').each(function(i,ele){$(ele).removeClass('selected')});
        $(this).parent().addClass('selected');
        $('div#appInfo div.explain').children().remove();
        $('div#appInfo div.explain').append(explanationContent[$(this).parent().text()].htmlContent);

				if (explanationContent[$(this).parent().text()].graph) {
					var varName = $(this).attr('id');
					var chartData = "";
					var maxValue = -99999999999;
					var minValue = 99999999999;
					var lastYear = 1981;
					for (year=1987; year<=2011; year++) {

						var value = max_min_avg[varName+"_"+year+"_avg"];
						if (value == undefined) continue;
						if (value > maxValue) {
							maxValue = value;
						}
						if (value < minValue) {
							minValue = value;
						}
						chartData += value+",";
						lastYear = year;
					}
					if (chartData.charAt(chartData.length-1) == ',') {
						chartData = chartData.substring(0,chartData.length-1);
					}
					minValue -= 0.1*maxValue;
					maxValue += 0.1*maxValue;
					var urlChart = "http://chart.apis.google.com/chart?chs=480x166&cht=ls&chco=862071&chd=t:"+chartData+"&chg=5,-1,0,1&chls=3&chma=|0,3&chm=B,E6DBE4,0,0,0&chds="+minValue+","+maxValue;
        	$('div#appInfo div.explain').append("");
        	$('div#appInfo div.explain').append("
"+max_min_avg[varName+"_"+lastYear+"_avg"]+"
"+explanationContent[$(this).parent().text()].units+" en "+lastYear+"")
				}
        $('div#appInfo div.explain').append(explanationContent[$(this).parent().text()].sourceText);
				var offset = $(this).position().top;
        $('div#appInfo span.arrow').animate({top:offset+'px'},300);
      }

    });

    $(this.div).draggable({containment: 'parent'});
  }

  ExplanationWindow.prototype.show = function() {
    $(this.div).css({margin:'-237px 0 0 -385px',top:'50%',left:'50%'});
    $(this.div).fadeIn();
  }

  ExplanationWindow.prototype.hide = function() {
    $(this.div).fadeOut();
  }
<commit_msg>Fixed the ranges for the graphs<commit_after>
  function ExplanationWindow() {
    this.create();
  }

  ExplanationWindow.prototype = {};

  ExplanationWindow.prototype.create = function() {
    var me = this;
    this.div = document.createElement('div');
    this.div.setAttribute('id','appInfo');
    this.div.innerHTML =
      ''+
      '
'+
        ''+
        '
¿DE DÓNDE SALEN LOS DATOS?
'+
        '
Datos electorales
'+
        '
'+
          '
Resultados electorales
'+
        '
'+
        '
Datos demográficos
'+
        '
'+
          '
Edad media
'+
          '
Envejecimiento
'+
          '
Porcentaje de inmigración
'+
          '
Saldo vegetativo
'+
        '
'+
        '
Datos económicos
'+
        '
'+
          '
Tasa de paro
'+
          '
Parados larga duración
'+
          '
Jóvenes parados larga duración
'+
          '
PIB per cápita
'+
          '
Salario medio
'+
          '
Matriculaciones
'+
        '
'+
        '
Datos sociológicos
'+
        '
'+
          '
Estudios superiores
'+
          '
Consumo de TV
'+
          '
Consumo de prensa
'+
          '
Penetración de internet
'+
          '
Detenidos
'+
        '
'+

      '
'+
      '

';

    $('body').append(this.div);
    $(this.div).children('a.close_info').click(function(ev){ev.stopPropagation();ev.preventDefault();me.hide();});

    $(this.div).find('h4').click(function(ev){
      ev.stopPropagation(); ev.preventDefault();
			$(this).parent().find('ul').hide("slow");
			var theList = $(this).next("ul");
			theList.toggle("slow");
		});

    $(this.div).find('li').children('a').click(function(ev){

      ev.stopPropagation(); ev.preventDefault();

      if (!$(this).parent().hasClass('selected')) {

	      $('div#appInfo ul li').each(function(i,ele){$(ele).removeClass('selected')});
        $(this).parent().addClass('selected');
        $('div#appInfo div.explain').children().remove();
        $('div#appInfo div.explain').append(explanationContent[$(this).parent().text()].htmlContent);

				if (explanationContent[$(this).parent().text()].graph) {
					var varName = $(this).attr('id');
					var chartData = "";
					var maxValue = -99999999999;
					var minValue = 99999999999;
					var lastYear = 1981;
					for (year=1987; year<=2011; year++) {

						var value = max_min_avg[varName+"_"+year+"_avg"];
						if (value == undefined) continue;
						if (value < 0) value = 0;
						if (value > maxValue) {
							maxValue = value;
						}
						chartData += value+",";
						lastYear = year;
					}
					if (chartData.charAt(chartData.length-1) == ',') {
						chartData = chartData.substring(0,chartData.length-1);
					}
					// minValue -= 0.1*maxValue;
					minValue = 0;
					maxValue += 0.1*maxValue;
					var urlChart = "http://chart.apis.google.com/chart?chs=480x166&cht=ls&chco=862071&chd=t:"+chartData+"&chg=5,-1,0,1&chls=3&chma=|0,3&chm=B,E6DBE4,0,0,0&chds="+minValue+","+maxValue;
        	$('div#appInfo div.explain').append("");
        	$('div#appInfo div.explain').append("
"+max_min_avg[varName+"_"+lastYear+"_avg"]+"
"+explanationContent[$(this).parent().text()].units+" en "+lastYear+"")
				}
        $('div#appInfo div.explain').append(explanationContent[$(this).parent().text()].sourceText);
				var offset = $(this).position().top;
        $('div#appInfo span.arrow').animate({top:offset+'px'},300);
      }

    });

    $(this.div).draggable({containment: 'parent'});
  }

  ExplanationWindow.prototype.show = function() {
    $(this.div).css({margin:'-237px 0 0 -385px',top:'50%',left:'50%'});
    $(this.div).fadeIn();
  }

  ExplanationWindow.prototype.hide = function() {
    $(this.div).fadeOut();
  }
<|endoftext|>


<commit_before>'use strict';

const path = require('path');
const loaderUtils = require('loader-utils');
const getConfig = require('../utils/get-config');
const resolvePlugins = require('../utils/resolve-plugins');
const markdownData = require('../utils/markdown-data');

module.exports = function markdownLoader(content) {
  if (this.cacheable) {
    this.cacheable();
  }
  const webpackRemainingChain = loaderUtils.getRemainingRequest(this).split('!');
  const fullPath = webpackRemainingChain[webpackRemainingChain.length - 1];
  const filename = path.relative(process.cwd(), fullPath);

  const query = loaderUtils.parseQuery(this.query);
  const plugins = resolvePlugins(getConfig(query.config).plugins, 'node');

  const parsedMarkdown = markdownData.process(filename, content, plugins, query.isBuild);
  return `module.exports = ${JSON.stringify(parsedMarkdown, null, 2)};`;
};
<commit_msg>feat: support embeded code in JSON<commit_after>'use strict';

const path = require('path');
const loaderUtils = require('loader-utils');
const getConfig = require('../utils/get-config');
const resolvePlugins = require('../utils/resolve-plugins');
const markdownData = require('../utils/markdown-data');

function extractCode(key, value) {
  if (value.__BISHENG_EMBEDED_CODE) {
    return value.code;
  }
  return value;
}

module.exports = function markdownLoader(content) {
  if (this.cacheable) {
    this.cacheable();
  }
  const webpackRemainingChain = loaderUtils.getRemainingRequest(this).split('!');
  const fullPath = webpackRemainingChain[webpackRemainingChain.length - 1];
  const filename = path.relative(process.cwd(), fullPath);

  const query = loaderUtils.parseQuery(this.query);
  const plugins = resolvePlugins(getConfig(query.config).plugins, 'node');

  const parsedMarkdown = markdownData.process(filename, content, plugins, query.isBuild);
  return `module.exports = ${JSON.stringify(parsedMarkdown, extractCode, 2)};`;
};
<|endoftext|>