<commit_before>/*jslint node: true  es5: true */

/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2016 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */

var log = require("./logging.js").log;
var prettyLog = require("./logging.js").prettyLog;
var joynr = require("joynr");
var LocalStorage = require("node-localstorage").LocalStorage;
var persistencyLocation = "./radioLocalStorageConsumer";
var localStorage = new LocalStorage(persistencyLocation);
var RadioStation;
var Country;
var currentStationSubscriptionId = localStorage.getItem("currentStationSubscriptionId");
var multicastSubscriptionId = localStorage.getItem("multicastSubscriptionId");
var multicastPSubscriptionId = localStorage.getItem("multicastPSubscriptionId");
var subscriptionQosOnChange;

var runDemo = function(radioProxy) {
    prettyLog("ATTRIBUTE GET: currentStation...");
    radioProxy.currentStation.get().catch(function(error) {
        prettyLog("ATTRIBUTE GET: currentStation failed: " + error);
    }).then(function(value) {
        prettyLog("ATTRIBUTE GET: currentStation returned: " + JSON.stringify(value));
        prettyLog("RPC: radioProxy.addFavoriteStation(radioStation)...");
        return radioProxy.addFavoriteStation(
            {
                newFavoriteStation : new RadioStation({
                    name : "runDemoFavoriteStation",
                    trafficService : true,
                    country : Country.GERMANY
                })
            }
        );
    }).catch(function(error) {
        prettyLog("RPC: radioProxy.addFavoriteStation(radioStation) failed: " + JSON.stringify(error));
    }).then(function() {
        prettyLog("RPC: radioProxy.addFavoriteStation(radioStation) returned");
        prettyLog("radioProxy.shuffleStations()...");
        return radioProxy.shuffleStations();
    }).catch(function(error) {
        prettyLog("RPC: radioProxy.shuffleStations() failed: " + JSON.stringify(error));
    }).then(function(value) {
        prettyLog("RPC: radioProxy.shuffleStations() returned");
        prettyLog("ATTRIBUTE GET: currentStation after shuffle...");
        return radioProxy.currentStation.get();
    }).catch(function(error) {
        prettyLog("ATTRIBUTE GET: currentStation failed: " + JSON.stringify(error));
    }).then(function(value) {
        prettyLog("ATTRIBUTE GET: currentStation returned: " + JSON.stringify(value));
    });
};

var runInteractiveConsole =
        function(radioProxy, onDone) {
            var readline = require('readline');
            var rl = readline.createInterface(process.stdin, process.stdout);
            rl.setPrompt('>> ');
            var MODES = {
                HELP : {
                    value : "h",
                    description : "help",
                    options : {}
                },
                QUIT : {
                    value : "q",
                    description : "quit",
                    options : {}
                },
                SHUFFLE_STATIONS : {
                    value : "s",
                    description : "shuffle stations",
                    options : {}
                },
                ADD_FAVORITE_STATION : {
                    value : "a",
                    description : "add a Favorite Station",
                    options : {
                        NAME : "name"
                    }
                },
                SUBSCRIBE : {
                    value : "subscribe",
                    description : "subscribe to current station",
                    options : {}
                },
                MULTICAST : {
                    value : "subscribeMulticast",
                    description : "subscribe to weak signal multicast",
                    options : {}
                },
                MULTICASTP : {
                    value : "subscribeMulticastP",
                    description : "subscribe to weak signal multicast with partition \"GERMANY\"",
                    options : {}
                },
                UNSUBSCRIBE : {
                    value : "unsubscribe",
                    description : "unsubscribe from all subscriptions",
                    options : {}
                },
                GET_CURRENT_STATION : {
                    value : "c",
                    description : "get current station",
                    options : {}
                }
            };

            var showHelp = require("./console_common.js");
            rl.on('line', function(line) {
                var input = line.trim().split(' ');

                function subscribeHelper(settings) {
                    var partitionsString = settings.partitions ? JSON.stringify(settings.partitions) : "";
                    var onReceiveCallback = function onReceiveCallback(value) {
                        prettyLog("radioProxy." + settings.subscribeToName + partitionsString + ".subscribe.onReceive",
                                  JSON.stringify(value));
                    };

                    var onErrorCallback = function onErrorCallback(error) {
                        prettyLog("radioProxy." + settings.subscribeToName + partitionsString + ".subscribe.onError", error);
                    };

                    var parameters = {
                        subscriptionQos : subscriptionQosOnChange,
                        onReceive : onReceiveCallback,
                        onError : onErrorCallback,
                        partitions : settings.partitions
                    };

                    if (settings.subscriptionId !== undefined) {
                        parameters.subscriptionId = settings.subscriptionId;
                    }
                    return radioProxy[settings.subscribeToName].subscribe(parameters).then(function(subscriptionId) {
                        prettyLog("radioProxy." + settings.subscribeToName + partitionsString + ".subscribe.done",
                                  "Subscription ID: "+ subscriptionId);
                        return subscriptionId;
                    }).catch(function(error) {
                        prettyLog("radioProxy." + settings.subscribeToName + partitionsString + ".subscribe.failed: " + JSON.stringify(error));
                        return error;
                    });
                }
                function unsubscribeHelper(settings) {
                    var partitionsString = settings.partitions ? JSON.stringify(settings.partitions) : "";
                    return radioProxy[settings.subscribeToName].unsubscribe({
                        subscriptionId : settings.subscriptionId
                    }).then(function() {
                        prettyLog("radioProxy." + settings.subscribeToName + partitionsString + ".unsubscribe.done",
                                  "Subscription ID: " + settings.subscriptionId);
                        return null;
                    }).catch(function(error) {
                        prettyLog("radioProxy." + settings.subscribeToName + partitionsString + ".unsubscribe.fail",
                                  "Subscription ID: " + settings.subscriptionId + " ERROR: " + error
                        );
                        return null;
                    });
                }
                switch (input[0]) {
                    case MODES.HELP.value:
                        showHelp(MODES);
                        break;
                    case MODES.QUIT.value:
                        rl.close();
                        break;
                    case MODES.ADD_FAVORITE_STATION.value:
                        var newFavoriteStation = new RadioStation({
                            name : input[1] || "",
                            trafficService : true,
                            country : Country.GERMANY
                        });

                        radioProxy.addFavoriteStation({newFavoriteStation: newFavoriteStation})
                            .then(
                                function(returnValue) {
                                    prettyLog("RPC: radioProxy.addFavoriteStation("
                                        + JSON.stringify(newFavoriteStation)
                                        + ") returned: "
                                        + JSON.stringify(returnValue));
                                    return returnValue;
                                }).catch(
                                function(error) {
                                    prettyLog("RPC: radioProxy.addFavoriteStation("
                                        + JSON.stringify(newFavoriteStation)
                                        + ") failed."
                                        + error);
                                    return error;
                                });
                        break;
                    case MODES.SHUFFLE_STATIONS.value:
                        radioProxy.shuffleStations().then(function() {
                            prettyLog("RPC: radioProxy.shuffleStations returned. ");
                            return null;
                        }).catch(function(error) {
                            prettyLog("RPC: radioProxy.shuffleStations failed: " + JSON.stringify(error));
                            return error;
                       });
                        break;
                    case MODES.SUBSCRIBE.value:
                        subscribeHelper({
                            subscribeToName : "currentStation",
                            subscriptionId : currentStationSubscriptionId
                        }).then(function(suscriptionId) {
                            currentStationSubscriptionId = suscriptionId;
                            localStorage.setItem("currentStationSubscriptionId", suscriptionId);
                        });
                        break;
                    case MODES.MULTICAST.value:
                        subscribeHelper({
                            subscribeToName : "weakSignal",
                            subscriptionId : multicastSubscriptionId
                        }).then(function(suscriptionId) {
                            multicastSubscriptionId = suscriptionId;
                            localStorage.setItem("multicastSubscriptionId", suscriptionId);
                        });
                        break;
                    case MODES.MULTICASTP.value:
                        subscribeHelper({
                            subscribeToName : "weakSignal",
                            partitions: [ "GERMANY" ],
                            subscriptionId : multicastPSubscriptionId
                        }).then(function(suscriptionId) {
                            multicastPSubscriptionId = suscriptionId;
                            localStorage.setItem("multicastPSubscriptionId", suscriptionId);
                        });
                        break;
                    case MODES.UNSUBSCRIBE.value:
                        if (currentStationSubscriptionId !== undefined) {
                            unsubscribeHelper({
                                subscribeToName: "currentStation",
                                subscriptionId: currentStationSubscriptionId
                            }).then(function() {
                                localStorage.removeItem(currentStationSubscriptionId);
                                currentStationSubscriptionId = undefined;
                            });
                        }
                        if (multicastSubscriptionId !== undefined) {
                            unsubscribeHelper({
                                subscribeToName: "weakSignal",
                                subscriptionId: multicastSubscriptionId
                            }).then(function() {
                                localStorage.removeItem(multicastSubscriptionId);
                                multicastSubscriptionId = undefined;
                            });
                        }
                        if (multicastPSubscriptionId !== undefined) {
                            unsubscribeHelper({
                                subscribeToName: "weakSignal",
                                partitions: [ "GERMANY" ],
                                subscriptionId: multicastPSubscriptionId
                            }).then(function() {
                                localStorage.removeItem(multicastPSubscriptionId);
                                multicastPSubscriptionId = undefined;
                            });
                        }
                        break;
                    case MODES.GET_CURRENT_STATION.value:
                        radioProxy.currentStation.get().then(function(currentStation) {
                            prettyLog("RPC: radioProxy.getCurrentStation returned: " + JSON.stringify(currentStation));
                        }).catch(function(error) {
                            prettyLog("RPC: radioProxy.getCurrentStation failed: " + error);
                        });
                        break;
                    case '':
                        break;
                    default:
                        log('unknown input: ' + input);
                        break;
                }
                rl.prompt();
            });

            rl.on('close', function() {
                if (onDone) {
                    onDone();
                }
            });

            showHelp(MODES);
            rl.prompt();
        };

if (process.env.domain === undefined) {
    log("please pass a domain as argument");
    process.exit(0);
}
var domain = process.env.domain;
log("domain: " + domain);

var provisioning = require("./provisioning_common.js");

provisioning.persistency = {
    //clearPersistency : true,
    location : persistencyLocation
};

if (process.env.runtime !== undefined) {
    if (process.env.runtime === "inprocess") {
        provisioning.brokerUri = process.env.brokerUri;
        provisioning.bounceProxyBaseUrl = process.env.bounceProxyBaseUrl;
        provisioning.bounceProxyUrl = provisioning.bounceProxyBaseUrl + "/bounceproxy/";
        joynr.selectRuntime("inprocess");
    } else if (process.env.runtime === "websocket") {
        provisioning.ccAddress.host = process.env.cchost;
        provisioning.ccAddress.port = process.env.ccport;
        joynr.selectRuntime("websocket.libjoynr");
    }
}

RadioStation = require("../generated/js/joynr/vehicle/RadioStation");
Country = require("../generated/js/joynr/vehicle/Country");
require("../generated/js/joynr/vehicle/GeoPosition");
var AddFavoriteStationErrorEnum = require("../generated/js/joynr/vehicle/Radio/AddFavoriteStationErrorEnum");
var RadioProxy = require("../generated/js/joynr/vehicle/RadioProxy.js");
joynr.load(provisioning).then(function(loadedJoynr) {
    log("joynr started");
    joynr = loadedJoynr;
    var messagingQos = new joynr.messaging.MessagingQos({
        ttl : 60000
    });

    subscriptionQosOnChange = new joynr.proxy.OnChangeSubscriptionQos({
        minIntervalMs : 50
	});

    joynr.proxyBuilder.build(RadioProxy, {
        domain : domain,
        messagingQos : messagingQos
    }).then(function(radioProxy) {
        log("radio proxy build");
        runDemo(radioProxy);
        runInteractiveConsole(radioProxy, function() {
            log("exiting...");
            process.exit(0);
        });
        return radioProxy;
    }).catch(function(error) {
        log("error running radioProxy: " + error);
    });
    return loadedJoynr;
}).catch(function(error){
    throw error;
});
<commit_msg>[JS] fix unsubscribe in radio-node consumer<commit_after>/*jslint node: true  es5: true */

/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2016 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */

var log = require("./logging.js").log;
var prettyLog = require("./logging.js").prettyLog;
var joynr = require("joynr");
var LocalStorage = require("node-localstorage").LocalStorage;
var persistencyLocation = "./radioLocalStorageConsumer";
var localStorage = new LocalStorage(persistencyLocation);
var RadioStation;
var Country;
var currentStationSubscriptionId = localStorage.getItem("currentStationSubscriptionId");
var multicastSubscriptionId = localStorage.getItem("multicastSubscriptionId");
var multicastPSubscriptionId = localStorage.getItem("multicastPSubscriptionId");
var subscriptionQosOnChange;

var runDemo = function(radioProxy) {
    prettyLog("ATTRIBUTE GET: currentStation...");
    radioProxy.currentStation.get().catch(function(error) {
        prettyLog("ATTRIBUTE GET: currentStation failed: " + error);
    }).then(function(value) {
        prettyLog("ATTRIBUTE GET: currentStation returned: " + JSON.stringify(value));
        prettyLog("RPC: radioProxy.addFavoriteStation(radioStation)...");
        return radioProxy.addFavoriteStation(
            {
                newFavoriteStation : new RadioStation({
                    name : "runDemoFavoriteStation",
                    trafficService : true,
                    country : Country.GERMANY
                })
            }
        );
    }).catch(function(error) {
        prettyLog("RPC: radioProxy.addFavoriteStation(radioStation) failed: " + JSON.stringify(error));
    }).then(function() {
        prettyLog("RPC: radioProxy.addFavoriteStation(radioStation) returned");
        prettyLog("radioProxy.shuffleStations()...");
        return radioProxy.shuffleStations();
    }).catch(function(error) {
        prettyLog("RPC: radioProxy.shuffleStations() failed: " + JSON.stringify(error));
    }).then(function(value) {
        prettyLog("RPC: radioProxy.shuffleStations() returned");
        prettyLog("ATTRIBUTE GET: currentStation after shuffle...");
        return radioProxy.currentStation.get();
    }).catch(function(error) {
        prettyLog("ATTRIBUTE GET: currentStation failed: " + JSON.stringify(error));
    }).then(function(value) {
        prettyLog("ATTRIBUTE GET: currentStation returned: " + JSON.stringify(value));
    });
};

var runInteractiveConsole =
        function(radioProxy, onDone) {
            var readline = require('readline');
            var rl = readline.createInterface(process.stdin, process.stdout);
            rl.setPrompt('>> ');
            var MODES = {
                HELP : {
                    value : "h",
                    description : "help",
                    options : {}
                },
                QUIT : {
                    value : "q",
                    description : "quit",
                    options : {}
                },
                SHUFFLE_STATIONS : {
                    value : "s",
                    description : "shuffle stations",
                    options : {}
                },
                ADD_FAVORITE_STATION : {
                    value : "a",
                    description : "add a Favorite Station",
                    options : {
                        NAME : "name"
                    }
                },
                SUBSCRIBE : {
                    value : "subscribe",
                    description : "subscribe to current station",
                    options : {}
                },
                MULTICAST : {
                    value : "subscribeMulticast",
                    description : "subscribe to weak signal multicast",
                    options : {}
                },
                MULTICASTP : {
                    value : "subscribeMulticastP",
                    description : "subscribe to weak signal multicast with partition \"GERMANY\"",
                    options : {}
                },
                UNSUBSCRIBE : {
                    value : "unsubscribe",
                    description : "unsubscribe from all subscriptions",
                    options : {}
                },
                GET_CURRENT_STATION : {
                    value : "c",
                    description : "get current station",
                    options : {}
                }
            };

            var showHelp = require("./console_common.js");
            rl.on('line', function(line) {
                var input = line.trim().split(' ');

                function subscribeHelper(settings) {
                    var partitionsString = settings.partitions ? JSON.stringify(settings.partitions) : "";
                    var onReceiveCallback = function onReceiveCallback(value) {
                        prettyLog("radioProxy." + settings.subscribeToName + partitionsString + ".subscribe.onReceive",
                                  JSON.stringify(value));
                    };

                    var onErrorCallback = function onErrorCallback(error) {
                        prettyLog("radioProxy." + settings.subscribeToName + partitionsString + ".subscribe.onError", error);
                    };

                    var parameters = {
                        subscriptionQos : subscriptionQosOnChange,
                        onReceive : onReceiveCallback,
                        onError : onErrorCallback,
                        partitions : settings.partitions
                    };

                    if (settings.subscriptionId !== undefined) {
                        parameters.subscriptionId = settings.subscriptionId;
                    }
                    return radioProxy[settings.subscribeToName].subscribe(parameters).then(function(subscriptionId) {
                        prettyLog("radioProxy." + settings.subscribeToName + partitionsString + ".subscribe.done",
                                  "Subscription ID: "+ subscriptionId);
                        return subscriptionId;
                    }).catch(function(error) {
                        prettyLog("radioProxy." + settings.subscribeToName + partitionsString + ".subscribe.failed: " + JSON.stringify(error));
                        return error;
                    });
                }
                function unsubscribeHelper(settings) {
                    var partitionsString = settings.partitions ? JSON.stringify(settings.partitions) : "";
                    return radioProxy[settings.subscribeToName].unsubscribe({
                        subscriptionId : settings.subscriptionId
                    }).then(function() {
                        prettyLog("radioProxy." + settings.subscribeToName + partitionsString + ".unsubscribe.done",
                                  "Subscription ID: " + settings.subscriptionId);
                        return null;
                    }).catch(function(error) {
                        prettyLog("radioProxy." + settings.subscribeToName + partitionsString + ".unsubscribe.fail",
                                  "Subscription ID: " + settings.subscriptionId + " ERROR: " + error
                        );
                        return null;
                    });
                }
                switch (input[0]) {
                    case MODES.HELP.value:
                        showHelp(MODES);
                        break;
                    case MODES.QUIT.value:
                        rl.close();
                        break;
                    case MODES.ADD_FAVORITE_STATION.value:
                        var newFavoriteStation = new RadioStation({
                            name : input[1] || "",
                            trafficService : true,
                            country : Country.GERMANY
                        });

                        radioProxy.addFavoriteStation({newFavoriteStation: newFavoriteStation})
                            .then(
                                function(returnValue) {
                                    prettyLog("RPC: radioProxy.addFavoriteStation("
                                        + JSON.stringify(newFavoriteStation)
                                        + ") returned: "
                                        + JSON.stringify(returnValue));
                                    return returnValue;
                                }).catch(
                                function(error) {
                                    prettyLog("RPC: radioProxy.addFavoriteStation("
                                        + JSON.stringify(newFavoriteStation)
                                        + ") failed."
                                        + error);
                                    return error;
                                });
                        break;
                    case MODES.SHUFFLE_STATIONS.value:
                        radioProxy.shuffleStations().then(function() {
                            prettyLog("RPC: radioProxy.shuffleStations returned. ");
                            return null;
                        }).catch(function(error) {
                            prettyLog("RPC: radioProxy.shuffleStations failed: " + JSON.stringify(error));
                            return error;
                       });
                        break;
                    case MODES.SUBSCRIBE.value:
                        subscribeHelper({
                            subscribeToName : "currentStation",
                            subscriptionId : currentStationSubscriptionId
                        }).then(function(suscriptionId) {
                            currentStationSubscriptionId = suscriptionId;
                            localStorage.setItem("currentStationSubscriptionId", suscriptionId);
                        });
                        break;
                    case MODES.MULTICAST.value:
                        subscribeHelper({
                            subscribeToName : "weakSignal",
                            subscriptionId : multicastSubscriptionId
                        }).then(function(suscriptionId) {
                            multicastSubscriptionId = suscriptionId;
                            localStorage.setItem("multicastSubscriptionId", suscriptionId);
                        });
                        break;
                    case MODES.MULTICASTP.value:
                        subscribeHelper({
                            subscribeToName : "weakSignal",
                            partitions: [ "GERMANY" ],
                            subscriptionId : multicastPSubscriptionId
                        }).then(function(suscriptionId) {
                            multicastPSubscriptionId = suscriptionId;
                            localStorage.setItem("multicastPSubscriptionId", suscriptionId);
                        });
                        break;
                    case MODES.UNSUBSCRIBE.value:
                        if (currentStationSubscriptionId !== undefined && currentStationSubscriptionId !== null) {
                            unsubscribeHelper({
                                subscribeToName: "currentStation",
                                subscriptionId: currentStationSubscriptionId
                            }).then(function() {
                                localStorage.removeItem(currentStationSubscriptionId);
                                currentStationSubscriptionId = undefined;
                            });
                        }
                        if (multicastSubscriptionId !== undefined && multicastSubscriptionId !== null) {
                            unsubscribeHelper({
                                subscribeToName: "weakSignal",
                                subscriptionId: multicastSubscriptionId
                            }).then(function() {
                                localStorage.removeItem(multicastSubscriptionId);
                                multicastSubscriptionId = undefined;
                            });
                        }
                        if (multicastPSubscriptionId !== undefined && multicastPSubscriptionId !== null) {
                            unsubscribeHelper({
                                subscribeToName: "weakSignal",
                                partitions: [ "GERMANY" ],
                                subscriptionId: multicastPSubscriptionId
                            }).then(function() {
                                localStorage.removeItem(multicastPSubscriptionId);
                                multicastPSubscriptionId = undefined;
                            });
                        }
                        break;
                    case MODES.GET_CURRENT_STATION.value:
                        radioProxy.currentStation.get().then(function(currentStation) {
                            prettyLog("RPC: radioProxy.getCurrentStation returned: " + JSON.stringify(currentStation));
                        }).catch(function(error) {
                            prettyLog("RPC: radioProxy.getCurrentStation failed: " + error);
                        });
                        break;
                    case '':
                        break;
                    default:
                        log('unknown input: ' + input);
                        break;
                }
                rl.prompt();
            });

            rl.on('close', function() {
                if (onDone) {
                    onDone();
                }
            });

            showHelp(MODES);
            rl.prompt();
        };

if (process.env.domain === undefined) {
    log("please pass a domain as argument");
    process.exit(0);
}
var domain = process.env.domain;
log("domain: " + domain);

var provisioning = require("./provisioning_common.js");

provisioning.persistency = {
    //clearPersistency : true,
    location : persistencyLocation
};

if (process.env.runtime !== undefined) {
    if (process.env.runtime === "inprocess") {
        provisioning.brokerUri = process.env.brokerUri;
        provisioning.bounceProxyBaseUrl = process.env.bounceProxyBaseUrl;
        provisioning.bounceProxyUrl = provisioning.bounceProxyBaseUrl + "/bounceproxy/";
        joynr.selectRuntime("inprocess");
    } else if (process.env.runtime === "websocket") {
        provisioning.ccAddress.host = process.env.cchost;
        provisioning.ccAddress.port = process.env.ccport;
        joynr.selectRuntime("websocket.libjoynr");
    }
}

RadioStation = require("../generated/js/joynr/vehicle/RadioStation");
Country = require("../generated/js/joynr/vehicle/Country");
require("../generated/js/joynr/vehicle/GeoPosition");
var AddFavoriteStationErrorEnum = require("../generated/js/joynr/vehicle/Radio/AddFavoriteStationErrorEnum");
var RadioProxy = require("../generated/js/joynr/vehicle/RadioProxy.js");
joynr.load(provisioning).then(function(loadedJoynr) {
    log("joynr started");
    joynr = loadedJoynr;
    var messagingQos = new joynr.messaging.MessagingQos({
        ttl : 60000
    });

    subscriptionQosOnChange = new joynr.proxy.OnChangeSubscriptionQos({
        minIntervalMs : 50
	});

    joynr.proxyBuilder.build(RadioProxy, {
        domain : domain,
        messagingQos : messagingQos
    }).then(function(radioProxy) {
        log("radio proxy build");
        runDemo(radioProxy);
        runInteractiveConsole(radioProxy, function() {
            log("exiting...");
            process.exit(0);
        });
        return radioProxy;
    }).catch(function(error) {
        log("error running radioProxy: " + error);
    });
    return loadedJoynr;
}).catch(function(error){
    throw error;
});
<|endoftext|>


<commit_before>define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/Deferred", "dojo/_base/array", "dojo/when" /*=====, "./api/Store" =====*/
], function(kernel, lang, Deferred, array, when /*=====, Store =====*/){

// module:
//		dojo/store/Observable

var Observable = function(/*Store*/ store){
	// summary:
	//		The Observable store wrapper takes a store and sets an observe method on query()
	//		results that can be used to monitor results for changes.
	//
	// description:
	//		Observable wraps an existing store so that notifications can be made when a query
	//		is performed.
	//
	// example:
	//		Create a Memory store that returns an observable query, and then log some
	//		information about that query.
	//
	//	|	var store = Observable(new Memory({
	//	|		data: [
	//	|			{id: 1, name: "one", prime: false},
	//	|			{id: 2, name: "two", even: true, prime: true},
	//	|			{id: 3, name: "three", prime: true},
	//	|			{id: 4, name: "four", even: true, prime: false},
	//	|			{id: 5, name: "five", prime: true}
	//	|		]
	//	|	}));
	//	|	var changes = [], results = store.query({ prime: true });
	//	|	var observer = results.observe(function(object, previousIndex, newIndex){
	//	|		changes.push({previousIndex:previousIndex, newIndex:newIndex, object:object});
	//	|	});
	//
	//		See the Observable tests for more information.

	var undef, queryUpdaters = [], revision = 0;
	// a Comet driven store could directly call notify to notify observers when data has
	// changed on the backend
	// create a new instance
	store = lang.delegate(store);

	store.notify = function(object, existingId, methodOptions ){
		revision++;
		var updaters = queryUpdaters.slice();
		for(var i = 0, l = updaters.length; i < l; i++){
			updaters[i](object, existingId, methodOptions);
		}
	};
	var originalQuery = store.query;
	store.query = function(query, options){
		options = options || {};

		var results = originalQuery.apply(this, arguments);
		if(results && results.forEach){
			var nonPagedOptions = lang.mixin({}, options);
			delete nonPagedOptions.start;
			delete nonPagedOptions.count;

			var queryExecutor = store.queryEngine && store.queryEngine(query, nonPagedOptions);
			var queryRevision = revision;
			var listeners = [], queryUpdater;

			var newQueryTotal = options.start + options.count; // Added by MERC, needed later

			results.observe = function(listener, includeObjectUpdates){
				if(listeners.push(listener) == 1){
					// first listener was added, create the query checker and updater
					queryUpdaters.push(queryUpdater = function(changed, existingId, methodOptions){
						Deferred.when(results, function(resultsArray){

							var atEnd = resultsArray.length != options.count;
							var i, l, listener;
							if(++queryRevision != revision){
								throw new Error("Query is out of date, you must observe() the query prior to any data modifications");
							}

							// Look for an object with id objectId in resultsArray
							function findObjectInResult( objectId ) {
								var i, l, object;
								for(i = 0, l = resultsArray.length; i < l; i++){
									object = resultsArray[ i ];
									if( store.getIdentity( object ) == objectId ){
										return i;
									}
								}
								return -1;
							}

							// CASE #1: It's a deletion. No dramas.
							if( changed === undef && existingId !== undef ){
								var ownPosition = findObjectInResult( existingId );
								if( ownPosition != -1 ){
									newQueryTotal --;
									tellAllListeners( resultsArray[ownPosition], ownPosition, -1 );
									resultsArray.splice( ownPosition, 1 );
								}
							}

							// It's either an insert or a replace
							if( changed !== undef ){

								// Look for self in the query
								var ownPosition = findObjectInResult( existingId );

								// CASE 2: it's an update and includeObjectUpdates
								// is true: place record in-place
								if( ownPosition != -1 && includeObjectUpdates ){

									console.log("METHOD OPTIONS:" , methodOptions, changed, existingId );

									if( methodOptions && typeof( methodOptions.before ) !== 'undefined' ){
										console.log("MOVING THE ITEM...:" );

										console.log("RESULTARRAY BEFORE WAS:" );
										resultsArray.forEach( function(e, k){ console.log( k, e.name ); } );

										// methodOptions.before is null: the item needs to be at the end
                    // of the resultsArray
										if( methodOptions.before === null ){
								    	var pos = resultsArray.length;
											console.log("POS IS:", pos );
											resultsArray.splice( ownPosition, 1 );
											resultsArray.push( changed );
											tellAllListeners( changed, ownPosition, pos );
										} else {

											var beforePosition = findObjectInResult( store.getIdentity( methodOptions.before ) );
											if( beforePosition > ownPosition ) beforePosition --;

											console.log("BEFOREPOSITION:", beforePosition, "OWNPOSITION: ", ownPosition );

											resultsArray.splice(beforePosition, 0, resultsArray.splice(ownPosition, 1)[0]);
										  tellAllListeners( changed, ownPosition, beforePosition );
										}

										// Tell all listeners...
										console.log("RESULTARRAY NOW IS:" );
										resultsArray.forEach( function(e, k){ console.log( k, e.name ); } );

									} else {
										resultsArray.splice( ownPosition, 1, changed );
										tellAllListeners( changed, ownPosition, ownPosition );
									}

								}

								// CASE 3: it's an add.

								if( ownPosition == -1 ){

									// There are three possibilities: it might go:
									// * before methodOptions.before
									// * first (options.placeNew === 'first'
									// * last (options.placeNew === 'last' OR options.before === null )
									// * none (options.placeNew === 'none' OR anything else )

									// CASE 3a: options.before is indeed specified.
									// In this case, look for that, and place it there
									if( methodOptions && methodOptions.before ){

										var beforePosition = findObjectInResult( store.getIdentity( methodOptions.before ) )

										if( beforePosition != -1 ){
											resultsArray.splice( beforePosition, 0, changed );
											newQueryTotal ++;
											tellAllListeners( changed, -1, beforePosition );
										}

									// CASE 3b: it's an add, and query.placeNew is "last" OR undefined
									// _OR_ options.before === null (required by store API): add the item
									// to the query marked as "last" (note: the query might not have been
									// made and therefore observed yet)
									} else if( options.placeNew === 'last' || options.placeNew === undefined || methodOptions.before === null ){

										// var queryTo = options.start + options.count; // var queryTo = results.ioArgs.args.headers.Range.split('-')[1];
										when( results.total ).then( function( grandTotal ) {

											// If there are no limits to the query, OR if the new element will be outside the range of
											// the current query, OR if methodOptions.before is null, add it
											if( (options.start == 0 && options.count == 0 ) || newQueryTotal >= grandTotal || methodOptions.before === null ){
												var pos = resultsArray.length;
												resultsArray.push( changed );
												tellAllListeners( changed, -1, pos );
												newQueryTotal ++;
											}
										});

									// CASE 3c: it's an add, where query.placeNew is "first": will add the item
									// to the top of the list
									} else if( options.placeNew === 'first') {

										// This query has the beginning of the result: add to it
										if( options.start == 0 ){
											resultsArray.splice( 0, 0, changed );
											tellAllListeners( changed, -1, 0 );
										}

									// CASE 3d: it's an add, but query.placeNew is probably
									// "none" or undefined, do nothing
									} else{

									}

								}

							}

							function tellAllListeners( element, removedFrom, insertedInto ){
								var listener, i, copyListeners = listeners.slice();
								for(var i = 0;listener = copyListeners[i]; i++){
									listener(element, removedFrom, insertedInto );
								}
							}

/*

							var removedObject, removedFrom = -1, insertedInto = -1;
							if(existingId !== undef){
								// remove the old one
								for(i = 0, l = resultsArray.length; i < l; i++){
									var object = resultsArray[i];
									if(store.getIdentity(object) == existingId){
										removedObject = object;
										removedFrom = i;
										if(queryExecutor || !changed){// if it was changed and we don't have a queryExecutor, we shouldn't remove it because updated objects would be eliminated
											resultsArray.splice(i, 1);
										}
										break;
									}
								}
							}
							if(queryExecutor){
								// add the new one
								if(changed &&
										// if a matches function exists, use that (probably more efficient)
										(queryExecutor.matches ? queryExecutor.matches(changed) : queryExecutor([changed]).length)){

									var firstInsertedInto = removedFrom > -1 ?
										removedFrom : // put back in the original slot so it doesn't move unless it needs to (relying on a stable sort below)
										resultsArray.length;
									resultsArray.splice(firstInsertedInto, 0, changed); // add the new item
									insertedInto = array.indexOf(queryExecutor(resultsArray), changed); // sort it
									// we now need to push the chagne back into the original results array
									resultsArray.splice(firstInsertedInto, 1); // remove the inserted item from the previous index

									if((options.start && insertedInto == 0) ||
										(!atEnd && insertedInto == resultsArray.length)){
										// if it is at the end of the page, assume it goes into the prev or next page
										insertedInto = -1;
									}else{
										resultsArray.splice(insertedInto, 0, changed); // and insert into the results array with the correct index
									}
								}
							}else if(changed){
								// we don't have a queryEngine, so we can't provide any information
								// about where it was inserted or moved to. If it is an update, we leave it's position alone, other we at least indicate a new object
								if(existingId !== undef){
									// an update, keep the index the same
									insertedInto = removedFrom;
								}else if(!options.start){
									// a new object
									insertedInto = store.defaultIndex || 0;
									resultsArray.splice(insertedInto, 0, changed);
								}
							}
							if((removedFrom > -1 || insertedInto > -1) &&
									(includeObjectUpdates || !queryExecutor || (removedFrom != insertedInto))){
								var copyListeners = listeners.slice();
								for(i = 0;listener = copyListeners[i]; i++){
									listener(changed || removedObject, removedFrom, insertedInto);
								}
							}
*/

						});

					});
				}
				var handle = {};
				// TODO: Remove cancel in 2.0.
				handle.remove = handle.cancel = function(){
					// remove this listener
					var index = array.indexOf(listeners, listener);
					if(index > -1){ // check to make sure we haven't already called cancel
						listeners.splice(index, 1);
						if(!listeners.length){
							// no more listeners, remove the query updater too
							queryUpdaters.splice(array.indexOf(queryUpdaters, queryUpdater), 1);
						}
					}
				};
				return handle;
			};
		}
		return results;
	};
	var inMethod;
	function whenFinished(method, action ){
		var original = store[method];
		if(original){
			store[method] = function(value){
			console.log( arguments );
			var params = arguments[1];

				if(inMethod){
					// if one method calls another (like add() calling put()) we don't want two events
					return original.apply(this, arguments);
				}
				inMethod = true;
				try{
					var results = original.apply(this, arguments);
					Deferred.when(results, function(results){
						action((typeof results == "object" && results) || value, params );
					});
					return results;
				}finally{
					inMethod = false;
				}
			};
		}
	}
	// monitor for updates by listening to these methods
	whenFinished("put", function(object, methodOptions ){
		console.log("METHOD OPTIONS HERE:", methodOptions );
		store.notify(object, store.getIdentity(object), methodOptions);
	});
	whenFinished("add", function(object){
		store.notify(object, undefined, methodOptions);
	});
	whenFinished("remove", function(id){
		store.notify(undefined, id, methodOptions);
	});

	return store;
};

lang.setObject("dojo.store.Observable", Observable);

return Observable;
});
<commit_msg>Completing the rewrite of JsonObservable<commit_after>define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/Deferred", "dojo/_base/array", "dojo/when" /*=====, "./api/Store" =====*/
], function(kernel, lang, Deferred, array, when /*=====, Store =====*/){

// module:
//		dojo/store/Observable

var Observable = function(/*Store*/ store){
	// summary:
	//		The Observable store wrapper takes a store and sets an observe method on query()
	//		results that can be used to monitor results for changes.
	//
	// description:
	//		Observable wraps an existing store so that notifications can be made when a query
	//		is performed.
	//
	// example:
	//		Create a Memory store that returns an observable query, and then log some
	//		information about that query.
	//
	//	|	var store = Observable(new Memory({
	//	|		data: [
	//	|			{id: 1, name: "one", prime: false},
	//	|			{id: 2, name: "two", even: true, prime: true},
	//	|			{id: 3, name: "three", prime: true},
	//	|			{id: 4, name: "four", even: true, prime: false},
	//	|			{id: 5, name: "five", prime: true}
	//	|		]
	//	|	}));
	//	|	var changes = [], results = store.query({ prime: true });
	//	|	var observer = results.observe(function(object, previousIndex, newIndex){
	//	|		changes.push({previousIndex:previousIndex, newIndex:newIndex, object:object});
	//	|	});
	//
	//		See the Observable tests for more information.

	var undef, queryUpdaters = [], revision = 0;
	// a Comet driven store could directly call notify to notify observers when data has
	// changed on the backend
	// create a new instance
	store = lang.delegate(store);

	store.notify = function(object, existingId, methodOptions ){
		revision++;
		var updaters = queryUpdaters.slice();
		for(var i = 0, l = updaters.length; i < l; i++){
			updaters[i](object, existingId, methodOptions);
		}
	};
	var originalQuery = store.query;
	store.query = function(query, options){
		options = options || {};

		var results = originalQuery.apply(this, arguments);
		if(results && results.forEach){
			var nonPagedOptions = lang.mixin({}, options);
			delete nonPagedOptions.start;
			delete nonPagedOptions.count;

			var queryExecutor = store.queryEngine && store.queryEngine(query, nonPagedOptions);
			var queryRevision = revision;
			var listeners = [], queryUpdater;

			var newQueryTotal = options.start + options.count; // Added by MERC, needed later

			results.observe = function(listener, includeObjectUpdates){
				if(listeners.push(listener) == 1){
					// first listener was added, create the query checker and updater
					queryUpdaters.push(queryUpdater = function(changed, existingId, methodOptions){
						Deferred.when(results, function(resultsArray){

							var atEnd = resultsArray.length != options.count;
							var i, l, listener;
							if(++queryRevision != revision){
								throw new Error("Query is out of date, you must observe() the query prior to any data modifications");
							}

							// Look for an object with id objectId in resultsArray
							function findObjectInResult( objectId ) {
								var i, l, object;
								for(i = 0, l = resultsArray.length; i < l; i++){
									object = resultsArray[ i ];
									if( store.getIdentity( object ) == objectId ){
										return i;
									}
								}
								return -1;
							}

							// CASE #1: It's a deletion. No dramas.
							if( changed === undef && existingId !== undef ){
								var ownPosition = findObjectInResult( existingId );
								if( ownPosition != -1 ){
									newQueryTotal --;
									tellAllListeners( resultsArray[ownPosition], ownPosition, -1 );
									resultsArray.splice( ownPosition, 1 );
								}
							}

							// It's either an insert or a replace
							if( changed !== undef ){

								// Look for self in the query
								var ownPosition = findObjectInResult( existingId );

								// CASE 2: it's an update and includeObjectUpdates
								// is true: place record in-place
								if( ownPosition != -1 && includeObjectUpdates ){

									//console.log("METHOD OPTIONS:" , methodOptions, changed, existingId );

									if( methodOptions && typeof( methodOptions.before ) !== 'undefined' ){
										//console.log("MOVING THE ITEM...:" );

										//console.log("RESULTARRAY BEFORE WAS:" );
										//resultsArray.forEach( function(e, k){ console.log( k, e.name ); } );

										// methodOptions.before is null: the item needs to be at the end
                    // of the resultsArray
										if( methodOptions.before === null ){
								    	var pos = resultsArray.length;
											resultsArray.splice( ownPosition, 1 );
											resultsArray.push( changed );
											tellAllListeners( changed, ownPosition, pos -1 );
										} else {

											var beforePosition = findObjectInResult( store.getIdentity( methodOptions.before ) );
											if( beforePosition > ownPosition ) beforePosition --;

											//console.log("BEFOREPOSITION:", beforePosition, "OWNPOSITION: ", ownPosition );

											resultsArray.splice(beforePosition, 0, resultsArray.splice(ownPosition, 1)[0]);
										  tellAllListeners( changed, ownPosition, beforePosition );
										}

										// Tell all listeners...
										//console.log("RESULTARRAY NOW IS:" );
										//resultsArray.forEach( function(e, k){ console.log( k, e.name ); } );

									} else {
										resultsArray.splice( ownPosition, 1, changed );
										tellAllListeners( changed, ownPosition, ownPosition );
									}

								}

								// CASE 3: it's an add.

								if( ownPosition == -1 ){

									// There are three possibilities: it might go:
									// * first (options.placeNew === 'first'
									// * last (options.placeNew === 'last' OR options.before === null )
									// * none (options.placeNew === 'none' OR anything else )

									// CASE 3a: options.before is indeed specified.
									// In this case, look for that, and place it there
									if( methodOptions && methodOptions.before ){

										var beforePosition = findObjectInResult( store.getIdentity( methodOptions.before ) )

										if( beforePosition != -1 ){
											resultsArray.splice( beforePosition, 0, changed );
											newQueryTotal ++;
											tellAllListeners( changed, -1, beforePosition );
										}

									// CASE 3b: it's an add, and query.placeNew is "last" OR undefined
									// _OR_ options.before === null (required by store API): add the item
									// to the query marked as "last" (note: the query might not have been
									// made and therefore observed yet)
									} else if( options.placeNew === 'last' || options.placeNew === undefined || methodOptions.before === null ){

										// var queryTo = options.start + options.count; // var queryTo = results.ioArgs.args.headers.Range.split('-')[1];
										when( results.total ).then( function( grandTotal ) {

											// If there are no limits to the query, OR if the new element will be outside the range of
											// the current query, OR if methodOptions.before is null, add it
											if( (options.start == 0 && options.count == 0 ) || newQueryTotal >= grandTotal || methodOptions.before === null ){
												var pos = resultsArray.length;
												resultsArray.push( changed );
												tellAllListeners( changed, -1, pos );
												newQueryTotal ++;
											}
										});

									// CASE 3c: it's an add, where query.placeNew is "first": will add the item
									// to the top of the list
									} else if( options.placeNew === 'first') {

										// This query has the beginning of the result: add to it
										if( options.start == 0 ){
											resultsArray.splice( 0, 0, changed );
											tellAllListeners( changed, -1, 0 );
										}

									// CASE 3d: it's an add, but query.placeNew is probably
									// "none" or undefined, do nothing
									} else{

									}

								}

							}

							function tellAllListeners( element, removedFrom, insertedInto ){
								var listener, i, copyListeners = listeners.slice();
								for(var i = 0;listener = copyListeners[i]; i++){
									listener(element, removedFrom, insertedInto );
								}
							}

/*

							var removedObject, removedFrom = -1, insertedInto = -1;
							if(existingId !== undef){
								// remove the old one
								for(i = 0, l = resultsArray.length; i < l; i++){
									var object = resultsArray[i];
									if(store.getIdentity(object) == existingId){
										removedObject = object;
										removedFrom = i;
										if(queryExecutor || !changed){// if it was changed and we don't have a queryExecutor, we shouldn't remove it because updated objects would be eliminated
											resultsArray.splice(i, 1);
										}
										break;
									}
								}
							}
							if(queryExecutor){
								// add the new one
								if(changed &&
										// if a matches function exists, use that (probably more efficient)
										(queryExecutor.matches ? queryExecutor.matches(changed) : queryExecutor([changed]).length)){

									var firstInsertedInto = removedFrom > -1 ?
										removedFrom : // put back in the original slot so it doesn't move unless it needs to (relying on a stable sort below)
										resultsArray.length;
									resultsArray.splice(firstInsertedInto, 0, changed); // add the new item
									insertedInto = array.indexOf(queryExecutor(resultsArray), changed); // sort it
									// we now need to push the chagne back into the original results array
									resultsArray.splice(firstInsertedInto, 1); // remove the inserted item from the previous index

									if((options.start && insertedInto == 0) ||
										(!atEnd && insertedInto == resultsArray.length)){
										// if it is at the end of the page, assume it goes into the prev or next page
										insertedInto = -1;
									}else{
										resultsArray.splice(insertedInto, 0, changed); // and insert into the results array with the correct index
									}
								}
							}else if(changed){
								// we don't have a queryEngine, so we can't provide any information
								// about where it was inserted or moved to. If it is an update, we leave it's position alone, other we at least indicate a new object
								if(existingId !== undef){
									// an update, keep the index the same
									insertedInto = removedFrom;
								}else if(!options.start){
									// a new object
									insertedInto = store.defaultIndex || 0;
									resultsArray.splice(insertedInto, 0, changed);
								}
							}
							if((removedFrom > -1 || insertedInto > -1) &&
									(includeObjectUpdates || !queryExecutor || (removedFrom != insertedInto))){
								var copyListeners = listeners.slice();
								for(i = 0;listener = copyListeners[i]; i++){
									listener(changed || removedObject, removedFrom, insertedInto);
								}
							}
*/

						});

					});
				}
				var handle = {};
				// TODO: Remove cancel in 2.0.
				handle.remove = handle.cancel = function(){
					// remove this listener
					var index = array.indexOf(listeners, listener);
					if(index > -1){ // check to make sure we haven't already called cancel
						listeners.splice(index, 1);
						if(!listeners.length){
							// no more listeners, remove the query updater too
							queryUpdaters.splice(array.indexOf(queryUpdaters, queryUpdater), 1);
						}
					}
				};
				return handle;
			};
		}
		return results;
	};
	var inMethod;
	function whenFinished(method, action ){
		var original = store[method];
		if(original){
			store[method] = function(value){
			console.log( arguments );
			var params = arguments[1];

				if(inMethod){
					// if one method calls another (like add() calling put()) we don't want two events
					return original.apply(this, arguments);
				}
				inMethod = true;
				try{
					var results = original.apply(this, arguments);
					Deferred.when(results, function(results){
						action((typeof results == "object" && results) || value, params );
					});
					return results;
				}finally{
					inMethod = false;
				}
			};
		}
	}
	// monitor for updates by listening to these methods
	whenFinished("put", function(object, methodOptions ){
		console.log("METHOD OPTIONS HERE:", methodOptions );
		store.notify(object, store.getIdentity(object), methodOptions);
	});
	whenFinished("add", function(object){
		store.notify(object, undefined, methodOptions);
	});
	whenFinished("remove", function(id){
		store.notify(undefined, id, methodOptions);
	});

	return store;
};

lang.setObject("dojo.store.Observable", Observable);

return Observable;
});
<|endoftext|>


<commit_before>define([],function(){
    var KEY = "_id";
    var BID = "*#*";
    var ClientCommitInfo = function(parameters){
        var refreshId = setInterval(refreshCommits,parameters.refreshrate),
            storage = parameters.storage,
            commits = {};

        var getCommitList = function(){
            var returnlist = [];
            for(var i in commits){
                returnlist.push(i);
            }
            return returnlist;
        };
        var getCommitObj = function(commitid){
            return commits[commitid];
        };
        var getAllCommits = function(){
            var returnlist = [];
            for(var i in commits){
                returnlist.push(commits[i]);
            }
            return returnlist;
        };

        var refreshCommits = function(callback){
            callback = callback || function(){};
            storage.find({type:'commit'},function(err,findobjects){
                if(err){
                    console.log("cannot update commit list due to: "+err);
                } else {
                    commits={};
                    for(var i=0;i<findobjects.length;i++){
                        commits[findobjects[i][KEY]] = findobjects[i];
                    }
                }
                callback(err);
            });
        };

        var getAllCommitsNow = function(callback){
            callback = callback || function(){};
            refreshCommits(function(err){
                if(err){
                    callback(err,getAllCommits());
                } else {
                    callback(null,getAllCommits());
                }
            })
        };

        var produceCommitTimeline = function(commitid){
            var timeline = {};
            timeline[commitid] = 0;
            if(commits[commitid]){
                for(var i=0;i<commits[commitid].parents.length;i++){
                    var parentline = produceCommitTimeline(commits[commitid].parents[i]);
                    for(var j in parentline){
                        timeline[j] = parentline[j]+1;
                    }
                }
            }

            return timeline;
        };
        var getCommitDifference = function(commitid,callback){
            getAllCommitsNow(function(err,commitobjects){
                if(commits[commitid]){
                    storage.load(BID+commits[commitid].name,function(err,branch){
                       if(!err && branch){
                           //here comes the real counting
                           if(branch.commit === commitid){
                               callback(null,0);
                           } else {
                               //ok here comes the real counting...
                               var myline = produceCommitTimeline(commitid);
                               var serverline = produceCommitTimeline(branch.commit);
                               if(myline[branch.commit]){
                                   //we are ahead of the server
                                   callback(null,myline[branch.commit]);
                               } else {
                                   var mindist = null;
                                   var mincommit = null;
                                   for(var i in myline){
                                       if(serverline[i]){
                                           if(mindist === null || serverline[i]<mindist){
                                               mindist = serverline[i];
                                               mincommit = i;
                                           }
                                       }
                                   }
                                   //we are behind the server...
                                   callback(null,(-1)*mindist);
                               }
                           }
                       } else {
                           callback('no branch info is available');
                       }
                    });
                } else {
                    callback('commit not found');
                }
            });
        };

        return {
            getCommitList : getCommitList,
            getCommitObj : getCommitObj,
            getAllCommits : getAllCommits,
            getAllCommitsNow : getAllCommitsNow,
            getCommitDifference : getCommitDifference
        }
    };
    return ClientCommitInfo;
});
<commit_msg>refreshing have been corrected<commit_after>define([],function(){
    var KEY = "_id";
    var BID = "*#*";
    var ClientCommitInfo = function(parameters){
        var refreshId = null,
            storage = parameters.storage,
            commits = {};

        var getCommitList = function(){
            var returnlist = [];
            for(var i in commits){
                returnlist.push(i);
            }
            return returnlist;
        };
        var getCommitObj = function(commitid){
            return commits[commitid];
        };
        var getAllCommits = function(){
            var returnlist = [];
            for(var i in commits){
                returnlist.push(commits[i]);
            }
            return returnlist;
        };

        var refreshCommits = function(callback){
            callback = callback || function(){};
            storage.find({type:'commit'},function(err,findobjects){
                if(err){
                    console.log("cannot update commit list due to: "+err);
                } else {
                    commits={};
                    for(var i=0;i<findobjects.length;i++){
                        commits[findobjects[i][KEY]] = findobjects[i];
                    }
                }
                callback(err);
            });
        };

        var getAllCommitsNow = function(callback){
            callback = callback || function(){};
            refreshCommits(function(err){
                if(err){
                    callback(err,getAllCommits());
                } else {
                    callback(null,getAllCommits());
                }
            })
        };

        var produceCommitTimeline = function(commitid){
            var timeline = {};
            timeline[commitid] = 0;
            if(commits[commitid]){
                for(var i=0;i<commits[commitid].parents.length;i++){
                    var parentline = produceCommitTimeline(commits[commitid].parents[i]);
                    for(var j in parentline){
                        timeline[j] = parentline[j]+1;
                    }
                }
            }

            return timeline;
        };
        var getCommitDifference = function(commitid,callback){
            getAllCommitsNow(function(err,commitobjects){
                if(commits[commitid]){
                    storage.load(BID+commits[commitid].name,function(err,branch){
                       if(!err && branch){
                           //here comes the real counting
                           if(branch.commit === commitid){
                               callback(null,0);
                           } else {
                               //ok here comes the real counting...
                               var myline = produceCommitTimeline(commitid);
                               var serverline = produceCommitTimeline(branch.commit);
                               if(myline[branch.commit]){
                                   //we are ahead of the server
                                   callback(null,myline[branch.commit]);
                               } else {
                                   var mindist = null;
                                   var mincommit = null;
                                   for(var i in myline){
                                       if(serverline[i]){
                                           if(mindist === null || serverline[i]<mindist){
                                               mindist = serverline[i];
                                               mincommit = i;
                                           }
                                       }
                                   }
                                   //we are behind the server...
                                   callback(null,(-1)*mindist);
                               }
                           }
                       } else {
                           callback('no branch info is available');
                       }
                    });
                } else {
                    callback('commit not found');
                }
            });
        };

        refreshId = setInterval(refreshCommits,parameters.refreshrate);

        return {
            getCommitList : getCommitList,
            getCommitObj : getCommitObj,
            getAllCommits : getAllCommits,
            getAllCommitsNow : getAllCommitsNow,
            getCommitDifference : getCommitDifference
        }
    };
    return ClientCommitInfo;
});
<|endoftext|>


<commit_before>"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var supertest = require("supertest");
var httpStatus = require('http-status');
var util = require('util');
var logger = require("../../src/util/logger");
// system under test
var server = require("../../src/server");
var user_key = process.env.THREESCALE_USER_KEY;
describe('heartbeat route test', function () {
    it('server should be valid', function (done) {
        expect(server).toBeTruthy();
        expect(server.listen).toBeDefined();
        done();
    });
    it('port should be set', function (done) {
        expect(port).toBeTruthy();
        logger.info('port=%s', port);
        done();
    });
    it('user_key should be set', function (done) {
        expect(user_key).toBeTruthy();
        logger.error('user_key=%s', user_key);
        done();
    });
    it('POST heartbeat', function (done) {
        var payload = {
            host: "ESP_TEST",
            uptime: (new Date()).getMinutes()
        };
        supertest(server)
            .post('/api/heartbeat?user_key=' + user_key)
            .send(payload)
            .expect(httpStatus.OK)
            .end(function (err, res) {
            logger.error("err: " + util.inspect(err));
            expect(err).toBeNull();
            expect(res).toBeTruthy();
            logger.error("res: " + util.inspect(res));
            expect(res.body).toBeDefined();
            logger.error('res.body: ' + util.inspect(res.body));
            expect(res.body._id).toBeDefined();
            expect(res.body.rc).toBe("OK");
            done();
        });
    });
});
<commit_msg>LG-85 - fix port setting before server start in test<commit_after>"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var supertest = require("supertest");
var httpStatus = require('http-status');
var util = require('util');
var logger = require("../../src/util/logger");
// system under test
var user_key = process.env.THREESCALE_USER_KEY;
var port = process.env.TEST_PORT || "4321";
process.env.PORT = port;
var server = require("../../src/server");
describe('heartbeat route test', function () {
    it('server should be valid', function (done) {
        expect(server).toBeTruthy();
        expect(server.listen).toBeDefined();
        done();
    });
    it('port should be set', function (done) {
        expect(port).toBeTruthy();
        logger.info('port=%s', port);
        done();
    });
    it('user_key should be set', function (done) {
        expect(user_key).toBeTruthy();
        logger.error('user_key=%s', user_key);
        done();
    });
    it('POST heartbeat', function (done) {
        var payload = {
            host: "ESP_TEST",
            uptime: (new Date()).getMinutes()
        };
        supertest(server)
            .post('/api/heartbeat?user_key=' + user_key)
            .send(payload)
            .expect(httpStatus.OK)
            .end(function (err, res) {
            logger.error("err: " + util.inspect(err));
            expect(err).toBeNull();
            expect(res).toBeTruthy();
            logger.error("res: " + util.inspect(res));
            expect(res.body).toBeDefined();
            logger.error('res.body: ' + util.inspect(res.body));
            expect(res.body._id).toBeDefined();
            expect(res.body.rc).toBe("OK");
            done();
        });
    });
});
<|endoftext|>


<commit_before>/********************************************************************************
 *   Ledger Node JS API
 *   (c) 2017-2018 Ledger
 *
 *  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.
 ********************************************************************************/
//@flow

import crc16xmodem from "crc/lib/crc16_xmodem";
import base32 from "base32.js";
import nacl from "tweetnacl";
import { sha256 } from "sha.js";

// TODO use bip32-path library
export function splitPath(path: string): number[] {
  let result = [];
  let components = path.split("/");
  components.forEach(element => {
    let number = parseInt(element, 10);
    if (isNaN(number)) {
      return; // FIXME shouldn't it throws instead?
    }
    if (element.length > 1 && element[element.length - 1] === "'") {
      number += 0x80000000;
    }
    result.push(number);
  });
  return result;
}

export function foreach<T, A>(
  arr: T[],
  callback: (T, number) => Promise
): Promise {
  function iterate(index, array, result) {
    if (index >= array.length) {
      return result;
    } else {
      return callback(array[index], index).then(function(res) {
        result.push(res);
        return iterate(index + 1, array, result);
      });
    }
  }
  return Promise.resolve().then(() => iterate(0, arr, []));
}

export function encodeEd25519PublicKey(rawPublicKey: Buffer): string {
  let versionByte = 6 << 3; // 'G'
  let data = Buffer.from(rawPublicKey);
  let versionBuffer = Buffer.from([versionByte]);
  let payload = Buffer.concat([versionBuffer, data]);
  let checksum = Buffer.alloc(2);
  checksum.writeUInt16LE(crc16xmodem(payload), 0);
  let unencoded = Buffer.concat([payload, checksum]);
  return base32.encode(unencoded);
}

export function verifyEd25519Signature(
  data: Buffer,
  signature: Buffer,
  publicKey: Buffer
): boolean {
  return nacl.sign.detached.verify(
    new Uint8Array(data.toJSON().data),
    new Uint8Array(signature.toJSON().data),
    new Uint8Array(publicKey.toJSON().data)
  );
}

export function hash(data: Buffer) {
  let hasher = new sha256();
  hasher.update(data, "utf8");
  return hasher.digest();
}

export function checkStellarBip32Path(path: string): void {
  if (!path.startsWith("44'/148'")) {
    throw new Error(
      "Not a Stellar BIP32 path. Path: " +
        path +
        "." +
        " The Stellar app is authorized only for paths starting with 44'/148'." +
        " Example: 44'/148'/0'"
    );
  }
  path.split("/").forEach(function(element) {
    if (!element.toString().endsWith("'")) {
      throw new Error(
        "Detected a non-hardened path element in requested BIP32 path." +
          " Non-hardended paths are not supported at this time. Please use an all-hardened path." +
          " Example: 44'/148'/0'"
      );
    }
  });
}
<commit_msg>feat: implement crc16xmodem<commit_after>/********************************************************************************
 *   Ledger Node JS API
 *   (c) 2017-2018 Ledger
 *
 *  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.
 ********************************************************************************/
//@flow

import base32 from "base32.js";
import nacl from "tweetnacl";
import { sha256 } from "sha.js";

// TODO use bip32-path library
export function splitPath(path: string): number[] {
  let result = [];
  let components = path.split("/");
  components.forEach(element => {
    let number = parseInt(element, 10);
    if (isNaN(number)) {
      return; // FIXME shouldn't it throws instead?
    }
    if (element.length > 1 && element[element.length - 1] === "'") {
      number += 0x80000000;
    }
    result.push(number);
  });
  return result;
}

export function foreach<T, A>(
  arr: T[],
  callback: (T, number) => Promise
): Promise {
  function iterate(index, array, result) {
    if (index >= array.length) {
      return result;
    } else {
      return callback(array[index], index).then(function(res) {
        result.push(res);
        return iterate(index + 1, array, result);
      });
    }
  }
  return Promise.resolve().then(() => iterate(0, arr, []));
}

export function crc16xmodem(buf, previous) {
  let crc = typeof previous !== 'undefined' ? ~~previous : 0x0;

  for (var index = 0; index < buf.length; index++) {
    const byte = buf[index];
    let code = crc >>> 8 & 0xFF;

    code ^= byte & 0xFF;
    code ^= code >>> 4;
    crc = crc << 8 & 0xFFFF;
    crc ^= code;
    code = code << 5 & 0xFFFF;
    crc ^= code;
    code = code << 7 & 0xFFFF;
    crc ^= code;
  }

  return crc;
}

export function encodeEd25519PublicKey(rawPublicKey: Buffer): string {
  let versionByte = 6 << 3; // 'G'
  let data = Buffer.from(rawPublicKey);
  let versionBuffer = Buffer.from([versionByte]);
  let payload = Buffer.concat([versionBuffer, data]);
  let checksum = Buffer.alloc(2);
  checksum.writeUInt16LE(crc16xmodem(payload), 0);
  let unencoded = Buffer.concat([payload, checksum]);
  return base32.encode(unencoded);
}

export function verifyEd25519Signature(
  data: Buffer,
  signature: Buffer,
  publicKey: Buffer
): boolean {
  return nacl.sign.detached.verify(
    new Uint8Array(data.toJSON().data),
    new Uint8Array(signature.toJSON().data),
    new Uint8Array(publicKey.toJSON().data)
  );
}

export function hash(data: Buffer) {
  let hasher = new sha256();
  hasher.update(data, "utf8");
  return hasher.digest();
}

export function checkStellarBip32Path(path: string): void {
  if (!path.startsWith("44'/148'")) {
    throw new Error(
      "Not a Stellar BIP32 path. Path: " +
        path +
        "." +
        " The Stellar app is authorized only for paths starting with 44'/148'." +
        " Example: 44'/148'/0'"
    );
  }
  path.split("/").forEach(function(element) {
    if (!element.toString().endsWith("'")) {
      throw new Error(
        "Detected a non-hardened path element in requested BIP32 path." +
          " Non-hardended paths are not supported at this time. Please use an all-hardened path." +
          " Example: 44'/148'/0'"
      );
    }
  });
}
<|endoftext|>


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

    var serviceId = 'datacontext';
    angular.module('app').factory(serviceId,
        ['$q', '$http', 'common', datacontext]);

    function datacontext($q, $http, common) {

        var getLogFn = common.logger.getLogFn;
        var log = getLogFn(serviceId);
        var logError = getLogFn(serviceId, 'error');
        var logSuccess = getLogFn(serviceId, 'success');
        var threatModel = null;

        var service = {
            repos: repos,
            branches: branches,
            models: models,
            load: load,
            create: create,
            update: update,
            deleteModel: deleteModel,
            saveThreatModelDiagram: saveThreatModelDiagram,
            threatModel: threatModel
        };

        return service;

        function repos() {

            var reposUri = 'threatmodel/repos';
            var config = {
                headers: { Accept: 'application/json' }
            };

            return $http.get(reposUri, config);
        }

        function branches(organisation, repo) {

            var branchesUri = 'threatmodel/' + organisation + '/' + repo + '/branches';
             var config = {
                headers: { Accept: 'application/json' }
            };

            return $http.get(branchesUri, config);
        }

        function models(organisation, repo, branch) {

            var modelsUri = 'threatmodel/' + organisation + '/' + repo + '/' + branch + '/models';
             var config = {
                headers: { Accept: 'application/json' }
            };

            return $http.get(modelsUri, config);
        }

        function load(threatModelLocation, forceQuery) {

            var loc = {
                organisation: threatModelLocation.organisation,
                repo: threatModelLocation.repo,
                branch: threatModelLocation.branch,
                model: threatModelLocation.model
            };

            //don't refetch if the location has not changed
            if (service.threatModel && JSON.stringify(loc) === JSON.stringify(service.threatModel.location) && !forceQuery) {
                return $q.when(service.threatModel);
            }

            var threatModelUri = buildUri(loc) + '/data';

            var config = {
                headers: {Accept: 'application/json'}
            };

			return $http.get(threatModelUri, config).then(onLoadedThreatModel, onLoadError);

            function onLoadedThreatModel(result) {
                service.threatModel = result.data;
                service.threatModel.location = loc;
                return $q.resolve(service.threatModel);
            }
        }

        function create(threatModelLocation, threatModel) {
            var loc = {
                organisation: threatModelLocation.organisation,
                repo: threatModelLocation.repo,
                branch: threatModelLocation.branch,
                model: threatModel.summary.title.replace(' ', '_')
            };

            var threatModelUri = buildUri(loc) + '/create';

            var request = {
                method: 'PUT',
                url: threatModelUri,
                data: threatModel
            };

            threatModel.location = loc;
            service.threatModel = threatModel;

            return $http(request);
        }

        function update() {

            var threatModelUri = buildUri(service.threatModel.location) + '/update';

            var request = {
                method: 'PUT',
                url: threatModelUri,
                data: service.threatModel
            };

            return $http(request);
        }

        function deleteModel() {

            var threatModelUri = buildUri(service.threatModel.location);

            return $http.delete(threatModelUri).then(onDeletedModel);

            function onDeletedModel() {
                service.threatModel = null;
                return $q.resolve(service.threatModel);
            }

            function onDeleteError(error) {
                return $q.reject(error);
            }
        }

        function saveThreatModelDiagram(diagramId, diagramData) {

            //console.log(service.threatModel.detail.diagrams);

            var diagramToSave = service.threatModel.detail.diagrams.find(function(diagram) {
                return diagram.id == diagramId;
            });

            if(diagramToSave) {
                diagramToSave.diagramJson = diagramData.diagramJson;
                diagramToSave.size = diagramData.size;
                return update();
            } else {
                return $q.reject(new Error('invalid diagram id'));
            }
        }

        //private functions
        function onLoadError(err) {
            service.threatModel = null;
            return $q.reject(err);
        }

        function buildUri(threatModelLocation) {

            var uri = 'threatmodel/';
            uri += threatModelLocation.organisation + '/';
            uri += threatModelLocation.repo + '/';
            uri += threatModelLocation.branch + '/';
            uri += threatModelLocation.model;

            return uri;
        }
    }
})();<commit_msg>made datacontext code more consistent<commit_after>(function () {
    'use strict';

    var serviceId = 'datacontext';
    angular.module('app').factory(serviceId,
        ['$q', '$http', 'common', datacontext]);

    function datacontext($q, $http, common) {

        var getLogFn = common.logger.getLogFn;
        var log = getLogFn(serviceId);
        var logError = getLogFn(serviceId, 'error');
        var logSuccess = getLogFn(serviceId, 'success');
        var threatModel = null;

        var service = {
            repos: repos,
            branches: branches,
            models: models,
            load: load,
            create: create,
            update: update,
            deleteModel: deleteModel,
            saveThreatModelDiagram: saveThreatModelDiagram,
            threatModel: threatModel
        };

        return service;

        function repos() {

            var reposUri = 'threatmodel/repos';
            var config = {
                headers: { Accept: 'application/json' }
            };

            return $http.get(reposUri, config);
        }

        function branches(organisation, repo) {

            var branchesUri = 'threatmodel/' + organisation + '/' + repo + '/branches';
             var config = {
                headers: { Accept: 'application/json' }
            };

            return $http.get(branchesUri, config);
        }

        function models(organisation, repo, branch) {

            var modelsUri = 'threatmodel/' + organisation + '/' + repo + '/' + branch + '/models';
             var config = {
                headers: { Accept: 'application/json' }
            };

            return $http.get(modelsUri, config);
        }

        function load(threatModelLocation, forceQuery) {

            var loc = {
                organisation: threatModelLocation.organisation,
                repo: threatModelLocation.repo,
                branch: threatModelLocation.branch,
                model: threatModelLocation.model
            };

            //don't refetch if the location has not changed
            if (service.threatModel && JSON.stringify(loc) === JSON.stringify(service.threatModel.location) && !forceQuery) {
                return $q.when(service.threatModel);
            }

            var threatModelUri = buildUri(loc) + '/data';

            var config = {
                headers: {Accept: 'application/json'}
            };

			return $http.get(threatModelUri, config).then(onLoadedThreatModel, onLoadError);

            function onLoadedThreatModel(result) {
                service.threatModel = result.data;
                service.threatModel.location = loc;
                return $q.resolve(service.threatModel);
            }
        }

        function create(threatModelLocation, threatModel) {
            var loc = {
                organisation: threatModelLocation.organisation,
                repo: threatModelLocation.repo,
                branch: threatModelLocation.branch,
                model: threatModel.summary.title.replace(' ', '_')
            };

            var threatModelUri = buildUri(loc) + '/create';

            threatModel.location = loc;
            service.threatModel = threatModel;

            return $http.put(threatModelUri, threatModel);
        }

        function update() {

            var threatModelUri = buildUri(service.threatModel.location) + '/update';

            return $http.put(threatModelUri, service.threatModel);
        }

        function deleteModel() {

            var threatModelUri = buildUri(service.threatModel.location);

            return $http.delete(threatModelUri).then(onDeletedModel);

            function onDeletedModel() {
                service.threatModel = null;
                return $q.resolve(service.threatModel);
            }

            function onDeleteError(error) {
                return $q.reject(error);
            }
        }

        function saveThreatModelDiagram(diagramId, diagramData) {

            //console.log(service.threatModel.detail.diagrams);

            var diagramToSave = service.threatModel.detail.diagrams.find(function(diagram) {
                return diagram.id == diagramId;
            });

            if(diagramToSave) {
                diagramToSave.diagramJson = diagramData.diagramJson;
                diagramToSave.size = diagramData.size;
                return update();
            } else {
                return $q.reject(new Error('invalid diagram id'));
            }
        }

        //private functions
        function onLoadError(err) {
            service.threatModel = null;
            return $q.reject(err);
        }

        function buildUri(threatModelLocation) {

            var uri = 'threatmodel/';
            uri += threatModelLocation.organisation + '/';
            uri += threatModelLocation.repo + '/';
            uri += threatModelLocation.branch + '/';
            uri += threatModelLocation.model;

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


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

var App = require('app');

/**
 * Popover for configs widgets
 * Usage:
 *
 *  didInsertElement: function () {
 *    this._super();
 *    this.initPopover();
 *  }
 *
 * @type {Em.Mixin}
 */
App.WidgetPopoverSupport = Em.Mixin.create({

  /**
   * Should popover be on the page
   * @type {boolean}
   */
  isPopoverEnabled: true,

  /**
   * Where popover should be displayed - top|left|right|bottom
   * popover to left if config is located at the right most sub-section of the right most section.
   *
   * @type {string}
   */
  popoverPlacement: function () {
    return this.get('section.isLastColumn') && this.get('subSection.isLastColumn')? 'left' : 'right';
  }.property('section.isLastColumn', 'subSection.isLastColumn'),

  initPopover: function () {
    if (this.get('isPopoverEnabled') !== false) {
      this.destroyPopover();
      var leftPopoverTemplate = '

',
        isWidget = !Em.isEmpty(this.$('.original-widget')),
        popoverSelector = isWidget ? this.$('.original-widget') : this.$('.input-append');

      App.popover(popoverSelector, {
        template: this.get('popoverPlacement') === 'left'? leftPopoverTemplate : undefined,
        title: Em.I18n.t('installer.controls.serviceConfigPopover.title').format(
          this.get('configLabel'),
          this.get('configLabel') === this.get('config.name') ? '' : this.get('config.name')
        ),
        content: this.get('config.description'),
        placement: this.get('popoverPlacement'),
        trigger: 'hover',
        delay: {
          show: 1000,
          hide: 0
        }
      });
      this.on('willDestroyElement', this, this.destroyPopover);
    }
  },

  /**
   * Destroy popover after config becomes hidden
   */
  destroyPopover: function () {
    this.movePopover('destroy');
  },

  /**
   * Hide popover on config state changing (from widget-view to raw-mode and from raw-mode to widget-view)
   */
  hidePopover: function () {
    this.movePopover('hide');
  }.observes('config.showAsTextBox'),

  movePopover: function (action) {
    var popoverSelector = Em.isEmpty(this.$('.original-widget')) ? this.$('.input-append') : this.$('.original-widget');
    this.$(popoverSelector).popover(action);
  }

});
<commit_msg>AMBARI-17958. Ranger smart config tabs are broken for HDP 2.2 installation (akovalenko)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

var App = require('app');

/**
 * Popover for configs widgets
 * Usage:
 *
 *  didInsertElement: function () {
 *    this._super();
 *    this.initPopover();
 *  }
 *
 * @type {Em.Mixin}
 */
App.WidgetPopoverSupport = Em.Mixin.create({

  /**
   * Should popover be on the page
   * @type {boolean}
   */
  isPopoverEnabled: true,

  /**
   * Where popover should be displayed - top|left|right|bottom
   * popover to left if config is located at the right most sub-section of the right most section.
   *
   * @type {string}
   */
  popoverPlacement: function () {
    return this.get('section.isLastColumn') && this.get('subSection.isLastColumn')? 'left' : 'right';
  }.property('section.isLastColumn', 'subSection.isLastColumn'),

  initPopover: function () {
    if (this.get('isPopoverEnabled') !== false) {
      this.destroyPopover();
      var leftPopoverTemplate = '

',
        isWidget = !Em.isEmpty(this.$('.original-widget')),
        popoverSelector = isWidget ? this.$('.original-widget') : this.$('.input-append');

      App.popover(popoverSelector, {
        template: this.get('popoverPlacement') === 'left'? leftPopoverTemplate : undefined,
        title: Em.I18n.t('installer.controls.serviceConfigPopover.title').format(
          this.get('configLabel'),
          this.get('configLabel') === this.get('config.name') ? '' : this.get('config.name')
        ),
        content: this.get('config.description'),
        placement: this.get('popoverPlacement'),
        trigger: 'hover',
        delay: {
          show: 1000,
          hide: 0
        }
      });
      this.on('willDestroyElement', this, this.destroyPopover);
    }
  },

  /**
   * Destroy popover after config becomes hidden
   */
  destroyPopover: function () {
    this.movePopover('destroy');
  },

  /**
   * Hide popover on config state changing (from widget-view to raw-mode and from raw-mode to widget-view)
   */
  hidePopover: function () {
    this.movePopover('hide');
  }.observes('config.showAsTextBox'),

  movePopover: function (action) {
    var popoverSelector = Em.isEmpty(this.$('.original-widget')) ? this.$('.input-append') : this.$('.original-widget');
    if (popoverSelector) {
      this.$(popoverSelector).popover(action)
    }
  }

});
<|endoftext|>


<commit_before>import SPELLS from 'common/SPELLS';
import CoreGlobalCooldown from 'Parser/Core/Modules/GlobalCooldown';
import Channeling from 'Parser/Core/Modules/Channeling';
import Combatants from 'Parser/Core/Modules/Combatants';

import Abilities from '../Features/Abilities';
import Haste from './Haste';

/**
 * The talent Starlord reduces GCD and cast time of empowered Lunar Strikes and Solar Wraths by 20%.
 * Since Solar Wrath cast time == GCD the GCD needs to be reduced.
 */
class GlobalCooldown extends CoreGlobalCooldown {
  static dependencies = {
    abilities: Abilities,
    haste: Haste,
    combatants: Combatants,
    channeling: Channeling,
  };

  isStarlordBuffedSolarWrath(event) {
  	return event.ability.guid === SPELLS.SOLAR_WRATH_MOONKIN.id && this.combatants.selected.hasTalent(SPELLS.STARLORD_TALENT.id) && this.combatants.selected.hasBuff(SPELLS.SOLAR_EMP_BUFF.id);
  }

  on_byPlayer_begincast(event) {
    if (this.isStarlordBuffedSolarWrath(event)) {
      this.triggerStarlordGlobalCooldown(event, 'begincast');
    }
    return;
  }
  on_byPlayer_beginchannel(event) {
  	if (this.isStarlordBuffedSolarWrath(event)) {
      return;
    }
    super.on_byPlayer_beginchannel(event);
  }
  on_byPlayer_cast(event) {
  	if (this.isStarlordBuffedSolarWrath(event)) {
      return;
    }
    super.on_byPlayer_cast(event);
  }

  triggerStarlordGlobalCooldown(event, trigger) {
    this.owner.triggerEvent('globalcooldown', {
      type: 'globalcooldown',
      ability: event.ability,
      timestamp: event.timestamp,
      duration: Math.max(750, this.getCurrentGlobalCooldown(event.ability.guid) * 0.8), //Starlord multiplier
      reason: event,
      trigger,
    });
  }
}

export default GlobalCooldown;
<commit_msg>Attempt #2, overwritten the correct method (I hope)<commit_after>import SPELLS from 'common/SPELLS';
import CoreGlobalCooldown from 'Parser/Core/Modules/GlobalCooldown';
import Channeling from 'Parser/Core/Modules/Channeling';
import Combatants from 'Parser/Core/Modules/Combatants';

import Abilities from '../Features/Abilities';
import Haste from './Haste';

/**
 * The talent Starlord reduces GCD and cast time of empowered Lunar Strikes and Solar Wraths by 20%.
 * Since Solar Wrath cast time == GCD the GCD needs to be reduced.
 */
class GlobalCooldown extends CoreGlobalCooldown {
  static dependencies = {
    abilities: Abilities,
    haste: Haste,
    combatants: Combatants,
    channeling: Channeling,
  };

  getCurrentGlobalCooldown(spellId = null) {
  	//Starlord Solar Wrath
    if (spellId === SPELLS.SOLAR_WRATH_MOONKIN.id && this.combatants.selected.hasTalent(SPELLS.STARLORD_TALENT.id) && this.combatants.selected.hasBuff(SPELLS.SOLAR_EMP_BUFF.id)){
      return Math.max(this.owner.modules.alwaysBeCasting.constructor.MINIMUM_GCD, this.owner.modules.alwaysBeCasting.constructor.BASE_GCD / (1 + this.haste.current) * 0.8);
    }
    //Default
    return (spellId && this.owner.modules.alwaysBeCasting.constructor.STATIC_GCD_ABILITIES[spellId]) || this.constructor.calculateGlobalCooldown(this.haste.current, this.owner.modules.alwaysBeCasting.constructor.BASE_GCD, this.owner.modules.alwaysBeCasting.constructor.MINIMUM_GCD);
  }
}

export default GlobalCooldown;
<|endoftext|>