<commit_before>'use strict';

angular.module('ehelseEditor').factory('Document', ['$rootScope', 'DocumentField', 'Topic', function($rootScope, DocumentField, Topic) {

    function newDocument() {
        return {
            id: null,
            timestamp: null,
            title: "",
            description: "",
            statusId: 1,
            sequence: 0,
            topicId: Topic.getSelected().id,
            comment: "",
            documentTypeId: "1",
            standardId: null,
            previousDocumentId: null,
            internalId: null,
            hisNumber: null,
            profiles: [],
            links: [],
            fields: [],
            targetGroups: [],
            populatedProfiles: []
        };
    }

    function newProfile(standardId) {
        return {
            id: null,
            timestamp: null,
            title: "",
            description: "",
            statusId: 1,
            sequence: 0,
            topicId: Topic.getSelected().id,
            comment: "",
            documentTypeId: "2",
            standardId: standardId,
            previousDocumentId: null,
            internalId: null,
            hisNumber: null,
            profiles: [],
            links: [],
            fields: [],
            targetGroups: [],
            populatedProfiles: []
        }
    }

    var current_document = newDocument();
    var topic_documents = [];
    var link_category_list = [];
    var documents = [];
    var documents_dict = {};

    function extendCurrentDocumentTargetGroupsByTargetGroupIds(target_groups_ids) {
        for (var i = 0; i < target_groups_ids.length; i++) {
            current_document.targetGroups.push({
                targetGroupId: target_groups_ids[i],
                description: "",
                actionId: null,
                deadline: "",
                mandatoryId: null
            });
        }
    }

    function extendCurrentDocumentFieldsByFieldIds(field_ids) {
        for (var i = 0; i < field_ids.length; i++) {
            current_document.fields.push({fieldId: field_ids[i], value: ""});
        }
    }

    function removeTargetGroup(group) {

        var index = current_document.targetGroups.indexOf(group);
        if (index > -1) {
            current_document.targetGroups.splice(index, 1);
        }
    }

    function removeField(field) {

        var index = current_document.fields.indexOf(field);
        if (index > -1) {
            current_document.fields.splice(index, 1);
        }
    }

    function removeCurrentDocumentLink(link) {

        var index = current_document.links.indexOf(link);
        if (index > -1) {
            current_document.links.splice(index, 1);
        }
        generateCurrentDocumentLinksAsLinkCategoryList();
    }

    function submitCurrentDocument() {
        console.log(current_document.standardId);
        if (current_document.id) {

            $rootScope.put(
                'documents/' + current_document.id,
                current_document,
                function (data) {
                    updateDocumentInDocumentsList(data);
                    $rootScope.notifySuccess("Dokumentet ble oppdatert", 6000);
                }
                ,
                function () {
                    $rootScope.notifyError("Standard kunne ikke opprettes", 6000);
                }
            );
        }
        else {
            $rootScope.post(
                'documents/',
                current_document,
                function (data) {
                    setCurrentDocument(data);
                    topic_documents.push(data);
                    $rootScope.notifySuccess("Ny standard ble opprettet", 6000);
                    $rootScope.buttonState = 'editDocument';
                }
                ,
                function () {
                    $rootScope.notifyError("Standard kunne ikke opprettes", 6000);
                }
            );
        }
    }

    function deleteCurrentDocument() {
        $rootScope.delete(
            'documents/' + current_document.id,
            function(){
                deleteCurrentDocumentFromDocumentsList();
                $rootScope.notifySuccess("Dokumentet ble slettet", 5000);
                $rootScope.changeContentView('');
            },
            function(){
                console.log("Document could not be deleted");
                $rootScope.notifyError("Dokument kunne ikke bli slettet", 5000);
            }
        )
    }

    function getCurrentDocument() {
        return current_document;
    }

    function getTargetGroupsIdsHelper(targetGroups) {
        var ids = [];
        for (var i = 0; i < targetGroups.length; i++) {
            ids.push(targetGroups[i].targetGroupId);
        }
        return ids;
    }

    function getTargetGroupsIds() {
        return getTargetGroupsIdsHelper(current_document.targetGroups);
    }

    function updateDocumentInDocumentsList(document) {
        for (var i = 0; i < topic_documents.length; i++) {
            if (topic_documents[i].id == document.id) {
                setDocument(topic_documents[i], document);
                break;
            }
        }
    }

    function deleteCurrentDocumentFromDocumentsList() {
        for (var i = 0; i < topic_documents.length; i++) {
            if (topic_documents[i].id == current_document.id) {
                topic_documents.splice(i,1);
                break;
            }
        }
    }

    function getDocumentFieldIdsHelper(documentFields) {
        var ids = [];
        for (var i = 0; i < documentFields.length; i++) {
            ids.push(documentFields[i].fieldId);
        }
        return ids;
    }

    function getCurrentDocumentFieldIds() {
        return getDocumentFieldIdsHelper(current_document.fields);
    }

    function setDocument(a, b) {
        a.id = b.id;
        a.topicId = b.topicId;
        a.title = b.title;
        a.documentTypeId = b.documentTypeId;
        a.statusId = b.statusId;
        a.internalId = b.internalId;
        a.hisNumber = b.hisNumber;
        a.nextDocumentId = b.nextDocumentId;
        a.previousDocumentId = b.previousDocumentId;
        a.description = b.description;
        a.sequence = b.sequence;
        a.comment = b.comment;
        a.targetGroups = b.targetGroups;
        a.fields = b.fields;
        a.links = b.links;
        a.standardId = b.standardId;
        a.populatedProfiles = b.populatedProfiles || [];
    }

    function setCurrentDocument(document) {
        if (!document) {
            document = newDocument();
            setDocument(current_document, document);
            setCurrentDocumentFieldsByDocumentDocumentTypeId();
        }
        else {
            setDocument(current_document, document);
        }
        generateCurrentDocumentLinksAsLinkCategoryList();

        if(document.standardId){
            getRelatedProfiles(document);
        }else{
            getProfiles(document)
        }
    }

    function getDocumentsByTopicId(id) {
        topic_documents = [];
        $rootScope.get('topics/' + id, function (data) {
            topic_documents.length = 0;

            for(var i = 0; i < data.documents.length; i++){
                var document = data.documents[i];
                document.populatedProfiles = [];
                topic_documents.push(document);
            }

        }, function () {
        });
        return topic_documents;
    }

    function setCurrentDocumentFieldsByDocumentDocumentTypeId() {
        current_document.fields.length = 0;
        extendCurrentDocumentFieldsByFieldIds(DocumentField.getRequiredDocumentFieldIdsByDocumentTypeId(current_document.documentTypeId))
    }

    function generateCurrentDocumentLinksAsLinkCategoryList() {

        var link_category_dict = {};
        for (var i = 0; i < current_document.links.length; i++) {
            var link = current_document.links[i];
            if (!link_category_dict[link.linkCategoryId]) {
                link_category_dict[link.linkCategoryId] = {id: link.linkCategoryId, links: []};
            }
            link_category_dict[link.linkCategoryId].links.push(link);
        }
        link_category_list.length = 0;

        for (var prop in link_category_dict) {
            // skip loop if the property is from prototype
            if (!link_category_dict.hasOwnProperty(prop)) continue;

            link_category_list.push(link_category_dict[prop]);
        }
    }

    function getCurrentDocumentLinksAsLinkCategoryList() {
        return link_category_list;
    }

    function getCurrentDocumentLinkCategoriesIds() {
        var link_category_ids = [];
        for (var i = 0; i < current_document.links.length; i++) {
            link_category_ids.push(current_document.links[i].linkCategoryId);
        }
        return link_category_ids;
    }

    function extendCurrentDocumentLinkCategoriesByLinkCategoriesIds(ids) {
        for (var i = 0; i < ids.length; i++) {
            addLinkToCurrentDocumentByLinkCategoryId(ids[i]);
        }
        generateCurrentDocumentLinksAsLinkCategoryList();
    }

    function addLinkToCurrentDocumentByLinkCategoryId(id) {
        current_document.links.push({linkCategoryId: id, text: "", url: ""});
        generateCurrentDocumentLinksAsLinkCategoryList();
    }

    function removeCurrentDocumentLinksByCategoryId(linkCategoryId) {
        var tmp_list = [];
        for (var i = 0; i < current_document.links.length; i++) {
            if (current_document.links[i].linkCategoryId != linkCategoryId) {
                tmp_list.push(current_document.links[i]);
            }
        }
        current_document.links.length = 0;
        Array.prototype.push.apply(current_document.links, tmp_list);
        generateCurrentDocumentLinksAsLinkCategoryList();
    }

    function getNewProfile(standardId) {
        return newProfile(standardId);
    }

    function getAllDocuments() {
        $rootScope.get(
            'documents/',
            function (data) {
                documents.length = 0;

                for(var i = 0; i < data.documents.length; i++){
                    var document = data.documents[i];
                    document.populatedProfiles = [];
                    documents.push(document);
                }

                generateDocumentDict(documents);
            },
            function () {
                console.log("Could not load documents");
            }
        );
    }

    function generateDocumentDict(documents){
        for(var i = 0; i < documents.length; i++){
            documents_dict[documents[i].id] = documents[i];
        }
    }

    function getAll(){
        return documents;
    }

    function getProfiles(document) {

        var profiles = null;
        if(documents_dict[document.id]) {
            profiles = documents_dict[document.id].profiles;
        }

        if(profiles) {
            document.populatedProfiles.length = 0;
            for (var i = 0; i < profiles.length; i++) {
                document.populatedProfiles.push(documents_dict[profiles[i].id])
            }
        }
        console.log(document);
    }

    function getRelatedProfiles(document) {

        var profiles = null;
        if(documents_dict[document.standardId]) {
            profiles = documents_dict[document.standardId].profiles;
        }

        if(profiles) {
            document.populatedProfiles.length = 0;
            for (var i = 0; i < profiles.length; i++) {
                document.populatedProfiles.push(documents_dict[profiles[i].id])
            }
        }
    }

    getAllDocuments();

    return {
        getCurrentDocumentTargetGroupsIds: getTargetGroupsIds,
        getCurrentDocument: getCurrentDocument,
        extendCurrentDocumentTargetGroupsByTargetGroupIds: extendCurrentDocumentTargetGroupsByTargetGroupIds,
        removeCurrentDocumentTargetGroup: removeTargetGroup,
        submitCurrentDocument: submitCurrentDocument,
        setCurrentDocument: setCurrentDocument,
        getNewProfile: getNewProfile,
        getAll: getAll,
        deleteCurrentDocument: deleteCurrentDocument,
        getCurrentDocumentFieldIds: getCurrentDocumentFieldIds,
        extendCurrentDocumentFieldsByFieldIds: extendCurrentDocumentFieldsByFieldIds,
        removeCurrentDocumentField: removeField,
        getDocumentsByTopicId: getDocumentsByTopicId,
        setCurrentDocumentFieldsByDocumentDocumentTypeId: setCurrentDocumentFieldsByDocumentDocumentTypeId,
        getCurrentDocumentLinksAsLinkCategoryList: getCurrentDocumentLinksAsLinkCategoryList,
        getCurrentDocumentLinkCategoriesIds: getCurrentDocumentLinkCategoriesIds,
        extendCurrentDocumentLinkCategoriesByLinkCategoriesIds: extendCurrentDocumentLinkCategoriesByLinkCategoriesIds,
        addLinkToCurrentDocumentByLinkCategoryId: addLinkToCurrentDocumentByLinkCategoryId,
        removeCurrentDocumentLink: removeCurrentDocumentLink,
        removeCurrentDocumentLinksByCategoryId: removeCurrentDocumentLinksByCategoryId
    };
}]);
<commit_msg>Fixed problem with editing profiles<commit_after>'use strict';

angular.module('ehelseEditor').factory('Document', ['$rootScope', 'DocumentField', 'Topic', function($rootScope, DocumentField, Topic) {

    function newDocument() {
        return {
            id: null,
            timestamp: null,
            title: "",
            description: "",
            statusId: 1,
            sequence: 0,
            topicId: Topic.getSelected().id,
            comment: "",
            documentTypeId: "1",
            standardId: null,
            previousDocumentId: null,
            internalId: null,
            hisNumber: null,
            profiles: [],
            links: [],
            fields: [],
            targetGroups: [],
            populatedProfiles: []
        };
    }

    function newProfile(standardId) {
        return {
            id: null,
            timestamp: null,
            title: "",
            description: "",
            statusId: 1,
            sequence: 0,
            topicId: Topic.getSelected().id,
            comment: "",
            documentTypeId: "2",
            standardId: standardId,
            previousDocumentId: null,
            internalId: null,
            hisNumber: null,
            profiles: [],
            links: [],
            fields: [],
            targetGroups: [],
            populatedProfiles: []
        }
    }

    var current_document = newDocument();
    var topic_documents = [];
    var link_category_list = [];
    var documents = [];
    var documents_dict = {};

    function extendCurrentDocumentTargetGroupsByTargetGroupIds(target_groups_ids) {
        for (var i = 0; i < target_groups_ids.length; i++) {
            current_document.targetGroups.push({
                targetGroupId: target_groups_ids[i],
                description: "",
                actionId: null,
                deadline: "",
                mandatoryId: null
            });
        }
    }

    function extendCurrentDocumentFieldsByFieldIds(field_ids) {
        for (var i = 0; i < field_ids.length; i++) {
            current_document.fields.push({fieldId: field_ids[i], value: ""});
        }
    }

    function removeTargetGroup(group) {

        var index = current_document.targetGroups.indexOf(group);
        if (index > -1) {
            current_document.targetGroups.splice(index, 1);
        }
    }

    function removeField(field) {

        var index = current_document.fields.indexOf(field);
        if (index > -1) {
            current_document.fields.splice(index, 1);
        }
    }

    function removeCurrentDocumentLink(link) {

        var index = current_document.links.indexOf(link);
        if (index > -1) {
            current_document.links.splice(index, 1);
        }
        generateCurrentDocumentLinksAsLinkCategoryList();
    }

    function submitCurrentDocument() {

        var populatedProfiles = [];
        Array.prototype.push.apply(populatedProfiles, current_document.populatedProfiles);
        current_document.populatedProfiles.length = 0;
        if (current_document.id) {

            $rootScope.put(
                'documents/' + current_document.id,
                current_document,
                function (data) {
                    updateDocumentInDocumentsList(data);
                    $rootScope.notifySuccess("Dokumentet ble oppdatert", 6000);
                    Array.prototype.push.apply(current_document.populatedProfiles, populatedProfiles);
                }
                ,
                function () {
                    $rootScope.notifyError("Standard kunne ikke opprettes", 6000);
                }
            );
        }
        else {
            $rootScope.post(
                'documents/',
                current_document,
                function (data) {
                    setCurrentDocument(data);
                    topic_documents.push(data);
                    $rootScope.notifySuccess("Ny standard ble opprettet", 6000);
                    $rootScope.buttonState = 'editDocument';
                    Array.prototype.push.apply(current_document.populatedProfiles, populatedProfiles);
                }
                ,
                function () {
                    $rootScope.notifyError("Standard kunne ikke opprettes", 6000);
                }
            );
        }
    }

    function deleteCurrentDocument() {
        $rootScope.delete(
            'documents/' + current_document.id,
            function(){
                deleteCurrentDocumentFromDocumentsList();
                $rootScope.notifySuccess("Dokumentet ble slettet", 5000);
                $rootScope.changeContentView('');
            },
            function(){
                console.log("Document could not be deleted");
                $rootScope.notifyError("Dokument kunne ikke bli slettet", 5000);
            }
        )
    }

    function getCurrentDocument() {
        return current_document;
    }

    function getTargetGroupsIdsHelper(targetGroups) {
        var ids = [];
        for (var i = 0; i < targetGroups.length; i++) {
            ids.push(targetGroups[i].targetGroupId);
        }
        return ids;
    }

    function getTargetGroupsIds() {
        return getTargetGroupsIdsHelper(current_document.targetGroups);
    }

    function updateDocumentInDocumentsList(document) {
        for (var i = 0; i < topic_documents.length; i++) {
            if (topic_documents[i].id == document.id) {
                setDocument(topic_documents[i], document);
                break;
            }
        }
    }

    function deleteCurrentDocumentFromDocumentsList() {
        for (var i = 0; i < topic_documents.length; i++) {
            if (topic_documents[i].id == current_document.id) {
                topic_documents.splice(i,1);
                break;
            }
        }
    }

    function getDocumentFieldIdsHelper(documentFields) {
        var ids = [];
        for (var i = 0; i < documentFields.length; i++) {
            ids.push(documentFields[i].fieldId);
        }
        return ids;
    }

    function getCurrentDocumentFieldIds() {
        return getDocumentFieldIdsHelper(current_document.fields);
    }

    function setDocument(a, b) {
        a.id = b.id;
        a.topicId = b.topicId;
        a.title = b.title;
        a.documentTypeId = b.documentTypeId;
        a.statusId = b.statusId;
        a.internalId = b.internalId;
        a.hisNumber = b.hisNumber;
        a.nextDocumentId = b.nextDocumentId;
        a.previousDocumentId = b.previousDocumentId;
        a.description = b.description;
        a.sequence = b.sequence;
        a.comment = b.comment;
        a.targetGroups = b.targetGroups;
        a.fields = b.fields;
        a.links = b.links;
        a.standardId = b.standardId;
        a.populatedProfiles = b.populatedProfiles || [];
    }

    function setCurrentDocument(document) {
        if (!document) {
            document = newDocument();
            setDocument(current_document, document);
            setCurrentDocumentFieldsByDocumentDocumentTypeId();
        }
        else {
            setDocument(current_document, document);
        }
        generateCurrentDocumentLinksAsLinkCategoryList();

        if(document.standardId){
            getRelatedProfiles(document);
        }else{
            getProfiles(document)
        }
    }

    function getDocumentsByTopicId(id) {
        topic_documents = [];
        $rootScope.get('topics/' + id, function (data) {
            topic_documents.length = 0;

            for(var i = 0; i < data.documents.length; i++){
                var document = data.documents[i];
                document.populatedProfiles = [];
                topic_documents.push(document);
            }

        }, function () {
        });
        return topic_documents;
    }

    function setCurrentDocumentFieldsByDocumentDocumentTypeId() {
        current_document.fields.length = 0;
        extendCurrentDocumentFieldsByFieldIds(DocumentField.getRequiredDocumentFieldIdsByDocumentTypeId(current_document.documentTypeId))
    }

    function generateCurrentDocumentLinksAsLinkCategoryList() {

        var link_category_dict = {};
        for (var i = 0; i < current_document.links.length; i++) {
            var link = current_document.links[i];
            if (!link_category_dict[link.linkCategoryId]) {
                link_category_dict[link.linkCategoryId] = {id: link.linkCategoryId, links: []};
            }
            link_category_dict[link.linkCategoryId].links.push(link);
        }
        link_category_list.length = 0;

        for (var prop in link_category_dict) {
            // skip loop if the property is from prototype
            if (!link_category_dict.hasOwnProperty(prop)) continue;

            link_category_list.push(link_category_dict[prop]);
        }
    }

    function getCurrentDocumentLinksAsLinkCategoryList() {
        return link_category_list;
    }

    function getCurrentDocumentLinkCategoriesIds() {
        var link_category_ids = [];
        for (var i = 0; i < current_document.links.length; i++) {
            link_category_ids.push(current_document.links[i].linkCategoryId);
        }
        return link_category_ids;
    }

    function extendCurrentDocumentLinkCategoriesByLinkCategoriesIds(ids) {
        for (var i = 0; i < ids.length; i++) {
            addLinkToCurrentDocumentByLinkCategoryId(ids[i]);
        }
        generateCurrentDocumentLinksAsLinkCategoryList();
    }

    function addLinkToCurrentDocumentByLinkCategoryId(id) {
        current_document.links.push({linkCategoryId: id, text: "", url: ""});
        generateCurrentDocumentLinksAsLinkCategoryList();
    }

    function removeCurrentDocumentLinksByCategoryId(linkCategoryId) {
        var tmp_list = [];
        for (var i = 0; i < current_document.links.length; i++) {
            if (current_document.links[i].linkCategoryId != linkCategoryId) {
                tmp_list.push(current_document.links[i]);
            }
        }
        current_document.links.length = 0;
        Array.prototype.push.apply(current_document.links, tmp_list);
        generateCurrentDocumentLinksAsLinkCategoryList();
    }

    function getNewProfile(standardId) {
        return newProfile(standardId);
    }

    function getAllDocuments() {
        $rootScope.get(
            'documents/',
            function (data) {
                documents.length = 0;

                for(var i = 0; i < data.documents.length; i++){
                    var document = data.documents[i];
                    document.populatedProfiles = [];
                    documents.push(document);
                }

                generateDocumentDict(documents);
            },
            function () {
                console.log("Could not load documents");
            }
        );
    }

    function generateDocumentDict(documents){
        for(var i = 0; i < documents.length; i++){
            documents_dict[documents[i].id] = documents[i];
        }
    }

    function getAll(){
        return documents;
    }

    function getProfiles(document) {

        var profiles = null;
        if(documents_dict[document.id]) {
            profiles = documents_dict[document.id].profiles;
        }

        if(profiles) {
            document.populatedProfiles.length = 0;
            for (var i = 0; i < profiles.length; i++) {
                document.populatedProfiles.push(documents_dict[profiles[i].id])
            }
        }
        console.log(document);
    }

    function getRelatedProfiles(document) {

        var profiles = null;
        if(documents_dict[document.standardId]) {
            profiles = documents_dict[document.standardId].profiles;
        }

        if(profiles) {
            document.populatedProfiles.length = 0;
            for (var i = 0; i < profiles.length; i++) {
                document.populatedProfiles.push(documents_dict[profiles[i].id])
            }
        }
    }

    getAllDocuments();

    return {
        getCurrentDocumentTargetGroupsIds: getTargetGroupsIds,
        getCurrentDocument: getCurrentDocument,
        extendCurrentDocumentTargetGroupsByTargetGroupIds: extendCurrentDocumentTargetGroupsByTargetGroupIds,
        removeCurrentDocumentTargetGroup: removeTargetGroup,
        submitCurrentDocument: submitCurrentDocument,
        setCurrentDocument: setCurrentDocument,
        getNewProfile: getNewProfile,
        getAll: getAll,
        deleteCurrentDocument: deleteCurrentDocument,
        getCurrentDocumentFieldIds: getCurrentDocumentFieldIds,
        extendCurrentDocumentFieldsByFieldIds: extendCurrentDocumentFieldsByFieldIds,
        removeCurrentDocumentField: removeField,
        getDocumentsByTopicId: getDocumentsByTopicId,
        setCurrentDocumentFieldsByDocumentDocumentTypeId: setCurrentDocumentFieldsByDocumentDocumentTypeId,
        getCurrentDocumentLinksAsLinkCategoryList: getCurrentDocumentLinksAsLinkCategoryList,
        getCurrentDocumentLinkCategoriesIds: getCurrentDocumentLinkCategoriesIds,
        extendCurrentDocumentLinkCategoriesByLinkCategoriesIds: extendCurrentDocumentLinkCategoriesByLinkCategoriesIds,
        addLinkToCurrentDocumentByLinkCategoryId: addLinkToCurrentDocumentByLinkCategoryId,
        removeCurrentDocumentLink: removeCurrentDocumentLink,
        removeCurrentDocumentLinksByCategoryId: removeCurrentDocumentLinksByCategoryId
    };
}]);
<|endoftext|>


<commit_before>/* global FastBoot */
import Ember from "ember";

const { deprecate, computed, get } = Ember;
const { alias, deprecatingAlias, readOnly } = computed;

const RequestObject = Ember.Object.extend({
  init() {
    this._super(...arguments);

    let request = this.request;
    delete this.request;

    this.cookies = request.cookies;
    this.headers = request.headers;
    this.queryParams = request.queryParams;
    this.path = request.path;
    this.protocol = request.protocol;
    this._host = function() {
      return request.host();
    }
  },

  host: computed(function() {
    return this._host();
  })
});

export default Ember.Service.extend({
  cookies: deprecatingAlias('request.cookies', { id: 'fastboot.cookies-to-request', until: '0.9.9' }),
  headers: deprecatingAlias('request.headers', { id: 'fastboot.headers-to-request', until: '0.9.9' }),

  host: computed(function() {
    deprecate(
      'Usage of fastboot service\'s `host` property is deprecated.  Please use `request.host` instead.',
      false,
      { id: 'fastboot.host-to-request', until: '0.9.9' }
    );

    return this._fastbootInfo.request.host();
  }),

  response: readOnly('_fastbootInfo.response'),

  request: computed(function() {
    return RequestObject.create({ request: get(this, '_fastbootInfo.request') });
  }),

  isFastBoot: computed(function() {
    return typeof FastBoot !== 'undefined';
  }),

  deferRendering(promise) {
    Ember.assert('deferRendering requires a promise or thennable object', promise.then);
    this._fastbootInfo.deferRendering(promise);
  }
});
<commit_msg>better thennable check (#189)<commit_after>/* global FastBoot */
import Ember from "ember";

const { deprecate, computed, get } = Ember;
const { alias, deprecatingAlias, readOnly } = computed;

const RequestObject = Ember.Object.extend({
  init() {
    this._super(...arguments);

    let request = this.request;
    delete this.request;

    this.cookies = request.cookies;
    this.headers = request.headers;
    this.queryParams = request.queryParams;
    this.path = request.path;
    this.protocol = request.protocol;
    this._host = function() {
      return request.host();
    }
  },

  host: computed(function() {
    return this._host();
  })
});

export default Ember.Service.extend({
  cookies: deprecatingAlias('request.cookies', { id: 'fastboot.cookies-to-request', until: '0.9.9' }),
  headers: deprecatingAlias('request.headers', { id: 'fastboot.headers-to-request', until: '0.9.9' }),

  host: computed(function() {
    deprecate(
      'Usage of fastboot service\'s `host` property is deprecated.  Please use `request.host` instead.',
      false,
      { id: 'fastboot.host-to-request', until: '0.9.9' }
    );

    return this._fastbootInfo.request.host();
  }),

  response: readOnly('_fastbootInfo.response'),

  request: computed(function() {
    return RequestObject.create({ request: get(this, '_fastbootInfo.request') });
  }),

  isFastBoot: computed(function() {
    return typeof FastBoot !== 'undefined';
  }),

  deferRendering(promise) {
    Ember.assert('deferRendering requires a promise or thennable object', typeof promise.then === 'function');
    this._fastbootInfo.deferRendering(promise);
  }
});
<|endoftext|>


<commit_before>module.exports = [
    {
        label: 'Perusmerit ja kreikkalaiset aakkoset',
        characters: [
            { character: '°', popular: true },
            { character: '·', latexCommand: '\\cdot', popular: true },
            { character: '±', latexCommand: '\\pm', popular: true },
            { character: '∞', latexCommand: '\\infty', popular: true },
            { character: '²', latexCommand: '^2', popular: true },
            { character: '³', latexCommand: '^3', popular: true },
            { character: '½', latexCommand: '1/2', popular: true },
            { character: '⅓', latexCommand: '1/3', popular: true },
            { character: 'π', latexCommand: '\\pi', popular: true },
            { character: 'α', latexCommand: '\\alpha', popular: true },
            { character: 'β', latexCommand: '\\beta', popular: true  },
            { character: 'Γ', latexCommand: '\\Gamma' },
            { character: 'γ', latexCommand: '\\gamma' },
            { character: 'Δ', latexCommand: '\\Delta' },
            { character: 'δ', latexCommand: '\\delta' },
            { character: 'ε', latexCommand: '\\varepsilon' },
            { character: 'ζ', latexCommand: '\\zeta' },
            { character: 'η', latexCommand: '\\eta' },
            { character: 'Θ', latexCommand: '\\Theta' },
            { character: 'ϑ', latexCommand: '\\vartheta' },
            { character: '𝜄', latexCommand: '\\iota' },
            { character: 'κ', latexCommand: '\\kappa' },
            { character: 'Λ', latexCommand: '\\Lambda' },
            { character: 'λ', latexCommand: '\\lambda' },
            { character: 'µ', latexCommand: '\\mu' },
            { character: 'Ξ', latexCommand: '\\Xi' },
            { character: 'ξ', latexCommand: '\\xi' },
            { character: '∏', latexCommand: '\\Pi' },
            { character: 'ρ', latexCommand: '\\rho' },
            { character: '∑', latexCommand: '\\Sigma' },
            { character: 'σ', latexCommand: '\\sigma' },
            { character: 'τ', latexCommand: '\\tau' },
            { character: 'Υ', latexCommand: '\\Upsilon' },
            { character: 'υ', latexCommand: '\\upsilon' },
            { character: 'Φ', latexCommand: '\\Phi' },
            { character: 'Ф', latexCommand: '\\phi' },
            { character: 'χ', latexCommand: '\\chi' },
            { character: 'Ψ', latexCommand: '\\Psi' },
            { character: 'ψ', latexCommand: '\\psi' },
            { character: 'Ω', latexCommand: '\\Omega' },
            { character: 'ω', latexCommand: '\\omega' },
            { character: '∂', latexCommand: '\\partial' }
        ]
    },
    {
        label: 'Algebra',
        characters: [
            { character: '≠', latexCommand: '\\neq', popular: true },
            { character: '≈', latexCommand: '\\approx', popular: true },
            { character: '≤', latexCommand: '\\leq', popular: true },
            { character: '≥', latexCommand: '\\geq' },
            { character: '∼', latexCommand: '\\sim' },
            { character: '≡', latexCommand: '\\equiv' },
            { character: '≢' }, // \nequiv or \not\equiv
            { character: '∘', latexCommand: '\\circ' },
            { character: '…', latexCommand: '\\ldots' }
        ]
    },
    {
        label: 'Geometria ja vektorioppi',
        characters: [
            { character: '∠', latexCommand: '\\angle', popular: true },
            { character: '→', latexCommand: '\\rightarrow', popular: true },
            { character: '⇅', popular: true  },
            { character: '↑', latexCommand: '\\uparrow' },
            { character: '↓', latexCommand: '\\downarrow' },
            { character: '↔', latexCommand: '\\leftrightarrow' },
            { character: '⊥', latexCommand: '\\perp'},
            { character: '‖', latexCommand: '\\parallel'},
            { character: '⇌' } // \rightleftharpoons
        ]
    },
    {
        label: 'Logiikka ja joukko-oppi',
        characters: [
            { character: '⇒', latexCommand: '\\Rightarrow', popular: true },
            { character: '⇔', latexCommand: '\\Leftrightarrow', popular: true },
            { character: '∃', latexCommand: '\\exists', popular: true },
            { character: '∀', latexCommand: '\\forall', popular: true },
            { character: 'ℝ', popular: true },
            { character: 'ℕ' },
            { character: 'ℤ' },
            { character: 'ℚ' },
            { character: '∩', latexCommand: '\\cap' },
            { character: '∪', latexCommand: '\\cup' },
            { character: '∖', latexCommand: '\\setminus' },
            { character: '⊂', latexCommand: '\\subset' },
            { character: '⊄', latexCommand: '\\notsubset' },
            { character: '∈', latexCommand: '\\in' },
            { character: '∉', latexCommand: '\\notin' },
            { character: '∅', latexCommand: '\\empty' },
            { character: '∧', latexCommand: '\\and' },
            { character: '∨', latexCommand: '\\or' },
            { character: '¬' }
        ]
    }
]
<commit_msg>Add sign used in kennokaavio (|) <commit_after>module.exports = [
    {
        label: 'Perusmerit ja kreikkalaiset aakkoset',
        characters: [
            { character: '°', popular: true },
            { character: '·', latexCommand: '\\cdot', popular: true },
            { character: '±', latexCommand: '\\pm', popular: true },
            { character: '∞', latexCommand: '\\infty', popular: true },
            { character: '²', latexCommand: '^2', popular: true },
            { character: '³', latexCommand: '^3', popular: true },
            { character: '½', latexCommand: '1/2', popular: true },
            { character: '⅓', latexCommand: '1/3', popular: true },
            { character: 'π', latexCommand: '\\pi', popular: true },
            { character: 'α', latexCommand: '\\alpha', popular: true },
            { character: 'β', latexCommand: '\\beta', popular: true  },
            { character: 'Γ', latexCommand: '\\Gamma' },
            { character: 'γ', latexCommand: '\\gamma' },
            { character: 'Δ', latexCommand: '\\Delta' },
            { character: 'δ', latexCommand: '\\delta' },
            { character: 'ε', latexCommand: '\\varepsilon' },
            { character: 'ζ', latexCommand: '\\zeta' },
            { character: 'η', latexCommand: '\\eta' },
            { character: 'Θ', latexCommand: '\\Theta' },
            { character: 'ϑ', latexCommand: '\\vartheta' },
            { character: '𝜄', latexCommand: '\\iota' },
            { character: 'κ', latexCommand: '\\kappa' },
            { character: 'Λ', latexCommand: '\\Lambda' },
            { character: 'λ', latexCommand: '\\lambda' },
            { character: 'µ', latexCommand: '\\mu' },
            { character: 'Ξ', latexCommand: '\\Xi' },
            { character: 'ξ', latexCommand: '\\xi' },
            { character: '∏', latexCommand: '\\Pi' },
            { character: 'ρ', latexCommand: '\\rho' },
            { character: '∑', latexCommand: '\\Sigma' },
            { character: 'σ', latexCommand: '\\sigma' },
            { character: 'τ', latexCommand: '\\tau' },
            { character: 'Υ', latexCommand: '\\Upsilon' },
            { character: 'υ', latexCommand: '\\upsilon' },
            { character: 'Φ', latexCommand: '\\Phi' },
            { character: 'Ф', latexCommand: '\\phi' },
            { character: 'χ', latexCommand: '\\chi' },
            { character: 'Ψ', latexCommand: '\\Psi' },
            { character: 'ψ', latexCommand: '\\psi' },
            { character: 'Ω', latexCommand: '\\Omega' },
            { character: 'ω', latexCommand: '\\omega' },
            { character: '∂', latexCommand: '\\partial' }
        ]
    },
    {
        label: 'Algebra',
        characters: [
            { character: '≠', latexCommand: '\\neq', popular: true },
            { character: '≈', latexCommand: '\\approx', popular: true },
            { character: '≤', latexCommand: '\\leq', popular: true },
            { character: '≥', latexCommand: '\\geq' },
            { character: '∼', latexCommand: '\\sim' },
            { character: '≡', latexCommand: '\\equiv' },
            { character: '≢' }, // \nequiv or \not\equiv
            { character: '∘', latexCommand: '\\circ' },
            { character: '…', latexCommand: '\\ldots' },
            { character: '|' }
        ]
    },
    {
        label: 'Geometria ja vektorioppi',
        characters: [
            { character: '∠', latexCommand: '\\angle', popular: true },
            { character: '→', latexCommand: '\\rightarrow', popular: true },
            { character: '⇅', popular: true  },
            { character: '↑', latexCommand: '\\uparrow' },
            { character: '↓', latexCommand: '\\downarrow' },
            { character: '↔', latexCommand: '\\leftrightarrow' },
            { character: '⊥', latexCommand: '\\perp'},
            { character: '‖', latexCommand: '\\parallel'},
            { character: '⇌' } // \rightleftharpoons
        ]
    },
    {
        label: 'Logiikka ja joukko-oppi',
        characters: [
            { character: '⇒', latexCommand: '\\Rightarrow', popular: true },
            { character: '⇔', latexCommand: '\\Leftrightarrow', popular: true },
            { character: '∃', latexCommand: '\\exists', popular: true },
            { character: '∀', latexCommand: '\\forall', popular: true },
            { character: 'ℝ', popular: true },
            { character: 'ℕ' },
            { character: 'ℤ' },
            { character: 'ℚ' },
            { character: '∩', latexCommand: '\\cap' },
            { character: '∪', latexCommand: '\\cup' },
            { character: '∖', latexCommand: '\\setminus' },
            { character: '⊂', latexCommand: '\\subset' },
            { character: '⊄', latexCommand: '\\notsubset' },
            { character: '∈', latexCommand: '\\in' },
            { character: '∉', latexCommand: '\\notin' },
            { character: '∅', latexCommand: '\\empty' },
            { character: '∧', latexCommand: '\\and' },
            { character: '∨', latexCommand: '\\or' },
            { character: '¬' }
        ]
    }
]
<|endoftext|>


<commit_before>module.exports = [
    { character: '°' },
    { character: '≡', latexCommand: '\\equiv' },
    { character: '≢' }, // \nequiv or \not\equiv
    { character: '⌐' }, // \backneg
    { character: '×', latexCommand: '\\times' },
    { character: '÷', latexCommand: '\\div' },
    { character: '·', latexCommand: '\\cdot' },
    { character: '«' }, // \guillemotleft
    { character: '»' }, // \guillemotright
    { character: '…', latexCommand: '\\dots' },
    { character: '¬', latexCommand: '\\neg' },
    { character: '≅', latexCommand: '\\cong' },
    { character: '≈', latexCommand: '\\approx' },
    { character: '∼', latexCommand: '\\sim' },
    { character: '‹' }, // \guilsinglleft
    { character: '›' }, // \guilsinglright
    { character: '‰' }, // \permil, \textpertenthousand or \textperthousand
    { character: '¹', latexCommand: '^1' },
    { character: '²', latexCommand: '^2' },
    { character: '³', latexCommand: '^3' },
    { character: '½', latexCommand: '1/2' },
    { character: '¼', latexCommand: '1/4' },
    { character: '¾', latexCommand: '3/4' },
    { character: '←', latexCommand: '\\leftarrow' },
    { character: '↑', latexCommand: '\\uparrow' },
    { character: '→', latexCommand: '\\rightarrow' },
    { character: '↓', latexCommand: '\\downarrow' },
    { character: '↔', latexCommand: '\\leftrightarrow' },
    { character: '↕', latexCommand: '\\updownarrow' },
    { character: '↨' }, // \vertical
    { character: '⇐', latexCommand: '\\Leftarrow' },
    { character: '⇒', latexCommand: '\\Rightarrow' },
    { character: '⇌' }, // \rightleftharpoons
    { character: '≠', latexCommand: '\\neq' },
    { character: '∅', latexCommand: '\\empty' },
    { character: '∞', latexCommand: '\\infty' },
    { character: '±', latexCommand: '\\pm' },
    { character: '∓', latexCommand: '\\mp' },
    { character: '≤', latexCommand: '\\leq' },
    { character: '≥', latexCommand: '\\geq' },
    { character: 'µ', latexCommand: '\\mu' },
    { character: '∂', latexCommand: '\\partial' },
    { character: '∑', latexCommand: '\\Sigma' },
    { character: '∏', latexCommand: '\\Pi' },
    { character: 'Ω', latexCommand: '\\Omega' },
    { character: 'Δ', latexCommand: '\\Delta' },
    { character: '𝜄', latexCommand: '\\iota' },
    { character: 'Ð' }, // \Eth
    { character: 'ð' }, // \eth
    { character: 'Þ' }, // \thorn
    { character: 'þ' }, // \Thorn
    { character: 'Γ', latexCommand: '\\Gamma' },
    { character: 'Θ', latexCommand: '\\Theta' },
    { character: 'Φ', latexCommand: '\\Phi' },
    { character: 'α', latexCommand: '\\alpha' },
    { character: 'δ', latexCommand: '\\delta' },
    { character: 'ε', latexCommand: '\\varepsilon' },
    { character: 'σ', latexCommand: '\\sigma' },
    { character: 'τ', latexCommand: '\\tau' },
    { character: 'Ω', latexCommand: '\\Omega' },
    { character: 'ω', latexCommand: '\\omega' },
    { character: 'Д' }, // \cyrd
    { character: 'π', latexCommand: '\\pi' },
    { character: 'Ф', latexCommand: '\\phi' },
    { character: '∈', latexCommand: '\\in' },
    { character: '∉', latexCommand: '\\notin' },
    { character: '∋', latexCommand: '\\ni' },
    { character: '⊂', latexCommand: '\\subset' },
    { character: '⊃', latexCommand: '\\supset' },
    { character: '∩', latexCommand: '\\cap' },
    { character: '∪', latexCommand: '\\cup' },
    { character: '∖', latexCommand: '\\setminus' },
    { character: '∠', latexCommand: '\\angle' },
    { character: '∧', latexCommand: '\\and' },
    { character: '∨', latexCommand: '\\or' },
    { character: '∀', latexCommand: '\\forall' },
    { character: '∃', latexCommand: '\\exists' },
    { character: '∄', latexCommand: '\\nexists' },
    { character: '△', latexCommand: '\\triangle' },
    { character: '⊥', latexCommand: '\\perp' },
    { character: '‖', latexCommand: '\\parallel' },
    { character: 'ℕ', latexCommand: '\\N' },
    { character: 'ℤ', latexCommand: '\\Z' },
    { character: 'ℚ', latexCommand: '\\Q' },
    { character: 'ℝ', latexCommand: '\\R' },
    { character: 'ℂ', latexCommand: '\\C' },
    { character: 'ℙ', latexCommand: '\\P' },
    { character: '∘', latexCommand: '\\circ' }
]
<commit_msg>Remove number group symbols from symbol list;<commit_after>module.exports = [
    { character: '°' },
    { character: '≡', latexCommand: '\\equiv' },
    { character: '≢' }, // \nequiv or \not\equiv
    { character: '⌐' }, // \backneg
    { character: '×', latexCommand: '\\times' },
    { character: '÷', latexCommand: '\\div' },
    { character: '·', latexCommand: '\\cdot' },
    { character: '«' }, // \guillemotleft
    { character: '»' }, // \guillemotright
    { character: '…', latexCommand: '\\dots' },
    { character: '¬', latexCommand: '\\neg' },
    { character: '≅', latexCommand: '\\cong' },
    { character: '≈', latexCommand: '\\approx' },
    { character: '∼', latexCommand: '\\sim' },
    { character: '‹' }, // \guilsinglleft
    { character: '›' }, // \guilsinglright
    { character: '‰' }, // \permil, \textpertenthousand or \textperthousand
    { character: '¹', latexCommand: '^1' },
    { character: '²', latexCommand: '^2' },
    { character: '³', latexCommand: '^3' },
    { character: '½', latexCommand: '1/2' },
    { character: '¼', latexCommand: '1/4' },
    { character: '¾', latexCommand: '3/4' },
    { character: '←', latexCommand: '\\leftarrow' },
    { character: '↑', latexCommand: '\\uparrow' },
    { character: '→', latexCommand: '\\rightarrow' },
    { character: '↓', latexCommand: '\\downarrow' },
    { character: '↔', latexCommand: '\\leftrightarrow' },
    { character: '↕', latexCommand: '\\updownarrow' },
    { character: '↨' }, // \vertical
    { character: '⇐', latexCommand: '\\Leftarrow' },
    { character: '⇒', latexCommand: '\\Rightarrow' },
    { character: '⇌' }, // \rightleftharpoons
    { character: '≠', latexCommand: '\\neq' },
    { character: '∅', latexCommand: '\\empty' },
    { character: '∞', latexCommand: '\\infty' },
    { character: '±', latexCommand: '\\pm' },
    { character: '∓', latexCommand: '\\mp' },
    { character: '≤', latexCommand: '\\leq' },
    { character: '≥', latexCommand: '\\geq' },
    { character: 'µ', latexCommand: '\\mu' },
    { character: '∂', latexCommand: '\\partial' },
    { character: '∑', latexCommand: '\\Sigma' },
    { character: '∏', latexCommand: '\\Pi' },
    { character: 'Ω', latexCommand: '\\Omega' },
    { character: 'Δ', latexCommand: '\\Delta' },
    { character: '𝜄', latexCommand: '\\iota' },
    { character: 'Ð' }, // \Eth
    { character: 'ð' }, // \eth
    { character: 'Þ' }, // \thorn
    { character: 'þ' }, // \Thorn
    { character: 'Γ', latexCommand: '\\Gamma' },
    { character: 'Θ', latexCommand: '\\Theta' },
    { character: 'Φ', latexCommand: '\\Phi' },
    { character: 'α', latexCommand: '\\alpha' },
    { character: 'δ', latexCommand: '\\delta' },
    { character: 'ε', latexCommand: '\\varepsilon' },
    { character: 'σ', latexCommand: '\\sigma' },
    { character: 'τ', latexCommand: '\\tau' },
    { character: 'Ω', latexCommand: '\\Omega' },
    { character: 'ω', latexCommand: '\\omega' },
    { character: 'Д' }, // \cyrd
    { character: 'π', latexCommand: '\\pi' },
    { character: 'Ф', latexCommand: '\\phi' },
    { character: '∈', latexCommand: '\\in' },
    { character: '∉', latexCommand: '\\notin' },
    { character: '∋', latexCommand: '\\ni' },
    { character: '⊂', latexCommand: '\\subset' },
    { character: '⊃', latexCommand: '\\supset' },
    { character: '∩', latexCommand: '\\cap' },
    { character: '∪', latexCommand: '\\cup' },
    { character: '∖', latexCommand: '\\setminus' },
    { character: '∠', latexCommand: '\\angle' },
    { character: '∧', latexCommand: '\\and' },
    { character: '∨', latexCommand: '\\or' },
    { character: '∀', latexCommand: '\\forall' },
    { character: '∃', latexCommand: '\\exists' },
    { character: '∄', latexCommand: '\\nexists' },
    { character: '△', latexCommand: '\\triangle' },
    { character: '⊥', latexCommand: '\\perp' },
    { character: '‖', latexCommand: '\\parallel' },
    { character: '∘', latexCommand: '\\circ' }
]
<|endoftext|>


<commit_before>module.exports = [
    {
        label: 'Perusmerit ja kreikkalaiset aakkoset',
        characters: [
            { character: '°', popular: true },
            { character: '·', latexCommand: '\\cdot', popular: true },
            { character: '±', latexCommand: '\\pm', popular: true },
            { character: '∞', latexCommand: '\\infty', popular: true },
            { character: '²', latexCommand: '^2', popular: true },
            { character: '³', latexCommand: '^3', popular: true },
            { character: '½', latexCommand: '1/2', popular: true },
            { character: '⅓', latexCommand: '1/3', popular: true },
            { character: 'π', latexCommand: '\\pi', popular: true },
            { character: 'α', latexCommand: '\\alpha', popular: true },
            { character: 'β', latexCommand: '\\beta', popular: true  },
            { character: 'Γ', latexCommand: '\\Gamma' },
            { character: 'γ', latexCommand: '\\gamma' },
            { character: 'Δ', latexCommand: '\\Delta' },
            { character: 'δ', latexCommand: '\\delta' },
            { character: 'ε', latexCommand: '\\varepsilon' },
            { character: 'ζ', latexCommand: '\\zeta' },
            { character: 'η', latexCommand: '\\eta' },
            { character: 'Θ', latexCommand: '\\Theta' },
            { character: 'ϑ', latexCommand: '\\vartheta' },
            { character: '𝜄', latexCommand: '\\iota' },
            { character: 'κ', latexCommand: '\\kappa' },
            { character: 'Λ', latexCommand: '\\Lambda' },
            { character: 'λ', latexCommand: '\\lambda' },
            { character: 'µ', latexCommand: '\\mu' },
            { character: 'Ξ', latexCommand: '\\Xi' },
            { character: 'ξ', latexCommand: '\\xi' },
            { character: '∏', latexCommand: '\\Pi' },
            { character: 'ρ', latexCommand: '\\rho' },
            { character: '∑', latexCommand: '\\Sigma' },
            { character: 'σ', latexCommand: '\\sigma' },
            { character: 'τ', latexCommand: '\\tau' },
            { character: 'Υ', latexCommand: '\\Upsilon' },
            { character: 'υ', latexCommand: '\\upsilon' },
            { character: 'Φ', latexCommand: '\\Phi' },
            { character: 'Ф', latexCommand: '\\phi' },
            { character: 'χ', latexCommand: '\\chi' },
            { character: 'Ψ', latexCommand: '\\Psi' },
            { character: 'ψ', latexCommand: '\\psi' },
            { character: 'Ω', latexCommand: '\\Omega' },
            { character: 'ω', latexCommand: '\\omega' },
            { character: '∂', latexCommand: '\\partial' },
            { character: 'φ', latexCommand: '\\varphi' }
        ]
    },
    {
        label: 'Algebra',
        characters: [
            { character: '≠', latexCommand: '\\neq', popular: true },
            { character: '≈', latexCommand: '\\approx', popular: true },
            { character: '≤', latexCommand: '\\leq', popular: true },
            { character: '≥', latexCommand: '\\geq' },
            { character: '∼', latexCommand: '\\sim' },
            { character: '≡', latexCommand: '\\equiv' },
            { character: '≢' }, // \nequiv or \not\equiv
            { character: '∘', latexCommand: '\\circ' },
            { character: '…', latexCommand: '\\ldots' }
        ]
    },
    {
        label: 'Geometria ja vektorioppi',
        characters: [
            { character: '∠', latexCommand: '\\angle', popular: true },
            { character: '→', latexCommand: '\\rightarrow', popular: true },
            { character: '⇅', popular: true  },
            { character: '↑', latexCommand: '\\uparrow' },
            { character: '↓', latexCommand: '\\downarrow' },
            { character: '↔', latexCommand: '\\leftrightarrow' },
            { character: '⊥', latexCommand: '\\perp'},
            { character: '‖', latexCommand: '\\parallel'},
            { character: '⇌' }, // \rightleftharpoons
            { character: '|' } // \pipe
        ]
    },
    {
        label: 'Logiikka ja joukko-oppi',
        characters: [
            { character: '⇒', latexCommand: '\\Rightarrow', popular: true },
            { character: '⇔', latexCommand: '\\Leftrightarrow', popular: true },
            { character: '∃', latexCommand: '\\exists', popular: true },
            { character: '∀', latexCommand: '\\forall', popular: true },
            { character: 'ℝ', popular: true },
            { character: 'ℕ' },
            { character: 'ℤ' },
            { character: 'ℚ' },
            { character: '∩', latexCommand: '\\cap' },
            { character: '∪', latexCommand: '\\cup' },
            { character: '∖', latexCommand: '\\setminus' },
            { character: '⊂', latexCommand: '\\subset' },
            { character: '⊄', latexCommand: '\\notsubset' },
            { character: '∈', latexCommand: '\\in' },
            { character: '∉', latexCommand: '\\notin' },
            { character: '∅', latexCommand: '\\empty' },
            { character: '∧', latexCommand: '\\and' },
            { character: '∨', latexCommand: '\\or' },
            { character: '¬' }
        ]
    }
]
<commit_msg>Add propto character<commit_after>module.exports = [
    {
        label: 'Perusmerit ja kreikkalaiset aakkoset',
        characters: [
            { character: '°', popular: true },
            { character: '·', latexCommand: '\\cdot', popular: true },
            { character: '±', latexCommand: '\\pm', popular: true },
            { character: '∞', latexCommand: '\\infty', popular: true },
            { character: '²', latexCommand: '^2', popular: true },
            { character: '³', latexCommand: '^3', popular: true },
            { character: '½', latexCommand: '1/2', popular: true },
            { character: '⅓', latexCommand: '1/3', popular: true },
            { character: 'π', latexCommand: '\\pi', popular: true },
            { character: 'α', latexCommand: '\\alpha', popular: true },
            { character: 'β', latexCommand: '\\beta', popular: true  },
            { character: 'Γ', latexCommand: '\\Gamma' },
            { character: 'γ', latexCommand: '\\gamma' },
            { character: 'Δ', latexCommand: '\\Delta' },
            { character: 'δ', latexCommand: '\\delta' },
            { character: 'ε', latexCommand: '\\varepsilon' },
            { character: 'ζ', latexCommand: '\\zeta' },
            { character: 'η', latexCommand: '\\eta' },
            { character: 'Θ', latexCommand: '\\Theta' },
            { character: 'ϑ', latexCommand: '\\vartheta' },
            { character: '𝜄', latexCommand: '\\iota' },
            { character: 'κ', latexCommand: '\\kappa' },
            { character: 'Λ', latexCommand: '\\Lambda' },
            { character: 'λ', latexCommand: '\\lambda' },
            { character: 'µ', latexCommand: '\\mu' },
            { character: 'Ξ', latexCommand: '\\Xi' },
            { character: 'ξ', latexCommand: '\\xi' },
            { character: '∏', latexCommand: '\\Pi' },
            { character: 'ρ', latexCommand: '\\rho' },
            { character: '∑', latexCommand: '\\Sigma' },
            { character: 'σ', latexCommand: '\\sigma' },
            { character: 'τ', latexCommand: '\\tau' },
            { character: 'Υ', latexCommand: '\\Upsilon' },
            { character: 'υ', latexCommand: '\\upsilon' },
            { character: 'Φ', latexCommand: '\\Phi' },
            { character: 'Ф', latexCommand: '\\phi' },
            { character: 'χ', latexCommand: '\\chi' },
            { character: 'Ψ', latexCommand: '\\Psi' },
            { character: 'ψ', latexCommand: '\\psi' },
            { character: 'Ω', latexCommand: '\\Omega' },
            { character: 'ω', latexCommand: '\\omega' },
            { character: '∂', latexCommand: '\\partial' },
            { character: 'φ', latexCommand: '\\varphi' }
        ]
    },
    {
        label: 'Algebra',
        characters: [
            { character: '≠', latexCommand: '\\neq', popular: true },
            { character: '≈', latexCommand: '\\approx', popular: true },
            { character: '≤', latexCommand: '\\leq', popular: true },
            { character: '≥', latexCommand: '\\geq' },
            { character: '∼', latexCommand: '\\sim' },
            { character: '≡', latexCommand: '\\equiv' },
            { character: '≢' }, // \nequiv or \not\equiv
            { character: '∘', latexCommand: '\\circ' },
            { character: '…', latexCommand: '\\ldots' },
            { character: '∝', latexCommand: '\\propto' }
        ]
    },
    {
        label: 'Geometria ja vektorioppi',
        characters: [
            { character: '∠', latexCommand: '\\angle', popular: true },
            { character: '→', latexCommand: '\\rightarrow', popular: true },
            { character: '⇅', popular: true  },
            { character: '↑', latexCommand: '\\uparrow' },
            { character: '↓', latexCommand: '\\downarrow' },
            { character: '↔', latexCommand: '\\leftrightarrow' },
            { character: '⊥', latexCommand: '\\perp'},
            { character: '‖', latexCommand: '\\parallel'},
            { character: '⇌' }, // \rightleftharpoons
            { character: '|' } // \pipe
        ]
    },
    {
        label: 'Logiikka ja joukko-oppi',
        characters: [
            { character: '⇒', latexCommand: '\\Rightarrow', popular: true },
            { character: '⇔', latexCommand: '\\Leftrightarrow', popular: true },
            { character: '∃', latexCommand: '\\exists', popular: true },
            { character: '∀', latexCommand: '\\forall', popular: true },
            { character: 'ℝ', popular: true },
            { character: 'ℕ' },
            { character: 'ℤ' },
            { character: 'ℚ' },
            { character: '∩', latexCommand: '\\cap' },
            { character: '∪', latexCommand: '\\cup' },
            { character: '∖', latexCommand: '\\setminus' },
            { character: '⊂', latexCommand: '\\subset' },
            { character: '⊄', latexCommand: '\\notsubset' },
            { character: '∈', latexCommand: '\\in' },
            { character: '∉', latexCommand: '\\notin' },
            { character: '∅', latexCommand: '\\empty' },
            { character: '∧', latexCommand: '\\and' },
            { character: '∨', latexCommand: '\\or' },
            { character: '¬' }
        ]
    }
]
<|endoftext|>


<commit_before>#!/usr/bin/env node

/*
    ___ usage ___ en_US ___
    usage: prolific <pipeline> <program>

        -i, --inherit   <number>        file handles to inherit
        -s, --siblings                  run monitors as siblings
        -I, --ipc                       enable Node.js IPC forwarding
            --configuration <string>    base configuration JSON or environment variable
            --help                      display this message

    ___ $ ___ en_US ___

        log is required:
            the `--log` address and port is a required argument

        port is not an integer:
            the `--log` port must be an integer

    ___ . ___
*/

// Node.js API.
var assert = require('assert')
var children = require('child_process')
var path = require('path')
var url = require('url')

var cadence = require('cadence')
var inherit = require('prolific.inherit')
var ipc = require('prolific.ipc')
var delta = require('delta')
var exit = require('./exit')

var Thereafter = require('thereafter')

// Construct a prolific pipeline from a configuration.
var Pipeline = require('prolific.pipeline')

var Destructible = require('destructible')
var Synchronous = require('prolific.consolidator/synchronous')
var Asynchronous = require('prolific.consolidator/asynchronous')

// Lots of struggle as I reconsider how to manage errors, return values and the
// this pointer.

var direct = cadence(function (async, program, inheritance, configuration, argv) {
    var destructible = new Destructible('direct')
    program.on('shutdown', destructible.destroy.bind(destructible))

    var thereafter = new Thereafter
    destructible.addDestructor('thereafter', thereafter, 'cancel')

    var pipeline = new Pipeline(configuration)
    var synchronous = new Synchronous
    var asynchronous = new Asynchronous(pipeline.processors[0])

    async([function () {
        pipeline.close(async())
    }], function () {
        pipeline.open(async())
    }, function () {
        var child = children.spawn(argv.shift(), argv, { stdio: inheritance.stdio })
        ipc(program.ultimate.ipc, process, child)
        destructible.addDestructor('kill', child, 'kill')
        synchronous.addConsumer('0', asynchronous)
// This is a strange useage where the method is going to return an error, it
// will be the error used to report.
        thereafter.run(function (ready) {
            cadence(function (async) {
                async(function () {
                    delta(async()).ee(child).on('exit')
                    ready.unlatch()
                }, function (exitCode, signal) {
                    return exit(exitCode, signal)
                })
            })(destructible.monitor('child'))
        })
        thereafter.run(function (ready) {
            cadence(function (async) {
                synchronous.listen(child.stderr, program.stderr, async())
                ready.unlatch()
            })(destructible.monitor('synchronous'))
        })
        thereafter.run(function (ready) {
// It does not seem likely that you'll get an error out of the child pipes and
// if you do, it is uncommon enough that there is not much more to do for now
// besides crash. Can't do anything if the synchronous pipe crashes, so maybe
// only worry about the asynchronous pipe. Ah, so, we could just shutdown when
// we see the asynchronous pipe error, or maybe even finish for any reason.
            cadence(function (async) {
                async([function () {
                    child.kill()
                }], function () {
                    asynchronous.listen(child.stdio[inheritance.fd], async())
                    ready.unlatch()
                })
            })(destructible.monitor('asynchronous'))
        })
// TODO Considered giving `Destructible.completed` an array of gathered
// responses. That way you could use it as the response from the function.
// Instead I'm calling it here first, except that isn't how Cadence works.
// Cadence returns the first error caught. Thus, the callback we create above
// could catch an error, that error would be returned from this function,
// swallowing a nicer hung interrupt exception.
//
// Two directions to go. First, make Cadence return errors in the order
// specified by their callback creation. Then this can move to the top it is
// always the first error returns. Second, make destructible gather responeses
// from monitor and return them in completed. But, the moment I try to work that
// out in Destructible, it gets confusing. Where to keep them. How to signal you
// want them gathered. Always gather? What about rescue. Don't gather, right?
//
// If you do use some sort of gathered completed, then you can't really make too
// much use of the returns. Also, you'll note that all of the above will
// rethrow their errors, so this timeout is not actually going to cause a hang
// to timeout.
//
// Hello, again. Considering how it worked before. There was this orthoginal
// timer that would raise an uncatchable exception and crash the program because
// the inability to quit is more of a programmer error than a run time error.
// Here I'm trying to funnel that exception to the completed latch. When using
// the Cadence-friendly Destructible invocation this will mean that we're adding
// a wait for many sub-Cadences.
        destructible.completed(5000, async())
    }, function () {
        asynchronous.exit()
    })
})

var siblings = cadence(function (async, program, inheritance, configuration, argv) {
    var destructible = new Destructible('siblings')
    program.on('shutdown', destructible.destroy.bind(destructible))

    var thereafter = new Thereafter
    var child = children.spawn(argv.shift(), argv, { stdio: inheritance.stdio })

    var synchronous = new Synchronous(child.stderr, program.stderr)
    destructible.addDestructor('thereafter', thereafter, 'cancel')

    var monitors = 0
    thereafter.run(function (ready) {
        cadence(function (async) {
            async(function () {
                delta(async()).ee(child).on('exit')
                ready.unlatch()
            }, function (exitCode, signal) {
                return exit(exitCode, signal)
            })
        })(destructible.monitor('child'))
    })
    child.on('message', function (message) {
        if (message.module != 'prolific' || message.method != 'monitor') {
            return
        }
        var pid = message.pid
        var monitor = children.spawn('node', [
            path.join(__dirname, 'monitor.bin.js')
        ], {
            stdio: [ 0, 1, 2, 'pipe', 'ipc' ]
        })
        monitor.once('message', function (message) {
            console.log('ONCE message', message)
            // TODO Maybe there's a race here.
            child.send({
                module: 'prolific',
                method: 'socket',
                pid: pid
            }, monitor.stdio[3])
            synchronous.addConsumer(pid, {
                consume: function (chunk) {
                    monitor.send({
                        module: 'prolific',
                        method: 'chunk',
                        body: chunk
                    })
                }
            })
        })
        destructible.addDestructor([ 'kill', monitors ], monitor, 'kill')
        thereafter.run(function (ready) {
            cadence(function (async) {
                async(function () {
                    delta(async()).ee(monitor).on('exit')
                    ready.unlatch()
                }, function (errorCode, signal) {
                    assert(signal == 'SIGTERM' || errorCode == 0)
                    return []
                })
            })(destructible.monitor([ 'monitor', monitors ]))
        })
        monitors++
    })
    thereafter.run(function (ready) {
        synchronous.listen(child.stderr, program.stderr, destructible.monitor('synchronous'))
        ready.unlatch()
    })
    destructible.completed(10000, async())
})

require('arguable')(module, require('cadence')(function (async, program) {
    var configure = require('./configure')

    if (program.ultimate.siblings) {
        program.ultimate.ipc = true
    }

    program.helpIf(program.ultimate.help)

    var configuration = configure(program.env, program.ultimate.configuration)

    // TODO `inherit` skips write fd if cluster
    var inheritance = inherit(program)
    configuration.fd = program.ultimate.siblings ? 'IPC' : inheritance.fd
    async(function () {
        Pipeline.parse(program, configuration, async())
    }, function (configuration, argv) {
        process.env.PROLIFIC_CONFIGURATION = JSON.stringify(configuration)
        if (program.ultimate.siblings) {
            siblings(program, inheritance, configuration, argv, async())
        } else {
            direct(program, inheritance, configuration, argv, async())
        }
    })
}))
<commit_msg>Note when destroyed.<commit_after>#!/usr/bin/env node

/*
    ___ usage ___ en_US ___
    usage: prolific <pipeline> <program>

        -i, --inherit   <number>        file handles to inherit
        -s, --siblings                  run monitors as siblings
        -I, --ipc                       enable Node.js IPC forwarding
            --configuration <string>    base configuration JSON or environment variable
            --help                      display this message

    ___ $ ___ en_US ___

        log is required:
            the `--log` address and port is a required argument

        port is not an integer:
            the `--log` port must be an integer

    ___ . ___
*/

// Node.js API.
var assert = require('assert')
var children = require('child_process')
var path = require('path')
var url = require('url')

var cadence = require('cadence')
var inherit = require('prolific.inherit')
var ipc = require('prolific.ipc')
var delta = require('delta')
var exit = require('./exit')

var Thereafter = require('thereafter')

// Construct a prolific pipeline from a configuration.
var Pipeline = require('prolific.pipeline')

var Destructible = require('destructible')
var Synchronous = require('prolific.consolidator/synchronous')
var Asynchronous = require('prolific.consolidator/asynchronous')

// Lots of struggle as I reconsider how to manage errors, return values and the
// this pointer.

var direct = cadence(function (async, program, inheritance, configuration, argv) {
    var destructible = new Destructible('direct')
    program.on('shutdown', destructible.destroy.bind(destructible))

    var thereafter = new Thereafter
    destructible.addDestructor('thereafter', thereafter, 'cancel')

    var pipeline = new Pipeline(configuration)
    var synchronous = new Synchronous
    var asynchronous = new Asynchronous(pipeline.processors[0])

    async([function () {
        pipeline.close(async())
    }], function () {
        pipeline.open(async())
    }, function () {
        var child = children.spawn(argv.shift(), argv, { stdio: inheritance.stdio })
        ipc(program.ultimate.ipc, process, child)
        destructible.addDestructor('kill', child, 'kill')
        synchronous.addConsumer('0', asynchronous)
// This is a strange useage where the method is going to return an error, it
// will be the error used to report.
        thereafter.run(function (ready) {
            cadence(function (async) {
                async(function () {
                    delta(async()).ee(child).on('exit')
                    ready.unlatch()
                }, function (exitCode, signal) {
                    return exit(exitCode, signal)
                })
            })(destructible.monitor('child'))
        })
        thereafter.run(function (ready) {
            cadence(function (async) {
                synchronous.listen(child.stderr, program.stderr, async())
                ready.unlatch()
            })(destructible.monitor('synchronous'))
        })
        thereafter.run(function (ready) {
// It does not seem likely that you'll get an error out of the child pipes and
// if you do, it is uncommon enough that there is not much more to do for now
// besides crash. Can't do anything if the synchronous pipe crashes, so maybe
// only worry about the asynchronous pipe. Ah, so, we could just shutdown when
// we see the asynchronous pipe error, or maybe even finish for any reason.
            cadence(function (async) {
                async([function () {
                    child.kill()
                }], function () {
                    asynchronous.listen(child.stdio[inheritance.fd], async())
                    ready.unlatch()
                })
            })(destructible.monitor('asynchronous'))
        })
// TODO Considered giving `Destructible.completed` an array of gathered
// responses. That way you could use it as the response from the function.
// Instead I'm calling it here first, except that isn't how Cadence works.
// Cadence returns the first error caught. Thus, the callback we create above
// could catch an error, that error would be returned from this function,
// swallowing a nicer hung interrupt exception.
//
// Two directions to go. First, make Cadence return errors in the order
// specified by their callback creation. Then this can move to the top it is
// always the first error returns. Second, make destructible gather responeses
// from monitor and return them in completed. But, the moment I try to work that
// out in Destructible, it gets confusing. Where to keep them. How to signal you
// want them gathered. Always gather? What about rescue. Don't gather, right?
//
// If you do use some sort of gathered completed, then you can't really make too
// much use of the returns. Also, you'll note that all of the above will
// rethrow their errors, so this timeout is not actually going to cause a hang
// to timeout.
//
// Hello, again. Considering how it worked before. There was this orthoginal
// timer that would raise an uncatchable exception and crash the program because
// the inability to quit is more of a programmer error than a run time error.
// Here I'm trying to funnel that exception to the completed latch. When using
// the Cadence-friendly Destructible invocation this will mean that we're adding
// a wait for many sub-Cadences.
        destructible.completed(5000, async())
    }, function () {
        asynchronous.exit()
    })
})

var siblings = cadence(function (async, program, inheritance, configuration, argv) {
    var destructible = new Destructible('siblings')
    program.on('shutdown', destructible.destroy.bind(destructible))

    var thereafter = new Thereafter
    var child = children.spawn(argv.shift(), argv, { stdio: inheritance.stdio })

    var synchronous = new Synchronous(child.stderr, program.stderr)
    destructible.addDestructor('thereafter', thereafter, 'cancel')
    destructible.addDestructor('DEBUG TODO', function () {
        console.log('DESTROYED!!!')
    })

    var monitors = 0
    thereafter.run(function (ready) {
        cadence(function (async) {
            async(function () {
                delta(async()).ee(child).on('exit')
                ready.unlatch()
            }, function (exitCode, signal) {
                return exit(exitCode, signal)
            })
        })(destructible.monitor('child'))
    })
    child.on('message', function (message) {
        if (message.module != 'prolific' || message.method != 'monitor') {
            return
        }
        var pid = message.pid
        var monitor = children.spawn('node', [
            path.join(__dirname, 'monitor.bin.js')
        ], {
            stdio: [ 0, 1, 2, 'pipe', 'ipc' ]
        })
        monitor.once('message', function (message) {
            console.log('ONCE message', message)
            // TODO Maybe there's a race here.
            child.send({
                module: 'prolific',
                method: 'socket',
                pid: pid
            }, monitor.stdio[3])
            synchronous.addConsumer(pid, {
                consume: function (chunk) {
                    monitor.send({
                        module: 'prolific',
                        method: 'chunk',
                        body: chunk
                    })
                }
            })
        })
        destructible.addDestructor([ 'kill', monitors ], monitor, 'kill')
        thereafter.run(function (ready) {
            cadence(function (async) {
                async(function () {
                    delta(async()).ee(monitor).on('exit')
                    ready.unlatch()
                }, function (errorCode, signal) {
                    assert(signal == 'SIGTERM' || errorCode == 0)
                    return []
                })
            })(destructible.monitor([ 'monitor', monitors ]))
        })
        monitors++
    })
    thereafter.run(function (ready) {
        synchronous.listen(child.stderr, program.stderr, destructible.monitor('synchronous'))
        ready.unlatch()
    })
    destructible.completed(10000, async())
})

require('arguable')(module, require('cadence')(function (async, program) {
    var configure = require('./configure')

    if (program.ultimate.siblings) {
        program.ultimate.ipc = true
    }

    program.helpIf(program.ultimate.help)

    var configuration = configure(program.env, program.ultimate.configuration)

    // TODO `inherit` skips write fd if cluster
    var inheritance = inherit(program)
    configuration.fd = program.ultimate.siblings ? 'IPC' : inheritance.fd
    async(function () {
        Pipeline.parse(program, configuration, async())
    }, function (configuration, argv) {
        process.env.PROLIFIC_CONFIGURATION = JSON.stringify(configuration)
        if (program.ultimate.siblings) {
            siblings(program, inheritance, configuration, argv, async())
        } else {
            direct(program, inheritance, configuration, argv, async())
        }
    })
}))
<|endoftext|>


<commit_before>/* global JsonRoutes:true */

var Fiber = Npm.require('fibers');
var connect = Npm.require('connect');
var connectRoute = Npm.require('connect-route');

JsonRoutes = {};

WebApp.connectHandlers.use(connect.urlencoded());
WebApp.connectHandlers.use(connect.json());
WebApp.connectHandlers.use(connect.query());

// Handler for adding middleware before an endpoint (JsonRoutes.middleWare
// is just for legacy reasons). Also serves as a namespace for middleware
// packages to declare their middleware functions.
JsonRoutes.Middleware = JsonRoutes.middleWare = connect();
WebApp.connectHandlers.use(JsonRoutes.Middleware);

// List of all defined JSON API endpoints
JsonRoutes.routes = [];

// Save reference to router for later
var connectRouter;

// Register as a middleware
WebApp.connectHandlers.use(connectRoute(function (router) {
  connectRouter = router;
}));

// Error middleware must be added last, to catch errors from prior middleware.
// That's why we cache them and then add after startup.
var errorMiddlewares = [];
JsonRoutes.ErrorMiddleware = {
  use: function () {
    errorMiddlewares.push(arguments);
  },
};

Meteor.startup(function () {
  _.each(errorMiddlewares, function (errorMiddleware) {
    WebApp.connectHandlers.use.apply(WebApp.connectHandlers, errorMiddleware);
  });

  errorMiddlewares = [];
});

JsonRoutes.add = function (method, path, handler) {
  // Make sure path starts with a slash
  if (path[0] !== '/') {
    path = '/' + path;
  }

  // Add to list of known endpoints
  JsonRoutes.routes.push({
    method: method,
    path: path,
  });

  connectRouter[method.toLowerCase()](path, function (req, res, next) {
    // Set headers on response
    setHeaders(res, responseHeaders);
    Fiber(function () {
      try {
        handler(req, res, next);
      } catch (error) {
        next(error);
      }
    }).run();
  });
};

var responseHeaders = {
  'Cache-Control': 'no-store',
  Pragma: 'no-cache',
};

JsonRoutes.setResponseHeaders = function (headers) {
  responseHeaders = headers;
};

/**
 * Sets the response headers, status code, and body, and ends it.
 * The JSON response will be pretty printed if NODE_ENV is `development`.
 *
 * @param {Object} res Response object
 * @param {Object} [options]
 * @param {Number} [options.code] HTTP status code. Default is 200.
 * @param {Object} [options.headers] Dictionary of headers.
 * @param {Object|Array|null|undefined} [options.data] The object to
 *   stringify as the response. If `null`, the response will be "null".
 *   If `undefined`, there will be no response body.
 */
JsonRoutes.sendResult = function (res, options) {
  options = options || {};

  // We've already set global headers on response, but if they
  // pass in more here, we set those.
  if (options.headers) setHeaders(res, options.headers);

  // Set status code on response
  res.statusCode = options.code || 200;

  // Set response body
  writeJsonToBody(res, options.data);

  // Send the response
  res.end();
};

function setHeaders(res, headers) {
  _.each(headers, function (value, key) {
    res.setHeader(key, value);
  });
}

function writeJsonToBody(res, json) {
  if (json !== undefined) {
    var shouldPrettyPrint = (process.env.NODE_ENV === 'development');
    var spacer = shouldPrettyPrint ? 2 : null;
    res.setHeader('Content-type', 'application/json');
    res.write(JSON.stringify(json, null, spacer));
  }
}
<commit_msg>Increase request size limit to 50mb<commit_after>/* global JsonRoutes:true */

var Fiber = Npm.require('fibers');
var connect = Npm.require('connect');
var connectRoute = Npm.require('connect-route');

JsonRoutes = {};

WebApp.connectHandlers.use(connect.urlencoded({limit: '50mb'})); //Override default request size
WebApp.connectHandlers.use(connect.json({limit: '50mb'})); //Override default request size
WebApp.connectHandlers.use(connect.query());

// Handler for adding middleware before an endpoint (JsonRoutes.middleWare
// is just for legacy reasons). Also serves as a namespace for middleware
// packages to declare their middleware functions.
JsonRoutes.Middleware = JsonRoutes.middleWare = connect();
WebApp.connectHandlers.use(JsonRoutes.Middleware);

// List of all defined JSON API endpoints
JsonRoutes.routes = [];

// Save reference to router for later
var connectRouter;

// Register as a middleware
WebApp.connectHandlers.use(connectRoute(function (router) {
  connectRouter = router;
}));

// Error middleware must be added last, to catch errors from prior middleware.
// That's why we cache them and then add after startup.
var errorMiddlewares = [];
JsonRoutes.ErrorMiddleware = {
  use: function () {
    errorMiddlewares.push(arguments);
  },
};

Meteor.startup(function () {
  _.each(errorMiddlewares, function (errorMiddleware) {
    WebApp.connectHandlers.use.apply(WebApp.connectHandlers, errorMiddleware);
  });

  errorMiddlewares = [];
});

JsonRoutes.add = function (method, path, handler) {
  // Make sure path starts with a slash
  if (path[0] !== '/') {
    path = '/' + path;
  }

  // Add to list of known endpoints
  JsonRoutes.routes.push({
    method: method,
    path: path,
  });

  connectRouter[method.toLowerCase()](path, function (req, res, next) {
    // Set headers on response
    setHeaders(res, responseHeaders);
    Fiber(function () {
      try {
        handler(req, res, next);
      } catch (error) {
        next(error);
      }
    }).run();
  });
};

var responseHeaders = {
  'Cache-Control': 'no-store',
  Pragma: 'no-cache',
};

JsonRoutes.setResponseHeaders = function (headers) {
  responseHeaders = headers;
};

/**
 * Sets the response headers, status code, and body, and ends it.
 * The JSON response will be pretty printed if NODE_ENV is `development`.
 *
 * @param {Object} res Response object
 * @param {Object} [options]
 * @param {Number} [options.code] HTTP status code. Default is 200.
 * @param {Object} [options.headers] Dictionary of headers.
 * @param {Object|Array|null|undefined} [options.data] The object to
 *   stringify as the response. If `null`, the response will be "null".
 *   If `undefined`, there will be no response body.
 */
JsonRoutes.sendResult = function (res, options) {
  options = options || {};

  // We've already set global headers on response, but if they
  // pass in more here, we set those.
  if (options.headers) setHeaders(res, options.headers);

  // Set status code on response
  res.statusCode = options.code || 200;

  // Set response body
  writeJsonToBody(res, options.data);

  // Send the response
  res.end();
};

function setHeaders(res, headers) {
  _.each(headers, function (value, key) {
    res.setHeader(key, value);
  });
}

function writeJsonToBody(res, json) {
  if (json !== undefined) {
    var shouldPrettyPrint = (process.env.NODE_ENV === 'development');
    var spacer = shouldPrettyPrint ? 2 : null;
    res.setHeader('Content-type', 'application/json');
    res.write(JSON.stringify(json, null, spacer));
  }
}
<|endoftext|>


<commit_before>var path = require('path');
var OFF = 0;
var ERROR = 2;

module.exports = {
  env: {
    es6: true,
    browser: true,
    node: true,
  },
  overrides: [
    {
      files: ['*.spec.js'],
      env: {
        es6: true,
        browser: true,
        node: true,
        jest: true,
      },
    },
    {
      files: ['*.int.js'],
      env: {
        jest: true,
      },
      globals: {
        page: true,
        browser: true,
        context: true,
        jestPuppeteer: true,
      },
    },
  ],
  parserOptions: {
    sourceType: 'module',
    ecmaVersion: 2018,
    ecmaFeatures: {
      impliedStrict: true,
    },
  },
  globals: {
    __version: true,
    __filename: true,
    __copyrightYear: true,
    __kolibriModuleName: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:vue/recommended',
    'plugin:import/errors',
    'plugin:import/warnings',
    'prettier',
  ],
  plugins: ['import', 'vue', 'kolibri'],
  settings: {
    'import/resolver': {
      [path.resolve(path.join(path.dirname(__filename), './lib/alias_import_resolver.js'))]: {
        extensions: ['.js', '.vue'],
      },
    },
  },
  rules: {
    'comma-style': ERROR,
    'max-len': [
      ERROR,
      100,
      {
        ignoreStrings: true,
        ignoreTemplateLiterals: true,
        ignoreUrls: true,
      },
    ],
    'vue/attribute-hyphenation': [ERROR, 'never'],
    'vue/require-default-prop': OFF,
    'vue/html-self-closing': [
      ERROR,
      {
        html: {
          void: 'never',
          normal: 'never',
          component: 'always',
        },
        svg: 'always',
        math: 'always',
      },
    ],
    'vue/max-attributes-per-line': [
      ERROR,
      {
        singleline: 5,
        multiline: {
          max: 1,
          allowFirstLine: false,
        },
      },
    ],
    'vue/html-closing-bracket-newline': [
      ERROR,
      {
        singleline: 'never',
        multiline: 'always',
      },
    ],
    'vue/component-name-in-template-casing': [
      ERROR,
      'PascalCase',
      {
        ignores: [
          'mat-svg',
          'file-svg',
          'component',
          'transition',
          'transition-group',
          'router-link',
          'router-view',
        ],
      },
    ],
    'vue/no-spaces-around-equal-signs-in-attribute': ERROR,
    'vue/multiline-html-element-content-newline': [
      ERROR,
      {
        // because of compatibility with our custom HTMLHint rule
        // enforcing top-level content surrounded by one empty line
        allowEmptyLines: true,
      },
    ],
    'vue/order-in-components': [
      ERROR,
      {
        order: [
          'el',
          'name',
          'metaInfo',
          'parent',
          'functional',
          ['delimiters', 'comments'],
          ['components', 'directives', 'filters'],
          'extends',
          'mixins',
          'inheritAttrs',
          'model',
          ['props', 'propsData'],
          'data',
          'computed',
          'watch',
          'beforeRouteEnter',
          'beforeRouteUpdate',
          'beforeRouteLeave',
          'LIFECYCLE_HOOKS',
          'methods',
          ['template', 'render'],
          'renderError',
          '$trs',
        ],
      },
    ],
    'vue/html-indent': [
      ERROR,
      2, // Base indent spaces
      {
        'attribute': 1,
        'baseIndent': 1,
        'closeBracket': 0,
        'alignAttributesVertically': true,
      }
    ],
    'vue/static-class-names-order': ERROR,
    'vue/no-deprecated-scope-attribute': ERROR,
    'vue/valid-v-bind-sync': ERROR,
    // TODO Enforcing these rules requires bigger refactor
    // 'vue/no-deprecated-slot-attribute': ERROR,
    // 'vue/no-deprecated-slot-scope-attribute': ERROR,
    'vue/valid-v-slot': ERROR,

    // ESLint rules for interpolated JS
    'vue/object-curly-spacing': [ERROR, 'always'],
    'vue/eqeqeq': [ERROR, 'always'],
    'vue/key-spacing': [ERROR, { afterColon: true }],
    'vue/space-infix-ops': ERROR,
    'vue/space-unary-ops': ERROR,

    'import/first': ERROR,
    'import/no-duplicates': ERROR,
    'import/newline-after-import': ERROR,
    'import/order': ERROR,

    // Custom vue rules
    'kolibri/vue-filename-and-component-name-match': ERROR,
    'kolibri/vue-component-registration-casing': ERROR,
    'kolibri/vue-no-unused-properties': ERROR,
    'kolibri/vue-no-unused-vuex-properties': ERROR,
    'kolibri/vue-no-unused-methods': ERROR,
    'kolibri/vue-no-unused-vuex-methods': ERROR,
    'kolibri/vue-watch-no-string': ERROR,
    'kolibri/vue-no-unused-translations': ERROR,
    'kolibri/vue-no-undefined-string-uses': ERROR,
  },
};
<commit_msg>loosen max-len linting of vue files<commit_after>var path = require('path');
var OFF = 0;
var ERROR = 2;

module.exports = {
  env: {
    es6: true,
    browser: true,
    node: true,
  },
  overrides: [
    {
      files: ['*.spec.js'],
      env: {
        es6: true,
        browser: true,
        node: true,
        jest: true,
      },
    },
    {
      files: ['*.int.js'],
      env: {
        jest: true,
      },
      globals: {
        page: true,
        browser: true,
        context: true,
        jestPuppeteer: true,
      },
    },
  ],
  parserOptions: {
    sourceType: 'module',
    ecmaVersion: 2018,
    ecmaFeatures: {
      impliedStrict: true,
    },
  },
  globals: {
    __version: true,
    __filename: true,
    __copyrightYear: true,
    __kolibriModuleName: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:vue/recommended',
    'plugin:import/errors',
    'plugin:import/warnings',
    'prettier',
  ],
  plugins: ['import', 'vue', 'kolibri'],
  settings: {
    'import/resolver': {
      [path.resolve(path.join(path.dirname(__filename), './lib/alias_import_resolver.js'))]: {
        extensions: ['.js', '.vue'],
      },
    },
  },
  rules: {
    'comma-style': ERROR,
    'max-len': [
      ERROR,
      100,
      {
        ignoreStrings: true,
        ignoreTemplateLiterals: true,
        ignoreUrls: true,
        ignoreTrailingComments: true,
      },
    ],
    'vue/max-len': [
      ERROR,
      {
        code: 100,
        template: 100,
        comments: 100,
        ignoreUrls: true,
        ignoreStrings: true,
        ignoreTemplateLiterals: true,
        ignoreHTMLTextContents: true,
        ignoreTrailingComments: true,
      },

    ],
    'vue/attribute-hyphenation': [ERROR, 'never'],
    'vue/require-default-prop': OFF,
    'vue/html-self-closing': [
      ERROR,
      {
        html: {
          void: 'never',
          normal: 'never',
          component: 'always',
        },
        svg: 'always',
        math: 'always',
      },
    ],
    'vue/max-attributes-per-line': [
      ERROR,
      {
        singleline: 5,
        multiline: {
          max: 1,
          allowFirstLine: false,
        },
      },
    ],
    'vue/html-closing-bracket-newline': [
      ERROR,
      {
        singleline: 'never',
        multiline: 'always',
      },
    ],
    'vue/component-name-in-template-casing': [
      ERROR,
      'PascalCase',
      {
        ignores: [
          'mat-svg',
          'file-svg',
          'component',
          'transition',
          'transition-group',
          'router-link',
          'router-view',
        ],
      },
    ],
    'vue/no-spaces-around-equal-signs-in-attribute': ERROR,
    'vue/multiline-html-element-content-newline': [
      ERROR,
      {
        // because of compatibility with our custom HTMLHint rule
        // enforcing top-level content surrounded by one empty line
        allowEmptyLines: true,
      },
    ],
    'vue/order-in-components': [
      ERROR,
      {
        order: [
          'el',
          'name',
          'metaInfo',
          'parent',
          'functional',
          ['delimiters', 'comments'],
          ['components', 'directives', 'filters'],
          'extends',
          'mixins',
          'inheritAttrs',
          'model',
          ['props', 'propsData'],
          'data',
          'computed',
          'watch',
          'beforeRouteEnter',
          'beforeRouteUpdate',
          'beforeRouteLeave',
          'LIFECYCLE_HOOKS',
          'methods',
          ['template', 'render'],
          'renderError',
          '$trs',
        ],
      },
    ],
    'vue/html-indent': [
      ERROR,
      2, // Base indent spaces
      {
        'attribute': 1,
        'baseIndent': 1,
        'closeBracket': 0,
        'alignAttributesVertically': true,
      }
    ],
    'vue/static-class-names-order': ERROR,
    'vue/no-deprecated-scope-attribute': ERROR,
    'vue/valid-v-bind-sync': ERROR,
    // TODO Enforcing these rules requires bigger refactor
    // 'vue/no-deprecated-slot-attribute': ERROR,
    // 'vue/no-deprecated-slot-scope-attribute': ERROR,
    'vue/valid-v-slot': ERROR,

    // ESLint rules for interpolated JS
    'vue/object-curly-spacing': [ERROR, 'always'],
    'vue/eqeqeq': [ERROR, 'always'],
    'vue/key-spacing': [ERROR, { afterColon: true }],
    'vue/space-infix-ops': ERROR,
    'vue/space-unary-ops': ERROR,

    'import/first': ERROR,
    'import/no-duplicates': ERROR,
    'import/newline-after-import': ERROR,
    'import/order': ERROR,

    // Custom vue rules
    'kolibri/vue-filename-and-component-name-match': ERROR,
    'kolibri/vue-component-registration-casing': ERROR,
    'kolibri/vue-no-unused-properties': ERROR,
    'kolibri/vue-no-unused-vuex-properties': ERROR,
    'kolibri/vue-no-unused-methods': ERROR,
    'kolibri/vue-no-unused-vuex-methods': ERROR,
    'kolibri/vue-watch-no-string': ERROR,
    'kolibri/vue-no-unused-translations': ERROR,
    'kolibri/vue-no-undefined-string-uses': ERROR,
  },
};
<|endoftext|>