<commit_before>/*
 * (c) Copyright Ascensio System SIA 2010-2017
 *
 * This program is a free software product. You can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License (AGPL)
 * version 3 as published by the Free Software Foundation. In accordance with
 * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
 * that Ascensio System SIA expressly excludes the warranty of non-infringement
 * of any third-party rights.
 *
 * This program is distributed WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE. For
 * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
 *
 * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
 * EU, LV-1021.
 *
 * The  interactive user interfaces in modified source and object code versions
 * of the Program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU AGPL version 3.
 *
 * Pursuant to Section 7(b) of the License you must retain the original Product
 * logo when distributing the program. Pursuant to Section 7(e) we decline to
 * grant you any rights under trademark law for use of our trademarks.
 *
 * All the Product's GUI elements, including illustrations and icon sets, as
 * well as technical writing content are licensed under the terms of the
 * Creative Commons Attribution-ShareAlike 4.0 International. See the License
 * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
 *
 */

var sockjs = require('sockjs'),
	nodehun = require('nodehun'),
    config = require('config').get('SpellChecker'),
	logger = require('./../../Common/sources/logger'),
	fs = require('fs'),
	cfgSockjsUrl = require('config').get('services.CoAuthoring.server.sockjsUrl');
var arrDictionaries = {};

(function() {
	// Read dictionaries
	var arrDictionariesConfig = config.get('dictionaries');
	var oDictTmp = null, pathTmp = '', oDictName = null;
	for (var indexDict = 0, lengthDict = arrDictionariesConfig.length; indexDict < lengthDict; ++indexDict) {
		oDictTmp = arrDictionariesConfig[indexDict];
		oDictName = oDictTmp.name;
		pathTmp = __dirname + '/../dictionaries/' + oDictName + '/' + oDictName + '.';
		arrDictionaries[oDictTmp.id] = new nodehun(pathTmp + 'aff', pathTmp + 'dic');
	}
})();

/*function CheckDictionary (dict, correct, unCorrect) {
	if (dict) {
		dict.isCorrect(correct, function (err, correct, origWord) {
			console.log(err, correct, origWord);
			if (err || !correct) logger.error('Error: spelling correct word %s failed!', correct);
		});

		dict.spellSuggestions(unCorrect, function (err, correct, suggestions, origWord) {
			console.log(err, correct, suggestions, origWord);
			if (err || correct) logger.error('Error: spelling unCorrect word %s failed!', unCorrect);
		});
	} else {
		logger.error('Error: no dictionary');
	}
}
CheckDictionary(arrDictionaries[0x0409], 'color', 'calor');*/

exports.install = function (server, callbackFunction) {
	'use strict';
	var sockjs_opts = {sockjs_url: cfgSockjsUrl},
		sockjs_echo = sockjs.createServer(sockjs_opts);

	sockjs_echo.on('connection', function (conn) {
		if (null == conn) {
			logger.error ("null == conn");
			return;
		}
		conn.on('data', function (message) {
			try {
				var data = JSON.parse(message);
				switch (data.type) {
					case 'spellCheck':	spellCheck(conn, data);break;
				}
			} catch (e) {
				logger.error("error receiving response: %s", e);
			}
		});
		conn.on('error', function () {
			logger.error("On error");
		});
		conn.on('close', function () {
			logger.info("Connection closed or timed out");
		});
	});

	function sendData(conn, data) {
		conn.write(JSON.stringify(data));
	}

	function spellCheck(conn, data) {
		var oSpellInfo;
		function checkEnd() {
			if (0 === oSpellInfo.usrWordsLength) {
				sendData(conn, { type:"spellCheck", spellCheckData:JSON.stringify(data) });
			}
		}
		function spellSuggest(index, word, lang) {
			oSpellInfo.arrTimes[index] = new Date();
			logger.info('start %s word = %s, lang = %s', data.type, word, lang);
			var oDictionary = arrDictionaries[lang];
			if (undefined === oDictionary) {
				data.usrCorrect[index] = false;
				--data.usrWordsLength;
				checkEnd();
			} else if ("spell" === data.type) {
				oDictionary.isCorrect(word, function (err, correct, origWord) {
					data.usrCorrect[index] = (!err && correct);
					logger.info('spell word = %s, lang = %s, time = %s', word, lang, new Date() - oSpellInfo.arrTimes[index]);
					--oSpellInfo.usrWordsLength;
					checkEnd();
				});
			} else if ("suggest" === data.type) {
				oDictionary.spellSuggestions(word, function (err, correct, suggestions, origWord) {
					data.usrSuggest[index] = suggestions;
					logger.info('suggest word = %s, lang = %s, time = %s', word, lang, new Date() - oSpellInfo.arrTimes[index]);
					--oSpellInfo.usrWordsLength;
					checkEnd();
				});
			}
		}

		data = JSON.parse(data.spellCheckData);
		// Ответ
		data.usrCorrect = [];
		data.usrSuggest = [];

		oSpellInfo = {usrWordsLength: data.usrWords.length, arrTimes: []};

		//data.start = new Date();
		for (var i = 0, length = data.usrWords.length; i < length; ++i) {
			spellSuggest(i, data.usrWords[i], data.usrLang[i]);
		}
	}

	sockjs_echo.installHandlers(server, {prefix:'/doc/[0-9-.a-zA-Z_=]*/c', log:function (severity, message) {
		//TODO: handle severity
		logger.info(message);
	}});

	callbackFunction();
};
exports.spellSuggest = function (type, word, lang, callbackFunction) {
	var oDictionary = arrDictionaries[lang];
	if (undefined === oDictionary) {
		callbackFunction(false);
	} else if ('spell' === type) {
		oDictionary.isCorrect(word, function (err, correct, origWord) {
			callbackFunction(!err && correct);
		});
	} else if ('suggest' === type) {
		oDictionary.spellSuggestions(word, function (err, correct, suggestions, origWord) {
			callbackFunction(suggestions);
		});
	}
};
<commit_msg>no dictionary - word correct<commit_after>/*
 * (c) Copyright Ascensio System SIA 2010-2017
 *
 * This program is a free software product. You can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License (AGPL)
 * version 3 as published by the Free Software Foundation. In accordance with
 * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
 * that Ascensio System SIA expressly excludes the warranty of non-infringement
 * of any third-party rights.
 *
 * This program is distributed WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE. For
 * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
 *
 * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
 * EU, LV-1021.
 *
 * The  interactive user interfaces in modified source and object code versions
 * of the Program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU AGPL version 3.
 *
 * Pursuant to Section 7(b) of the License you must retain the original Product
 * logo when distributing the program. Pursuant to Section 7(e) we decline to
 * grant you any rights under trademark law for use of our trademarks.
 *
 * All the Product's GUI elements, including illustrations and icon sets, as
 * well as technical writing content are licensed under the terms of the
 * Creative Commons Attribution-ShareAlike 4.0 International. See the License
 * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
 *
 */

var sockjs = require('sockjs'),
	nodehun = require('nodehun'),
    config = require('config').get('SpellChecker'),
	logger = require('./../../Common/sources/logger'),
	fs = require('fs'),
	cfgSockjsUrl = require('config').get('services.CoAuthoring.server.sockjsUrl');
var arrDictionaries = {};

(function() {
	// Read dictionaries
	var arrDictionariesConfig = config.get('dictionaries');
	var oDictTmp = null, pathTmp = '', oDictName = null;
	for (var indexDict = 0, lengthDict = arrDictionariesConfig.length; indexDict < lengthDict; ++indexDict) {
		oDictTmp = arrDictionariesConfig[indexDict];
		oDictName = oDictTmp.name;
		pathTmp = __dirname + '/../dictionaries/' + oDictName + '/' + oDictName + '.';
		arrDictionaries[oDictTmp.id] = new nodehun(pathTmp + 'aff', pathTmp + 'dic');
	}
})();

/*function CheckDictionary (dict, correct, unCorrect) {
	if (dict) {
		dict.isCorrect(correct, function (err, correct, origWord) {
			console.log(err, correct, origWord);
			if (err || !correct) logger.error('Error: spelling correct word %s failed!', correct);
		});

		dict.spellSuggestions(unCorrect, function (err, correct, suggestions, origWord) {
			console.log(err, correct, suggestions, origWord);
			if (err || correct) logger.error('Error: spelling unCorrect word %s failed!', unCorrect);
		});
	} else {
		logger.error('Error: no dictionary');
	}
}
CheckDictionary(arrDictionaries[0x0409], 'color', 'calor');*/

exports.install = function (server, callbackFunction) {
	'use strict';
	var sockjs_opts = {sockjs_url: cfgSockjsUrl},
		sockjs_echo = sockjs.createServer(sockjs_opts);

	sockjs_echo.on('connection', function (conn) {
		if (null == conn) {
			logger.error ("null == conn");
			return;
		}
		conn.on('data', function (message) {
			try {
				var data = JSON.parse(message);
				switch (data.type) {
					case 'spellCheck':	spellCheck(conn, data);break;
				}
			} catch (e) {
				logger.error("error receiving response: %s", e);
			}
		});
		conn.on('error', function () {
			logger.error("On error");
		});
		conn.on('close', function () {
			logger.info("Connection closed or timed out");
		});
	});

	function sendData(conn, data) {
		conn.write(JSON.stringify(data));
	}

	function spellCheck(conn, data) {
		var oSpellInfo;
		function checkEnd() {
			if (0 === oSpellInfo.usrWordsLength) {
				sendData(conn, { type:"spellCheck", spellCheckData:JSON.stringify(data) });
			}
		}
		function spellSuggest(index, word, lang) {
			oSpellInfo.arrTimes[index] = new Date();
			logger.info('start %s word = %s, lang = %s', data.type, word, lang);
			var oDictionary = arrDictionaries[lang];
			if (!oDictionary) {
				data.usrCorrect[index] = true;
				--data.usrWordsLength;
				checkEnd();
			} else if ("spell" === data.type) {
				oDictionary.isCorrect(word, function (err, correct, origWord) {
					data.usrCorrect[index] = (!err && correct);
					logger.info('spell word = %s, lang = %s, time = %s', word, lang, new Date() - oSpellInfo.arrTimes[index]);
					--oSpellInfo.usrWordsLength;
					checkEnd();
				});
			} else if ("suggest" === data.type) {
				oDictionary.spellSuggestions(word, function (err, correct, suggestions, origWord) {
					data.usrSuggest[index] = suggestions;
					logger.info('suggest word = %s, lang = %s, time = %s', word, lang, new Date() - oSpellInfo.arrTimes[index]);
					--oSpellInfo.usrWordsLength;
					checkEnd();
				});
			}
		}

		data = JSON.parse(data.spellCheckData);
		// Ответ
		data.usrCorrect = [];
		data.usrSuggest = [];

		oSpellInfo = {usrWordsLength: data.usrWords.length, arrTimes: []};

		//data.start = new Date();
		for (var i = 0, length = data.usrWords.length; i < length; ++i) {
			spellSuggest(i, data.usrWords[i], data.usrLang[i]);
		}
	}

	sockjs_echo.installHandlers(server, {prefix:'/doc/[0-9-.a-zA-Z_=]*/c', log:function (severity, message) {
		//TODO: handle severity
		logger.info(message);
	}});

	callbackFunction();
};
exports.spellSuggest = function (type, word, lang, callbackFunction) {
	var oDictionary = arrDictionaries[lang];
	if (undefined === oDictionary) {
		callbackFunction(false);
	} else if ('spell' === type) {
		oDictionary.isCorrect(word, function (err, correct, origWord) {
			callbackFunction(!err && correct);
		});
	} else if ('suggest' === type) {
		oDictionary.spellSuggestions(word, function (err, correct, suggestions, origWord) {
			callbackFunction(suggestions);
		});
	}
};
<|endoftext|>


<commit_before>
;

import angular from 'angular';
import inviewModule from 'angular-inview';

import won from '../won-es6.js';
import jld from 'jsonld';
import Immutable from 'immutable';
import squareImageModule from './square-image.js';
import labelledHrModule from './labelled-hr.js';
import {
    relativeTime,
} from '../won-label-utils.js'
import {
    connect2Redux,
} from '../won-utils.js';
import {
    attach,
    delay,
    get,
    getIn,
    deepFreeze,
    dispatchEvent,
} from '../utils.js'
import {
	buildProposalMessage,
	buildModificationMessage,
} from '../won-message-utils.js';
import {
    actionCreators
}  from '../actions/actions.js';
import {
    selectOpenConnectionUri,
    selectNeedByConnectionUri,
} from '../selectors.js';
import autoresizingTextareaModule from '../directives/textarea-autogrow.js';

const MESSAGE_READ_TIMEOUT = 1500;

const serviceDependencies = ['$ngRedux', '$scope', '$element'];

function genComponentConf() {
    let template = `
        <won-square-image
            title="self.theirNeed.get('title')"
            src="self.theirNeed.get('TODOtitleImgSrc')"
            uri="self.theirNeed.get('uri')"
            ng-click="self.router__stateGoCurrent({postUri: self.theirNeed.get('uri')})"
            ng-show="!self.message.get('outgoingMessage')">
        </won-square-image>

Proposal

Accept

ProposeToCancel

                        {{ self.text? self.text : self.noTextPlaceholder }}

	                        <svg class="won-cm__center__carret clickable"
	                                ng-click="self.showDetail = !self.showDetail"
	                                ng-if="self.allowProposals"
	                                ng-show="!self.showDetail">
	                            <use href="#ico16_arrow_down"></use>
	                        </svg>

	                        	<won-labelled-hr arrow="'up'" style="margin-top: .5rem; margin-bottom: .5rem;"></won-labelled-hr>

                    	<button class="won-button--filled thin black"
                        		ng-click="self.sendProposal(); self.showDetail = !self.showDetail"
                        		ng-show="self.showDetail">Propose (again)
                        </button>

                        @prefix ...
                        {{ self.contentGraphTrigPrefixes }}

                        {{ self.contentGraphTrig }}

                        <button class="won-button--filled thin red"
                        		ng-show="!self.message.get('outgoingMessage') && !self.clicked"
    							ng-click="self.acceptProposal()">
    						Accept
    					</button>

                        <button class="won-button--filled thin red"
                        		ng-show="!self.message.get('outgoingMessage')"
                        		ng-click="self.acceptProposeToCancel()">
                        	Accept
                        </button>

                    Pending …

                    {{ self.relativeTime(self.lastUpdateTime, self.message.get('date')) }}

                    <svg class="rdflink__small clickable">
                            <use href="#rdf_logo_2"></use>
                    </svg>

                    <svg class="rdflink__small clickable">
                        <use href="#rdf_logo_2"></use>
                    </svg>

    `;

    class Controller {
        constructor(/* arguments = dependency injections */) {
            attach(this, serviceDependencies, arguments);
            this.relativeTime = relativeTime;
            this.clicked = false;
            this.showDetail = false;

            window.cmsg4dbg = this;

            const self = this;

            self.noTextPlaceholder =
                        '«This message couldn\'t be displayed as it didn\'t contain text! ' +
                        'Click on the \"RDF\"-logo in ' +
                        'the context-menu on the right side of the header to see the \"raw\" message-data.»'

            const selectFromState = state => {
                /*
                const connectionUri = selectOpenConnectionUri(state);
                */

                const ownNeed = this.connectionUri && selectNeedByConnectionUri(state, this.connectionUri);
                const connection = ownNeed && ownNeed.getIn(["connections", this.connectionUri]);
                const chatMessages = connection && connection.get("messages");
                const theirNeed = connection && state.getIn(["needs", connection.get('remoteNeedUri')]);
                const message = connection && this.messageUri ?
                    getIn(connection, ["messages", this.messageUri]) :
                    Immutable.Map();

                let text = undefined;
                if(chatMessages && message && (message.get("isProposeMessage") || message.get("isProposeToCancel"))) {
                	const clauses = message.get("clauses");
                	//TODO: delete me
                	//console.log("clauses: " + clauses);

                	//TODO: Array from clauses
                	//now just one message proposed at a time
                	text = this.getClausesText(chatMessages, message, clauses);
                }

                return {
                    ownNeed,
                    theirNeed,
                    connection,
                    message,
                    isRelevant: message.get('isRelevant')? !this.hideOption : false,
                    text: text? text : message? message.get("text") : undefined,
                    contentGraphs: get(message, 'contentGraphs') || Immutable.List(),
                    contentGraphTrigPrefixes: getIn(message, ['contentGraphTrig', 'prefixes']),
                    contentGraphTrig: getIn(message, ['contentGraphTrig', 'body']),
                    lastUpdateTime: state.get('lastUpdateTime'),
                    shouldShowRdf: state.get('showRdf'),
                    allowProposals: connection && connection.get("state") === won.WON.Connected && message.get('text'), //allow showing details only when the connection is already present
                    //isLoading: isLoading,
                }
            };

            connect2Redux(selectFromState, actionCreators, ['self.connectionUri', 'self.messageUri'], this);

            // gotta do this via a $watch, as the whole message parsing before
            // this point happens synchronously but jsonLdToTrig needs to be async.
            /*
            this.$scope.$watch(
                () => this.contentGraphs,
                (newVal, oldVal) => {
                    won.jsonLdToTrig(newVal.toJS())
                    .then(trig => {
                        this.contentGraphTrig = trig;
                    })
                    .catch(e => {
                        this.contentGraphTrig = JSON.stringify(e);
                    })
                }
            )
            */
        }

        getClausesText(chatMessages, message, clausesUri) {
        	for(msg of Array.from(chatMessages)) {
    			if(msg[1].get("uri") === clausesUri || msg[1].get("remoteUri") === clausesUri) {
    				//Get through the caluses "chain" and add the original text
    				if(!msg[1].get("clauses")) {
    					return msg[1].get("text");
    				} else {
    					//TODO: Mutliple clauses
    					return this.getClausesText(chatMessages, msg, msg[1].get("clauses"));
    				}

    			}
        	}
        }

        markAsRead(){
            if(this.message && this.message.get("unread")){
                const payload = {
                    messageUri: this.message.get("uri"),
                    connectionUri: this.connectionUri,
                    needUri: this.ownNeed.get("uri")
                };

                const tmp_messages__markAsRead = this.messages__markAsRead;

                setTimeout(function(){
                    tmp_messages__markAsRead(payload);
                }, MESSAGE_READ_TIMEOUT);
            }
        }

        markAsRelevant(relevant){
        	const payload = {
    			 messageUri: this.message.get("uri"),
                 connectionUri: this.connectionUri,
                 needUri: this.ownNeed.get("uri"),
                 relevant: relevant,
        	}

        	this.messages__markAsRelevant(payload);
        }

        sendProposal(){
        	this.clicked = true;
        	const uri = this.message.get("remoteUri")? this.message.get("remoteUri") : this.message.get("uri");
        	const trimmedMsg = buildProposalMessage(uri, "proposes", this.message.get("text"));
        	this.connections__sendChatMessage(trimmedMsg, this.connectionUri, isTTL=true);

        	this.onSendProposal({proposalUri: uri});
        }

        acceptProposal() {
        	this.clicked = true;
        	const msg = ("Accepted proposal : " + this.message.get("remoteUri"));
        	const trimmedMsg = buildProposalMessage(this.message.get("remoteUri"), "accepts", msg);
        	this.connections__sendChatMessage(trimmedMsg, this.connectionUri, isTTL=true);

        	this.markAsRelevant(false);
        	this.onRemoveData({proposalUri: this.messageUri});
        }

        proposeToCancel() {
        	this.clicked = true;
        	const uri = this.isOwn? this.message.get("uri") : this.message.get("remoteUri");
        	const msg = ("Propose to cancel agreement : " + uri);
        	const trimmedMsg = buildProposalMessage(uri, "proposesToCancel", msg);
        	this.connections__sendChatMessage(trimmedMsg, this.connectionUri, isTTL=true);

        	this.onUpdate();
        }

        acceptProposeToCancel() {
        	this.clicked = true;
        	const msg = ("Accepted propose to cancel : " + this.message.get("remoteUri"));
        	const trimmedMsg = buildProposalMessage(this.message.get("remoteUri"), "accepts", msg);
        	this.connections__sendChatMessage(trimmedMsg, this.connectionUri, isTTL=true);

        	this.markAsRelevant(false);
        	this.onRemoveData({proposalUri: this.messageUri});
        }

        retractMessage() {
        	this.clicked = true;
        	const uri = this.message.get("remoteUri")? this.message.get("remoteUri") : this.message.get("uri");
        	const trimmedMsg = buildModificationMessage(uri, "retracts", this.message.get("text"));
        	this.connections__sendChatMessage(trimmedMsg, this.connectionUri, isTTL=true);
        	this.onUpdate();
        }

        rejectMessage() {
        	this.clicked = true;
        	const uri = this.message.get("remoteUri")? this.message.get("remoteUri") : this.message.get("uri");
        	const trimmedMsg = buildProposalMessage(uri, "rejects",  this.message.get("text"));
        	this.connections__sendChatMessage(trimmedMsg, this.connectionUri, isTTL=true);
        	this.onUpdate();
        }

        rdfToString(jsonld){
        	return JSON.stringify(jsonld);
        }

        isNormalMessage() {
        	return !(this.message.get('isProposeMessage') ||
					this.message.get('isAcceptMessage') ||
					this.message.get('isProposeToCancel') ||
					this.message.get('isRetractMessage'));
        }

        encodeParam(param) {
            var encoded = encodeURIComponent(param);
            // console.log("encoding: ",param);
            // console.log("encoded: ",encoded)
            return encoded;
        }

    }
    Controller.$inject = serviceDependencies;

    return {
        restrict: 'E',
        controller: Controller,
        controllerAs: 'self',
        bindToController: true, //scope-bindings -> ctrl
        scope: {
            messageUri: '=',
            connectionUri: '=',
            hideOption: '=',
            /*
             * Usage:
             *  on-update="::myCallback(draft)"
             */
            onUpdate: '&',
            onSendProposal: '&',
            onRemoveData: '&',
        },
        template: template,
    }
}

export default angular.module('won.owner.components.connectionMessage', [
    squareImageModule,
    labelledHrModule,
    inviewModule.name
])
    .directive('wonConnectionMessage', genComponentConf)
    .name;
<commit_msg>update description for rdf only connection message (rdf toggle was moved to a different component)<commit_after>
;

import angular from 'angular';
import inviewModule from 'angular-inview';

import won from '../won-es6.js';
import jld from 'jsonld';
import Immutable from 'immutable';
import squareImageModule from './square-image.js';
import labelledHrModule from './labelled-hr.js';
import {
    relativeTime,
} from '../won-label-utils.js'
import {
    connect2Redux,
} from '../won-utils.js';
import {
    attach,
    delay,
    get,
    getIn,
    deepFreeze,
    dispatchEvent,
} from '../utils.js'
import {
	buildProposalMessage,
	buildModificationMessage,
} from '../won-message-utils.js';
import {
    actionCreators
}  from '../actions/actions.js';
import {
    selectOpenConnectionUri,
    selectNeedByConnectionUri,
} from '../selectors.js';
import autoresizingTextareaModule from '../directives/textarea-autogrow.js';

const MESSAGE_READ_TIMEOUT = 1500;

const serviceDependencies = ['$ngRedux', '$scope', '$element'];

function genComponentConf() {
    let template = `
        <won-square-image
            title="self.theirNeed.get('title')"
            src="self.theirNeed.get('TODOtitleImgSrc')"
            uri="self.theirNeed.get('uri')"
            ng-click="self.router__stateGoCurrent({postUri: self.theirNeed.get('uri')})"
            ng-show="!self.message.get('outgoingMessage')">
        </won-square-image>

Proposal

Accept

ProposeToCancel

                        {{ self.text? self.text : self.noTextPlaceholder }}

	                        <svg class="won-cm__center__carret clickable"
	                                ng-click="self.showDetail = !self.showDetail"
	                                ng-if="self.allowProposals"
	                                ng-show="!self.showDetail">
	                            <use href="#ico16_arrow_down"></use>
	                        </svg>

	                        	<won-labelled-hr arrow="'up'" style="margin-top: .5rem; margin-bottom: .5rem;"></won-labelled-hr>

                    	<button class="won-button--filled thin black"
                        		ng-click="self.sendProposal(); self.showDetail = !self.showDetail"
                        		ng-show="self.showDetail">Propose (again)
                        </button>

                        @prefix ...
                        {{ self.contentGraphTrigPrefixes }}

                        {{ self.contentGraphTrig }}

                        <button class="won-button--filled thin red"
                        		ng-show="!self.message.get('outgoingMessage') && !self.clicked"
    							ng-click="self.acceptProposal()">
    						Accept
    					</button>

                        <button class="won-button--filled thin red"
                        		ng-show="!self.message.get('outgoingMessage')"
                        		ng-click="self.acceptProposeToCancel()">
                        	Accept
                        </button>

                    Pending …

                    {{ self.relativeTime(self.lastUpdateTime, self.message.get('date')) }}

                    <svg class="rdflink__small clickable">
                            <use href="#rdf_logo_2"></use>
                    </svg>

                    <svg class="rdflink__small clickable">
                        <use href="#rdf_logo_2"></use>
                    </svg>

    `;

    class Controller {
        constructor(/* arguments = dependency injections */) {
            attach(this, serviceDependencies, arguments);
            this.relativeTime = relativeTime;
            this.clicked = false;
            this.showDetail = false;

            window.cmsg4dbg = this;

            const self = this;

            self.noTextPlaceholder =
                        '«This message couldn\'t be displayed as it didn\'t contain text! ' +
                        'Click on the \"Show raw RDF data\"-button in ' +
                        'the main-menu on the right side of the navigationbar to see the \"raw\" message-data.»';

            const selectFromState = state => {
                /*
                const connectionUri = selectOpenConnectionUri(state);
                */

                const ownNeed = this.connectionUri && selectNeedByConnectionUri(state, this.connectionUri);
                const connection = ownNeed && ownNeed.getIn(["connections", this.connectionUri]);
                const chatMessages = connection && connection.get("messages");
                const theirNeed = connection && state.getIn(["needs", connection.get('remoteNeedUri')]);
                const message = connection && this.messageUri ?
                    getIn(connection, ["messages", this.messageUri]) :
                    Immutable.Map();

                let text = undefined;
                if(chatMessages && message && (message.get("isProposeMessage") || message.get("isProposeToCancel"))) {
                	const clauses = message.get("clauses");
                	//TODO: delete me
                	//console.log("clauses: " + clauses);

                	//TODO: Array from clauses
                	//now just one message proposed at a time
                	text = this.getClausesText(chatMessages, message, clauses);
                }

                return {
                    ownNeed,
                    theirNeed,
                    connection,
                    message,
                    isRelevant: message.get('isRelevant')? !this.hideOption : false,
                    text: text? text : message? message.get("text") : undefined,
                    contentGraphs: get(message, 'contentGraphs') || Immutable.List(),
                    contentGraphTrigPrefixes: getIn(message, ['contentGraphTrig', 'prefixes']),
                    contentGraphTrig: getIn(message, ['contentGraphTrig', 'body']),
                    lastUpdateTime: state.get('lastUpdateTime'),
                    shouldShowRdf: state.get('showRdf'),
                    allowProposals: connection && connection.get("state") === won.WON.Connected && message.get('text'), //allow showing details only when the connection is already present
                    //isLoading: isLoading,
                }
            };

            connect2Redux(selectFromState, actionCreators, ['self.connectionUri', 'self.messageUri'], this);

            // gotta do this via a $watch, as the whole message parsing before
            // this point happens synchronously but jsonLdToTrig needs to be async.
            /*
            this.$scope.$watch(
                () => this.contentGraphs,
                (newVal, oldVal) => {
                    won.jsonLdToTrig(newVal.toJS())
                    .then(trig => {
                        this.contentGraphTrig = trig;
                    })
                    .catch(e => {
                        this.contentGraphTrig = JSON.stringify(e);
                    })
                }
            )
            */
        }

        getClausesText(chatMessages, message, clausesUri) {
        	for(msg of Array.from(chatMessages)) {
    			if(msg[1].get("uri") === clausesUri || msg[1].get("remoteUri") === clausesUri) {
    				//Get through the caluses "chain" and add the original text
    				if(!msg[1].get("clauses")) {
    					return msg[1].get("text");
    				} else {
    					//TODO: Mutliple clauses
    					return this.getClausesText(chatMessages, msg, msg[1].get("clauses"));
    				}

    			}
        	}
        }

        markAsRead(){
            if(this.message && this.message.get("unread")){
                const payload = {
                    messageUri: this.message.get("uri"),
                    connectionUri: this.connectionUri,
                    needUri: this.ownNeed.get("uri")
                };

                const tmp_messages__markAsRead = this.messages__markAsRead;

                setTimeout(function(){
                    tmp_messages__markAsRead(payload);
                }, MESSAGE_READ_TIMEOUT);
            }
        }

        markAsRelevant(relevant){
        	const payload = {
    			 messageUri: this.message.get("uri"),
                 connectionUri: this.connectionUri,
                 needUri: this.ownNeed.get("uri"),
                 relevant: relevant,
        	}

        	this.messages__markAsRelevant(payload);
        }

        sendProposal(){
        	this.clicked = true;
        	const uri = this.message.get("remoteUri")? this.message.get("remoteUri") : this.message.get("uri");
        	const trimmedMsg = buildProposalMessage(uri, "proposes", this.message.get("text"));
        	this.connections__sendChatMessage(trimmedMsg, this.connectionUri, isTTL=true);

        	this.onSendProposal({proposalUri: uri});
        }

        acceptProposal() {
        	this.clicked = true;
        	const msg = ("Accepted proposal : " + this.message.get("remoteUri"));
        	const trimmedMsg = buildProposalMessage(this.message.get("remoteUri"), "accepts", msg);
        	this.connections__sendChatMessage(trimmedMsg, this.connectionUri, isTTL=true);

        	this.markAsRelevant(false);
        	this.onRemoveData({proposalUri: this.messageUri});
        }

        proposeToCancel() {
        	this.clicked = true;
        	const uri = this.isOwn? this.message.get("uri") : this.message.get("remoteUri");
        	const msg = ("Propose to cancel agreement : " + uri);
        	const trimmedMsg = buildProposalMessage(uri, "proposesToCancel", msg);
        	this.connections__sendChatMessage(trimmedMsg, this.connectionUri, isTTL=true);

        	this.onUpdate();
        }

        acceptProposeToCancel() {
        	this.clicked = true;
        	const msg = ("Accepted propose to cancel : " + this.message.get("remoteUri"));
        	const trimmedMsg = buildProposalMessage(this.message.get("remoteUri"), "accepts", msg);
        	this.connections__sendChatMessage(trimmedMsg, this.connectionUri, isTTL=true);

        	this.markAsRelevant(false);
        	this.onRemoveData({proposalUri: this.messageUri});
        }

        retractMessage() {
        	this.clicked = true;
        	const uri = this.message.get("remoteUri")? this.message.get("remoteUri") : this.message.get("uri");
        	const trimmedMsg = buildModificationMessage(uri, "retracts", this.message.get("text"));
        	this.connections__sendChatMessage(trimmedMsg, this.connectionUri, isTTL=true);
        	this.onUpdate();
        }

        rejectMessage() {
        	this.clicked = true;
        	const uri = this.message.get("remoteUri")? this.message.get("remoteUri") : this.message.get("uri");
        	const trimmedMsg = buildProposalMessage(uri, "rejects",  this.message.get("text"));
        	this.connections__sendChatMessage(trimmedMsg, this.connectionUri, isTTL=true);
        	this.onUpdate();
        }

        rdfToString(jsonld){
        	return JSON.stringify(jsonld);
        }

        isNormalMessage() {
        	return !(this.message.get('isProposeMessage') ||
					this.message.get('isAcceptMessage') ||
					this.message.get('isProposeToCancel') ||
					this.message.get('isRetractMessage'));
        }

        encodeParam(param) {
            var encoded = encodeURIComponent(param);
            // console.log("encoding: ",param);
            // console.log("encoded: ",encoded)
            return encoded;
        }

    }
    Controller.$inject = serviceDependencies;

    return {
        restrict: 'E',
        controller: Controller,
        controllerAs: 'self',
        bindToController: true, //scope-bindings -> ctrl
        scope: {
            messageUri: '=',
            connectionUri: '=',
            hideOption: '=',
            /*
             * Usage:
             *  on-update="::myCallback(draft)"
             */
            onUpdate: '&',
            onSendProposal: '&',
            onRemoveData: '&',
        },
        template: template,
    }
}

export default angular.module('won.owner.components.connectionMessage', [
    squareImageModule,
    labelledHrModule,
    inviewModule.name
])
    .directive('wonConnectionMessage', genComponentConf)
    .name;
<|endoftext|>


<commit_before>
// Objects shown in the game for this level.
var gameObjects;

// Objects offered in the palette, they can be dragged on to the level to add a game object.
var paletteObjects;

var PALETTE_OBJECT_NAMES = [
                      "pyramid",
                      "spell",
                      "sphinx",
                      "hazard",
];

var background;
var canvas;
var ctx;

// Sprite type used for collision detection and drawing. Matches the size of an image.
function Sprite(name, firstLeft, firstTop) {

	this.image = new Image();
	this.image.src = name + ".png";
	this.image.onload = function() {
		draw();
	}

	this.move = function(newLeft, newTop) {
		this.left = newLeft;
		this.top = newTop;
		this.right = newLeft + this.image.width;
		this.bottom = newTop + this.image.height;
	}
	this.move(firstLeft, firstTop);
}

function handleLoad() {

	canvas = document.getElementById('gameCanvas');
	ctx = canvas.getContext('2d');
	background = new Image();
	background.src = "background.png";
	background.onload = function() {
		draw();
	}

	gameObjects = new Array();
	gameObjects[0] = new Sprite("sphinx", canvas.width / 2, canvas.height / 2);
	gameObjects[1] = new Sprite("pyramid", canvas.width / 2, 0);

	paletteObjects = new Array();
	var paletteIndex;
	for( var i in PALETTE_OBJECT_NAMES ) {
		paletteObjects[paletteIndex++] = new Sprite(
				PALETTE_OBJECT_NAMES[i], 80, 25 + 80 * paletteIndex);
	}

	draw();
}

function draw() {

	ctx.drawImage(background, 0, 0);

	//Draw game objects.
	for( var i in gameObjects ) {
		var gameObject = gameObjects[i];
		ctx.drawImage(gameObject.image, gameObject.left, gameObject.top);
	}

	//Draw palette objects.
	/*
	for( var i in paletteObjects ) {
		var paletteObject = paletteObjects[i];
		ctx.drawImage(paletteObject.image, paletteObject.left, paletteObject.top);
	}
	*/

	//Draw label for the palette area of the editor.
	ctx.font = "bold x-large sans-serif";
	ctx.fillStyle = "white";
	ctx.textAlign = "left";
	ctx.fillText("Palette", 5, 25);

	//Draw a vertical line separating it.
	ctx.moveTo(90, 0);
	ctx.lineTo(90, 512);
	ctx.lineWidth = 5;
	ctx.strokeStyle = "#000";
	ctx.stroke();

	//Draw label for the play area area of the editor.
	ctx.font = "bold x-large sans-serif";
	ctx.fillStyle = "white";
	ctx.textAlign = "left";
	ctx.fillText("Play Area", 100, 25);

}

function collisionCheckSprites(a, b) {
	if ( null == a || null == b ) {
		return false;
	}
	return (a.left <= b.right &&
		b.left <= a.right &&
		a.top <= b.bottom &&
		b.top <= a.bottom)
}

function handleClick() {
}

function handleMouseOver() {
}

function handleMouseOut() {
}

function handleMouseMove(e) {
}
<commit_msg>Show a set of objects in the palette.<commit_after>// Prevent errors in browsers without FireBug.
if (!window.console)
{
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
    window.console = {};
    for (var i = 0; i < names.length; ++i)
        window.console[names[i]] = function() {}
}

// Objects shown in the game for this level.
var gameObjects;

// Objects offered in the palette, they can be dragged on to the level to add a game object.
var paletteObjects;

var PALETTE_OBJECT_NAMES = [
                      "pyramid",
                      "spell",
                      "sphinx",
                      "hazard",
];

var background;
var canvas;
var ctx;

// Sprite type used for collision detection and drawing. Matches the size of an image.
function Sprite(name, firstLeft, firstTop) {

	this.image = new Image();
	this.image.src = name + ".png";
	this.image.onload = function() {
		draw();
	}

	this.move = function(newLeft, newTop) {
		this.left = newLeft;
		this.top = newTop;
		this.right = newLeft + this.image.width;
		this.bottom = newTop + this.image.height;
	}
	this.move(firstLeft, firstTop);
}

function handleLoad() {

	canvas = document.getElementById('gameCanvas');
	ctx = canvas.getContext('2d');
	background = new Image();
	background.src = "background.png";
	background.onload = function() {
		draw();
	}

	gameObjects = new Array();
	gameObjects[0] = new Sprite("sphinx", canvas.width / 2, canvas.height / 2);
	gameObjects[1] = new Sprite("pyramid", canvas.width / 2, 0);

	paletteObjects = new Array();
	var paletteIndex = 0;
	for( var i in PALETTE_OBJECT_NAMES ) {
		console.log(PALETTE_OBJECT_NAMES[i]);
		console.log(paletteIndex);
		paletteObjects[paletteIndex] = new Sprite(
				PALETTE_OBJECT_NAMES[i], 15, 35 + 80 * paletteIndex);
		paletteIndex++;
	}

	draw();
}

function draw() {

	ctx.drawImage(background, 0, 0);

	//Draw game objects.
	for( var i in gameObjects ) {
		var gameObject = gameObjects[i];
		ctx.drawImage(gameObject.image, gameObject.left, gameObject.top);
	}

	//Draw palette objects.
	for( var i in paletteObjects ) {
		var paletteObject = paletteObjects[i];
		ctx.drawImage(paletteObject.image, paletteObject.left, paletteObject.top);
	}

	//Draw label for the palette area of the editor.
	ctx.font = "bold x-large sans-serif";
	ctx.fillStyle = "white";
	ctx.textAlign = "left";
	ctx.fillText("Palette", 5, 25);

	//Draw a vertical line separating it.
	ctx.moveTo(90, 0);
	ctx.lineTo(90, 512);
	ctx.lineWidth = 5;
	ctx.strokeStyle = "#000";
	ctx.stroke();

	//Draw label for the play area area of the editor.
	ctx.font = "bold x-large sans-serif";
	ctx.fillStyle = "white";
	ctx.textAlign = "left";
	ctx.fillText("Play Area", 100, 25);

}

function collisionCheckSprites(a, b) {
	if ( null == a || null == b ) {
		return false;
	}
	return (a.left <= b.right &&
		b.left <= a.right &&
		a.top <= b.bottom &&
		b.top <= a.bottom)
}

function handleClick() {
}

function handleMouseOver() {
}

function handleMouseOut() {
}

function handleMouseMove(e) {
}
<|endoftext|>


<commit_before>'use strict';

const BaseEntity = require('./baseentity.js');

var itemDefinitionIndexMap = {
  1: {
    itemName: 'Desert Eagle',
    className: 'weapon_deagle',
  },
  2: {
    itemName: 'Dual Berettas',
    className: 'weapon_elite',
  },
  3: {
    itemName: 'Five-SeveN',
    className: 'weapon_fiveseven',
  },
  4: {
    itemName: 'Glock-18',
    className: 'weapon_glock',
  },
  7: {
    itemName: 'AK-47',
    className: 'weapon_ak47',
  },
  8: {
    itemName: 'AUG',
    className: 'weapon_aug',
  },
  9: {
    itemName: 'AWP',
    className: 'weapon_awp',
  },
  10: {
    itemName: 'FAMAS',
    className: 'weapon_famas',
  },
  11: {
    itemName: 'G3SG1',
    className: 'weapon_g3sg1',
  },
  13: {
    itemName: 'Galil AR',
    className: 'weapon_galilar',
  },
  14: {
    itemName: 'M249',
    className: 'weapon_m249',
  },
  16: {
    itemName: 'M4A4',
    className: 'weapon_m4a1',
  },
  17: {
    itemName: 'MAC-10',
    className: 'weapon_mac10',
  },
  19: {
    itemName: 'P90',
    className: 'weapon_p90',
  },
  24: {
    itemName: 'UMP-45',
    className: 'weapon_ump45',
  },
  25: {
    itemName: 'XM1014',
    className: 'weapon_xm1014',
  },
  26: {
    itemName: 'PP-Bizon',
    className: 'weapon_bizon',
  },
  27: {
    itemName: 'MAG-7',
    className: 'weapon_mag7',
  },
  28: {
    itemName: 'Negev',
    className: 'weapon_negev',
  },
  29: {
    itemName: 'Sawed-Off',
    className: 'weapon_sawedoff',
  },
  30: {
    itemName: 'Tec-9',
    className: 'weapon_tec9',
  },
  31: {
    itemName: 'Zeus x27',
    className: 'weapon_taser',
  },
  32: {
    itemName: 'P2000',
    className: 'weapon_hkp2000',
  },
  33: {
    itemName: 'MP7',
    className: 'weapon_mp7',
  },
  34: {
    itemName: 'MP9',
    className: 'weapon_mp9',
  },
  35: {
    itemName: 'Nova',
    className: 'weapon_nova',
  },
  36: {
    itemName: 'P250',
    className: 'weapon_p250',
  },
  38: {
    itemName: 'SCAR-20',
    className: 'weapon_scar20',
  },
  39: {
    itemName: 'SG 553',
    className: 'weapon_sg556',
  },
  40: {
    itemName: 'SSG 08',
    className: 'weapon_ssg08',
  },
  42: {
    itemName: 'Knife',
    className: 'weapon_knife',
  },
  43: {
    itemName: 'Flashbang',
    className: 'weapon_flashbang',
  },
  44: {
    itemName: 'High Explosive Grenade',
    className: 'weapon_hegrenade',
  },
  45: {
    itemName: 'Smoke Grenade',
    className: 'weapon_smokegrenade',
  },
  46: {
    itemName: 'Molotov',
    className: 'weapon_molotov',
  },
  47: {
    itemName: 'Decoy Grenade',
    className: 'weapon_decoy',
  },
  48: {
    itemName: 'Incendiary Grenade',
    className: 'weapon_incgrenade',
  },
  49: {
    itemName: 'C4 Explosive',
    className: 'weapon_c4',
  },
  59: {
    itemName: 'Knife',
    className: 'weapon_knife_t',
  },
  60: {
    itemName: 'M4A1-S',
    className: 'weapon_m4a1_silencer',
  },
  61: {
    itemName: 'USP-S',
    className: 'weapon_usp_silencer',
  },
  63: {
    itemName: 'CZ75-Auto',
    className: 'weapon_cz75a',
  },
  64: {
    itemName: 'R8 Revolver',
    className: 'weapon_revolver',
  },
  500: {
    itemName: 'Bayonet',
    className: 'weapon_bayonet',
  },
  505: {
    itemName: 'Flip Knife',
    className: 'weapon_knife_flip',
  },
  506: {
    itemName: 'Gut Knife',
    className: 'weapon_knife_gut',
  },
  507: {
    itemName: 'Karambit',
    className: 'weapon_knife_karambit',
  },
  508: {
    itemName: 'M9 Bayonet',
    className: 'weapon_knife_m9_bayonet',
  },
  509: {
    itemName: 'Huntsman Knife',
    className: 'weapon_knife_tactical',
  },
  512: {
    itemName: 'Falchion Knife',
    className: 'weapon_knife_falchion',
  },
  514: {
    itemName: 'Bowie Knife',
    className: 'weapon_knife_survival_bowie',
  },
  515: {
    itemName: 'Butterfly Knife',
    className: 'weapon_knife_butterfly',
  },
  516: {
    itemName: 'Shadow Dag',
    className: 'weapon_knife_push',
  },
};

/**
 * Represents an in-game weapon (guns, grenades, knifes).
 */
class Weapon extends BaseEntity {
  /**
   * @returns {integer} Item index
   */
  get itemIndex() {
    return this.getProp('DT_ScriptCreatedItem', 'm_iItemDefinitionIndex');
  }

  /**
   * @returns {string} Name of the weapon
   */
  get itemName() {
    var weaponId = this.itemIndex;

    return itemDefinitionIndexMap[weaponId] != undefined ? itemDefinitionIndexMap[weaponId].itemName : 'unknown';
  }

  /**
   * @returns {string} Class Name of the weapon
   */
  get className() {
    var weaponId = this.itemIndex;

    return itemDefinitionIndexMap[weaponId] != undefined ? itemDefinitionIndexMap[weaponId].className : 'unknown';
  }

  /**
   * @returns {Player|null} Previous Owner
   */
  get prevOwner() {
    var userId = this.getProp('DT_WeaponCSBase', 'm_hPrevOwner'),
        user = null;

    if (user = this._demo.entities.getByUserId(userId)) {
      return user;
    }

    return null;
  }
}

module.exports = Weapon;
<commit_msg>Fixing prevOwner property from Weapon entity<commit_after>'use strict';

const BaseEntity = require('./baseentity.js');

var itemDefinitionIndexMap = {
  1: {
    itemName: 'Desert Eagle',
    className: 'weapon_deagle',
  },
  2: {
    itemName: 'Dual Berettas',
    className: 'weapon_elite',
  },
  3: {
    itemName: 'Five-SeveN',
    className: 'weapon_fiveseven',
  },
  4: {
    itemName: 'Glock-18',
    className: 'weapon_glock',
  },
  7: {
    itemName: 'AK-47',
    className: 'weapon_ak47',
  },
  8: {
    itemName: 'AUG',
    className: 'weapon_aug',
  },
  9: {
    itemName: 'AWP',
    className: 'weapon_awp',
  },
  10: {
    itemName: 'FAMAS',
    className: 'weapon_famas',
  },
  11: {
    itemName: 'G3SG1',
    className: 'weapon_g3sg1',
  },
  13: {
    itemName: 'Galil AR',
    className: 'weapon_galilar',
  },
  14: {
    itemName: 'M249',
    className: 'weapon_m249',
  },
  16: {
    itemName: 'M4A4',
    className: 'weapon_m4a1',
  },
  17: {
    itemName: 'MAC-10',
    className: 'weapon_mac10',
  },
  19: {
    itemName: 'P90',
    className: 'weapon_p90',
  },
  24: {
    itemName: 'UMP-45',
    className: 'weapon_ump45',
  },
  25: {
    itemName: 'XM1014',
    className: 'weapon_xm1014',
  },
  26: {
    itemName: 'PP-Bizon',
    className: 'weapon_bizon',
  },
  27: {
    itemName: 'MAG-7',
    className: 'weapon_mag7',
  },
  28: {
    itemName: 'Negev',
    className: 'weapon_negev',
  },
  29: {
    itemName: 'Sawed-Off',
    className: 'weapon_sawedoff',
  },
  30: {
    itemName: 'Tec-9',
    className: 'weapon_tec9',
  },
  31: {
    itemName: 'Zeus x27',
    className: 'weapon_taser',
  },
  32: {
    itemName: 'P2000',
    className: 'weapon_hkp2000',
  },
  33: {
    itemName: 'MP7',
    className: 'weapon_mp7',
  },
  34: {
    itemName: 'MP9',
    className: 'weapon_mp9',
  },
  35: {
    itemName: 'Nova',
    className: 'weapon_nova',
  },
  36: {
    itemName: 'P250',
    className: 'weapon_p250',
  },
  38: {
    itemName: 'SCAR-20',
    className: 'weapon_scar20',
  },
  39: {
    itemName: 'SG 553',
    className: 'weapon_sg556',
  },
  40: {
    itemName: 'SSG 08',
    className: 'weapon_ssg08',
  },
  42: {
    itemName: 'Knife',
    className: 'weapon_knife',
  },
  43: {
    itemName: 'Flashbang',
    className: 'weapon_flashbang',
  },
  44: {
    itemName: 'High Explosive Grenade',
    className: 'weapon_hegrenade',
  },
  45: {
    itemName: 'Smoke Grenade',
    className: 'weapon_smokegrenade',
  },
  46: {
    itemName: 'Molotov',
    className: 'weapon_molotov',
  },
  47: {
    itemName: 'Decoy Grenade',
    className: 'weapon_decoy',
  },
  48: {
    itemName: 'Incendiary Grenade',
    className: 'weapon_incgrenade',
  },
  49: {
    itemName: 'C4 Explosive',
    className: 'weapon_c4',
  },
  59: {
    itemName: 'Knife',
    className: 'weapon_knife_t',
  },
  60: {
    itemName: 'M4A1-S',
    className: 'weapon_m4a1_silencer',
  },
  61: {
    itemName: 'USP-S',
    className: 'weapon_usp_silencer',
  },
  63: {
    itemName: 'CZ75-Auto',
    className: 'weapon_cz75a',
  },
  64: {
    itemName: 'R8 Revolver',
    className: 'weapon_revolver',
  },
  500: {
    itemName: 'Bayonet',
    className: 'weapon_bayonet',
  },
  505: {
    itemName: 'Flip Knife',
    className: 'weapon_knife_flip',
  },
  506: {
    itemName: 'Gut Knife',
    className: 'weapon_knife_gut',
  },
  507: {
    itemName: 'Karambit',
    className: 'weapon_knife_karambit',
  },
  508: {
    itemName: 'M9 Bayonet',
    className: 'weapon_knife_m9_bayonet',
  },
  509: {
    itemName: 'Huntsman Knife',
    className: 'weapon_knife_tactical',
  },
  512: {
    itemName: 'Falchion Knife',
    className: 'weapon_knife_falchion',
  },
  514: {
    itemName: 'Bowie Knife',
    className: 'weapon_knife_survival_bowie',
  },
  515: {
    itemName: 'Butterfly Knife',
    className: 'weapon_knife_butterfly',
  },
  516: {
    itemName: 'Shadow Dag',
    className: 'weapon_knife_push',
  },
};

/**
 * Represents an in-game weapon (guns, grenades, knifes).
 */
class Weapon extends BaseEntity {
  /**
   * @returns {integer} Item index
   */
  get itemIndex() {
    return this.getProp('DT_ScriptCreatedItem', 'm_iItemDefinitionIndex');
  }

  /**
   * @returns {string} Name of the weapon
   */
  get itemName() {
    var weaponId = this.itemIndex;

    return itemDefinitionIndexMap[weaponId] != undefined ? itemDefinitionIndexMap[weaponId].itemName : 'unknown';
  }

  /**
   * @returns {string} Class Name of the weapon
   */
  get className() {
    var weaponId = this.itemIndex;

    return itemDefinitionIndexMap[weaponId] != undefined ? itemDefinitionIndexMap[weaponId].className : 'unknown';
  }

  /**
   * @returns {Player|null} Previous Owner
   */
  get prevOwner() {
    var userId = this.getProp('DT_WeaponCSBase', 'm_hPrevOwner'),
        user = null;

    if (user = this._demo.entities.getByHandle(userId)) {
      return user;
    }

    return null;
  }
}

module.exports = Weapon;
<|endoftext|>


<commit_before>var VP9 = VP9 || {};

VP9.playerHTML5 = function(player) {
	var _this = this;

	this.name = 'HTML5';
	this.state =  'IDLE';

	this.init = function() {
		player.$player.empty();

		_this.creatDisplay();
	    player.creatDisplay();
		_this.creatControls();
		player.creatControls();

		//init plugin before set video
    	player.plugins.init();

		this.ui.hideControls();

	    //onclick
	    player.$playBtn.on('click', function() {
			if (_this.player.paused) {
				_this.player.play();
			}
			else {
				_this.player.pause();
			}
	    });

	   	player.ready.call(this);
    	if (typeof(player.options.ready) == 'function') {
	   		player.options.ready.call(this, player);
	   	}

		player.setPlaylist(player.options.playlist);
		player.setVideo(player.options.activeVideo);
	}

	this.destroy = function() {}

	this.creatDisplay = function() {
		player.$display = $('

').appendTo(player.$player);
		player.$media = $('

')
			.css({
				overflow: 'hidden',
				height: '100%',
				width: '100%',
				top: '0px',
				left: '0px',
				padding: '0px',
				margin: '0px',
				display: 'block'
			})
			.appendTo(player.$display);

		player.$start = $('

')
			.on('click', function(event) {
				event.preventDefault();
				player.$playBtn.click();
			})
			.appendTo(player.$display);

		player.$buffering = $('

').appendTo(player.$display);
	}

	this.creatControls = function() {}

    this.ui = {};
    this.ui.onEvent = function() {}

    this.ui.resume = function() {}

    this.ui.autoPlay = function() {}

    this.ui.scale = function() {}

	_this.ui.hideTimeout = null;
    this.ui.hideControls = function() {}

    this.ui.setDuration = function(duration) {};

    this.ui.setCurrentTime = function(currentTime, duration) {}

    this.ui.setStop = function() {}

    this.ui.setVideo = function(id) {}

    //Events
    player.onReady = function(func) {}

    player.onPlay = function(func) {}

    player.onFirstPlay = function(func) {}

    player.onPause = function(func) {}

    player.onEnded = function(func) {}

    var onStop = [];
    player.onStop = function(func) {}

    var onSetVideo = [];
    player.onSetVideo = function(func) {}

    player.onTimeupdate = function(func) {}

    player.onError = function(func) {}

    player.onSeeking = function(func) {}

    player.onSeeked = function(func) {}

    //methods
    player.setPlay = function() {}

    player.setPause = function() {}

	player.setStop = function() {}

	player.setSeek = function(time) {}

	player.setVideo = function(item, seekTime) {}

	player.setPlaylist = function(playlist) {}

	player.setAutoNext = function(auto) {}

    player.addItem = function(data) {}

    player.removeItem = function(data) {}

	player.getCurrentVideo = function() {}

	player.getCurrentTime = function() {}

	player.getState = function(state) {}

    this.init();
}
<commit_msg>player.HTML5 createControls<commit_after>var VP9 = VP9 || {};

VP9.playerHTML5 = function(player) {
	var _this = this;

	this.name = 'HTML5';
	this.state =  'IDLE';

	this.init = function() {
		player.$player.empty();

		_this.creatDisplay();
	    player.creatDisplay();
		_this.creatControls();
		player.creatControls();

		//init plugin before set video
    	player.plugins.init();

		this.ui.hideControls();

	    //onclick
	    player.$playBtn.on('click', function() {
			if (_this.player.paused) {
				_this.player.play();
			}
			else {
				_this.player.pause();
			}
	    });

	   	player.ready.call(this);
    	if (typeof(player.options.ready) == 'function') {
	   		player.options.ready.call(this, player);
	   	}

		player.setPlaylist(player.options.playlist);
		player.setVideo(player.options.activeVideo);
	}

	this.destroy = function() {}

	this.creatDisplay = function() {
		player.$display = $('

').appendTo(player.$player);
		player.$media = $('

')
			.css({
				overflow: 'hidden',
				height: '100%',
				width: '100%',
				top: '0px',
				left: '0px',
				padding: '0px',
				margin: '0px',
				display: 'block'
			})
			.appendTo(player.$display);

		player.$start = $('

')
			.on('click', function(event) {
				event.preventDefault();
				player.$playBtn.click();
			})
			.appendTo(player.$display);

		player.$buffering = $('

').appendTo(player.$display);
	}

	this.creatControls = function() {
		player.$controls = $('

')
			.appendTo(player.$player);

		if ($.inArray('fullscreen', player.options.controls) >= 0 && window.screenfull) {
			player.addControl('fsExitBtn', '

', '.right')
				.on('click', function(event) {
					event.preventDefault();
					screenfull.exit();
					player.$fsExitBtn.removeClass('active').addClass('inactive');
					player.$fsEnterBtn.removeClass('inactive').addClass('active');
				});
			player.addControl('fsEnterBtn', '

', '.right')
				.on('click', function(event) {
					event.preventDefault();
					screenfull.request();
					player.$fsExitBtn.removeClass('inactive').addClass('active');
					player.$fsEnterBtn.removeClass('active').addClass('inactive');
				});
		}

		if ($.inArray('timeleft', player.options.controls) >= 0) {
			player.addControl('timeleftBar', '
00:00:00 | 00:00:00
', '.right');

	    	_this.$dur = player.$timeleftBar.find('.ppdur');
	    	_this.$elp = player.$timeleftBar.find('.ppelp');
		}

		if ($.inArray('progress', player.options.controls) >= 0) {
			player.addControl('progressBar', '

', '.bottom');

			player.$playhead = player.$progressBar.find('.ppplayhead');
			player.$scrubberdrag = player.$progressBar.find('.ppscrubberdrag')
				.on('click', function(event) {
					event.preventDefault();
					if (_this.player.readyState == 0) {
						return false;
					}

		            var x = $(this).offset().left;
		            var dx = event.clientX - x;
		            var widthSlider = $(this).width();
		            var seekTime = dx * _this.player.duration / widthSlider;
					_this.ui.setCurrentTime(seekTime, _this.player.duration);
		            _this.player.currentTime = seekTime;
				});
		}

		if ($.inArray('next', player.options.controls) >= 0) {
			player.addControl('nextBtn', '

', '.right')
				.on('click', function(event) {
					event.preventDefault();
					player.setVideo('next');
				});
		}

		if ($.inArray('prev', player.options.controls) >= 0) {
			player.addControl('prevBtn', '

', '.right')
				.on('click', function(event) {
					event.preventDefault();
					player.setVideo('prev');
				});
		}
	}

    this.ui = {};
    this.ui.onEvent = function() {}

    this.ui.resume = function() {}

    this.ui.autoPlay = function() {}

    this.ui.scale = function() {}

	_this.ui.hideTimeout = null;
    this.ui.hideControls = function() {}

    this.ui.setDuration = function(duration) {};

    this.ui.setCurrentTime = function(currentTime, duration) {}

    this.ui.setStop = function() {}

    this.ui.setVideo = function(id) {}

    //Events
    player.onReady = function(func) {}

    player.onPlay = function(func) {}

    player.onFirstPlay = function(func) {}

    player.onPause = function(func) {}

    player.onEnded = function(func) {}

    var onStop = [];
    player.onStop = function(func) {}

    var onSetVideo = [];
    player.onSetVideo = function(func) {}

    player.onTimeupdate = function(func) {}

    player.onError = function(func) {}

    player.onSeeking = function(func) {}

    player.onSeeked = function(func) {}

    //methods
    player.setPlay = function() {}

    player.setPause = function() {}

	player.setStop = function() {}

	player.setSeek = function(time) {}

	player.setVideo = function(item, seekTime) {}

	player.setPlaylist = function(playlist) {}

	player.setAutoNext = function(auto) {}

    player.addItem = function(data) {}

    player.removeItem = function(data) {}

	player.getCurrentVideo = function() {}

	player.getCurrentTime = function() {}

	player.getState = function(state) {}

    this.init();
}
<|endoftext|>


<commit_before>/*
---
script: template.js
license: MIT-style license.
description: Template - Context aware template engine with conditional replacement & iteration.
copyright: Copyright (c) 2011 Thierry Bela
authors: [Thierry Bela]

requires:
  core:1.3:
  - Class
  - Elements.from

provides: [Template]
...
*/

!function (context, undefined) {

"use strict";

	function log() { if(context.console && context.console.log) context.console.log.apply(context.console, arguments) }

	context.Template = new Class({

		options: {

			debug: true,
			multiline: false,
			placeholder: '\u21b5',
			//handle unknown tag
			parse: function (tag, matches /*, name, data, string, regExp, replace, simplereg, options */) {

				if(options.debug) log('unknown tag: ' + tag, matches);

				return matches[3]
			},
			begin: '{',
			end: '}'
		},

		modifiers: {},

		regExp: '{begin}([a-z0-9][a-z0-9-_]*):([a-z0-9_.-]*){end}(.*?){begin}\\/\\1:\\2{end}',

		initialize: function (options) {

			this.options = Object.append(this.options, options)
		},

		addModifier: function (name, fn) {

			if(typeof name == 'object') Object.each(function (name, value) { this.modifiers[name] = value }, this);

			else this.modifiers[name] = fn;

			return this
		},

		substitute: function (string, data, options) {

			options = Object.append({}, this.options, options);

			var replace ={begin: options.begin.escapeRegExp(), end: options.end.escapeRegExp()},
				regExp = new RegExp(this.regExp.substitute(replace), 'i'),
				simplereg = new RegExp(('\\\\?{begin}([^' + (['[', ']'].indexOf(options.begin) != -1 ? replace.begin : replace.begin.replace(/\\/g, '')) + ']+){end}').substitute(replace), 'g');

			if(options.multiline) return this.parse(string.replace(/\n/g, options.placeholder), data, regExp, replace, simplereg, options).replace(new RegExp(options.placeholder.escapeRegExp(), 'g'), '\n');

			return this.parse(string, data, regExp, replace, simplereg, options)
		},

		html: function () { return Elements.from(this.substitute.apply(this, arguments)) },

		parse: function (string, data, regExp, replace, simplereg, options) {

			if(data != undefined) {

				var matches = regExp.exec(string);

				if(matches) {

					var tag = matches[1], test, name = matches[2], context, el, html = '', subject;

					switch(tag) {

						case 'if':
						case 'defined':
						case 'empty':
						case 'not-empty':

								//switch context for object or array
								subject = this.evaluate(data, name);

								test = this.test(tag, subject);

								context = test && tag == 'if' && typeof subject == 'object';

								//if-else or something like that
								el = new RegExp('(.*?)' + replace.begin + 'else:' + name.escapeRegExp() + replace.end + '(.*)', 'i').exec(matches[3]);

								if(el) {

									if(!test) return this.parse(string.replace(matches[0], el[2]), data, regExp, replace, simplereg, options);

									if(context) return this.parse(string.replace(matches[0], this.parse(el[1], subject, regExp, replace, simplereg, options)), data, regExp, replace, simplereg, options);
									return this.parse(string.replace(matches[0], el[1]), data, regExp, replace, simplereg, options);
								}

								if(!test) return this.parse(string.replace(matches[0], ''), data, regExp, replace, simplereg, options);

								if(context) return this.parse(string.replace(matches[0], this.parse(matches[3], subject, regExp, replace, simplereg, options)), data, regExp, replace, simplereg, options);

								return this.parse(string.replace(matches[0], matches[3]), data, regExp, replace, simplereg, options);

						case 'repeat':
						case 'loop':

							subject = tag == 'loop' ? (typeof data == 'function' ? data() : data) : this.evaluate(data, name);

							if(!this.test(tag, subject)) return this.parse(string.replace(matches[0], ''), data, regExp, replace, simplereg, options);

							var value, property, single = new RegExp(replace.begin + '\.' + replace.end, 'g');

							//iterable - Array or Hash like
							if(typeof subject.each == 'function')  subject.each(function (value) {

								if(typeof value == 'function') value = value();

								if(value == undefined) return;

								html += typeof value != 'object' ? matches[3].replace(single, value) : this.parse(matches[3], value, regExp, replace,  simplereg, options)
							}, this);

							else for(property in subject) if(subject.hasOwnProperty(property)) {

								value = this.evaluate(subject, property);

								if(value == undefined) continue;

								//hopefully matches[3] should be a simple token. replace {.} by the property value
								html += typeof value != 'object' ? matches[3].replace(single, value) : this.parse(matches[3], value, regExp, replace,  simplereg, options)
							}

							return this.parse(string.replace(matches[0], html), data, regExp, replace, simplereg, options);

						default:

							//custom tag parsing
							if(options.parse) return this.parse(string.replace(matches[0], options.parse(tag, matches, name, data, string, regExp, replace, simplereg, options) || ''), data, regExp, replace, simplereg, options);
					}
				}
			}

			return string.replace(simplereg, function(match, name) {

				if (match.charAt(0) == '\\') return match.slice(1);

				if(options.debug && name.indexOf(':') != -1) log('suspicious token found: "' + match + '", is the ' + (match.charAt(1) == '/' ? 'opening' : 'closing') + ' token missing ? ' + (string.indexOf('\n') != -1 ? ' try to set the option {multiline: true}' : ''), string);

				var value = this.evaluate(data, name);

				return value == undefined ? '' : value

			}.bind(this))
		},

		test: function (tag, value) {

			switch(tag) {

				case 'if':
				case 'not-empty':
						return !!value;

				case 'defined':
						return value != undefined;
				case 'empty':
						return !value;

				case 'loop':
				case 'repeat':
						return value != undefined && ['object', 'function'].indexOf(typeof value)  != -1;
			}

			return true
		},

		evaluate: function (object, property) {

			if(object == undefined) return undefined;

			if(this.modifiers[property] != undefined) return this.modifiers[property](object, name);

			if(property.indexOf('.') != -1) {

				var value = typeof object == 'function' ? object() : object, paths = property.split('.'), key, i;

				for(i = 0; i < paths.length; i++) {

					key = paths[i];

					if(value[key] == undefined) return undefined;

					value = typeof value[key] == 'function' ? value[key]() : value[key]
				}

				return value
			}

			return typeof object[property] == 'function' ? object[property]() : object[property]
		}
	})

}(this);
<commit_msg>fix parameter<commit_after>/*
---
script: template.js
license: MIT-style license.
description: Template - Context aware template engine with conditional replacement & iteration.
copyright: Copyright (c) 2011 Thierry Bela
authors: [Thierry Bela]

requires:
  core:1.3:
  - Class
  - Elements.from

provides: [Template]
...
*/

!function (context, undefined) {

"use strict";

	function log() { if(context.console && context.console.log) context.console.log.apply(context.console, arguments) }

	context.Template = new Class({

		options: {

			debug: true,
			multiline: false,
			placeholder: '\u21b5',
			//handle unknown tag
			parse: function (tag, matches /*, name, data, string, regExp, replace, simplereg, options */) {

				if(options.debug) log('unknown tag: ' + tag, matches);

				return matches[3]
			},
			begin: '{',
			end: '}'
		},

		modifiers: {},

		regExp: '{begin}([a-z0-9][a-z0-9-_]*):([a-z0-9_.-]*){end}(.*?){begin}\\/\\1:\\2{end}',

		initialize: function (options) {

			this.options = Object.append(this.options, options)
		},

		addModifier: function (name, fn) {

			if(typeof name == 'object') Object.each(function (name, value) { this.modifiers[name] = value }, this);

			else this.modifiers[name] = fn;

			return this
		},

		substitute: function (string, data, options) {

			options = Object.append({}, this.options, options);

			var replace ={begin: options.begin.escapeRegExp(), end: options.end.escapeRegExp()},
				regExp = new RegExp(this.regExp.substitute(replace), 'i'),
				simplereg = new RegExp(('\\\\?{begin}([^' + (['[', ']'].indexOf(options.begin) != -1 ? replace.begin : replace.begin.replace(/\\/g, '')) + ']+){end}').substitute(replace), 'g');

			if(options.multiline) return this.parse(string.replace(/\n/g, options.placeholder), data, regExp, replace, simplereg, options).replace(new RegExp(options.placeholder.escapeRegExp(), 'g'), '\n');

			return this.parse(string, data, regExp, replace, simplereg, options)
		},

		html: function () { return Elements.from(this.substitute.apply(this, arguments)) },

		parse: function (string, data, regExp, replace, simplereg, options) {

			if(data != undefined) {

				var matches = regExp.exec(string);

				if(matches) {

					var tag = matches[1], test, name = matches[2], context, el, html = '', subject;

					switch(tag) {

						case 'if':
						case 'defined':
						case 'empty':
						case 'not-empty':

								//switch context for object or array
								subject = this.evaluate(data, name);

								test = this.test(tag, subject);

								context = test && tag == 'if' && typeof subject == 'object';

								//if-else or something like that
								el = new RegExp('(.*?)' + replace.begin + 'else:' + name.escapeRegExp() + replace.end + '(.*)', 'i').exec(matches[3]);

								if(el) {

									if(!test) return this.parse(string.replace(matches[0], el[2]), data, regExp, replace, simplereg, options);

									if(context) return this.parse(string.replace(matches[0], this.parse(el[1], subject, regExp, replace, simplereg, options)), data, regExp, replace, simplereg, options);
									return this.parse(string.replace(matches[0], el[1]), data, regExp, replace, simplereg, options);
								}

								if(!test) return this.parse(string.replace(matches[0], ''), data, regExp, replace, simplereg, options);

								if(context) return this.parse(string.replace(matches[0], this.parse(matches[3], subject, regExp, replace, simplereg, options)), data, regExp, replace, simplereg, options);

								return this.parse(string.replace(matches[0], matches[3]), data, regExp, replace, simplereg, options);

						case 'repeat':
						case 'loop':

							subject = tag == 'loop' ? (typeof data == 'function' ? data() : data) : this.evaluate(data, name);

							if(!this.test(tag, subject)) return this.parse(string.replace(matches[0], ''), data, regExp, replace, simplereg, options);

							var value, property, single = new RegExp(replace.begin + '\.' + replace.end, 'g');

							//iterable - Array or Hash like
							if(typeof subject.each == 'function')  subject.each(function (value) {

								if(typeof value == 'function') value = value();

								if(value == undefined) return;

								html += typeof value != 'object' ? matches[3].replace(single, value) : this.parse(matches[3], value, regExp, replace,  simplereg, options)
							}, this);

							else for(property in subject) if(subject.hasOwnProperty(property)) {

								value = this.evaluate(subject, property);

								if(value == undefined) continue;

								//hopefully matches[3] should be a simple token. replace {.} by the property value
								html += typeof value != 'object' ? matches[3].replace(single, value) : this.parse(matches[3], value, regExp, replace,  simplereg, options)
							}

							return this.parse(string.replace(matches[0], html), data, regExp, replace, simplereg, options);

						default:

							//custom tag parsing
							if(options.parse) return this.parse(string.replace(matches[0], options.parse(tag, matches, name, data, string, regExp, replace, simplereg, options) || ''), data, regExp, replace, simplereg, options);
					}
				}
			}

			return string.replace(simplereg, function(match, name) {

				if (match.charAt(0) == '\\') return match.slice(1);

				if(options.debug && name.indexOf(':') != -1) log('suspicious token found: "' + match + '", is the ' + (match.charAt(1) == '/' ? 'opening' : 'closing') + ' token missing ? ' + (string.indexOf('\n') != -1 ? ' try to set the option {multiline: true}' : ''), string);

				var value = this.evaluate(data, name);

				return value == undefined ? '' : value

			}.bind(this))
		},

		test: function (tag, value) {

			switch(tag) {

				case 'if':
				case 'not-empty':
						return !!value;

				case 'defined':
						return value != undefined;
				case 'empty':
						return !value;

				case 'loop':
				case 'repeat':
						return value != undefined && ['object', 'function'].indexOf(typeof value)  != -1;
			}

			return true
		},

		evaluate: function (object, property) {

			if(object == undefined) return undefined;

			if(this.modifiers[property] != undefined) return this.modifiers[property](object, property);

			if(property.indexOf('.') != -1) {

				var value = typeof object == 'function' ? object() : object, paths = property.split('.'), key, i;

				for(i = 0; i < paths.length; i++) {

					key = paths[i];

					if(value[key] == undefined) return undefined;

					value = typeof value[key] == 'function' ? value[key]() : value[key]
				}

				return value
			}

			return typeof object[property] == 'function' ? object[property]() : object[property]
		}
	})

}(this);
<|endoftext|>


<commit_before>requirejs.config({
  "paths": {
    "jquery": "../libs/jquery.min",
    "imagesLoaded": "../libs/jquery.imagesloaded",
    "wookmark": "../jquery.wookmark",
    "colorbox": "../libs/jquery.colorbox-min"
  },
  "shim": {
    "colorbox": ["jquery"]
  }
});

requirejs(['jquery', 'imagesLoaded', 'wookmark', 'colorbox'], function($) {
  $('#tiles').imagesLoaded(function() {
    // Prepare layout options.
    var options = {
      autoResize: true, // This will auto-update the layout when the browser window is resized.
      container: $('#main'), // Optional, used for some extra CSS styling
      offset: 2, // Optional, the distance between grid items
      itemWidth: 210 // Optional, the width of a grid item
    };

    // Get a reference to your grid items.
    var handler = $('#tiles li');

    // Call the layout function.
    handler.wookmark(options);

    // Init lightbox
    $('a', handler).colorbox({
      rel: 'lightbox'
    });
  });
});
<commit_msg>FIX: example amd was missing required shim so imagesLoaded plugin attaches itself to jQuery<commit_after>requirejs.config({
  "paths": {
    "jquery": "../libs/jquery.min",
    "imagesLoaded": "../libs/jquery.imagesloaded",
    "wookmark": "../jquery.wookmark",
    "colorbox": "../libs/jquery.colorbox-min"
  },
  "shim": {
    "colorbox": ["jquery"],
    "imagesLoaded": ["jquery"]
  }
});

requirejs(['jquery', 'imagesLoaded', 'wookmark', 'colorbox'], function($) {
  $('#tiles').imagesLoaded(function() {
    // Prepare layout options.
    var options = {
      autoResize: true, // This will auto-update the layout when the browser window is resized.
      container: $('#main'), // Optional, used for some extra CSS styling
      offset: 2, // Optional, the distance between grid items
      itemWidth: 210 // Optional, the width of a grid item
    };

    // Get a reference to your grid items.
    var handler = $('#tiles li');

    // Call the layout function.
    handler.wookmark(options);

    // Init lightbox
    $('a', handler).colorbox({
      rel: 'lightbox'
    });
  });
});
<|endoftext|>


<commit_before>/**
 * Created by gbecan on 17/12/14.
 */

/**
 * Sort two elements by their names (accessed with x.name)
 * @param a
 * @param b
 * @returns {number}
 */
function sortByName(a, b) {
    if (a.name < b.name) {
        return -1;
    } else if (a.name > b.name) {
        return 1;
    } else {
        return 0;
    }
}

pcmApp.controller("PCMEditorController", function($scope, $http) {

    // Load PCM
    var pcmMM = Kotlin.modules['pcm'].pcm;
    var factory = new pcmMM.factory.DefaultPcmFactory();
    var loader = factory.createJSONLoader();
    var serializer = factory.createJSONSerializer();

    // Init
    var features = [];
    var featureHeaders = [];
    var productHeaders = [];
    var products = [];

    if (typeof id === 'undefined') {
        // Create example PCM
        $scope.pcm = factory.createPCM();

        var exampleFeature = factory.createFeature();
        exampleFeature.name = "Feature";
        $scope.pcm.addFeatures(exampleFeature);

        var exampleFeature1 = factory.createFeature();
        exampleFeature1.name = "Feature1";
        $scope.pcm.addFeatures(exampleFeature1);

        var exampleProduct = factory.createProduct();
        exampleProduct.name = "Product";
        $scope.pcm.addProducts(exampleProduct);

        var exampleCell = factory.createCell();
        exampleCell.feature = exampleFeature;
        exampleCell.content = "Yes";
        exampleProduct.addValues(exampleCell);

        var exampleCell1 = factory.createCell();
        exampleCell1.feature = exampleFeature1;
        exampleCell1.content = "No";
        exampleProduct.addValues(exampleCell1);

        initializeHOT();

    } else {

        $http.get("/api/get/" + id).success(function (data) {
            $scope.pcm = loader.loadModelFromString(JSON.stringify(data)).get(0);
            initializeHOT();
        });

    }

    function initializeHOT() {
        // Transform features to handonstable data structures
        var kFeatures = getConcreteFeatures($scope.pcm).sort(sortByName); // $scope.pcm.features.array
        for (var i = 0; i < kFeatures.length; i++) {
            features.push({
                data: property(kFeatures[i].generated_KMF_ID)
            });
            featureHeaders.push(kFeatures[i].name);
        }

        // Transform products to handonstable data structures
        var kProducts = $scope.pcm.products.array.sort(sortByName);
        for (var i = 0; i < kProducts.length; i++) {
            var product = kProducts[i];

            productHeaders.push(product.name);
            products.push(model(product));

        }

        var container = document.getElementById('hot');
        var hot = new Handsontable(container,
            {
                data: products,
                dataSchema: schema,
                rowHeaders: productHeaders,
                colHeaders: featureHeaders,
                columns: features,
                contextMenu: true,
                //stretchH: 'all', // Scroll bars ?!
                manualColumnMove: true,
                manualRowMove: true
            });
    }

    function getConcreteFeatures(pcm) {

        var aFeatures = pcm.features.array;

        var features = [];
        for (var i = 0; i < aFeatures.length; i++) {
            var aFeature = aFeatures[i];
            features = features.concat(getConcreteFeaturesRec(aFeature))
        }

        return features;
    }

    function getConcreteFeaturesRec(aFeature) {

        var features = [];

        if (typeof aFeature.subFeatures !== 'undefined') {
            var subFeatures = aFeature.subFeatures.array;
            for (var i = 0; i < subFeatures.length; i++) {
                var subFeature = subFeatures[i];
                features = features.concat(getConcreteFeaturesRec(subFeature));
            }
        } else {
            features.push(aFeature);
        }

        return features;
    }

    /**
     * Synchronization function between handsontable and a PCM model of a product
     * @param product : KMF model of a product
     * @returns synchronization object
     */
    function model(product) {
        var idKMF = product.generated_KMF_ID;
        return idKMF;
    }

    function schema() {
        var newProduct = factory.createProduct();
        $scope.pcm.addProducts(newProduct);

        for (var i = 0; i < $scope.pcm.features.array.length; i++) {
            var cell = factory.createCell();
            cell.feature = $scope.pcm.features.array[i];
            cell.content = "";
            newProduct.addValues(cell);
        }

        return model(newProduct);
    }

    /**
     * Bind handsontable cells to PCM cells
     * @param attr
     * @returns synchronization function
     */
    function property(attr) {
        return function (row, value) {
            var product = $scope.pcm.findProductsByID(row);
            //var cell = product.select("values[feature/id == " + attr + "]").get(0); // FIXME : does not work ! We need to find the cell that correponds to the feature id
            var cells = product.values.array
            for (var i = 0; i < cells.length; i++) {
                var cell = cells[i];
                if (cell.feature.generated_KMF_ID === attr) {
                    break;
                }
            }

            if (typeof value === 'undefined') {
                return cell.content;
            } else {
                cell.content = value;
                return row;
            }
        }
    }

    /**
     * Save PCM on the server
     */
    $scope.save = function() {
        var jsonModel = serializer.serialize($scope.pcm);

        if (typeof id === 'undefined') {
            $http.post("/api/create", JSON.parse(jsonModel)).success(function(data) {
                id = data;
                console.log("model created with id=" + id);
            });
        } else {
            $http.post("/api/save/" + id, JSON.parse(jsonModel)).success(function(data) {
                console.log("model saved");
            });
        }
    };

    $scope.remove = function() {
        if (typeof id !== 'undefined') {
            $http.get("/api/remove/" + id).success(function(data) {
                window.location.href = "/";
                console.log("model removed");
            });
        }
    };

});

<commit_msg>fix definition of data schema in HOT<commit_after>/**
 * Created by gbecan on 17/12/14.
 */

/**
 * Sort two elements by their names (accessed with x.name)
 * @param a
 * @param b
 * @returns {number}
 */
function sortByName(a, b) {
    if (a.name < b.name) {
        return -1;
    } else if (a.name > b.name) {
        return 1;
    } else {
        return 0;
    }
}

pcmApp.controller("PCMEditorController", function($scope, $http) {

    // Load PCM
    var pcmMM = Kotlin.modules['pcm'].pcm;
    var factory = new pcmMM.factory.DefaultPcmFactory();
    var loader = factory.createJSONLoader();
    var serializer = factory.createJSONSerializer();

    // Init
    var features = [];
    var featureHeaders = [];
    var productHeaders = [];
    var products = [];

    if (typeof id === 'undefined') {
        // Create example PCM
        $scope.pcm = factory.createPCM();

        var exampleFeature = factory.createFeature();
        exampleFeature.name = "Feature";
        $scope.pcm.addFeatures(exampleFeature);

        var exampleFeature1 = factory.createFeature();
        exampleFeature1.name = "Feature1";
        $scope.pcm.addFeatures(exampleFeature1);

        var exampleProduct = factory.createProduct();
        exampleProduct.name = "Product";
        $scope.pcm.addProducts(exampleProduct);

        var exampleCell = factory.createCell();
        exampleCell.feature = exampleFeature;
        exampleCell.content = "Yes";
        exampleProduct.addValues(exampleCell);

        var exampleCell1 = factory.createCell();
        exampleCell1.feature = exampleFeature1;
        exampleCell1.content = "No";
        exampleProduct.addValues(exampleCell1);

        initializeHOT();

    } else {

        $http.get("/api/get/" + id).success(function (data) {
            $scope.pcm = loader.loadModelFromString(JSON.stringify(data)).get(0);
            initializeHOT();
        });

    }

    function initializeHOT() {
        // Transform features to handonstable data structures
        var kFeatures = getConcreteFeatures($scope.pcm).sort(sortByName); // $scope.pcm.features.array
        for (var i = 0; i < kFeatures.length; i++) {
            features.push({
                data: property(kFeatures[i].generated_KMF_ID)
            });
            featureHeaders.push(kFeatures[i].name);
        }

        // Transform products to handonstable data structures
        var kProducts = $scope.pcm.products.array.sort(sortByName);
        for (var i = 0; i < kProducts.length; i++) {
            var product = kProducts[i];

            productHeaders.push(product.name);
            products.push(model(product));

        }

        var container = document.getElementById('hot');
        var hot = new Handsontable(container,
            {
                data: products,
                dataSchema: schema,
                rowHeaders: productHeaders,
                colHeaders: featureHeaders,
                columns: features,
                contextMenu: true,
                //stretchH: 'all', // Scroll bars ?!
                manualColumnMove: true,
                manualRowMove: true
            });
    }

    function getConcreteFeatures(pcm) {

        var aFeatures = pcm.features.array;

        var features = [];
        for (var i = 0; i < aFeatures.length; i++) {
            var aFeature = aFeatures[i];
            features = features.concat(getConcreteFeaturesRec(aFeature))
        }

        return features;
    }

    function getConcreteFeaturesRec(aFeature) {

        var features = [];

        if (typeof aFeature.subFeatures !== 'undefined') {
            var subFeatures = aFeature.subFeatures.array;
            for (var i = 0; i < subFeatures.length; i++) {
                var subFeature = subFeatures[i];
                features = features.concat(getConcreteFeaturesRec(subFeature));
            }
        } else {
            features.push(aFeature);
        }

        return features;
    }

    /**
     * Synchronization function between handsontable and a PCM model of a product
     * @param product : KMF model of a product
     * @returns synchronization object
     */
    function model(product) {
        var idKMF = product.generated_KMF_ID;
        return idKMF;
    }

    function schema(index) {
        var newProduct = factory.createProduct();
        if(typeof index !== 'undefined') {
            $scope.pcm.addProducts(newProduct);

            for (var i = 0; i < $scope.pcm.features.array.length; i++) {
                var cell = factory.createCell();
                cell.feature = $scope.pcm.features.array[i];
                cell.content = "";
                newProduct.addValues(cell);
            }
        }
        return model(newProduct);
    }

    /**
     * Bind handsontable cells to PCM cells
     * @param attr
     * @returns synchronization function
     */
    function property(attr) {
        return function (row, value) {
            var product = $scope.pcm.findProductsByID(row);
            //var cell = product.select("values[feature/id == " + attr + "]").get(0); // FIXME : does not work ! We need to find the cell that correponds to the feature id
            var cells = product.values.array
            for (var i = 0; i < cells.length; i++) {
                var cell = cells[i];
                if (cell.feature.generated_KMF_ID === attr) {
                    break;
                }
            }

            if (typeof value === 'undefined') {
                return cell.content;
            } else {
                cell.content = value;
                return row;
            }
        }
    }

    /**
     * Save PCM on the server
     */
    $scope.save = function() {
        var jsonModel = serializer.serialize($scope.pcm);

        if (typeof id === 'undefined') {
            $http.post("/api/create", JSON.parse(jsonModel)).success(function(data) {
                id = data;
                console.log("model created with id=" + id);
            });
        } else {
            $http.post("/api/save/" + id, JSON.parse(jsonModel)).success(function(data) {
                console.log("model saved");
            });
        }
    };

    $scope.remove = function() {
        if (typeof id !== 'undefined') {
            $http.get("/api/remove/" + id).success(function(data) {
                window.location.href = "/";
                console.log("model removed");
            });
        }
    };

});

<|endoftext|>