<commit_before>/*
Copyright 2019 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import dis from '../../../dispatcher';
import EditorModel from '../../../editor/model';
import {
    htmlSerializeIfNeeded,
    textSerialize,
    containsEmote,
    stripEmoteCommand,
    unescapeMessage,
} from '../../../editor/serialize';
import {CommandPartCreator} from '../../../editor/parts';
import BasicMessageComposer from "./BasicMessageComposer";
import ReplyPreview from "./ReplyPreview";
import RoomViewStore from '../../../stores/RoomViewStore';
import ReplyThread from "../elements/ReplyThread";
import {parseEvent} from '../../../editor/deserialize';
import {findEditableEvent} from '../../../utils/EventUtils';
import SendHistoryManager from "../../../SendHistoryManager";
import {processCommandInput} from '../../../SlashCommands';
import * as sdk from '../../../index';
import Modal from '../../../Modal';
import {_t, _td} from '../../../languageHandler';
import ContentMessages from '../../../ContentMessages';
import {Key} from "../../../Keyboard";
import MatrixClientContext from "../../../contexts/MatrixClientContext";

function addReplyToMessageContent(content, repliedToEvent, permalinkCreator) {
    const replyContent = ReplyThread.makeReplyMixIn(repliedToEvent);
    Object.assign(content, replyContent);

    // Part of Replies fallback support - prepend the text we're sending
    // with the text we're replying to
    const nestedReply = ReplyThread.getNestedReplyText(repliedToEvent, permalinkCreator);
    if (nestedReply) {
        if (content.formatted_body) {
            content.formatted_body = nestedReply.html + content.formatted_body;
        }
        content.body = nestedReply.body + content.body;
    }
}

function createMessageContent(model, permalinkCreator) {
    const isEmote = containsEmote(model);
    if (isEmote) {
        model = stripEmoteCommand(model);
    }
    model = unescapeMessage(model);
    const repliedToEvent = RoomViewStore.getQuotingEvent();

    const body = textSerialize(model);
    const content = {
        msgtype: isEmote ? "m.emote" : "m.text",
        body: body,
    };
    const formattedBody = htmlSerializeIfNeeded(model, {forceHTML: !!repliedToEvent});
    if (formattedBody) {
        content.format = "org.matrix.custom.html";
        content.formatted_body = formattedBody;
    }

    if (repliedToEvent) {
        addReplyToMessageContent(content, repliedToEvent, permalinkCreator);
    }

    return content;
}

export default class SendMessageComposer extends React.Component {
    static propTypes = {
        room: PropTypes.object.isRequired,
        placeholder: PropTypes.string,
        permalinkCreator: PropTypes.object.isRequired,
    };

    static contextType = MatrixClientContext;

    constructor(props) {
        super(props);
        this.model = null;
        this._editorRef = null;
        this.currentlyComposedEditorState = null;
    }

    _setEditorRef = ref => {
        this._editorRef = ref;
    };

    _onKeyDown = (event) => {
        // ignore any keypress while doing IME compositions
        if (this._editorRef.isComposing(event)) {
            return;
        }
        const hasModifier = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
        if (event.key === Key.ENTER && !hasModifier) {
            this._sendMessage();
            event.preventDefault();
        } else if (event.key === Key.ARROW_UP) {
            this.onVerticalArrow(event, true);
        } else if (event.key === Key.ARROW_DOWN) {
            this.onVerticalArrow(event, false);
        }
    }

    onVerticalArrow(e, up) {
        if (e.ctrlKey || e.shiftKey || e.metaKey) return;

        const shouldSelectHistory = e.altKey;
        const shouldEditLastMessage = !e.altKey && up && !RoomViewStore.getQuotingEvent();

        if (shouldSelectHistory) {
            // Try select composer history
            const selected = this.selectSendHistory(up);
            if (selected) {
                // We're selecting history, so prevent the key event from doing anything else
                e.preventDefault();
            }
        } else if (shouldEditLastMessage) {
            // selection must be collapsed and caret at start
            if (this._editorRef.isSelectionCollapsed() && this._editorRef.isCaretAtStart()) {
                const editEvent = findEditableEvent(this.props.room, false);
                if (editEvent) {
                    // We're selecting history, so prevent the key event from doing anything else
                    e.preventDefault();
                    dis.dispatch({
                        action: 'edit_event',
                        event: editEvent,
                    });
                }
            }
        }
    }

    // we keep sent messages/commands in a separate history (separate from undo history)
    // so you can alt+up/down in them
    selectSendHistory(up) {
        const delta = up ? -1 : 1;
        // True if we are not currently selecting history, but composing a message
        if (this.sendHistoryManager.currentIndex === this.sendHistoryManager.history.length) {
            // We can't go any further - there isn't any more history, so nop.
            if (!up) {
                return;
            }
            this.currentlyComposedEditorState = this.model.serializeParts();
        } else if (this.sendHistoryManager.currentIndex + delta === this.sendHistoryManager.history.length) {
            // True when we return to the message being composed currently
            this.model.reset(this.currentlyComposedEditorState);
            this.sendHistoryManager.currentIndex = this.sendHistoryManager.history.length;
            return;
        }
        const serializedParts = this.sendHistoryManager.getItem(delta);
        if (serializedParts) {
            this.model.reset(serializedParts);
            this._editorRef.focus();
        }
    }

    _isSlashCommand() {
        const parts = this.model.parts;
        const firstPart = parts[0];
        if (firstPart) {
            if (firstPart.type === "command") {
                return true;
            }
            // be extra resilient when somehow the AutocompleteWrapperModel or
            // CommandPartCreator fails to insert a command part, so we don't send
            // a command as a message
            if (firstPart.text.startsWith("/") && (firstPart.type === "plain" || firstPart.type === "pill-candidate")) {
                return true;
            }
        }
        return false;
    }

    async _runSlashCommand() {
        const commandText = this.model.parts.reduce((text, part) => {
            // use mxid to textify user pills in a command
            if (part.type === "user-pill") {
                return text + part.resourceId;
            }
            return text + part.text;
        }, "");
        const cmd = processCommandInput(this.props.room.roomId, commandText);

        if (cmd) {
            let error = cmd.error;
            if (cmd.promise) {
                try {
                    await cmd.promise;
                } catch (err) {
                    error = err;
                }
            }
            if (error) {
                console.error("Command failure: %s", error);
                const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
                // assume the error is a server error when the command is async
                const isServerError = !!cmd.promise;
                const title = isServerError ? _td("Server error") : _td("Command error");

                let errText;
                if (typeof error === 'string') {
                    errText = error;
                } else if (error.message) {
                    errText = error.message;
                } else {
                    errText = _t("Server unavailable, overloaded, or something else went wrong.");
                }

                Modal.createTrackedDialog(title, '', ErrorDialog, {
                    title: _t(title),
                    description: errText,
                });
            } else {
                console.log("Command success.");
            }
        }
    }

    _sendMessage() {
        if (this.model.isEmpty) {
            return;
        }
        if (!containsEmote(this.model) && this._isSlashCommand()) {
            this._runSlashCommand();
        } else {
            const isReply = !!RoomViewStore.getQuotingEvent();
            const {roomId} = this.props.room;
            const content = createMessageContent(this.model, this.props.permalinkCreator);
            this.context.sendMessage(roomId, content);
            if (isReply) {
                // Clear reply_to_event as we put the message into the queue
                // if the send fails, retry will handle resending.
                dis.dispatch({
                    action: 'reply_to_event',
                    event: null,
                });
            }
        }
        this.sendHistoryManager.save(this.model);
        // clear composer
        this.model.reset([]);
        this._editorRef.clearUndoHistory();
        this._editorRef.focus();
        this._clearStoredEditorState();
    }

    componentDidMount() {
        this._editorRef.getEditableRootNode().addEventListener("paste", this._onPaste, true);
    }

    componentWillUnmount() {
        dis.unregister(this.dispatcherRef);
        this._editorRef.getEditableRootNode().removeEventListener("paste", this._onPaste, true);
    }

    componentWillMount() {
        const partCreator = new CommandPartCreator(this.props.room, this.context);
        const parts = this._restoreStoredEditorState(partCreator) || [];
        this.model = new EditorModel(parts, partCreator);
        this.dispatcherRef = dis.register(this.onAction);
        this.sendHistoryManager = new SendHistoryManager(this.props.room.roomId, 'mx_cider_composer_history_');
    }

    get _editorStateKey() {
        return `cider_editor_state_${this.props.room.roomId}`;
    }

    _clearStoredEditorState() {
        localStorage.removeItem(this._editorStateKey);
    }

    _restoreStoredEditorState(partCreator) {
        const json = localStorage.getItem(this._editorStateKey);
        if (json) {
            const serializedParts = JSON.parse(json);
            const parts = serializedParts.map(p => partCreator.deserializePart(p));
            return parts;
        }
    }

    _saveStoredEditorState = () => {
        if (this.model.isEmpty) {
            this._clearStoredEditorState();
        } else {
            localStorage.setItem(this._editorStateKey, JSON.stringify(this.model.serializeParts()));
        }
    }

    onAction = (payload) => {
        switch (payload.action) {
            case 'reply_to_event':
            case 'focus_composer':
                this._editorRef && this._editorRef.focus();
                break;
            case 'insert_mention':
                this._insertMention(payload.user_id);
                break;
            case 'quote':
                this._insertQuotedMessage(payload.event);
                break;
        }
    };

    _insertMention(userId) {
        const {model} = this;
        const {partCreator} = model;
        const member = this.props.room.getMember(userId);
        const displayName = member ?
            member.rawDisplayName : userId;
        const caret = this._editorRef.getCaret();
        const position = model.positionForOffset(caret.offset, caret.atNodeEnd);
        const insertIndex = position.index + 1;
        const parts = partCreator.createMentionParts(insertIndex, displayName, userId);
        model.transform(() => {
            const addedLen = model.insert(parts, position);
            return model.positionForOffset(caret.offset + addedLen, true);
        });
        // refocus on composer, as we just clicked "Mention"
        this._editorRef && this._editorRef.focus();
    }

    _insertQuotedMessage(event) {
        const {model} = this;
        const {partCreator} = model;
        const quoteParts = parseEvent(event, partCreator, { isQuotedMessage: true });
        // add two newlines
        quoteParts.push(partCreator.newline());
        quoteParts.push(partCreator.newline());
        model.transform(() => {
            const addedLen = model.insert(quoteParts, model.positionForOffset(0));
            return model.positionForOffset(addedLen, true);
        });
        // refocus on composer, as we just clicked "Quote"
        this._editorRef && this._editorRef.focus();
    }

    _onPaste = (event) => {
        const {clipboardData} = event;
        if (clipboardData.files.length) {
            // This actually not so much for 'files' as such (at time of writing
            // neither chrome nor firefox let you paste a plain file copied
            // from Finder) but more images copied from a different website
            // / word processor etc.
            ContentMessages.sharedInstance().sendContentListToRoom(
                Array.from(clipboardData.files), this.props.room.roomId, this.context,
            );
        }
    }

    render() {
        return (

                    <ReplyPreview permalinkCreator={this.props.permalinkCreator} />

                <BasicMessageComposer
                    ref={this._setEditorRef}
                    model={this.model}
                    room={this.props.room}
                    label={this.props.placeholder}
                    placeholder={this.props.placeholder}
                    onChange={this._saveStoredEditorState}
                />

        );
    }
}
<commit_msg>Fix index for _insertMention<commit_after>/*
Copyright 2019 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import dis from '../../../dispatcher';
import EditorModel from '../../../editor/model';
import {
    htmlSerializeIfNeeded,
    textSerialize,
    containsEmote,
    stripEmoteCommand,
    unescapeMessage,
} from '../../../editor/serialize';
import {CommandPartCreator} from '../../../editor/parts';
import BasicMessageComposer from "./BasicMessageComposer";
import ReplyPreview from "./ReplyPreview";
import RoomViewStore from '../../../stores/RoomViewStore';
import ReplyThread from "../elements/ReplyThread";
import {parseEvent} from '../../../editor/deserialize';
import {findEditableEvent} from '../../../utils/EventUtils';
import SendHistoryManager from "../../../SendHistoryManager";
import {processCommandInput} from '../../../SlashCommands';
import * as sdk from '../../../index';
import Modal from '../../../Modal';
import {_t, _td} from '../../../languageHandler';
import ContentMessages from '../../../ContentMessages';
import {Key} from "../../../Keyboard";
import MatrixClientContext from "../../../contexts/MatrixClientContext";

function addReplyToMessageContent(content, repliedToEvent, permalinkCreator) {
    const replyContent = ReplyThread.makeReplyMixIn(repliedToEvent);
    Object.assign(content, replyContent);

    // Part of Replies fallback support - prepend the text we're sending
    // with the text we're replying to
    const nestedReply = ReplyThread.getNestedReplyText(repliedToEvent, permalinkCreator);
    if (nestedReply) {
        if (content.formatted_body) {
            content.formatted_body = nestedReply.html + content.formatted_body;
        }
        content.body = nestedReply.body + content.body;
    }
}

function createMessageContent(model, permalinkCreator) {
    const isEmote = containsEmote(model);
    if (isEmote) {
        model = stripEmoteCommand(model);
    }
    model = unescapeMessage(model);
    const repliedToEvent = RoomViewStore.getQuotingEvent();

    const body = textSerialize(model);
    const content = {
        msgtype: isEmote ? "m.emote" : "m.text",
        body: body,
    };
    const formattedBody = htmlSerializeIfNeeded(model, {forceHTML: !!repliedToEvent});
    if (formattedBody) {
        content.format = "org.matrix.custom.html";
        content.formatted_body = formattedBody;
    }

    if (repliedToEvent) {
        addReplyToMessageContent(content, repliedToEvent, permalinkCreator);
    }

    return content;
}

export default class SendMessageComposer extends React.Component {
    static propTypes = {
        room: PropTypes.object.isRequired,
        placeholder: PropTypes.string,
        permalinkCreator: PropTypes.object.isRequired,
    };

    static contextType = MatrixClientContext;

    constructor(props) {
        super(props);
        this.model = null;
        this._editorRef = null;
        this.currentlyComposedEditorState = null;
    }

    _setEditorRef = ref => {
        this._editorRef = ref;
    };

    _onKeyDown = (event) => {
        // ignore any keypress while doing IME compositions
        if (this._editorRef.isComposing(event)) {
            return;
        }
        const hasModifier = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
        if (event.key === Key.ENTER && !hasModifier) {
            this._sendMessage();
            event.preventDefault();
        } else if (event.key === Key.ARROW_UP) {
            this.onVerticalArrow(event, true);
        } else if (event.key === Key.ARROW_DOWN) {
            this.onVerticalArrow(event, false);
        }
    }

    onVerticalArrow(e, up) {
        if (e.ctrlKey || e.shiftKey || e.metaKey) return;

        const shouldSelectHistory = e.altKey;
        const shouldEditLastMessage = !e.altKey && up && !RoomViewStore.getQuotingEvent();

        if (shouldSelectHistory) {
            // Try select composer history
            const selected = this.selectSendHistory(up);
            if (selected) {
                // We're selecting history, so prevent the key event from doing anything else
                e.preventDefault();
            }
        } else if (shouldEditLastMessage) {
            // selection must be collapsed and caret at start
            if (this._editorRef.isSelectionCollapsed() && this._editorRef.isCaretAtStart()) {
                const editEvent = findEditableEvent(this.props.room, false);
                if (editEvent) {
                    // We're selecting history, so prevent the key event from doing anything else
                    e.preventDefault();
                    dis.dispatch({
                        action: 'edit_event',
                        event: editEvent,
                    });
                }
            }
        }
    }

    // we keep sent messages/commands in a separate history (separate from undo history)
    // so you can alt+up/down in them
    selectSendHistory(up) {
        const delta = up ? -1 : 1;
        // True if we are not currently selecting history, but composing a message
        if (this.sendHistoryManager.currentIndex === this.sendHistoryManager.history.length) {
            // We can't go any further - there isn't any more history, so nop.
            if (!up) {
                return;
            }
            this.currentlyComposedEditorState = this.model.serializeParts();
        } else if (this.sendHistoryManager.currentIndex + delta === this.sendHistoryManager.history.length) {
            // True when we return to the message being composed currently
            this.model.reset(this.currentlyComposedEditorState);
            this.sendHistoryManager.currentIndex = this.sendHistoryManager.history.length;
            return;
        }
        const serializedParts = this.sendHistoryManager.getItem(delta);
        if (serializedParts) {
            this.model.reset(serializedParts);
            this._editorRef.focus();
        }
    }

    _isSlashCommand() {
        const parts = this.model.parts;
        const firstPart = parts[0];
        if (firstPart) {
            if (firstPart.type === "command") {
                return true;
            }
            // be extra resilient when somehow the AutocompleteWrapperModel or
            // CommandPartCreator fails to insert a command part, so we don't send
            // a command as a message
            if (firstPart.text.startsWith("/") && (firstPart.type === "plain" || firstPart.type === "pill-candidate")) {
                return true;
            }
        }
        return false;
    }

    async _runSlashCommand() {
        const commandText = this.model.parts.reduce((text, part) => {
            // use mxid to textify user pills in a command
            if (part.type === "user-pill") {
                return text + part.resourceId;
            }
            return text + part.text;
        }, "");
        const cmd = processCommandInput(this.props.room.roomId, commandText);

        if (cmd) {
            let error = cmd.error;
            if (cmd.promise) {
                try {
                    await cmd.promise;
                } catch (err) {
                    error = err;
                }
            }
            if (error) {
                console.error("Command failure: %s", error);
                const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
                // assume the error is a server error when the command is async
                const isServerError = !!cmd.promise;
                const title = isServerError ? _td("Server error") : _td("Command error");

                let errText;
                if (typeof error === 'string') {
                    errText = error;
                } else if (error.message) {
                    errText = error.message;
                } else {
                    errText = _t("Server unavailable, overloaded, or something else went wrong.");
                }

                Modal.createTrackedDialog(title, '', ErrorDialog, {
                    title: _t(title),
                    description: errText,
                });
            } else {
                console.log("Command success.");
            }
        }
    }

    _sendMessage() {
        if (this.model.isEmpty) {
            return;
        }
        if (!containsEmote(this.model) && this._isSlashCommand()) {
            this._runSlashCommand();
        } else {
            const isReply = !!RoomViewStore.getQuotingEvent();
            const {roomId} = this.props.room;
            const content = createMessageContent(this.model, this.props.permalinkCreator);
            this.context.sendMessage(roomId, content);
            if (isReply) {
                // Clear reply_to_event as we put the message into the queue
                // if the send fails, retry will handle resending.
                dis.dispatch({
                    action: 'reply_to_event',
                    event: null,
                });
            }
        }
        this.sendHistoryManager.save(this.model);
        // clear composer
        this.model.reset([]);
        this._editorRef.clearUndoHistory();
        this._editorRef.focus();
        this._clearStoredEditorState();
    }

    componentDidMount() {
        this._editorRef.getEditableRootNode().addEventListener("paste", this._onPaste, true);
    }

    componentWillUnmount() {
        dis.unregister(this.dispatcherRef);
        this._editorRef.getEditableRootNode().removeEventListener("paste", this._onPaste, true);
    }

    componentWillMount() {
        const partCreator = new CommandPartCreator(this.props.room, this.context);
        const parts = this._restoreStoredEditorState(partCreator) || [];
        this.model = new EditorModel(parts, partCreator);
        this.dispatcherRef = dis.register(this.onAction);
        this.sendHistoryManager = new SendHistoryManager(this.props.room.roomId, 'mx_cider_composer_history_');
    }

    get _editorStateKey() {
        return `cider_editor_state_${this.props.room.roomId}`;
    }

    _clearStoredEditorState() {
        localStorage.removeItem(this._editorStateKey);
    }

    _restoreStoredEditorState(partCreator) {
        const json = localStorage.getItem(this._editorStateKey);
        if (json) {
            const serializedParts = JSON.parse(json);
            const parts = serializedParts.map(p => partCreator.deserializePart(p));
            return parts;
        }
    }

    _saveStoredEditorState = () => {
        if (this.model.isEmpty) {
            this._clearStoredEditorState();
        } else {
            localStorage.setItem(this._editorStateKey, JSON.stringify(this.model.serializeParts()));
        }
    }

    onAction = (payload) => {
        switch (payload.action) {
            case 'reply_to_event':
            case 'focus_composer':
                this._editorRef && this._editorRef.focus();
                break;
            case 'insert_mention':
                this._insertMention(payload.user_id);
                break;
            case 'quote':
                this._insertQuotedMessage(payload.event);
                break;
        }
    };

    _insertMention(userId) {
        const {model} = this;
        const {partCreator} = model;
        const member = this.props.room.getMember(userId);
        const displayName = member ?
            member.rawDisplayName : userId;
        const caret = this._editorRef.getCaret();
        const position = model.positionForOffset(caret.offset, caret.atNodeEnd);
        // index is -1 if there are no parts but we only care for if this would be the part in position 0
        const insertIndex = position.index > 0 ? position.index : 0;
        const parts = partCreator.createMentionParts(insertIndex, displayName, userId);
        model.transform(() => {
            const addedLen = model.insert(parts, position);
            return model.positionForOffset(caret.offset + addedLen, true);
        });
        // refocus on composer, as we just clicked "Mention"
        this._editorRef && this._editorRef.focus();
    }

    _insertQuotedMessage(event) {
        const {model} = this;
        const {partCreator} = model;
        const quoteParts = parseEvent(event, partCreator, { isQuotedMessage: true });
        // add two newlines
        quoteParts.push(partCreator.newline());
        quoteParts.push(partCreator.newline());
        model.transform(() => {
            const addedLen = model.insert(quoteParts, model.positionForOffset(0));
            return model.positionForOffset(addedLen, true);
        });
        // refocus on composer, as we just clicked "Quote"
        this._editorRef && this._editorRef.focus();
    }

    _onPaste = (event) => {
        const {clipboardData} = event;
        if (clipboardData.files.length) {
            // This actually not so much for 'files' as such (at time of writing
            // neither chrome nor firefox let you paste a plain file copied
            // from Finder) but more images copied from a different website
            // / word processor etc.
            ContentMessages.sharedInstance().sendContentListToRoom(
                Array.from(clipboardData.files), this.props.room.roomId, this.context,
            );
        }
    }

    render() {
        return (

                    <ReplyPreview permalinkCreator={this.props.permalinkCreator} />

                <BasicMessageComposer
                    ref={this._setEditorRef}
                    model={this.model}
                    room={this.props.room}
                    label={this.props.placeholder}
                    placeholder={this.props.placeholder}
                    onChange={this._saveStoredEditorState}
                />

        );
    }
}
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies
 */

var _ = require('lodash');
var validate = require('./validate');

/**
 * Module exports
 */

module.exports = Schema;

/**
 * Return a clone of 'object' with an additional key 'property' set to 'value'
 *
 * @param {object} object The object to extend
 * @param {string} property Key
 * @param {*} value Value
 * @return {object}
 */

function extend(object, property, value) {
    var clonedObject = _.clone(object);
    clonedObject[property] = value;
    return clonedObject;
}

/**
 * Helpers
 */

function constant(a) {
    return a;
}

function alwaysTrue() {
    return true;
}

function toBoolean(s) {
    return !!s;
}

function toString(s) {
    return s + '';
}

function toNumber(s) {
    return ~~s;
}

/**
 * Transform a Schema's ruleset into a standard format that lists the
 * validators to apply to each field; the sanitizer, if any, to apply to the
 * value before returning; an error message; and whether the value is
 * required.
 *
 * @param {object} rules The rules to transform
 * @return {object}
 */

function transformRules(rules) {
    return _.pairs(rules).map(function(pair) {
        var _splitProperty = pair[0].split('?');
        var property = _splitProperty[0];
        var rule = pair[1];
        var isRequired = _splitProperty.length === 1;
        var parsedRules = {};

        if (_.isFunction(rule)) {
            parsedRules[property] = {
                validators: [rule],
                message: 'Field "' + property + '" is invalid.',
                sanitizer: constant,
                required: isRequired,
            };
        } else if (_.isArray(rule)) {
            var validators = rule.reduce(function filterFunctions(acc, v) {
                if (_.isFunction(v)) {
                    return acc.concat(v);
                }

                return acc;
            }, []);

            parsedRules[property] = {
                validators: validators,
                message: 'Field "' + property + '" is invalid.',
                sanitizer: constant,
                required: isRequired,
            };
        } else if (_.isPlainObject(rule)) {
            parsedRules[property] = {
                validators: rule.validators || [],
                message: rule.message || 'Field "' + property + '" is invalid.',
                sanitizer: rule.sanitizer || constant,
                required: isRequired,
            };
        } else if (rule instanceof Schema) {
            parsedRules[property] = {
                validators: [rule],
                message: 'Field "' + property + '" is invalid.',
                sanitizer: constant,
                required: isRequired,
            };
        } else {
            var san;

            switch (typeof rule) {
                case 'boolean':
                    san = toBoolean;
                    break;
                case 'number':
                    san = toNumber;
                    break;
                case 'string':
                    san = toString;
                    break;
                default:
                    throw new Error('Invalid validator expression');
            }

            parsedRules[property] = {
                validators: [alwaysTrue],
                message: '',
                sanitizer: san,
                require: isRequired,
            };
        }

        return parsedRules;
    }).reduce(_.assign, {});
}

/**
 * Initialize a new schema with the given set of rules:
 *
 *    var personSchema = new Schema({
 *      firstName: Schema.type.String(1, 100),
 *      'middleName?': Schema.type.String(1, 100),
 *      lastName: Schema.type.String(1, 100),
 *      age: Schema.type.Number(1, 125)
 *    });
 *
 * @constructor
 * @param {object} rules
 */

function Schema(rules) {
    this._rules = rules;
}

/**
 * Return the transformed ruleset for this Schema.
 *
 * @return {object}
 */

Schema.prototype.rules = function getRules() {
    return (this._transformedRules = this._transformedRules || transformRules(this._rules));
};

/**
 * Validate the given object against this Schema. Returns an object that
 * describes whether the validation succeeded, a list of errors, if any, and
 * the sanitized object.
 *
 * @param {object} object The object to validate
 * @return {object}
 */

Schema.prototype.test = function(object) {
    var _this = this;
    var rules = _this.rules();
    var extra = Array.prototype.slice.call(arguments, 1);
    var initial = {
        valid: true,
        errors: [],
        object: {},
    };

    var proxiedTestProperty = function proxiedTestProperty(property) {
        return validate.testProperty(rules[property], object, extra, property);
    };

    return Object.keys(rules).map(proxiedTestProperty).reduce(function(acc, result) {
        return {
            valid: acc.valid && result.pass,
            errors: !result.pass ? acc.errors.concat(result.message) : acc.errors,
            object: result.pass && result.field ? extend(acc.object, result.field.name, result.field.value) : acc.object,
        };
    }, initial);
};

/**
 * Expose standard helpers under the Schema namespace.
 */

Schema.type = {
    String: require('./type/string'),
    Number: require('./type/number'),
    Pass: require('./type/pass'),
    Array: require('./type/array'),
};
<commit_msg>Document test splat arguments<commit_after>'use strict';

/**
 * Module dependencies
 */

var _ = require('lodash');
var validate = require('./validate');

/**
 * Module exports
 */

module.exports = Schema;

/**
 * Return a clone of 'object' with an additional key 'property' set to 'value'
 *
 * @param {object} object The object to extend
 * @param {string} property Key
 * @param {*} value Value
 * @return {object}
 */

function extend(object, property, value) {
    var clonedObject = _.clone(object);
    clonedObject[property] = value;
    return clonedObject;
}

/**
 * Helpers
 */

function constant(a) {
    return a;
}

function alwaysTrue() {
    return true;
}

function toBoolean(s) {
    return !!s;
}

function toString(s) {
    return s + '';
}

function toNumber(s) {
    return ~~s;
}

/**
 * Transform a Schema's ruleset into a standard format that lists the
 * validators to apply to each field; the sanitizer, if any, to apply to the
 * value before returning; an error message; and whether the value is
 * required.
 *
 * @param {object} rules The rules to transform
 * @return {object}
 */

function transformRules(rules) {
    return _.pairs(rules).map(function(pair) {
        var _splitProperty = pair[0].split('?');
        var property = _splitProperty[0];
        var rule = pair[1];
        var isRequired = _splitProperty.length === 1;
        var parsedRules = {};

        if (_.isFunction(rule)) {
            parsedRules[property] = {
                validators: [rule],
                message: 'Field "' + property + '" is invalid.',
                sanitizer: constant,
                required: isRequired,
            };
        } else if (_.isArray(rule)) {
            var validators = rule.reduce(function filterFunctions(acc, v) {
                if (_.isFunction(v)) {
                    return acc.concat(v);
                }

                return acc;
            }, []);

            parsedRules[property] = {
                validators: validators,
                message: 'Field "' + property + '" is invalid.',
                sanitizer: constant,
                required: isRequired,
            };
        } else if (_.isPlainObject(rule)) {
            parsedRules[property] = {
                validators: rule.validators || [],
                message: rule.message || 'Field "' + property + '" is invalid.',
                sanitizer: rule.sanitizer || constant,
                required: isRequired,
            };
        } else if (rule instanceof Schema) {
            parsedRules[property] = {
                validators: [rule],
                message: 'Field "' + property + '" is invalid.',
                sanitizer: constant,
                required: isRequired,
            };
        } else {
            var san;

            switch (typeof rule) {
                case 'boolean':
                    san = toBoolean;
                    break;
                case 'number':
                    san = toNumber;
                    break;
                case 'string':
                    san = toString;
                    break;
                default:
                    throw new Error('Invalid validator expression');
            }

            parsedRules[property] = {
                validators: [alwaysTrue],
                message: '',
                sanitizer: san,
                require: isRequired,
            };
        }

        return parsedRules;
    }).reduce(_.assign, {});
}

/**
 * Initialize a new schema with the given set of rules:
 *
 *    var personSchema = new Schema({
 *      firstName: Schema.type.String(1, 100),
 *      'middleName?': Schema.type.String(1, 100),
 *      lastName: Schema.type.String(1, 100),
 *      age: Schema.type.Number(1, 125)
 *    });
 *
 * @constructor
 * @param {object} rules
 */

function Schema(rules) {
    this._rules = rules;
}

/**
 * Return the transformed ruleset for this Schema.
 *
 * @return {object}
 */

Schema.prototype.rules = function getRules() {
    return (this._transformedRules = this._transformedRules || transformRules(this._rules));
};

/**
 * Validate the given object against this Schema. Returns an object that
 * describes whether the validation succeeded, a list of errors, if any, and
 * the sanitized object. Any additional arguments are passed to validators.
 *
 * @param {object} object The object to validate
 * @param {=...*} args Additional arguments to validators
 * @return {object}
 */

Schema.prototype.test = function(object) {
    var _this = this;
    var rules = _this.rules();
    var extra = Array.prototype.slice.call(arguments, 1);
    var initial = {
        valid: true,
        errors: [],
        object: {},
    };

    var proxiedTestProperty = function proxiedTestProperty(property) {
        return validate.testProperty(rules[property], object, extra, property);
    };

    return Object.keys(rules).map(proxiedTestProperty).reduce(function(acc, result) {
        return {
            valid: acc.valid && result.pass,
            errors: !result.pass ? acc.errors.concat(result.message) : acc.errors,
            object: result.pass && result.field ? extend(acc.object, result.field.name, result.field.value) : acc.object,
        };
    }, initial);
};

/**
 * Expose standard helpers under the Schema namespace.
 */

Schema.type = {
    String: require('./type/string'),
    Number: require('./type/number'),
    Pass: require('./type/pass'),
    Array: require('./type/array'),
};
<|endoftext|>


<commit_before>/* global TrelloPowerUp */
var Promise = TrelloPowerUp.Promise;
var t = TrelloPowerUp.iframe();
var formUrl = '';
var gFormUrl = '';
var cardName = '';
var cardShortLink = '';
var userName = '';

// this function we be called once on initial load
// and then called each time something changes
t.render(function(){
  return Promise.all([
    t.get('board', 'shared', 'url'),
    t.card('name','url')
  ])
  .spread(function(savedGFormUrl, cardData){
    if(savedGFormUrl){
      gFormUrl = savedGFormUrl;
    } else {
      document.getElementsById('overlay-message')[0]
      .textContent = 'Please add form url on settings';
    }
    if(cardData){
      cardName = cardData.name;
      cardUrl = cardData.url;
    }
  })
  .then(function(){
    userName = document.getElementsByClassName("js-member-name")[0].textContent;
    formUrl = gFormUrl + "?embedded=true&entry.995291397=" + cardName +
    "&entry.33315152=" + userName +
    "&entry.1600294234" + cardUrl;

    document.getElementsByTagName('iframe')[0].src = formUrl;
  })
});

// close overlay if user clicks outside our content
document.addEventListener('click', function(e) {
  if(e.target.tagName == 'BODY') {
    t.closeOverlay().done();
  }
});

// close overlay if user presses escape key
document.addEventListener('keyup', function(e) {
  if(e.keyCode == 27) {
    t.closeOverlay().done();
  }
});
<commit_msg>fix user name search<commit_after>/* global TrelloPowerUp */
var Promise = TrelloPowerUp.Promise;
var t = TrelloPowerUp.iframe();
var formUrl = '';
var gFormUrl = '';
var cardName = '';
var cardShortLink = '';
var userName = '';

// this function we be called once on initial load
// and then called each time something changes
t.render(function(){
  return Promise.all([
    t.get('board', 'shared', 'url'),
    t.card('name','url')
  ])
  .spread(function(savedGFormUrl, cardData){
    if(savedGFormUrl){
      gFormUrl = savedGFormUrl;
    } else {
      document.getElementById('overlay-message')
      .textContent = 'Please add form url on settings';
    }
    if(cardData){
      cardName = cardData.name;
      cardUrl = cardData.url;
    }
  })
  .then(function(){
    userName = '';
    formUrl = gFormUrl + "?embedded=true&entry.995291397=" + cardName +
    "&entry.33315152=" + userName +
    "&entry.1600294234" + cardUrl;

    document.getElementsByTagName('iframe')[0].src = formUrl;
  })
});

// close overlay if user clicks outside our content
document.addEventListener('click', function(e) {
  if(e.target.tagName == 'BODY') {
    t.closeOverlay().done();
  }
});

// close overlay if user presses escape key
document.addEventListener('keyup', function(e) {
  if(e.keyCode == 27) {
    t.closeOverlay().done();
  }
});
<|endoftext|>


<commit_before>Version = { id: 'be1249e' };
<commit_msg>Bump up version<commit_after>Version = { id: '60b8da7' };
<|endoftext|>


<commit_before>
var spotify = require('../lib/spotify-node-applescript.js');
var expect = require('chai').expect;

describe('Spotify Controller', function(){

    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // Make sure spotify is open before running these tests
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    beforeEach(function(done){
        spotify.playTrack('spotify:track:3AhXZa8sUQht0UEdBJgpGc', function(){
            done();
        });
    });

    after(function(done){
        spotify.pause(function(){
            done();
        });
    });

    it('should return playing track', function(done){
        spotify.getTrack(function(error, track){
            expect(track.artist).to.equal('Bob Dylan');
            expect(track.name).to.equal('Like A Rolling Stone');
            done();
        });
    });

    it('should return player status', function(done){
        spotify.getState(function(error, state){
            expect(state.state).to.equal('playing');
            done();
        });
    });

    it('should pause a track', function(done){
        spotify.pause(function(){
            spotify.getState(function(error, state){
                expect(state.state).to.equal('paused');
                done();
            });
        });
    });

    it('should resume playing a track after pausing', function(done){
        spotify.pause(function(){
            spotify.play(function(){
                spotify.getState(function(error, state){
                    expect(state.state).to.equal('playing');
                    done();
                });
            });
        });
    });

    it('should play and pause a track', function(done){
        spotify.playPause(function(){
            spotify.getState(function(error, state){
                expect(state.state).to.equal('paused');
                spotify.playPause(function(){
                    spotify.getState(function(error, state){
                        expect(state.state).to.equal('playing');
                        done();
                    });
                });
            });
        });
    });

    it('should turn volume up', function(done){
        // first do volumeDown in case volume is already 100
        spotify.volumeDown(function(){
            spotify.getState(function(error, state){
                var volume = parseInt(state.volume);
                spotify.volumeUp(function(){
                    spotify.getState(function(error, state){
                        expect(parseInt(state.volume)).to.be.greaterThan(volume);
                        done();
                    });
                });
            });
        });
    });

    it('should turn volume down', function(done){
        // first do volumeUp in case volume is already 0
        spotify.volumeUp(function(){
            spotify.getState(function(error, state){
                var volume = parseInt(state.volume);
                spotify.volumeDown(function(){
                    spotify.getState(function(error, state){
                        expect(parseInt(state.volume)).to.be.lessThan(volume);
                        done();
                    });
                });
            });
        });
    });

    it('should set the volume', function(done){
        spotify.setVolume(0, function(){
            spotify.getState(function(err, state){
                if (err) throw err;

                expect(parseInt(state.volume, 10)).to.equal(0);
                done();
            });
        });
    });

// Next and previous show buggy behaviour which makes testing it useless
//	it('play next track', function(done){
//		spotify.next(function(error, track){
//			spotify.getTrack(function(error, track){
//                console.log('>',track.name);
//                expect(track.name).to.not.equal('Like A Rolling Stone');
//				done();
//			});
//		});
//	});
//
//	it('play previous track', function(done){
//		spotify.previous(function(error, track){
//			spotify.getTrack(function(error, track){
//                console.log('>',track.name);
//				expect(track.name).to.equal('Like A Rolling Stone');
//				done();
//			});
//		});
//	});

    it('play track', function(done){
        spotify.playTrack('spotify:track:4EZz8Byhbjk0tOKFJlCgPB', function(){
            spotify.getTrack(function(error, track){
                expect(track.name).to.equal('Never Gonna Give You Up - 7" Vocal Mix');
                done();
            });
        });
    });

    it('should jump to a specific position of the song', function(done){
        // spotify needs some time to catch up with the jump or it will
        // simply return 0 as current player position
        setTimeout(function(){
            spotify.jumpTo(15, function(){
                spotify.getState(function(err, state){
                    expect(parseInt(state.position, 10)).to.equal(15)
                    done();
                });
            });
        }, 1100);
    });

    it('should return true when spotify is running', function(done) {
        spotify.isRunning(function(error, isRunning) {
            expect(error).to.be.null;
            expect(isRunning).to.be.true;
            done();
        });
    });

    it('should return the path to the PNG of the current artwork', function(done){
        spotify.getArtwork(function(err, path){
            if (err) throw err;

            var fileName = path.split('/').splice(-1)[0];
            expect(fileName).to.equal('spotify_track_3AhXZa8sUQht0UEdBJgpGc.png');
            done();
        });
    });
});
<commit_msg>add test for mute and unmute<commit_after>
var spotify = require('../lib/spotify-node-applescript.js');
var expect = require('chai').expect;

describe('Spotify Controller', function(){

    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // Make sure spotify is open before running these tests
    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    beforeEach(function(done){
        spotify.playTrack('spotify:track:3AhXZa8sUQht0UEdBJgpGc', function(){
            done();
        });
    });

    after(function(done){
        spotify.pause(function(){
            done();
        });
    });

    it('should return playing track', function(done){
        spotify.getTrack(function(error, track){
            expect(track.artist).to.equal('Bob Dylan');
            expect(track.name).to.equal('Like A Rolling Stone');
            done();
        });
    });

    it('should return player status', function(done){
        spotify.getState(function(error, state){
            expect(state.state).to.equal('playing');
            done();
        });
    });

    it('should pause a track', function(done){
        spotify.pause(function(){
            spotify.getState(function(error, state){
                expect(state.state).to.equal('paused');
                done();
            });
        });
    });

    it('should resume playing a track after pausing', function(done){
        spotify.pause(function(){
            spotify.play(function(){
                spotify.getState(function(error, state){
                    expect(state.state).to.equal('playing');
                    done();
                });
            });
        });
    });

    it('should play and pause a track', function(done){
        spotify.playPause(function(){
            spotify.getState(function(error, state){
                expect(state.state).to.equal('paused');
                spotify.playPause(function(){
                    spotify.getState(function(error, state){
                        expect(state.state).to.equal('playing');
                        done();
                    });
                });
            });
        });
    });

    it('should turn volume up', function(done){
        // first do volumeDown in case volume is already 100
        spotify.volumeDown(function(){
            spotify.getState(function(error, state){
                var volume = parseInt(state.volume);
                spotify.volumeUp(function(){
                    spotify.getState(function(error, state){
                        expect(parseInt(state.volume)).to.be.greaterThan(volume);
                        done();
                    });
                });
            });
        });
    });

    it('should turn volume down', function(done){
        // first do volumeUp in case volume is already 0
        spotify.volumeUp(function(){
            spotify.getState(function(error, state){
                var volume = parseInt(state.volume);
                spotify.volumeDown(function(){
                    spotify.getState(function(error, state){
                        expect(parseInt(state.volume)).to.be.lessThan(volume);
                        done();
                    });
                });
            });
        });
    });

    it('should set the volume', function(done){
        spotify.setVolume(0, function(){
            spotify.getState(function(err, state){
                if (err) throw err;

                expect(parseInt(state.volume, 10)).to.equal(0);
                done();
            });
        });
    });

    it('should mute and unmute the volume', function(done){
        spotify.setVolume(50, function(){
            spotify.muteVolume(function(err, state){
                spotify.getState(function(err, state){
                    if (err) throw err;

                    // volume now should be 0
                    expect(parseInt(state.volume, 10)).to.equal(0);

                    spotify.unmuteVolume(function(err, state){
                        spotify.getState(function(err, state){
                            if (err) throw err;

                            // volume now should be 50 again
                            // but spotify won't set volume exactly, so test if volume is within a range
                            expect(parseInt(state.volume, 10)).to.be.within(45, 55);
                            done();
                        });
                    });
                });
            });
        });
    });

// Next and previous show buggy behaviour which makes testing it useless
//	it('play next track', function(done){
//		spotify.next(function(error, track){
//			spotify.getTrack(function(error, track){
//                console.log('>',track.name);
//                expect(track.name).to.not.equal('Like A Rolling Stone');
//				done();
//			});
//		});
//	});
//
//	it('play previous track', function(done){
//		spotify.previous(function(error, track){
//			spotify.getTrack(function(error, track){
//                console.log('>',track.name);
//				expect(track.name).to.equal('Like A Rolling Stone');
//				done();
//			});
//		});
//	});

    it('play track', function(done){
        spotify.playTrack('spotify:track:4EZz8Byhbjk0tOKFJlCgPB', function(){
            spotify.getTrack(function(error, track){
                expect(track.name).to.equal('Never Gonna Give You Up - 7" Vocal Mix');
                done();
            });
        });
    });

    it('should jump to a specific position of the song', function(done){
        // spotify needs some time to catch up with the jump or it will
        // simply return 0 as current player position
        setTimeout(function(){
            spotify.jumpTo(15, function(){
                spotify.getState(function(err, state){
                    expect(parseInt(state.position, 10)).to.equal(15)
                    done();
                });
            });
        }, 1100);
    });

    it('should return true when spotify is running', function(done) {
        spotify.isRunning(function(error, isRunning) {
            expect(error).to.be.null;
            expect(isRunning).to.be.true;
            done();
        });
    });

    it('should return the path to the PNG of the current artwork', function(done){
        spotify.getArtwork(function(err, path){
            if (err) throw err;

            var fileName = path.split('/').splice(-1)[0];
            expect(fileName).to.equal('spotify_track_3AhXZa8sUQht0UEdBJgpGc.png');
            done();
        });
    });
});
<|endoftext|>


<commit_before>var mongoose  = require('mongoose')
  , elastical = require('elastical')
  , esClient  = new(require('elastical').Client)
  , should    = require('should')
  , config    = require('./config')
  , Schema    = mongoose.Schema
  , ObjectId  = Schema.ObjectId
  , mongoosastic = require('../lib/mongoosastic');

var TweetSchema = new Schema({
    user: String
  , post_date: {type:Date, es_type:'date'}
  , message: {type:String}
  , title: {type:String, es_boost:2.0}
});

TweetSchema.plugin(mongoosastic);
var BlogPost = mongoose.model('BlogPost', TweetSchema);

describe('Add Boost Option Per Field', function(){
  before(function(done){
    mongoose.connect(config.mongoUrl, function(){
      BlogPost.remove(function(){
        config.deleteIndexIfExists(['blogposts'], done)
      });
    });
  });

  it('should create a mapping with boost field added', function(done){
    BlogPost.createMapping(function(err, mapping){
      esClient.getMapping('blogposts', 'blogpost', function(err, mapping){
        var props = mapping.blogposts.mappings.blogpost.properties;
        props.title.type.should.eql('string');
        props.title.boost.should.eql(2.0);
        done();
      });
    });
  });
});
<commit_msg>Correct boost test field (support ES 0.9 and 1.0).<commit_after>var mongoose  = require('mongoose')
  , elastical = require('elastical')
  , esClient  = new(require('elastical').Client)
  , should    = require('should')
  , config    = require('./config')
  , Schema    = mongoose.Schema
  , ObjectId  = Schema.ObjectId
  , mongoosastic = require('../lib/mongoosastic');

var TweetSchema = new Schema({
    user: String
  , post_date: {type:Date, es_type:'date'}
  , message: {type:String}
  , title: {type:String, es_boost:2.0}
});

TweetSchema.plugin(mongoosastic);
var BlogPost = mongoose.model('BlogPost', TweetSchema);

describe('Add Boost Option Per Field', function(){
  before(function(done){
    mongoose.connect(config.mongoUrl, function(){
      BlogPost.remove(function(){
        config.deleteIndexIfExists(['blogposts'], done)
      });
    });
  });

  it('should create a mapping with boost field added', function(done){
    BlogPost.createMapping(function(err, mapping){
      esClient.getMapping('blogposts', 'blogpost', function(err, mapping){
        /* elasticsearch 1.0 & 0.9 support */
        var props =
          mapping.blogpost != undefined ?
            mapping.blogpost.properties: /* ES 0.9.11 */
            mapping.blogposts.mappings.blogpost.properties; /* ES 1.0.0 */
        props.title.type.should.eql('string');
        props.title.boost.should.eql(2.0);
        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

var cluster = require('cluster'),
	async = require('async'),
	os = require('os'),
	swintHelper = require('swint-helper'),
	print = swintHelper.print,
	EventEmitter = require('events').EventEmitter,
	defaultize = swintHelper.defaultize;

module.exports = function(options) {
	defaultize({
		preProcess: function(fork, cb) {
			cb({});
		},
		postProcess: function(fork, sharedData, cb) {
			cb({});
		},
		onExit: function( /* fork */ ) {
		},
		numFork: os.cpus().length,
		operator: null
	}, options);

	return new Fork(options);
};

var Fork = function(options) {
	this.options = options;
	this.sharedData = null;
	this.evt = new EventEmitter();
	this.start();
};

var _ = Fork.prototype;

_.start = function() {
	var that = this;

	if(cluster.isMaster) {
		if(this.options.operator !== null) {
			this.options.operator.start(function() {
				that.startPreProcess();
			});
		} else {
			this.startPreProcess();
		}
	}

	process.on('message', function(msg) {
		switch(msg.type) {
			case 'control':
				switch(msg.data) {
					case 'healthCheck':
						that.monitor(function(err, res) {
							if(err) {
								print(4, err);
								process.exit(-1);
								return;
							}
							process.emit('controlEnd', null, res);
						});
						break;
					case 'softReset':
						that.resetPost(function(err) {
							if(err) {
								print(4, err);
								process.exit(-1);
								return;
							}
							process.emit('controlEnd');
						});
						break;
					case 'hardReset':
						that.resetAll(function(err) {
							if(err) {
								print(4, err);
								process.exit(-1);
								return;
							}
							process.emit('controlEnd');
						});
						break;
				}
				break;
			case 'data':
				that.options.postProcess(that, msg.data, function() {
					process.send({
						type: 'complete'
					});
				});
				break;
		}
	});
};

_.startPreProcess = function() {
	var that = this,
		numFork = this.options.numFork;

	this.options.preProcess(this, function(sharedData) {
		that.sharedData = sharedData;
		for(var i = 0; i < numFork; i++) {
			that.createWorker(sharedData);
		}
	});

	cluster.on('exit', function(worker) {
		print(2, 'Worker ' + worker.process.pid + ' died');
		that.options.onExit(that);
		that.createWorker(that.sharedData);
	});

	cluster.on('error', function(worker) {
		worker.kill();
	});

	cluster.on('disconnect', function(worker) {
		worker.kill();
	});
};

_.createWorker = function(sharedData) {
	var that = this,
		worker = cluster.fork();

	worker.send({
		type: 'data',
		data: sharedData
	});

	worker.on('message', function(msg) {
		if(msg.type === 'complete') {
			that.evt.emit('complete');
		}
	});

	return worker;
};

_.monitor = function(callback) {
	var processes = [];

	for(var id in cluster.workers) {
		var worker = cluster.workers[id];

		processes.push({
			id: id,
			pid: worker.process.pid
		});
	}

	callback(null, processes);
};

_.resetAll = function(callback) {
	var that = this;

	that.options.preProcess(that, function() {
		var workers = [];

		for(var id in cluster.workers) {
			var worker = cluster.workers[id];

			workers.push(worker);
		}

		async.series(
			workers.map(function(v) {
				return function(cb) {
					that.evt.once('complete', function() {
						cb(null, true);
					});
					v.kill();
				};
			}),
			function(err) {
				callback(err, true);
			}
		);
	});
};

_.resetPost = function(callback) {
	var that = this,
		workers = [];

	for(var id in cluster.workers) {
		var worker = cluster.workers[id];

		workers.push(worker);
	}

	async.series(
		workers.map(function(v) {
			return function(cb) {
				that.evt.once('complete', function() {
					cb(null, true);
				});
				v.kill();
			};
		}),
		function(err) {
			callback(err, true);
		}
	);
};
<commit_msg>just to initiate travis<commit_after>'use strict';

var cluster = require('cluster'),
	async = require('async'),
	os = require('os'),
	swintHelper = require('swint-helper'),
	print = swintHelper.print,
	EventEmitter = require('events').EventEmitter,
	defaultize = swintHelper.defaultize;

module.exports = function(options) {
	defaultize({
		preProcess: function(fork, cb) {
			cb({});
		},
		postProcess: function(fork, sharedData, cb) {
			cb({});
		},
		onExit: function( /* fork */ ) {
		},
		numFork: os.cpus().length,
		operator: null
	}, options);

	return new Fork(options);
};

var Fork = function(options) {
	this.options = options;
	this.sharedData = null;
	this.evt = new EventEmitter();
	this.start();
};

var _ = Fork.prototype;

_.start = function() {
	var that = this;

	if(cluster.isMaster) {
		if(this.options.operator !== null) {
			this.options.operator.start(function() {
				that.startPreProcess();
			});
		} else {
			this.startPreProcess();
		}
	}

	process.on('message', function(msg) {
		switch(msg.type) {
			case 'control':
				switch(msg.data) {
					case 'healthCheck':
						that.monitor(function(err, res) {
							if(err) {
								print(4, err);
								process.exit(-1);
								return;
							}
							process.emit('controlEnd', null, res);
						});
						break;
					case 'softReset':
						that.resetPost(function(err) {
							if(err) {
								print(4, err);
								process.exit(-1);
								return;
							}
							process.emit('controlEnd');
						});
						break;
					case 'hardReset':
						that.resetAll(function(err) {
							if(err) {
								print(4, err);
								process.exit(-1);
								return;
							}
							process.emit('controlEnd');
						});
						break;
				}
				break;
			case 'data':
				that.options.postProcess(that, msg.data, function() {
					process.send({
						type: 'complete'
					});
				});
				break;
		}
	});
};

_.startPreProcess = function() {
	var that = this,
		numFork = this.options.numFork;

	this.options.preProcess(this, function(sharedData) {
		that.sharedData = sharedData;
		for(var i = 0; i < numFork; i++) {
			that.createWorker(sharedData);
		}
	});

	cluster.on('exit', function(worker) {
		print(2, 'Worker ' + worker.process.pid + ' died');
		that.options.onExit(that);
		that.createWorker(that.sharedData);
	});

	cluster.on('error', function(worker) {
		worker.kill();
	});

	cluster.on('disconnect', function(worker) {
		worker.kill();
	});
};

_.createWorker = function(sharedData) {
	var that = this,
		worker = cluster.fork();

	worker.send({
		type: 'data',
		data: sharedData
	});

	worker.on('message', function(msg) {
		if(msg.type === 'complete') {
			that.evt.emit('complete');
		}
	});

	return worker;
};

_.monitor = function(callback) {
	var processes = [];

	for(var id in cluster.workers) {
		var worker = cluster.workers[id];

		processes.push({
			id: id,
			pid: worker.process.pid
		});
	}

	callback(null, processes);
};

_.resetAll = function(callback) {
	var that = this;

	that.options.preProcess(that, function() {
		var workers = [];

		for(var id in cluster.workers) {
			var worker = cluster.workers[id];

			workers.push(worker);
		}

		async.series(
			workers.map(function(v) {
				return function(cb) {
					that.evt.once('complete', function() {
						cb(null, true);
					});
					v.kill();
				};
			}),
			function(err) {
				callback(err, true);
			}
		);
	});
};

_.resetPost = function(callback) {
	var that = this,
		workers = [];

	for(var id in cluster.workers) {
		var worker = cluster.workers[id];

		workers.push(worker);
	}

	async.series(
		workers.map(function(v) {
			return function(cb) {
				that.evt.once('complete', function() {
					cb(null, true);
				});
				v.kill();
			};
		}),
		function(err) {
			callback(err, true);
		}
	);
};

<|endoftext|>


<commit_before>window.hipanel = (function () {
    var locale = null;

    var notify = {
        create: function (options) {
            options = $.extend({
                buttons: {
                    sticker: false
                },
                icon: false,
                styling: 'bootstrap3'
            }, options, true);

            return new PNotify(options);
        },
        error: function (text) {
            return notify.create({type: 'error', text: text});
        },
        success: function (text) {
            return notify.create({type: 'success', text: text});
        }
    };

    var publicMethods = {
        updateCart: function (callback) {
            $('.dropdown.notifications-cart a.dropdown-toggle').html('');
            $.get("/cart/cart/topcart", function(data) {
                $("li.dropdown.notifications-menu.notifications-cart").html( data );
            }).done(callback());
        },
        loadingBar: function (options) {
            options = $.extend({}, options, true);

            return '
' +
                '
' +
                    '' + options.text + '' +
                '
' +
            '
';
        },
        notify: notify,
        form: {
            preventSubmitWithEnter: function (formId) {
                $(formId).on('keyup keypress', function (e) {
                    var keyCode = e.keyCode || e.which;
                    if (keyCode === 13) {
                        e.preventDefault();
                        e.stopPropagation();
                        $(e.target).blur();
                    }
                });
            }
        },
        spinner: {
            small: function() {
                return $('');
            }
        },
        locale: {
            get: function() {
                return locale;
            },
            set: function (newLocale) {
                locale = newLocale;
            }
        }
    };

    return publicMethods;
})();
<commit_msg>Changed spinner type (#76)<commit_after>window.hipanel = (function () {
    var locale = null;

    var notify = {
        create: function (options) {
            options = $.extend({
                buttons: {
                    sticker: false
                },
                icon: false,
                styling: 'bootstrap3'
            }, options, true);

            return new PNotify(options);
        },
        error: function (text) {
            return notify.create({type: 'error', text: text});
        },
        success: function (text) {
            return notify.create({type: 'success', text: text});
        }
    };

    var publicMethods = {
        updateCart: function (callback) {
            $('.dropdown.notifications-cart a.dropdown-toggle').html('');
            $.get("/cart/cart/topcart", function(data) {
                $("li.dropdown.notifications-menu.notifications-cart").html( data );
            }).done(callback());
        },
        loadingBar: function (options) {
            options = $.extend({}, options, true);

            return '
' +
                '
' +
                    '' + options.text + '' +
                '
' +
            '
';
        },
        notify: notify,
        form: {
            preventSubmitWithEnter: function (formId) {
                $(formId).on('keyup keypress', function (e) {
                    var keyCode = e.keyCode || e.which;
                    if (keyCode === 13) {
                        e.preventDefault();
                        e.stopPropagation();
                        $(e.target).blur();
                    }
                });
            }
        },
        spinner: {
            small: function() {
                return $('');
            }
        },
        locale: {
            get: function() {
                return locale;
            },
            set: function (newLocale) {
                locale = newLocale;
            }
        }
    };

    return publicMethods;
})();
<|endoftext|>


<commit_before>var ENEMY_DX = 1;
var ENEMY_DY = 20;

Object.prototype.isEmpty = function() {
    for (var prop in this) if (this.hasOwnProperty(prop)) return false;
    return true;
};

// Enemy Class
var Enemy = function(posX, posY, num) {
    this.x = posX;
    this.y = posY;
    this.dy = 0;
    this.dx = 1;
    this.num = num;
    this.population = 56;
    this.sprite = 'images/enemy1.png';
};

// Update the enemy's position, required method for game
// Parameter: dt, a time delta between ticks
Enemy.prototype.update = function(dt) {
    var movement = (ENEMY_DX * this.population) * dt;
    this.x += movement;
    this.y += this.dy * dt;

    if (this.x >= 1200 - 91 || this.x <= 0) {
        ENEMY_DX = -ENEMY_DX;
        allEnemies.forEach(function(allEnemy) {
        allEnemy.y += ENEMY_DY;
        allEnemy.x += ENEMY_DX;
        });
    }

	// Enemies will come out of alignment due to position not updating
	// at exacty the same time. This will keep them aligned
    if (this.num > 7) {
        this.x = allEnemies[this.num - 8].x;
    }

    if (this.num % 8 > 0) {
        this.x = allEnemies[this.num - 1].x + 135
    }

	// Balance enemy shooting by having each enemy only have a small
	// chance of firing
    var rand = Math.floor((Math.random() * 2500) + 1);
	if (rand === this.num) {
        this.shoot();
	}
};

// Draw the enemy on the screen, required method for game
Enemy.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

Enemy.prototype.move = function() {

};

Enemy.prototype.shoot = function() {
     bullets.push(new Bullet(this.x,this.y,"enemy",bullets.length));
};

var calcHeight = function (count) {
   if (count <= 8) {
    return 50;
   } else if (count <= 16) {
    return 70 + 81;
   } else if (count <= 24) {
    return 90 + (2 * 81);
   } else if (count <= 32) {
    return 110 + (3 * 81);
   } else if (count <= 40) {
    return 130 + (4 * 81);
   } else if (count <= 48) {
    return 150 + (5 * 81);
   }
}

// Player Class
var Player = function() {
    this.sprite = 'images/player.png';
    this.x = 600;
    this.y = 800;
    this.dx = 0;
    this.dy = 0;
    this.lives = 3;
    this.score = 0;
};

Player.prototype.update = function(dt) {
    this.x += this.dx * dt;
    if (this.x < 20) {
        this.x = 20;
    } else if (this.x > 1060) {
        this.x = 1060;
    }
};

Player.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

Player.prototype.handleInput = function(input) {
    if (keyboard['\%']) {
        this.dx = -100;
    } else if (keyboard["'"]) {
        this.dx = 100;
    } else if (keyboard.isEmpty) {
        this.dx = 0;
    }

    if (input === 'ctrl') {
        this.shoot();
    }
};

Player.prototype.shoot = function() {
    bullets.push(new Bullet(this.x,this.y,"player", bullets.length));

};

// Bullet class
var Bullet = function(posX,posY,type, num) {
    this.x = posX;
    this.y = posY;
    this.dx = 0;
    this.dy = 0;
    this.type = type;
    this.num = num;
    this.sprite = 'images/bullet.png';
};

Bullet.prototype.update = function(dt) {
    this.y += this.dy * dt;
};

Bullet.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite),this.x, this.y);
};

Bullet.prototype.move = function() {
    if (this.type === "player") {
        this.dy = -200;
    } else if (this.type === "enemy") {
        this.dy = 200;
    }
}

// Barrier class
var Barrier = function(posX, posY) {
    this.x = posX
    this.y = posY;
    this.heath = 10;
    this.sprite = 'images/barrier_full.png';

};

Barrier.prototype.update = function() {

};

Barrier.prototype.render= function() {
    ctx.drawImage(Resources.get(this.sprite),this.x, this.y);
};

// HUD class
var HUD = function() {
    this.score = score;
    this.lives = lives;

};

HUD.prototype.update = function() {

};

HUD.prototype.render = function() {

};

// Now instantiate your objects.
// Place all enemy objects in an array called allEnemies
// Place the player object in a variable called player
var allEnemies = [];
var barriers = [];
var bullets = []

var player = new Player();
//var hud = new HUD();

for (var x = 0; x < 49; x++) { allEnemies[x] = new Enemy(91 + 135 * (allEnemies.length % 8), calcHeight(x), x); }
for (var x = 0; x < 3; x++) {barriers[x] = new Barrier(230 + (x * 300),725)}

// This listens for key presses and sends the keys to your
// Player.handleInput() method. You don't need to modify this.
document.addEventListener('keydown', function(e) {
    var allowedKeys = {
        17: 'ctrl',
        37: 'left',
        39: 'right'

    };

    player.handleInput(allowedKeys[e.keyCode]);
});

// keyboard_module by RobKohr
// Properly handles when a key is held down and then released
function keyboard_module(onUpdate){
    var kb = {};
    var unicode_mapping = {};
    document.onkeydown = function(e){
        var unicode=e.charCode? e.charCode : e.keyCode
        var key = getKey(unicode);
        kb[key] = true;
        if(onUpdate){
            onUpdate(kb);
        }
    }

    document.onkeyup = function(e){
        var unicode=e.charCode? e.charCode : e.keyCode
        var key = getKey(unicode);
        delete kb[key];
        if(onUpdate){
            onUpdate(kb);
        }
    }

    function getKey(unicode){
        if(unicode_mapping[unicode]){
            var key = unicode_mapping[unicode];
        }else{
            var key= unicode_mapping[unicode] = String.fromCharCode(unicode);
        }
        return key;
    }
    return kb;
}

function testing(kb){
    console.log('These are the down keys', kb);
}

var keyboard = keyboard_module();

<commit_msg>feat: add function for testing collisions<commit_after>var ENEMY_DX = 1;
var ENEMY_DY = 20;

Object.prototype.isEmpty = function() {
    for (var prop in this) if (this.hasOwnProperty(prop)) return false;
    return true;
};

// Enemy Class
var Enemy = function(posX, posY, num) {
    this.x = posX;
    this.y = posY;
    this.dy = 0;
    this.dx = 1;
    this.num = num;
    this.population = 56;
    this.width = 73;
    this.height = 65;
    this.sprite = 'images/enemy1.png';
};

// Update the enemy's position, required method for game
// Parameter: dt, a time delta between ticks
Enemy.prototype.update = function(dt) {
    var movement = (ENEMY_DX * this.population) * dt;
    this.x += movement;
    this.y += this.dy * dt;

    if (this.x >= 1200 - 91 || this.x <= 0) {
        ENEMY_DX = -ENEMY_DX;
        allEnemies.forEach(function(allEnemy) {
        allEnemy.y += ENEMY_DY;
        allEnemy.x += ENEMY_DX;
        });
    }

	// Enemies will come out of alignment due to position not updating
	// at exacty the same time. This will keep them aligned
    if (this.num > 7) {
        this.x = allEnemies[this.num - 8].x;
    }

    if (this.num % 8 > 0) {
        this.x = allEnemies[this.num - 1].x + 135
    }

	// Balance enemy shooting by having each enemy only have a small
	// chance of firing
    var rand = Math.floor((Math.random() * 2500) + 1);
	if (rand === this.num) {
        this.shoot();
	}
};

// Draw the enemy on the screen, required method for game
Enemy.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

Enemy.prototype.move = function() {

};

Enemy.prototype.shoot = function() {
     bullets.push(new Bullet(this.x,this.y,"enemy",bullets.length));
};

var calcHeight = function (count) {
   if (count <= 8) {
    return 50;
   } else if (count <= 16) {
    return 70 + 81;
   } else if (count <= 24) {
    return 90 + (2 * 81);
   } else if (count <= 32) {
    return 110 + (3 * 81);
   } else if (count <= 40) {
    return 130 + (4 * 81);
   } else if (count <= 48) {
    return 150 + (5 * 81);
   }
}

// Player Class
var Player = function() {
    this.sprite = 'images/player.png';
    this.x = 600;
    this.y = 800;
    this.dx = 0;
    this.dy = 0;
    this.width = 131;
    this.height = 92;
    this.lives = 3;
    this.score = 0;
};

Player.prototype.update = function(dt) {
    this.x += this.dx * dt;
    if (this.x < 20) {
        this.x = 20;
    } else if (this.x > 1060) {
        this.x = 1060;
    }
};

Player.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y,131,92);
};

Player.prototype.handleInput = function(input) {
    if (keyboard['\%']) {
        this.dx = -100;
    } else if (keyboard["'"]) {
        this.dx = 100;
    } else if (keyboard.isEmpty) {
        this.dx = 0;
    }

    if (input === 'ctrl') {
        this.shoot();
    }
};

Player.prototype.shoot = function() {
    bullets.push(new Bullet(this.x,this.y,"player", bullets.length));
};

// Bullet class
var Bullet = function(posX,posY,type, num) {
    this.x = posX;
    this.y = posY;
    this.dx = 0;
    this.dy = 0;
    this.width = 92;
    this.height = 92;
    this.type = type;
    this.num = num;
    this.sprite = 'images/bullet.png';
};

Bullet.prototype.update = function(dt) {
    this.y += this.dy * dt;
};

Bullet.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite),this.x, this.y);
};

Bullet.prototype.move = function() {
    if (this.type === "player") {
        this.dy = -200;
    } else if (this.type === "enemy") {
        this.dy = 200;
    }
}

// Barrier class
var Barrier = function(posX, posY) {
    this.x = posX
    this.y = posY;
    this.width = 115;
    this.height = 81;
    this.heath = 10;
    this.sprite = 'images/barrier_full.png';

};

Barrier.prototype.update = function() {

};

Barrier.prototype.render= function() {
    ctx.drawImage(Resources.get(this.sprite),this.x, this.y);
};

// HUD class
var HUD = function() {
    this.score = score;
    this.lives = lives;

};

HUD.prototype.update = function() {

};

HUD.prototype.render = function() {

};

// Now instantiate your objects.
// Place all enemy objects in an array called allEnemies
// Place the player object in a variable called player
var allEnemies = [];
var barriers = [];
var bullets = []

var player = new Player();
//var hud = new HUD();

for (var x = 0; x < 49; x++) { allEnemies[x] = new Enemy(91 + 135 * (allEnemies.length % 8), calcHeight(x), x); }
for (var x = 0; x < 3; x++) {barriers[x] = new Barrier(230 + (x * 300),725)}

// This listens for key presses and sends the keys to your
// Player.handleInput() method. You don't need to modify this.
document.addEventListener('keydown', function(e) {
    var allowedKeys = {
        17: 'ctrl',
        37: 'left',
        39: 'right'

    };

    player.handleInput(allowedKeys[e.keyCode]);
});

// keyboard_module by RobKohr
// Properly handles when a key is held down and then released
function keyboard_module(onUpdate){
    var kb = {};
    var unicode_mapping = {};
    document.onkeydown = function(e){
        var unicode=e.charCode? e.charCode : e.keyCode
        var key = getKey(unicode);
        kb[key] = true;
        if(onUpdate){
            onUpdate(kb);
        }
    }

    document.onkeyup = function(e){
        var unicode=e.charCode? e.charCode : e.keyCode
        var key = getKey(unicode);
        delete kb[key];
        if(onUpdate){
            onUpdate(kb);
        }
    }

    function getKey(unicode){
        if(unicode_mapping[unicode]){
            var key = unicode_mapping[unicode];
        }else{
            var key= unicode_mapping[unicode] = String.fromCharCode(unicode);
        }
        return key;
    }
    return kb;
}

function testing(kb){
    //console.log('These are the down keys', kb);
}

function collisionTest(obj1,obj2) {

    if (obj1.x < obj2.x + obj2.width &&
       obj1.x + obj1.width > obj2.x &&
       obj1.y < obj2.y + obj2.height &&
       obj1.height + obj1.y > obj2.y) {
        console.log("collision!");
    }
}

var keyboard = keyboard_module();

<|endoftext|>


<commit_before>// Catalog Client Scripts
exports.catalog_script_client = {
  nameField: ['sys_scope', 'name'],
  formats: [
    {
      fileName: ':sys_scope-:name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};

// CMS CSS
exports.content_css = {
  nameField: ['sys_scope', 'name'],
  formats: [
    {
      fileName: ':sys_scope-:name-style-:sys_id.css',
      contentField: 'style'
    }
  ]
};

// Service Portal CSS
exports.sp_css = {
  nameField: ['sys_scope', 'name'],
  formats: [
    {
      fileName: ':sys_scope-:name-css-:sys_id.css',
      contentField: 'css'
    }
  ]
};

// Service Portal Header/Footer
exports.sp_header_footer = {
  nameField: ['sys_scope', 'id'],
  formats: [
    {
      fileName: ':sys_scope-:id-template-:sys_id.html',
      contentField: 'template'
    },
    {
      fileName: ':sys_scope-:id-css-:sys_id.css',
      contentField: 'css'
    },
    {
      fileName: ':sys_scope-:id-script-:sys_id.js',
      contentField: 'script'
    },
    {
      fileName: ':sys_scope-:id-client_script-:sys_id.js',
      contentField: 'client_script'
    },
    {
      fileName: ':sys_scope-:id-link-:sys_id.js',
      contentField: 'link'
    }
  ]
};

// Service Portal Page
exports.sp_page = {
  nameField: ['id'],
  formats: [
    {
      fileName: ':id-css-:sys_id.css',
      contentField: 'css'
    }
  ]
};

// Service Portal
exports.sp_portal = {
  nameField: 'url_suffix',
  formats: [
    {
      fileName: ':url_suffix-quick_start_config-:sys_id.json',
      contentField: 'quick_start_config'
    },
    {
      fileName: ':url_suffix-css_variables-:sys_id.scss',
      contentField: 'css_variables'
    }
  ]
};

// Service Portal Theme CSS
exports.sp_theme = {
  nameField: 'name',
  formats: [
    {
      fileName: ':name-css_variables-:sys_id.scss',
      contentField: 'css_variables'
    }
  ]
};

// Service Portal Widgets
exports.sp_widget = {
  nameField: 'name',
  formats: [
    {
      fileName: ':name-client_script-:sys_id.js',
      contentField: 'client_script'
    },
    {
      fileName: ':name-css-:sys_id.css',
      contentField: 'css'
    },
    {
      fileName: ':name-demo_data-:sys_id.json',
      contentField: 'demo_data'
    },
    {
      fileName: ':name-link-:sys_id.js',
      contentField: 'link'
    },
    {
      fileName: ':name-option_schema-:sys_id.json',
      contentField: 'option_schema'
    },
    {
      fileName: ':name-script-:sys_id.js',
      contentField: 'script'
    },
    {
      fileName: ':name-template-:sys_id.html',
      contentField: 'template'
    }
  ]
};

// Business Rules
exports.sys_script = {
  nameField: ['collection', 'name'],
  formats: [
    {
      fileName: ':collection-:name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};

// Client Scripts
exports.sys_script_client = {
  nameField: ['table', 'sys_scope', 'name'],
  formats: [
    {
      fileName: ':table-:sys_scope-:name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};

// Script Includes
exports.sys_script_include = {
  nameField: 'api_name',
  formats: [
    {
      fileName: ':api_name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};

// UI Scripts
exports.sys_ui_action = {
  nameField: 'name',
  formats: [
    {
      fileName: ':name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};

// UI Pages
exports.sys_ui_page = {
  nameField: ['sys_scope', 'name'],
  formats: [
    {
      fileName: ':sys_scope-:name-html-:sys_id.html',
      contentField: 'html'
    },
    {
      fileName: ':sys_scope-:name-client_script-:sys_id.js',
      contentField: 'client_script'
    }
  ]
};

// UI Scripts
exports.sys_ui_script = {
  nameField: 'name',
  formats: [
    {
      fileName: ':name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};

// Script REST Resources
exports.sys_ws_operation = {
  nameField: ['web_service_definition', 'name'],
  formats: [
    {
      fileName: ':web_service_definition-:name-operation_script-:sys_id.js',
      contentField: 'operation_script'
    }
  ]
};

// Scheduled Jobs
exports.sysauto_script = {
  nameField: ['sys_scope', 'name'],
  formats: [
    {
      fileName: ':sys_scope-:name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};
<commit_msg>changed service portal header_footer css to scss.<commit_after>// Catalog Client Scripts
exports.catalog_script_client = {
  nameField: ['sys_scope', 'name'],
  formats: [
    {
      fileName: ':sys_scope-:name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};

// CMS CSS
exports.content_css = {
  nameField: ['sys_scope', 'name'],
  formats: [
    {
      fileName: ':sys_scope-:name-style-:sys_id.css',
      contentField: 'style'
    }
  ]
};

// Service Portal CSS
exports.sp_css = {
  nameField: ['sys_scope', 'name'],
  formats: [
    {
      fileName: ':sys_scope-:name-css-:sys_id.css',
      contentField: 'css'
    }
  ]
};

// Service Portal Header/Footer
exports.sp_header_footer = {
  nameField: ['sys_scope', 'id'],
  formats: [
    {
      fileName: ':sys_scope-:id-template-:sys_id.html',
      contentField: 'template'
    },
    {
      fileName: ':sys_scope-:id-css-:sys_id.scss',
      contentField: 'css'
    },
    {
      fileName: ':sys_scope-:id-script-:sys_id.js',
      contentField: 'script'
    },
    {
      fileName: ':sys_scope-:id-client_script-:sys_id.js',
      contentField: 'client_script'
    },
    {
      fileName: ':sys_scope-:id-link-:sys_id.js',
      contentField: 'link'
    }
  ]
};

// Service Portal Page
exports.sp_page = {
  nameField: ['id'],
  formats: [
    {
      fileName: ':id-css-:sys_id.css',
      contentField: 'css'
    }
  ]
};

// Service Portal
exports.sp_portal = {
  nameField: 'url_suffix',
  formats: [
    {
      fileName: ':url_suffix-quick_start_config-:sys_id.json',
      contentField: 'quick_start_config'
    },
    {
      fileName: ':url_suffix-css_variables-:sys_id.scss',
      contentField: 'css_variables'
    }
  ]
};

// Service Portal Theme CSS
exports.sp_theme = {
  nameField: 'name',
  formats: [
    {
      fileName: ':name-css_variables-:sys_id.scss',
      contentField: 'css_variables'
    }
  ]
};

// Service Portal Widgets
exports.sp_widget = {
  nameField: 'name',
  formats: [
    {
      fileName: ':name-client_script-:sys_id.js',
      contentField: 'client_script'
    },
    {
      fileName: ':name-css-:sys_id.css',
      contentField: 'css'
    },
    {
      fileName: ':name-demo_data-:sys_id.json',
      contentField: 'demo_data'
    },
    {
      fileName: ':name-link-:sys_id.js',
      contentField: 'link'
    },
    {
      fileName: ':name-option_schema-:sys_id.json',
      contentField: 'option_schema'
    },
    {
      fileName: ':name-script-:sys_id.js',
      contentField: 'script'
    },
    {
      fileName: ':name-template-:sys_id.html',
      contentField: 'template'
    }
  ]
};

// Business Rules
exports.sys_script = {
  nameField: ['collection', 'name'],
  formats: [
    {
      fileName: ':collection-:name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};

// Client Scripts
exports.sys_script_client = {
  nameField: ['table', 'sys_scope', 'name'],
  formats: [
    {
      fileName: ':table-:sys_scope-:name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};

// Script Includes
exports.sys_script_include = {
  nameField: 'api_name',
  formats: [
    {
      fileName: ':api_name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};

// UI Scripts
exports.sys_ui_action = {
  nameField: 'name',
  formats: [
    {
      fileName: ':name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};

// UI Pages
exports.sys_ui_page = {
  nameField: ['sys_scope', 'name'],
  formats: [
    {
      fileName: ':sys_scope-:name-html-:sys_id.html',
      contentField: 'html'
    },
    {
      fileName: ':sys_scope-:name-client_script-:sys_id.js',
      contentField: 'client_script'
    }
  ]
};

// UI Scripts
exports.sys_ui_script = {
  nameField: 'name',
  formats: [
    {
      fileName: ':name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};

// Script REST Resources
exports.sys_ws_operation = {
  nameField: ['web_service_definition', 'name'],
  formats: [
    {
      fileName: ':web_service_definition-:name-operation_script-:sys_id.js',
      contentField: 'operation_script'
    }
  ]
};

// Scheduled Jobs
exports.sysauto_script = {
  nameField: ['sys_scope', 'name'],
  formats: [
    {
      fileName: ':sys_scope-:name-script-:sys_id.js',
      contentField: 'script'
    }
  ]
};
<|endoftext|>


<commit_before>"use strict";
var util = require('util'),
  Core = require('facet-core').Core;

/**
 * Commerce API constructor
 *
 * @param   {Object}  options   Options object - must contain 'db' (mongoose instance)
 *                              and 'intercom' (EventEmitter instance) keys.
 *
 * @return  {void}
 */
var CommerceAPI = function( options ){
  CommerceAPI.super_.call(this, options);

  // set the options
  this.setCommonAttributes( options );

  // check the contraints and set the custom modules
  // if( this.options.hasOwnProperty("ProductsAPI") && this.checkConstraints( this.options.ProductsAPI ) ) {
  //   ProductsAPI = this.options.ProductsAPI;
  // }
  // if( this.options.hasOwnProperty("CategoriesAPI") && this.checkConstraints( this.options.CategoriesAPI ) ) {
  //   CategoriesAPI = this.options.CategoriesAPI;
  // }

  // instantiate the api modules
  // this.Products = new ProductsAPI( this.options );
  // this.Categories = new CategoriesAPI( this.options );

  // register catalog's events
  this.registerEvents();

  // register catalog's routes
  this.registerRoutes();
};

/**
 * Catalog API inherits from Core
 */
util.inherits(CommerceAPI, Core);

CatalogAPI.prototype.registerEvents = function() {
};

CommerceAPI.prototype.registerRoutes = function() {

  // this.Products.routerManifest.addRoutes([
  //   { verb: 'GET', route: '/:productId/categories', emit: 'facet:product:category:find' },  // GET all the categories for the product
  // ]);
  // this.Categories.routerManifest.addRoutes([
  //   { verb: 'GET', route: '/:categoryId/products', emit: 'facet:category:product:find' }, // GET all the products for the category
  // ]);

};

// export the main function
exports = module.exports = CommerceAPI;
<commit_msg>small change<commit_after>"use strict";
var util = require('util'),
  Core = require('facet-core').Core;

/**
 * Commerce API constructor
 *
 * @param   {Object}  options   Options object - must contain 'db' (mongoose instance)
 *                              and 'intercom' (EventEmitter instance) keys.
 *
 * @return  {void}
 */
var CommerceAPI = function( options ){
  CommerceAPI.super_.call(this, options);

  // set the options
  this.setCommonAttributes( options );

  // check the contraints and set the custom modules
  // if( this.options.hasOwnProperty("ProductsAPI") && this.checkConstraints( this.options.ProductsAPI ) ) {
  //   ProductsAPI = this.options.ProductsAPI;
  // }
  // if( this.options.hasOwnProperty("CategoriesAPI") && this.checkConstraints( this.options.CategoriesAPI ) ) {
  //   CategoriesAPI = this.options.CategoriesAPI;
  // }

  // instantiate the api modules
  // this.Products = new ProductsAPI( this.options );
  // this.Categories = new CategoriesAPI( this.options );

  // register catalog's events
  this.registerEvents();

  // register catalog's routes
  this.registerRoutes();
};

/**
 * Catalog API inherits from Core
 */
util.inherits(CommerceAPI, Core);

CommerceAPI.prototype.registerEvents = function() {
};

CommerceAPI.prototype.registerRoutes = function() {

  // this.Products.routerManifest.addRoutes([
  //   { verb: 'GET', route: '/:productId/categories', emit: 'facet:product:category:find' },  // GET all the categories for the product
  // ]);
  // this.Categories.routerManifest.addRoutes([
  //   { verb: 'GET', route: '/:categoryId/products', emit: 'facet:category:product:find' }, // GET all the products for the category
  // ]);

};

// export the main function
exports = module.exports = CommerceAPI;
<|endoftext|>