<commit_before>var CONFIG = require("../config.js");
var CONSTANTS = require("../constants.js");
var UTIL = require("../util.js");
var adapterManager = require("../adapterManager.js");
var bidManager = require("../bidManager.js");
var GDPR = require("../gdpr.js");
var SLOT = require("../slot.js");
var PHOENIX = require("uas-adclient");

var slotsMap = {}; // key is div id, stores the mapping of divID ==> googletag.slot
/* start-test-block */
exports.slotsMap = slotsMap;
/* end-test-block */

var windowReference = null;
var refThis = this;

function setWindowReference(win) {
    if (UTIL.isObject(win)) {
        windowReference = win;
    }
}
/* start-test-block */
exports.setWindowReference = setWindowReference;
/* end-test-block */

function getWindowReference() {
    return windowReference;
}
/* start-test-block */
exports.getWindowReference = getWindowReference;
/* end-test-block */

function setDisplayFunctionCalledIfRequired(slot, arg) { // TDD, i/o : done
    /* istanbul ignore else */
    if (UTIL.isObject(slot) && UTIL.isFunction(slot.getDivID)) {
        /* istanbul ignore else */
        if (UTIL.isArray(arg) && arg[0] && arg[0] == slot.getDivID()) {
            slot.setDisplayFunctionCalled(true);
            slot.setArguments(arg);
        }
    }
}

/* start-test-block */
exports.setDisplayFunctionCalledIfRequired = setDisplayFunctionCalledIfRequired;
/* end-test-block */

function storeInSlotsMap(dmSlotName, currentPhoenixSlot, isDisplayFlow) {
    // note: here dmSlotName is actually the DivID
    if (!UTIL.isOwnProperty(refThis.slotsMap, dmSlotName)) {
        var slot = SLOT.createSlot(dmSlotName);
        slot.setDivID(dmSlotName);
        slot.setPubAdServerObject(currentPhoenixSlot);
        slot.setAdUnitID(currentPhoenixSlot.getAdUnit());
        slot.setAdUnitIndex(0);
        slot.setSizes(currentPhoenixSlot.getDimensions());
        slot.setStatus(CONSTANTS.SLOT_STATUS.CREATED);

        refThis.slotsMap[dmSlotName] = slot;
        UTIL.createVLogInfoPanel(dmSlotName, slot.getSizes());
    }
}

/* start-test-block */
exports.storeInSlotsMap = storeInSlotsMap;
/* end-test-block */

function updateSlotsMapFromPhoenixSlots(phoenixSlotsArray, argumentsFromCallingFunction, isDisplayFlow) { // TDD, i/o : done
    UTIL.log("Generating slotsMap");
    UTIL.forEachOnArray(phoenixSlotsArray, function(index, currentPhoenixSlot) {
        var dmSlotName = currentPhoenixSlot.getId();
        refThis.storeInSlotsMap(dmSlotName, currentPhoenixSlot, isDisplayFlow);
        if (isDisplayFlow && UTIL.isOwnProperty(refThis.slotsMap, dmSlotName)) {
            refThis.setDisplayFunctionCalledIfRequired(refThis.slotsMap[dmSlotName], argumentsFromCallingFunction);
        }
    });
    UTIL.log(refThis.slotsMap);
}

/* start-test-block */
exports.updateSlotsMapFromPhoenixSlots = updateSlotsMapFromPhoenixSlots;
/* end-test-block */

//todo: pass slotsMap in every function that uses it
function getStatusOfSlotForDivId(divID) { // TDD, i/o : done
    /* istanbul ignore else */
    if (UTIL.isOwnProperty(refThis.slotsMap, divID)) {
        return refThis.slotsMap[divID].getStatus();
    }
    return CONSTANTS.SLOT_STATUS.DISPLAYED;
}

/* start-test-block */
exports.getStatusOfSlotForDivId = getStatusOfSlotForDivId;
/* end-test-block */

function updateStatusAfterRendering(divID, isRefreshCall) {
    /* istanbul ignore else */
    if (UTIL.isOwnProperty(refThis.slotsMap, divID)) {
        refThis.slotsMap[divID].updateStatusAfterRendering(isRefreshCall);
    }
}

/* start-test-block */
exports.updateStatusAfterRendering = updateStatusAfterRendering;
/* end-test-block */

function findWinningBidAndApplyTargeting(divID) { // TDD, i/o : done
    var data = bidManager.getBid(divID);
    var winningBid = data.wb || null;
    var keyValuePairs = data.kvp || null;
    var phoenixDefinedSlot = refThis.slotsMap[divID].getPubAdServerObject();
    var ignoreTheseKeys = CONSTANTS.IGNORE_PREBID_KEYS;

    UTIL.log("DIV: " + divID + " winningBid: ");
    UTIL.log(winningBid);

    /* istanbul ignore else*/
    if (winningBid && winningBid.getNetEcpm() > 0) {
        refThis.slotsMap[divID].setStatus(CONSTANTS.SLOT_STATUS.TARGETING_ADDED);
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_ID, winningBid.getBidID());
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_STATUS, winningBid.getStatus());
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_ECPM, winningBid.getNetEcpm().toFixed(CONSTANTS.COMMON.BID_PRECISION));
        phoenixDefinedSlot.setWrapperEcpm(winningBid.getNetEcpm().toFixed(CONSTANTS.COMMON.BID_PRECISION));
        var dealID = winningBid.getDealID();
        if(dealID){
            phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_DEAL_ID, dealID);
        }
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_ADAPTER_ID, winningBid.getAdapterID());
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.PUBLISHER_ID, CONFIG.getPublisherId());
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.PROFILE_ID, CONFIG.getProfileID());
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.PROFILE_VERSION_ID, CONFIG.getProfileDisplayVersionID());
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.PLATFORM_KEY, CONSTANTS.PLATFORM_VALUES.DISPLAY);

    }

    // attaching keyValuePairs from adapters
    UTIL.forEachOnObject(keyValuePairs, function(key, value) {
        /* istanbul ignore else*/
        if (!UTIL.isOwnProperty(ignoreTheseKeys, key)) {
            phoenixDefinedSlot.setTargeting(key, value);
        }
    });
}

/* start-test-block */
exports.findWinningBidAndApplyTargeting = findWinningBidAndApplyTargeting;
/* end-test-block */

function findWinningBidIfRequired_Display(key, slot) { // TDD, i/o : done
    var status = slot.getStatus();
    if (status != CONSTANTS.SLOT_STATUS.DISPLAYED && status != CONSTANTS.SLOT_STATUS.TARGETING_ADDED) {
        refThis.findWinningBidAndApplyTargeting(key);
    }
}

/* start-test-block */
exports.findWinningBidIfRequired_Display = findWinningBidIfRequired_Display;
/* end-test-block */

// TODO: remove unnecessary theObject dependancy from flow, pass resolve object as originalFunction
function updateStatusAndCallOriginalFunction_Display(message, theObject, originalFunction, arg) {
    UTIL.log(message);
    UTIL.log(arg);
    refThis.updateStatusAfterRendering(arg[0], false);
    originalFunction(arg[0]);
}

/* start-test-block */
exports.updateStatusAndCallOriginalFunction_Display = updateStatusAndCallOriginalFunction_Display;
/* end-test-block */

function processDisplayCalledSlot(theObject, originalFunction, arg){
    if (refThis.getStatusOfSlotForDivId(arg[0]) != CONSTANTS.SLOT_STATUS.DISPLAYED) {
        refThis.updateStatusAndCallOriginalFunction_Display(
            "Calling original display function after timeout with arguments, ",
            theObject,
            originalFunction,
            arg
        );
    } else {
        UTIL.log("AdSlot already rendered");
    }
}

/* start-test-block */
exports.processDisplayCalledSlot = processDisplayCalledSlot;
/* end-test-block */

function arrayOfSelectedSlots(slotNames) { // TDD, i/o : done
    var output = [];
    UTIL.forEachOnArray(slotNames, function(index, slotName) {
        output.push(refThis.slotsMap[slotName]);
    });
    return output;
}

/* start-test-block */
exports.arrayOfSelectedSlots = arrayOfSelectedSlots;
/* end-test-block */

function getSlotNamesByStatus(statusObject) {
    var slots = [];
    UTIL.forEachOnObject(refThis.slotsMap, function(key, slot) {
        /* istanbul ignore else */
        if (UTIL.isOwnProperty(statusObject, slot.getStatus())) {
            slots.push(key);
        }
    });
    return slots;
}

/* start-test-block */
exports.getSlotNamesByStatus = getSlotNamesByStatus;
/* end-test-block */

function updateStatusOfQualifyingSlotsBeforeCallingAdapters(slotNames, argumentsFromCallingFunction, isRefreshCall) { // TDD : done
    UTIL.forEachOnArray(slotNames, function(index, slotName) {
        /* istanbul ignore else */
        if (UTIL.isOwnProperty(refThis.slotsMap, slotName)) {
            var slot = refThis.slotsMap[slotName];
            slot.setStatus(CONSTANTS.SLOT_STATUS.PARTNERS_CALLED);
        }
    });
}

/* start-test-block */
exports.updateStatusOfQualifyingSlotsBeforeCallingAdapters = updateStatusOfQualifyingSlotsBeforeCallingAdapters;
/* end-test-block */

function forQualifyingSlotNamesCallAdapters(qualifyingSlotNames, arg, isRefreshCall) { // TDD, i/o : done
    if (qualifyingSlotNames.length > 0) {
        refThis.updateStatusOfQualifyingSlotsBeforeCallingAdapters(qualifyingSlotNames, arg, isRefreshCall);
        var qualifyingSlots = refThis.arrayOfSelectedSlots(qualifyingSlotNames);
        adapterManager.callAdapters(qualifyingSlots);
    }
}

/* start-test-block */
exports.forQualifyingSlotNamesCallAdapters = forQualifyingSlotNamesCallAdapters;
/* end-test-block */

function executeDisplay(timeout, divIds, callback) {
    if (UTIL.getExternalBidderStatus(divIds) && bidManager.getAllPartnersBidStatuses(window.PWT.bidMap, divIds)) {
        UTIL.resetExternalBidderStatus(divIds);
        callback();
    } else {
        (timeout > 0) && window.setTimeout(function() {
          refThis.executeDisplay(timeout - 10, divIds, callback);
        }, 10);
    }
}

/* start-test-block */
exports.executeDisplay = executeDisplay;
/* end-test-block */

function displayFunctionStatusHandler(oldStatus, theObject, originalFunction, arg) {
    switch (oldStatus) {
        // display method was called for this slot
        /* istanbul ignore next */
        case CONSTANTS.SLOT_STATUS.CREATED:
        // dm flow is already intiated for this slot
        // just intitate the CONFIG.getTimeout() now
        // eslint-disable-line no-fallthrough
        /* istanbul ignore next */
        case CONSTANTS.SLOT_STATUS.PARTNERS_CALLED:
            var divIds = Object.keys(refThis.slotsMap);

            if (typeof window.OWT.externalBidderStatuses[arg[0]] === "object" && window.OWT.externalBidderStatuses[arg[0]]) {
               refThis.executeDisplay(CONFIG.getTimeout(), divIds, function() {
                   UTIL.forEachOnObject(refThis.slotsMap, function(key, slot) {
                       refThis.findWinningBidIfRequired_Display(key, slot);
                   });
                   refThis.processDisplayCalledSlot(theObject, originalFunction, arg);
                });
            }

            setTimeout(function() {
              UTIL.log("PostTimeout.. back in display function");
              UTIL.forEachOnObject(refThis.slotsMap, function(key, slot) {
                  refThis.findWinningBidIfRequired_Display(key, slot);
              });
              refThis.processDisplayCalledSlot(theObject, originalFunction, arg);
            }, CONFIG.getTimeout());

            break;
            // call the original function now
        case CONSTANTS.SLOT_STATUS.TARGETING_ADDED:
            refThis.updateStatusAndCallOriginalFunction_Display(
                "As DM processing is already done, Calling original display function with arguments",
                theObject,
                originalFunction,
                arg
            );
            break;

        case CONSTANTS.SLOT_STATUS.DISPLAYED:
            refThis.updateStatusAndCallOriginalFunction_Display(
                "As slot is already displayed, Calling original display function with arguments",
                theObject,
                originalFunction,
                arg
            );
            break;
    }
}

/* start-test-block */
exports.displayFunctionStatusHandler = displayFunctionStatusHandler;
/* end-test-block */

function initiateDisplay(win) {
  win.Phoenix.registerPreDisplayHandler(function(taskDone, divId){
    // Initiating getUserConsentDataFromCMP method to get the updated consentData
    // GDPR.getUserConsentDataFromCMP();

    var phoenixObj = window.Phoenix || {};

    /* istanbul ignore next */
    refThis.updateSlotsMapFromPhoenixSlots(phoenixObj.getSlots(), [divId], true);

    /* istanbul ignore next */
    refThis.displayFunctionStatusHandler(getStatusOfSlotForDivId(divId), {}, taskDone, [divId]);

    var statusObj = {};
    statusObj[CONSTANTS.SLOT_STATUS.CREATED] = "";

    refThis.forQualifyingSlotNamesCallAdapters(getSlotNamesByStatus(statusObj), [divId], false);

    /* istanbul ignore next */
    setTimeout(function() {
      UTIL.realignVLogInfoPanel(divId);
      bidManager.executeAnalyticsPixel();
    }, 2000 + CONFIG.getTimeout());

  });
}
/* start-test-block */
exports.initiateDisplay = initiateDisplay;
/* end-test-block */

function callJsLoadedIfRequired(win) { // TDD, i/o : done
    if (UTIL.isObject(win) && UTIL.isObject(win.PWT) && UTIL.isFunction(win.PWT.jsLoaded)) {
        win.PWT.jsLoaded();
        return true;
    }
    return false;
}
/* start-test-block */
exports.callJsLoadedIfRequired = callJsLoadedIfRequired;
/* end-test-block */

function initPhoenixScript(win) {
    if (UTIL.isUndefined(win.Phoenix.isJSLoaded) && UTIL.isObject(win.Phoenix) && UTIL.isArray(win.Phoenix.EQ)) {
        UTIL.log("Succeeded to load before UAS");
        var refThis = this;

        win.Phoenix.EQ.unshift(function () {
            /* istanbul ignore next */
            UTIL.log("OpenWrap initialization started");
            /* istanbul ignore next */
            refThis.initiateDisplay(win);
            /* istanbul ignore next */
            UTIL.log("OpenWrap initialization completed");
        });
        PHOENIX.init(win);
        return true;
    } else {
        UTIL.log("Failed to load before UAS");
        return false;
    }
}
/* start-test-block */
exports.initPhoenixScript = initPhoenixScript;
/* end-test-block */

exports.init = function(win) { // TDD, i/o : done
	CONFIG.initConfig();
    if (UTIL.isObject(win)) {
        refThis.setWindowReference(win);
        adapterManager.registerAdapters();
        refThis.initPhoenixScript(win);
        refThis.callJsLoadedIfRequired(win);
        return true;
    } else {
        return false;
    }
};
<commit_msg>uas controller not to use adapter-manager<commit_after>var CONFIG = require("../config.js");
var CONSTANTS = require("../constants.js");
var UTIL = require("../util.js");
var prebid = require("../adapters/prebid.js");
var bidManager = require("../bidManager.js");
var GDPR = require("../gdpr.js");
var SLOT = require("../slot.js");
var PHOENIX = require("uas-adclient");

var slotsMap = {}; // key is div id, stores the mapping of divID ==> googletag.slot
/* start-test-block */
exports.slotsMap = slotsMap;
/* end-test-block */

var windowReference = null;
var refThis = this;

function setWindowReference(win) {
    if (UTIL.isObject(win)) {
        windowReference = win;
    }
}
/* start-test-block */
exports.setWindowReference = setWindowReference;
/* end-test-block */

function getWindowReference() {
    return windowReference;
}
/* start-test-block */
exports.getWindowReference = getWindowReference;
/* end-test-block */

function setDisplayFunctionCalledIfRequired(slot, arg) { // TDD, i/o : done
    /* istanbul ignore else */
    if (UTIL.isObject(slot) && UTIL.isFunction(slot.getDivID)) {
        /* istanbul ignore else */
        if (UTIL.isArray(arg) && arg[0] && arg[0] == slot.getDivID()) {
            slot.setDisplayFunctionCalled(true);
            slot.setArguments(arg);
        }
    }
}

/* start-test-block */
exports.setDisplayFunctionCalledIfRequired = setDisplayFunctionCalledIfRequired;
/* end-test-block */

function storeInSlotsMap(dmSlotName, currentPhoenixSlot, isDisplayFlow) {
    // note: here dmSlotName is actually the DivID
    if (!UTIL.isOwnProperty(refThis.slotsMap, dmSlotName)) {
        var slot = SLOT.createSlot(dmSlotName);
        slot.setDivID(dmSlotName);
        slot.setPubAdServerObject(currentPhoenixSlot);
        slot.setAdUnitID(currentPhoenixSlot.getAdUnit());
        slot.setAdUnitIndex(0);
        slot.setSizes(currentPhoenixSlot.getDimensions());
        slot.setStatus(CONSTANTS.SLOT_STATUS.CREATED);

        refThis.slotsMap[dmSlotName] = slot;
        UTIL.createVLogInfoPanel(dmSlotName, slot.getSizes());
    }
}

/* start-test-block */
exports.storeInSlotsMap = storeInSlotsMap;
/* end-test-block */

function updateSlotsMapFromPhoenixSlots(phoenixSlotsArray, argumentsFromCallingFunction, isDisplayFlow) { // TDD, i/o : done
    UTIL.log("Generating slotsMap");
    UTIL.forEachOnArray(phoenixSlotsArray, function(index, currentPhoenixSlot) {
        var dmSlotName = currentPhoenixSlot.getId();
        refThis.storeInSlotsMap(dmSlotName, currentPhoenixSlot, isDisplayFlow);
        if (isDisplayFlow && UTIL.isOwnProperty(refThis.slotsMap, dmSlotName)) {
            refThis.setDisplayFunctionCalledIfRequired(refThis.slotsMap[dmSlotName], argumentsFromCallingFunction);
        }
    });
    UTIL.log(refThis.slotsMap);
}

/* start-test-block */
exports.updateSlotsMapFromPhoenixSlots = updateSlotsMapFromPhoenixSlots;
/* end-test-block */

//todo: pass slotsMap in every function that uses it
function getStatusOfSlotForDivId(divID) { // TDD, i/o : done
    /* istanbul ignore else */
    if (UTIL.isOwnProperty(refThis.slotsMap, divID)) {
        return refThis.slotsMap[divID].getStatus();
    }
    return CONSTANTS.SLOT_STATUS.DISPLAYED;
}

/* start-test-block */
exports.getStatusOfSlotForDivId = getStatusOfSlotForDivId;
/* end-test-block */

function updateStatusAfterRendering(divID, isRefreshCall) {
    /* istanbul ignore else */
    if (UTIL.isOwnProperty(refThis.slotsMap, divID)) {
        refThis.slotsMap[divID].updateStatusAfterRendering(isRefreshCall);
    }
}

/* start-test-block */
exports.updateStatusAfterRendering = updateStatusAfterRendering;
/* end-test-block */

function findWinningBidAndApplyTargeting(divID) { // TDD, i/o : done
    var data = bidManager.getBid(divID);
    var winningBid = data.wb || null;
    var keyValuePairs = data.kvp || null;
    var phoenixDefinedSlot = refThis.slotsMap[divID].getPubAdServerObject();
    var ignoreTheseKeys = CONSTANTS.IGNORE_PREBID_KEYS;

    UTIL.log("DIV: " + divID + " winningBid: ");
    UTIL.log(winningBid);

    /* istanbul ignore else*/
    if (winningBid && winningBid.getNetEcpm() > 0) {
        refThis.slotsMap[divID].setStatus(CONSTANTS.SLOT_STATUS.TARGETING_ADDED);
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_ID, winningBid.getBidID());
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_STATUS, winningBid.getStatus());
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_ECPM, winningBid.getNetEcpm().toFixed(CONSTANTS.COMMON.BID_PRECISION));
        phoenixDefinedSlot.setWrapperEcpm(winningBid.getNetEcpm().toFixed(CONSTANTS.COMMON.BID_PRECISION));
        var dealID = winningBid.getDealID();
        if(dealID){
            phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_DEAL_ID, dealID);
        }
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.BID_ADAPTER_ID, winningBid.getAdapterID());
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.PUBLISHER_ID, CONFIG.getPublisherId());
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.PROFILE_ID, CONFIG.getProfileID());
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.PROFILE_VERSION_ID, CONFIG.getProfileDisplayVersionID());
        phoenixDefinedSlot.setTargeting(CONSTANTS.WRAPPER_TARGETING_KEYS.PLATFORM_KEY, CONSTANTS.PLATFORM_VALUES.DISPLAY);

    }

    // attaching keyValuePairs from adapters
    UTIL.forEachOnObject(keyValuePairs, function(key, value) {
        /* istanbul ignore else*/
        if (!UTIL.isOwnProperty(ignoreTheseKeys, key)) {
            phoenixDefinedSlot.setTargeting(key, value);
        }
    });
}

/* start-test-block */
exports.findWinningBidAndApplyTargeting = findWinningBidAndApplyTargeting;
/* end-test-block */

function findWinningBidIfRequired_Display(key, slot) { // TDD, i/o : done
    var status = slot.getStatus();
    if (status != CONSTANTS.SLOT_STATUS.DISPLAYED && status != CONSTANTS.SLOT_STATUS.TARGETING_ADDED) {
        refThis.findWinningBidAndApplyTargeting(key);
    }
}

/* start-test-block */
exports.findWinningBidIfRequired_Display = findWinningBidIfRequired_Display;
/* end-test-block */

// TODO: remove unnecessary theObject dependancy from flow, pass resolve object as originalFunction
function updateStatusAndCallOriginalFunction_Display(message, theObject, originalFunction, arg) {
    UTIL.log(message);
    UTIL.log(arg);
    refThis.updateStatusAfterRendering(arg[0], false);
    originalFunction(arg[0]);
}

/* start-test-block */
exports.updateStatusAndCallOriginalFunction_Display = updateStatusAndCallOriginalFunction_Display;
/* end-test-block */

function processDisplayCalledSlot(theObject, originalFunction, arg){
    if (refThis.getStatusOfSlotForDivId(arg[0]) != CONSTANTS.SLOT_STATUS.DISPLAYED) {
        refThis.updateStatusAndCallOriginalFunction_Display(
            "Calling original display function after timeout with arguments, ",
            theObject,
            originalFunction,
            arg
        );
    } else {
        UTIL.log("AdSlot already rendered");
    }
}

/* start-test-block */
exports.processDisplayCalledSlot = processDisplayCalledSlot;
/* end-test-block */

function arrayOfSelectedSlots(slotNames) { // TDD, i/o : done
    var output = [];
    UTIL.forEachOnArray(slotNames, function(index, slotName) {
        output.push(refThis.slotsMap[slotName]);
    });
    return output;
}

/* start-test-block */
exports.arrayOfSelectedSlots = arrayOfSelectedSlots;
/* end-test-block */

function getSlotNamesByStatus(statusObject) {
    var slots = [];
    UTIL.forEachOnObject(refThis.slotsMap, function(key, slot) {
        /* istanbul ignore else */
        if (UTIL.isOwnProperty(statusObject, slot.getStatus())) {
            slots.push(key);
        }
    });
    return slots;
}

/* start-test-block */
exports.getSlotNamesByStatus = getSlotNamesByStatus;
/* end-test-block */

function updateStatusOfQualifyingSlotsBeforeCallingAdapters(slotNames, argumentsFromCallingFunction, isRefreshCall) { // TDD : done
    UTIL.forEachOnArray(slotNames, function(index, slotName) {
        /* istanbul ignore else */
        if (UTIL.isOwnProperty(refThis.slotsMap, slotName)) {
            var slot = refThis.slotsMap[slotName];
            slot.setStatus(CONSTANTS.SLOT_STATUS.PARTNERS_CALLED);
        }
    });
}

/* start-test-block */
exports.updateStatusOfQualifyingSlotsBeforeCallingAdapters = updateStatusOfQualifyingSlotsBeforeCallingAdapters;
/* end-test-block */

function forQualifyingSlotNamesCallAdapters(qualifyingSlotNames, arg, isRefreshCall) { // TDD, i/o : done
    if (qualifyingSlotNames.length > 0) {
        refThis.updateStatusOfQualifyingSlotsBeforeCallingAdapters(qualifyingSlotNames, arg, isRefreshCall);
        var qualifyingSlots = refThis.arrayOfSelectedSlots(qualifyingSlotNames);
        prebid.fetchBids(qualifyingSlots, util.generateUUID());
    }
}

/* start-test-block */
exports.forQualifyingSlotNamesCallAdapters = forQualifyingSlotNamesCallAdapters;
/* end-test-block */

function executeDisplay(timeout, divIds, callback) {
    if (UTIL.getExternalBidderStatus(divIds) && bidManager.getAllPartnersBidStatuses(window.PWT.bidMap, divIds)) {
        UTIL.resetExternalBidderStatus(divIds);
        callback();
    } else {
        (timeout > 0) && window.setTimeout(function() {
          refThis.executeDisplay(timeout - 10, divIds, callback);
        }, 10);
    }
}

/* start-test-block */
exports.executeDisplay = executeDisplay;
/* end-test-block */

function displayFunctionStatusHandler(oldStatus, theObject, originalFunction, arg) {
    switch (oldStatus) {
        // display method was called for this slot
        /* istanbul ignore next */
        case CONSTANTS.SLOT_STATUS.CREATED:
        // dm flow is already intiated for this slot
        // just intitate the CONFIG.getTimeout() now
        // eslint-disable-line no-fallthrough
        /* istanbul ignore next */
        case CONSTANTS.SLOT_STATUS.PARTNERS_CALLED:
            var divIds = Object.keys(refThis.slotsMap);

            if (typeof window.OWT.externalBidderStatuses[arg[0]] === "object" && window.OWT.externalBidderStatuses[arg[0]]) {
               refThis.executeDisplay(CONFIG.getTimeout(), divIds, function() {
                   UTIL.forEachOnObject(refThis.slotsMap, function(key, slot) {
                       refThis.findWinningBidIfRequired_Display(key, slot);
                   });
                   refThis.processDisplayCalledSlot(theObject, originalFunction, arg);
                });
            }

            setTimeout(function() {
              UTIL.log("PostTimeout.. back in display function");
              UTIL.forEachOnObject(refThis.slotsMap, function(key, slot) {
                  refThis.findWinningBidIfRequired_Display(key, slot);
              });
              refThis.processDisplayCalledSlot(theObject, originalFunction, arg);
            }, CONFIG.getTimeout());

            break;
            // call the original function now
        case CONSTANTS.SLOT_STATUS.TARGETING_ADDED:
            refThis.updateStatusAndCallOriginalFunction_Display(
                "As DM processing is already done, Calling original display function with arguments",
                theObject,
                originalFunction,
                arg
            );
            break;

        case CONSTANTS.SLOT_STATUS.DISPLAYED:
            refThis.updateStatusAndCallOriginalFunction_Display(
                "As slot is already displayed, Calling original display function with arguments",
                theObject,
                originalFunction,
                arg
            );
            break;
    }
}

/* start-test-block */
exports.displayFunctionStatusHandler = displayFunctionStatusHandler;
/* end-test-block */

function initiateDisplay(win) {
  win.Phoenix.registerPreDisplayHandler(function(taskDone, divId){
    // Initiating getUserConsentDataFromCMP method to get the updated consentData
    // GDPR.getUserConsentDataFromCMP();

    var phoenixObj = window.Phoenix || {};

    /* istanbul ignore next */
    refThis.updateSlotsMapFromPhoenixSlots(phoenixObj.getSlots(), [divId], true);

    /* istanbul ignore next */
    refThis.displayFunctionStatusHandler(getStatusOfSlotForDivId(divId), {}, taskDone, [divId]);

    var statusObj = {};
    statusObj[CONSTANTS.SLOT_STATUS.CREATED] = "";

    refThis.forQualifyingSlotNamesCallAdapters(getSlotNamesByStatus(statusObj), [divId], false);

    /* istanbul ignore next */
    setTimeout(function() {
      UTIL.realignVLogInfoPanel(divId);
      bidManager.executeAnalyticsPixel();
    }, 2000 + CONFIG.getTimeout());

  });
}
/* start-test-block */
exports.initiateDisplay = initiateDisplay;
/* end-test-block */

function callJsLoadedIfRequired(win) { // TDD, i/o : done
    if (UTIL.isObject(win) && UTIL.isObject(win.PWT) && UTIL.isFunction(win.PWT.jsLoaded)) {
        win.PWT.jsLoaded();
        return true;
    }
    return false;
}
/* start-test-block */
exports.callJsLoadedIfRequired = callJsLoadedIfRequired;
/* end-test-block */

function initPhoenixScript(win) {
    if (UTIL.isUndefined(win.Phoenix.isJSLoaded) && UTIL.isObject(win.Phoenix) && UTIL.isArray(win.Phoenix.EQ)) {
        UTIL.log("Succeeded to load before UAS");
        var refThis = this;

        win.Phoenix.EQ.unshift(function () {
            /* istanbul ignore next */
            UTIL.log("OpenWrap initialization started");
            /* istanbul ignore next */
            refThis.initiateDisplay(win);
            /* istanbul ignore next */
            UTIL.log("OpenWrap initialization completed");
        });
        PHOENIX.init(win);
        return true;
    } else {
        UTIL.log("Failed to load before UAS");
        return false;
    }
}
/* start-test-block */
exports.initPhoenixScript = initPhoenixScript;
/* end-test-block */

exports.init = function(win) { // TDD, i/o : done
	CONFIG.initConfig();
    if (UTIL.isObject(win)) {
        refThis.setWindowReference(win);
        refThis.initPhoenixScript(win);
        refThis.callJsLoadedIfRequired(win);
        return true;
    } else {
        return false;
    }
};
<|endoftext|>


<commit_before>import Users from "meteor/vulcan:users";
import { addCallback, getSetting } from 'meteor/vulcan:core';
import { Posts } from '../posts'
import request from 'request';

const MODERATE_OWN_PERSONAL_THRESHOLD = 50
const TRUSTLEVEL1_THRESHOLD = 2000
import { addEditableCallbacks } from '../../../server/editor/make_editable_callbacks.js'
import { makeEditableOptionsModeration } from './custom_fields.js'

function updateTrustedStatus ({newDocument, vote}) {

  const user = Users.findOne(newDocument.userId)
  if (user.karma >= TRUSTLEVEL1_THRESHOLD && (!Users.getGroups(user).includes('trustLevel1'))) {
    Users.update(user._id, {$push: {groups: 'trustLevel1'}});
    const updatedUser = Users.findOne(newDocument.userId)
    //eslint-disable-next-line no-console
    console.info("User gained trusted status", updatedUser.username, updatedUser._id, updatedUser.karma, updatedUser.groups)
  }
}
addCallback("votes.smallUpvote.async", updateTrustedStatus);
addCallback("votes.bigUpvote.async", updateTrustedStatus);

function updateModerateOwnPersonal({newDocument, vote}) {
  const user = Users.findOne(newDocument.userId)
  if (user.karma >= MODERATE_OWN_PERSONAL_THRESHOLD && (!Users.getGroups(user).includes('canModeratePersonal'))) {
    Users.update(user._id, {$push: {groups: 'canModeratePersonal'}});
    const updatedUser = Users.findOne(newDocument.userId)
    //eslint-disable-next-line no-console
    console.info("User gained trusted status", updatedUser.username, updatedUser._id, updatedUser.karma, updatedUser.groups)
  }
}
addCallback("votes.smallUpvote.async", updateModerateOwnPersonal);
addCallback("votes.bigUpvote.async", updateModerateOwnPersonal);

function maybeSendVerificationEmail (modifier, user)
{
  if(modifier.$set.whenConfirmationEmailSent
      && (!user.whenConfirmationEmailSent
          || user.whenConfirmationEmailSent.getTime() !== modifier.$set.whenConfirmationEmailSent.getTime()))
  {
    Accounts.sendVerificationEmail(user._id);
  }
}
addCallback("users.edit.sync", maybeSendVerificationEmail);

addEditableCallbacks({collection: Users, options: makeEditableOptionsModeration})

function approveUnreviewedPosts (newUser, oldUser)
{
  if(newUser.reviewedByUserId && !oldUser.reviewedByUserId)
  {
    Posts.update({userId:newUser._id, authorIsUnreviewed:true}, {$set:{authorIsUnreviewed:false, postedAt: new Date()}})
  }
}
addCallback("users.edit.async", approveUnreviewedPosts);

// When the very first user account is being created, add them to Sunshine
// Regiment. Patterned after a similar callback in
// vulcan-users/lib/server/callbacks.js which makes the first user an admin.
function makeFirstUserAdminAndApproved (user) {
  const realUsersCount = Users.find({'isDummy': {$in: [false,null]}}).count();
  if (realUsersCount === 0) {
    user.reviewedByUserId = "firstAccount"; //HACK

    // Add the first user to the Sunshine Regiment
    if (!user.groups) user.groups = [];
    user.groups.push("sunshineRegiment");
  }
  return user;
}
addCallback('users.new.sync', makeFirstUserAdminAndApproved);

function clearKarmaChangeBatchOnSettingsChange (modifier, user)
{
  if (modifier.$set && modifier.$set.karmaChangeNotifierSettings) {
    if (!user.karmaChangeNotifierSettings.updateFrequency
      || modifier.$set.karmaChangeNotifierSettings.updateFrequency !== user.karmaChangeNotifierSettings.updateFrequency) {
      modifier.$set.karmaChangeLastOpened = null;
      modifier.$set.karmaChangeBatchStart = null;
    }
  }
}
addCallback("users.edit.sync", clearKarmaChangeBatchOnSettingsChange);

const reCaptchaSecret = getSetting('reCaptcha.secret')
const getCaptchaRating = async (token) => {
  // Make an HTTP POST request to get reply text
  return new Promise((resolve, reject) => {
    request.post({url: 'https://www.google.com/recaptcha/api/siteverify',
        form: {
          secret: reCaptchaSecret,
          response: token
        }
      },
      function(err, httpResponse, body) {
        if (err) reject(err);
        return resolve(body);
      }
    );
  });
}
async function addReCaptchaRating (user) {
  if (reCaptchaSecret) {
    const reCaptchaToken = user?.profile?.reCaptchaToken
    if (reCaptchaToken) {
      const reCaptchaResponse = await getCaptchaRating(reCaptchaToken)
      const reCaptchaData = JSON.parse(reCaptchaResponse)
      if (reCaptchaData.success && reCaptchaData.action == "login/signup") {
        Users.update(user._id, {$set: {signUpReCaptchaRating: reCaptchaData.score}})
      } else {
        // eslint-disable-next-line no-console
        console.log("reCaptcha check failed:", reCaptchaData)
      }
    }
  }
}
addCallback('users.new.async', addReCaptchaRating);

async function subscribeOnSignup (user) {
  // If the subscribed-to-curated checkbox was checked, set the corresponding config setting
  const subscribeToCurated = user?.profile?.subscribeToCurated;
  if (subscribeToCurated) {
    Users.update(user._id, {$set: {emailSubscribedToCurated: true}});
  }

  // Regardless of the config setting, try to confirm the user's email address
  Accounts.sendVerificationEmail(user._id);
}
addCallback('users.new.async', subscribeOnSignup);<commit_msg>Fix Deepscan warning<commit_after>import Users from "meteor/vulcan:users";
import { addCallback, getSetting } from 'meteor/vulcan:core';
import { Posts } from '../posts'
import request from 'request';

const MODERATE_OWN_PERSONAL_THRESHOLD = 50
const TRUSTLEVEL1_THRESHOLD = 2000
import { addEditableCallbacks } from '../../../server/editor/make_editable_callbacks.js'
import { makeEditableOptionsModeration } from './custom_fields.js'

function updateTrustedStatus ({newDocument, vote}) {

  const user = Users.findOne(newDocument.userId)
  if (user.karma >= TRUSTLEVEL1_THRESHOLD && (!Users.getGroups(user).includes('trustLevel1'))) {
    Users.update(user._id, {$push: {groups: 'trustLevel1'}});
    const updatedUser = Users.findOne(newDocument.userId)
    //eslint-disable-next-line no-console
    console.info("User gained trusted status", updatedUser.username, updatedUser._id, updatedUser.karma, updatedUser.groups)
  }
}
addCallback("votes.smallUpvote.async", updateTrustedStatus);
addCallback("votes.bigUpvote.async", updateTrustedStatus);

function updateModerateOwnPersonal({newDocument, vote}) {
  const user = Users.findOne(newDocument.userId)
  if (user.karma >= MODERATE_OWN_PERSONAL_THRESHOLD && (!Users.getGroups(user).includes('canModeratePersonal'))) {
    Users.update(user._id, {$push: {groups: 'canModeratePersonal'}});
    const updatedUser = Users.findOne(newDocument.userId)
    //eslint-disable-next-line no-console
    console.info("User gained trusted status", updatedUser.username, updatedUser._id, updatedUser.karma, updatedUser.groups)
  }
}
addCallback("votes.smallUpvote.async", updateModerateOwnPersonal);
addCallback("votes.bigUpvote.async", updateModerateOwnPersonal);

function maybeSendVerificationEmail (modifier, user)
{
  if(modifier.$set.whenConfirmationEmailSent
      && (!user.whenConfirmationEmailSent
          || user.whenConfirmationEmailSent.getTime() !== modifier.$set.whenConfirmationEmailSent.getTime()))
  {
    Accounts.sendVerificationEmail(user._id);
  }
}
addCallback("users.edit.sync", maybeSendVerificationEmail);

addEditableCallbacks({collection: Users, options: makeEditableOptionsModeration})

function approveUnreviewedPosts (newUser, oldUser)
{
  if(newUser.reviewedByUserId && !oldUser.reviewedByUserId)
  {
    Posts.update({userId:newUser._id, authorIsUnreviewed:true}, {$set:{authorIsUnreviewed:false, postedAt: new Date()}})
  }
}
addCallback("users.edit.async", approveUnreviewedPosts);

// When the very first user account is being created, add them to Sunshine
// Regiment. Patterned after a similar callback in
// vulcan-users/lib/server/callbacks.js which makes the first user an admin.
function makeFirstUserAdminAndApproved (user) {
  const realUsersCount = Users.find({'isDummy': {$in: [false,null]}}).count();
  if (realUsersCount === 0) {
    user.reviewedByUserId = "firstAccount"; //HACK

    // Add the first user to the Sunshine Regiment
    if (!user.groups) user.groups = [];
    user.groups.push("sunshineRegiment");
  }
  return user;
}
addCallback('users.new.sync', makeFirstUserAdminAndApproved);

function clearKarmaChangeBatchOnSettingsChange (modifier, user)
{
  if (modifier.$set && modifier.$set.karmaChangeNotifierSettings) {
    if (!user.karmaChangeNotifierSettings.updateFrequency
      || modifier.$set.karmaChangeNotifierSettings.updateFrequency !== user.karmaChangeNotifierSettings.updateFrequency) {
      modifier.$set.karmaChangeLastOpened = null;
      modifier.$set.karmaChangeBatchStart = null;
    }
  }
}
addCallback("users.edit.sync", clearKarmaChangeBatchOnSettingsChange);

const reCaptchaSecret = getSetting('reCaptcha.secret')
const getCaptchaRating = async (token) => {
  // Make an HTTP POST request to get reply text
  return new Promise((resolve, reject) => {
    request.post({url: 'https://www.google.com/recaptcha/api/siteverify',
        form: {
          secret: reCaptchaSecret,
          response: token
        }
      },
      function(err, httpResponse, body) {
        if (err) reject(err);
        return resolve(body);
      }
    );
  });
}
async function addReCaptchaRating (user) {
  if (reCaptchaSecret) {
    const reCaptchaToken = user?.profile?.reCaptchaToken
    if (reCaptchaToken) {
      const reCaptchaResponse = await getCaptchaRating(reCaptchaToken)
      const reCaptchaData = JSON.parse(reCaptchaResponse)
      if (reCaptchaData.success && reCaptchaData.action == "login/signup") {
        Users.update(user._id, {$set: {signUpReCaptchaRating: reCaptchaData.score}})
      } else {
        // eslint-disable-next-line no-console
        console.log("reCaptcha check failed:", reCaptchaData)
      }
    }
  }
}
addCallback('users.new.async', addReCaptchaRating);

async function subscribeOnSignup (user) {
  // If the subscribed-to-curated checkbox was checked, set the corresponding config setting
  const subscribeToCurated = user.profile?.subscribeToCurated;
  if (subscribeToCurated) {
    Users.update(user._id, {$set: {emailSubscribedToCurated: true}});
  }

  // Regardless of the config setting, try to confirm the user's email address
  Accounts.sendVerificationEmail(user._id);
}
addCallback('users.new.async', subscribeOnSignup);<|endoftext|>


<commit_before>function CrocAnalogMeter(root, value, backgroundImagePath, needleImagePath) {
	CrocBase.call(this, root);

	backgroundImagePath = backgroundImagePath || root.themer.getValue(arguments.callee, "backgroundImage");
	needleImagePath = needleImagePath || root.themer.getValue(arguments.callee, "needleImage");

	this.value = value || 0;
	this.valueLabelPostfix = '';
	this.valueLabelPrefix = '';
	this.valueLabelScale = 1.0;
	this.valueLabelToFixed = 0;
	this.minValue = 0;
	this.maxValue = 100;

	this.background = new CrocImageSimple(root, backgroundImagePath);
	this.background.setScaling('none');

	this.needle = new CrocImageSimple(root, needleImagePath);
	this.needle.setScaling("none");

	this.valueLabel = new CrocLabel(root, this.value.toString(), root.themer.getValue(arguments.callee, "valueLabelFont"), root.themer.getValue(arguments.callee, "valueLabelFontColor"))
	this.valueLabel.setAlignment("right");
};

//We inherit everything from CrocBase
CrocAnalogMeter.prototype = Object.create(CrocBase.prototype);
CrocAnalogMeter.prototype.constructor = CrocAnalogMeter;

CrocAnalogMeter.prototype.setValue = function(value) {

	if(value < this.minValue) {
		value = this.minValue;
	}

	if(value > this.maxValue) {
		value = this.maxValue;
	}

	this.value = value;
	this.getRoot().repaint();

};

CrocAnalogMeter.prototype.setValueLabelPostfix = function(valueLabelPostfix) {
	this.valueLabelPostfix = valueLabelPostfix.toString();
};

CrocAnalogMeter.prototype.setValueLabelPrefix = function(valueLabelPrefix) {
	this.valueLabelPrefix = valueLabelPrefix.toString();
};

CrocAnalogMeter.prototype.setValueLabelScale = function(valueLabelScale) {
	this.valueLabelScale = Number(valueLabelScale);
};

CrocAnalogMeter.prototype.setValueLabelToFixed = function(valueLabelToFixed) {
	this.valueLabelToFixed = Number(valueLabelToFixed);
};

CrocAnalogMeter.prototype.setMaxValue = function(maxValue) {

	this.maxValue = maxValue;

	this.setValue(this.value);

};

CrocAnalogMeter.prototype.setMinValue = function(minValue) {
	this.minValue = minValue;

	this.setValue(this.value);
};

CrocAnalogMeter.prototype.paint = function(context, width, height) {
	CrocBase.prototype.paint.call(this, context, width, height);

	context.save();

	this.background.paint(context, width, height);

	context.save();

	context.translate(-14, 92);

	this.valueLabel.setText(this.valueLabelPrefix + (this.value * this.valueLabelScale).toFixed(this.valueLabelToFixed) + this.valueLabelPostfix);
	this.valueLabel.paint(context, this.background.getWidth(), this.background.getHeight());

	context.restore();

	var needleCenter = this.background.getHeight() / 1.6125;

	var backPadding = this.needle.getHeight() / 32;
	var needlePadding = this.needle.getHeight() / 1.33333333333333;
	var basePadding = this.needle.getHeight() - backPadding - needlePadding;

	var rad = ((Math.PI * (this.value - this.minValue)) / (this.maxValue - this.minValue));

	context.translate(this.background.getWidth() / 2, needleCenter);
	context.rotate((Math.PI/2) + (rad));
	context.translate(-(this.needle.getWidth() / 2), -backPadding - (basePadding/2));

	this.getRoot().setSmooth(true);
	this.needle.paint(context, width, height);
	this.getRoot().setSmooth(false);

	this.width = this.background.getWidth();
	this.height = this.background.getHeight();

	context.restore();

	return;
}
<commit_msg>Fix constant paint requests from CrocAnalogMeter<commit_after>function CrocAnalogMeter(root, value, backgroundImagePath, needleImagePath) {
	CrocBase.call(this, root);

	backgroundImagePath = backgroundImagePath || root.themer.getValue(arguments.callee, "backgroundImage");
	needleImagePath = needleImagePath || root.themer.getValue(arguments.callee, "needleImage");

	this.value = value || 0;
	this.valueLabelPostfix = '';
	this.valueLabelPrefix = '';
	this.valueLabelScale = 1.0;
	this.valueLabelToFixed = 0;
	this.minValue = 0;
	this.maxValue = 100;

	this.background = new CrocImageSimple(root, backgroundImagePath);
	this.background.setScaling('none');

	this.needle = new CrocImageSimple(root, needleImagePath);
	this.needle.setScaling("none");

	this.valueLabel = new CrocLabel(root, this.value.toString(), root.themer.getValue(arguments.callee, "valueLabelFont"), root.themer.getValue(arguments.callee, "valueLabelFontColor"))
	this.valueLabel.setAlignment("right");
};

//We inherit everything from CrocBase
CrocAnalogMeter.prototype = Object.create(CrocBase.prototype);
CrocAnalogMeter.prototype.constructor = CrocAnalogMeter;

CrocAnalogMeter.prototype.setValue = function(value) {

	if(value < this.minValue) {
		value = this.minValue;
	}

	if(value > this.maxValue) {
		value = this.maxValue;
	}

	this.value = value;
	this.getRoot().repaint();

};

CrocAnalogMeter.prototype.setValueLabelPostfix = function(valueLabelPostfix) {
	this.valueLabelPostfix = valueLabelPostfix.toString();
};

CrocAnalogMeter.prototype.setValueLabelPrefix = function(valueLabelPrefix) {
	this.valueLabelPrefix = valueLabelPrefix.toString();
};

CrocAnalogMeter.prototype.setValueLabelScale = function(valueLabelScale) {
	this.valueLabelScale = Number(valueLabelScale);
};

CrocAnalogMeter.prototype.setValueLabelToFixed = function(valueLabelToFixed) {
	this.valueLabelToFixed = Number(valueLabelToFixed);
};

CrocAnalogMeter.prototype.setMaxValue = function(maxValue) {

	this.maxValue = maxValue;

	this.setValue(this.value);

};

CrocAnalogMeter.prototype.setMinValue = function(minValue) {
	this.minValue = minValue;

	this.setValue(this.value);
};

CrocAnalogMeter.prototype.paint = function(context, width, height) {
	CrocBase.prototype.paint.call(this, context, width, height);

	context.save();

	this.background.paint(context, width, height);

	context.save();

	context.translate(-14, 92);

	this.valueLabel.text = this.valueLabelPrefix + (this.value * this.valueLabelScale).toFixed(this.valueLabelToFixed) + this.valueLabelPostfix;
	this.valueLabel.paint(context, this.background.getWidth(), this.background.getHeight());

	context.restore();

	var needleCenter = this.background.getHeight() / 1.6125;

	var backPadding = this.needle.getHeight() / 32;
	var needlePadding = this.needle.getHeight() / 1.33333333333333;
	var basePadding = this.needle.getHeight() - backPadding - needlePadding;

	var rad = ((Math.PI * (this.value - this.minValue)) / (this.maxValue - this.minValue));

	context.translate(this.background.getWidth() / 2, needleCenter);
	context.rotate((Math.PI/2) + (rad));
	context.translate(-(this.needle.getWidth() / 2), -backPadding - (basePadding/2));

	this.getRoot().setSmooth(true);
	this.needle.paint(context, width, height);
	this.getRoot().setSmooth(false);

	this.width = this.background.getWidth();
	this.height = this.background.getHeight();

	context.restore();

	return;
}
<|endoftext|>


<commit_before>d3.Module('d3', function(m) {
  var Vector3 = d3.Math.Vector3;
  var Matrix4 = d3.Math.Matrix4;
  var Quaternion4 = d3.Math.Quaternion4;

  m.Class('Node', {
    position: null,
    rotation: null,
    scalation: null,
    children: null,

    construct: function() {
      this.position = Vector3.create();
      this.rotation = Vector3.create();
      this.scalation = Vector3.create([1, 1, 1]);
      this.children = [];
    },

    setPosition: function(vec) {
      Vector3.set(vec, this.position);
    },

    setRotation: function(rot) {
      Vector3.set(rot, this.rotation);
    },

    yaw: function(angel) {
      this.rotation[0] += angel;
    },

    pitch: function(angel) {
      this.rotation[1] += angel;
    },

    roll: function(angel) {
      this.rotation[2] += angel;
    },

    setScalation: function(vec) {
      Vector3.set(vec, this.scalation);
    },

    addChild: function(child) {
      d3.assert(child instanceof d3.Node, 'Only d3.Node could be child');
      this.children.push(child);
    },

    render: function(gl, mvMatrix, pMatrix) {
      Matrix4.translate(mvMatrix, this.position);
      var q = Quaternion4.rotateByAngles(this.rotation[0], this.rotation[1], this.rotation[2]);
      Matrix4.multiply(mvMatrix, Quaternion4.toMat4(q));
      Matrix4.scale(mvMatrix, this.scalation);

      this.children.forEach(function(child) {
        child.render(gl, Matrix4.create(mvMatrix), pMatrix);
      }, this);
    }
  });
});
<commit_msg>Updated api<commit_after>d3.Module('d3', function(m) {
  var Vector3 = d3.Math.Vector3;
  var Matrix4 = d3.Math.Matrix4;
  var Quaternion4 = d3.Math.Quaternion4;

  m.Class('Node', {
    position: null,
    rotation: null,
    scale: null,
    children: null,

    construct: function() {
      this.position = Vector3.create();
      this.rotation = Vector3.create();
      this.scale = Vector3.create([1, 1, 1]);
      this.children = [];
    },

    setPosition: function(vec) {
      Vector3.set(vec, this.position);
    },

    setRotation: function(rot) {
      Vector3.set(rot, this.rotation);
    },

    yaw: function(angel) {
      this.rotation[0] += angel;
    },

    pitch: function(angel) {
      this.rotation[1] += angel;
    },

    roll: function(angel) {
      this.rotation[2] += angel;
    },

    setScale: function(vec) {
      Vector3.set(vec, this.scale);
    },

    addChild: function(child) {
      d3.assert(child instanceof d3.Node, 'Only d3.Node could be child');
      this.children.push(child);
    },

    render: function(gl, mvMatrix, pMatrix) {
      Matrix4.translate(mvMatrix, this.position);
      var q = Quaternion4.rotateByAngles(this.rotation[0], this.rotation[1], this.rotation[2]);
      Matrix4.multiply(mvMatrix, Quaternion4.toMat4(q));
      Matrix4.scale(mvMatrix, this.scale);

      this.children.forEach(function(child) {
        child.render(gl, Matrix4.create(mvMatrix), pMatrix);
      }, this);
    }
  });
});
<|endoftext|>


<commit_before>import React from 'react';
import { FormattedMessage } from 'react-intl';
import Relay from 'react-relay/classic';
import { graphql, commitMutation } from 'react-relay/compat';
import Box from '@material-ui/core/Box';
import Button from '@material-ui/core/Button';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Popover from '@material-ui/core/Popover';
import Radio from '@material-ui/core/Radio';
import RadioGroup from '@material-ui/core/RadioGroup';
import Switch from '@material-ui/core/Switch';
import TextField from '@material-ui/core/TextField';
import VisibilityOffIcon from '@material-ui/icons/VisibilityOff';
import { withSetFlashMessage } from '../FlashMessage';
import GenericUnknownErrorMessage from '../GenericUnknownErrorMessage';
import { getErrorMessage } from '../../helpers';
import globalStrings from '../../globalStrings';

const SensitiveContentMenu = ({
  anchorEl,
  onDismiss,
  projectMedia,
  setFlashMessage,
}) => {
  let warningType = null;
  let warningTypeCustom = null;

  const {
    dynamic_annotation_flag,
    show_warning_cover,
  } = projectMedia;

  if (dynamic_annotation_flag && show_warning_cover) {
    // Sort by flag category likelihood and display most likely
    let sortable = [];
    // Put custom flag at beginning of array
    if (dynamic_annotation_flag.data.custom) {
      sortable = sortable.concat([...Object.entries(dynamic_annotation_flag.data.custom)]);
    }
    sortable = sortable.concat([...Object.entries(dynamic_annotation_flag.data.flags)]);
    sortable.sort((a, b) => b[1] - a[1]);
    const type = sortable[0];
    [warningType] = type;

    if (
      warningType !== 'adult' &&
      warningType !== 'medical' &&
      warningType !== 'violence'
    ) {
      warningTypeCustom = warningType;
      warningType = 'other';
    }
  }

  const [enableSwitch, setEnableSwitch] = React.useState(show_warning_cover);
  const [contentType, setContentType] = React.useState(warningType);
  const [customType, setCustomType] = React.useState(warningTypeCustom);
  const [formError, setFormError] = React.useState(null);

  const handleSwitch = (e, inputChecked) => {
    setEnableSwitch(inputChecked);
    if (!inputChecked) {
      setContentType(null);
      setCustomType(null);
    }
  };

  const handleSetContentType = (value) => {
    setContentType(value);
    setCustomType(null);
  };

  const handleChangeCustom = (e) => {
    setContentType('other');
    setCustomType(e.target.value);
  };

  const submitFlagAnnotation = () => {
    const onFailure = (error) => {
      const message = getErrorMessage(error, <GenericUnknownErrorMessage />);
      setFlashMessage(message, 'error');
    };
    const onSuccess = () => { onDismiss(); };

    if (enableSwitch && !contentType) {
      setFormError('no_warning_type');
      return;
    }
    if (contentType && !enableSwitch) {
      setFormError('no_switch_enabled');
      return;
    }
    if (contentType === 'other' && !customType) {
      setFormError('no_custom_type');
      return;
    }

    const fields = {
      show_cover: enableSwitch,
      custom: {},
    };

    if (contentType !== 'other') {
      fields.flags = {
        adult: contentType === 'adult' ? 7 : 0,
        spoof: 0,
        medical: contentType === 'medical' ? 7 : 0,
        violence: contentType === 'violence' ? 7 : 0,
        racy: 0,
        spam: 0,
      };
    } else {
      fields.custom[customType] = 7;
      fields.flags = {
        adult: 0,
        spoof: 0,
        medical: 0,
        violence: 0,
        racy: 0,
        spam: 0,
      };
    }

    if (!dynamic_annotation_flag) {
      commitMutation(Relay.Store, {
        mutation: graphql`
          mutation SensitiveContentMenuButtonCreateDynamicAnnotationFlagMutation($input: CreateDynamicAnnotationFlagInput!) {
            createDynamicAnnotationFlag(input: $input) {
              project_media {
                id
                show_warning_cover
                dynamic_annotation_flag {
                  id
                  dbid
                  content
                  data
                  annotator {
                    name
                  }
                }
              }
            }
          }
        `,
        variables: {
          input: {
            annotated_id: projectMedia.dbid.toString(),
            annotated_type: 'ProjectMedia',
            set_fields: JSON.stringify(fields),
          },
        },
        onCompleted: ({ response, error }) => {
          if (error) {
            return onFailure(error);
          }
          return onSuccess(response);
        },
        onError: onFailure,
      });
    } else {
      commitMutation(Relay.Store, {
        mutation: graphql`
          mutation SensitiveContentMenuButtonUpdateDynamicAnnotationFlagMutation($input: UpdateDynamicAnnotationFlagInput!) {
            updateDynamicAnnotationFlag(input: $input) {
              project_media {
                id
                show_warning_cover
                dynamic_annotation_flag {
                  id
                  dbid
                  content
                  data
                  annotator {
                    name
                  }
                }
              }
            }
          }
        `,
        variables: {
          input: {
            id: dynamic_annotation_flag.id,
            set_fields: JSON.stringify(fields),
          },
        },
        onCompleted: ({ response, error }) => {
          if (error) {
            return onFailure(error);
          }
          return onSuccess(response);
        },
        onError: onFailure,
      });
    }
  };

  return (
    <Popover
      open={Boolean(anchorEl)}
      anchorEl={anchorEl}
      onClose={onDismiss}
    >
      <Box p={2}>
        <Box color={!enableSwitch && (formError === 'no_switch_enabled') ? 'red' : null}>
          <Switch checked={enableSwitch} onChange={handleSwitch} />
          <FormattedMessage
            id="sensitiveContentMenuButton.enableSwitch"
            defaultMessage="Enable content warning"
            description="Switch to enable sensitive content screen"
          />
        </Box>
        <Box
          my={2}
          fontWeight="bold"
          color={formError === 'no_warning_type' ? 'red' : null}
        >
          <FormattedMessage
            id="sensitiveContentMenuButton.selectCategory"
            defaultMessage="Select a category"
            description="Header for sensitive content types"
          />
        </Box>
        <RadioGroup
          name="select-sensitive-content-type"
          value={contentType}
          onChange={e => handleSetContentType(e.target.value)}
        >
          <FormControlLabel
            value="adult"
            control={<Radio />}
            label={<FormattedMessage
              id="sensitiveContentMenuButton.adult"
              defaultMessage="Adult (nudity, pornographic)"
              description="Label for adult content type"
            />}
          />
          <FormControlLabel
            value="medical"
            control={<Radio />}
            label={<FormattedMessage
              id="sensitiveContentMenuButton.medical"
              defaultMessage="Medical conditions/procedures"
              description="Label for medical content type"
            />}
          />
          <FormControlLabel
            value="violence"
            control={<Radio />}
            label={<FormattedMessage
              id="sensitiveContentMenuButton.violence"
              defaultMessage="Violence"
              description="Label for violence content type"
            />}
          />
          <FormControlLabel
            value="other"
            control={<Radio />}
            label={(
              <FormattedMessage
                id="sensitiveContentMenuButton.typeOther"
                defaultMessage="Type other"
                description="Label for other content type"
              >
                { label => (
                  <TextField
                    label={label}
                    error={(
                      formError &&
                      contentType === 'other' &&
                      !customType
                    )}
                    value={customType}
                    onChange={handleChangeCustom}
                    variant="outlined"
                    size="small"
                    fullWidth
                  />
                )}
              </FormattedMessage>
            )}
          />
        </RadioGroup>
        <Box mt={2} display="flex" justifyContent="flex-end">
          <Button onClick={onDismiss}>
            <FormattedMessage {...globalStrings.cancel} />
          </Button>
          <Button
            color="primary"
            onClick={submitFlagAnnotation}
            variant="contained"
          >
            <FormattedMessage {...globalStrings.save} />
          </Button>
        </Box>
      </Box>
    </Popover>
  );
};

const SensitiveContentMenuButton = ({
  currentUserRole,
  projectMedia,
  setFlashMessage,
}) => {
  const { show_warning_cover } = projectMedia;
  const [anchorEl, setAnchorEl] = React.useState();

  return (
    <React.Fragment>
      <Button
        disabled={(
          show_warning_cover &&
          currentUserRole !== 'admin' &&
          currentUserRole !== 'editor'
        )}
        startIcon={<VisibilityOffIcon />}
        onClick={e => setAnchorEl(e.currentTarget)}
      >
        <FormattedMessage
          id="sensitiveContentMenuButton.contentWarning"
          defaultMessage="Content warning"
          description="Button that pops sensitive content screen settings"
        />
      </Button>
      <SensitiveContentMenu
        key={anchorEl}
        anchorEl={anchorEl}
        onDismiss={() => setAnchorEl(null)}
        projectMedia={projectMedia}
        setFlashMessage={setFlashMessage}
      />
    </React.Fragment>
  );
};

// TODO createFragmentContainer
export default withSetFlashMessage(SensitiveContentMenuButton);
<commit_msg>CHECK-87: Limit custom warning category to 48 chars<commit_after>import React from 'react';
import { FormattedMessage } from 'react-intl';
import Relay from 'react-relay/classic';
import { graphql, commitMutation } from 'react-relay/compat';
import Box from '@material-ui/core/Box';
import Button from '@material-ui/core/Button';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Popover from '@material-ui/core/Popover';
import Radio from '@material-ui/core/Radio';
import RadioGroup from '@material-ui/core/RadioGroup';
import Switch from '@material-ui/core/Switch';
import TextField from '@material-ui/core/TextField';
import VisibilityOffIcon from '@material-ui/icons/VisibilityOff';
import { withSetFlashMessage } from '../FlashMessage';
import GenericUnknownErrorMessage from '../GenericUnknownErrorMessage';
import { getErrorMessage } from '../../helpers';
import globalStrings from '../../globalStrings';

const SensitiveContentMenu = ({
  anchorEl,
  onDismiss,
  projectMedia,
  setFlashMessage,
}) => {
  let warningType = null;
  let warningTypeCustom = null;

  const {
    dynamic_annotation_flag,
    show_warning_cover,
  } = projectMedia;

  if (dynamic_annotation_flag && show_warning_cover) {
    // Sort by flag category likelihood and display most likely
    let sortable = [];
    // Put custom flag at beginning of array
    if (dynamic_annotation_flag.data.custom) {
      sortable = sortable.concat([...Object.entries(dynamic_annotation_flag.data.custom)]);
    }
    sortable = sortable.concat([...Object.entries(dynamic_annotation_flag.data.flags)]);
    sortable.sort((a, b) => b[1] - a[1]);
    const type = sortable[0];
    [warningType] = type;

    if (
      warningType !== 'adult' &&
      warningType !== 'medical' &&
      warningType !== 'violence'
    ) {
      warningTypeCustom = warningType;
      warningType = 'other';
    }
  }

  const [enableSwitch, setEnableSwitch] = React.useState(show_warning_cover);
  const [contentType, setContentType] = React.useState(warningType);
  const [customType, setCustomType] = React.useState(warningTypeCustom);
  const [formError, setFormError] = React.useState(null);

  const handleSwitch = (e, inputChecked) => {
    setEnableSwitch(inputChecked);
    if (!inputChecked) {
      setContentType(null);
      setCustomType(null);
    }
  };

  const handleSetContentType = (value) => {
    setContentType(value);
    setCustomType(null);
  };

  const handleChangeCustom = (e) => {
    setContentType('other');
    setCustomType(e.target.value);
  };

  const submitFlagAnnotation = () => {
    const onFailure = (error) => {
      const message = getErrorMessage(error, <GenericUnknownErrorMessage />);
      setFlashMessage(message, 'error');
    };
    const onSuccess = () => { onDismiss(); };

    if (enableSwitch && !contentType) {
      setFormError('no_warning_type');
      return;
    }
    if (contentType && !enableSwitch) {
      setFormError('no_switch_enabled');
      return;
    }
    if (contentType === 'other' && !customType) {
      setFormError('no_custom_type');
      return;
    }

    const fields = {
      show_cover: enableSwitch,
      custom: {},
    };

    if (contentType !== 'other') {
      fields.flags = {
        adult: contentType === 'adult' ? 7 : 0,
        spoof: 0,
        medical: contentType === 'medical' ? 7 : 0,
        violence: contentType === 'violence' ? 7 : 0,
        racy: 0,
        spam: 0,
      };
    } else {
      fields.custom[customType] = 7;
      fields.flags = {
        adult: 0,
        spoof: 0,
        medical: 0,
        violence: 0,
        racy: 0,
        spam: 0,
      };
    }

    if (!dynamic_annotation_flag) {
      commitMutation(Relay.Store, {
        mutation: graphql`
          mutation SensitiveContentMenuButtonCreateDynamicAnnotationFlagMutation($input: CreateDynamicAnnotationFlagInput!) {
            createDynamicAnnotationFlag(input: $input) {
              project_media {
                id
                show_warning_cover
                dynamic_annotation_flag {
                  id
                  dbid
                  content
                  data
                  annotator {
                    name
                  }
                }
              }
            }
          }
        `,
        variables: {
          input: {
            annotated_id: projectMedia.dbid.toString(),
            annotated_type: 'ProjectMedia',
            set_fields: JSON.stringify(fields),
          },
        },
        onCompleted: ({ response, error }) => {
          if (error) {
            return onFailure(error);
          }
          return onSuccess(response);
        },
        onError: onFailure,
      });
    } else {
      commitMutation(Relay.Store, {
        mutation: graphql`
          mutation SensitiveContentMenuButtonUpdateDynamicAnnotationFlagMutation($input: UpdateDynamicAnnotationFlagInput!) {
            updateDynamicAnnotationFlag(input: $input) {
              project_media {
                id
                show_warning_cover
                dynamic_annotation_flag {
                  id
                  dbid
                  content
                  data
                  annotator {
                    name
                  }
                }
              }
            }
          }
        `,
        variables: {
          input: {
            id: dynamic_annotation_flag.id,
            set_fields: JSON.stringify(fields),
          },
        },
        onCompleted: ({ response, error }) => {
          if (error) {
            return onFailure(error);
          }
          return onSuccess(response);
        },
        onError: onFailure,
      });
    }
  };

  return (
    <Popover
      open={Boolean(anchorEl)}
      anchorEl={anchorEl}
      onClose={onDismiss}
    >
      <Box p={2}>
        <Box color={!enableSwitch && (formError === 'no_switch_enabled') ? 'red' : null}>
          <Switch checked={enableSwitch} onChange={handleSwitch} />
          <FormattedMessage
            id="sensitiveContentMenuButton.enableSwitch"
            defaultMessage="Enable content warning"
            description="Switch to enable sensitive content screen"
          />
        </Box>
        <Box
          my={2}
          fontWeight="bold"
          color={formError === 'no_warning_type' ? 'red' : null}
        >
          <FormattedMessage
            id="sensitiveContentMenuButton.selectCategory"
            defaultMessage="Select a category"
            description="Header for sensitive content types"
          />
        </Box>
        <RadioGroup
          name="select-sensitive-content-type"
          value={contentType}
          onChange={e => handleSetContentType(e.target.value)}
        >
          <FormControlLabel
            value="adult"
            control={<Radio />}
            label={<FormattedMessage
              id="sensitiveContentMenuButton.adult"
              defaultMessage="Adult (nudity, pornographic)"
              description="Label for adult content type"
            />}
          />
          <FormControlLabel
            value="medical"
            control={<Radio />}
            label={<FormattedMessage
              id="sensitiveContentMenuButton.medical"
              defaultMessage="Medical conditions/procedures"
              description="Label for medical content type"
            />}
          />
          <FormControlLabel
            value="violence"
            control={<Radio />}
            label={<FormattedMessage
              id="sensitiveContentMenuButton.violence"
              defaultMessage="Violence"
              description="Label for violence content type"
            />}
          />
          <FormControlLabel
            value="other"
            control={<Radio />}
            label={(
              <FormattedMessage
                id="sensitiveContentMenuButton.typeOther"
                defaultMessage="Type other"
                description="Label for other content type"
              >
                { label => (
                  <TextField
                    label={label}
                    error={(
                      formError &&
                      contentType === 'other' &&
                      !customType
                    )}
                    inputProps={{ maxLength: 48 }}
                    value={customType}
                    onChange={handleChangeCustom}
                    variant="outlined"
                    size="small"
                    fullWidth
                  />
                )}
              </FormattedMessage>
            )}
          />
        </RadioGroup>
        <Box mt={2} display="flex" justifyContent="flex-end">
          <Button onClick={onDismiss}>
            <FormattedMessage {...globalStrings.cancel} />
          </Button>
          <Button
            color="primary"
            onClick={submitFlagAnnotation}
            variant="contained"
          >
            <FormattedMessage {...globalStrings.save} />
          </Button>
        </Box>
      </Box>
    </Popover>
  );
};

const SensitiveContentMenuButton = ({
  currentUserRole,
  projectMedia,
  setFlashMessage,
}) => {
  const { show_warning_cover } = projectMedia;
  const [anchorEl, setAnchorEl] = React.useState();

  return (
    <React.Fragment>
      <Button
        disabled={(
          show_warning_cover &&
          currentUserRole !== 'admin' &&
          currentUserRole !== 'editor'
        )}
        startIcon={<VisibilityOffIcon />}
        onClick={e => setAnchorEl(e.currentTarget)}
      >
        <FormattedMessage
          id="sensitiveContentMenuButton.contentWarning"
          defaultMessage="Content warning"
          description="Button that pops sensitive content screen settings"
        />
      </Button>
      <SensitiveContentMenu
        key={anchorEl}
        anchorEl={anchorEl}
        onDismiss={() => setAnchorEl(null)}
        projectMedia={projectMedia}
        setFlashMessage={setFlashMessage}
      />
    </React.Fragment>
  );
};

// TODO createFragmentContainer
export default withSetFlashMessage(SensitiveContentMenuButton);
<|endoftext|>


<commit_before>
function generateRoutes() {

    // for use when rendering the schema out flat
    //    var resolver = new JSchemaInheritanceResolver(schema);
    //    resolver.resolve(true);

    var rpcGenerator = new CSharpRouteGenerator(smd.services.rpc, schema, "CIAPI.Rpc", "Client", ["System", "System.Collections.Generic", "CityIndex.JsonClient", "CIAPI.DTO"], routesPatch);
    var rpcRoutes = rpcGenerator.generate();

    document.getElementById("routes").value = rpcRoutes;
};

(function () {

    var generator = window.CSharpRouteGenerator = function (smd, schema, namespaceName, className, imports, routesPatch) {
        this.smd = smd;
        this.schema = schema;
        this._lines = [];
        this.routesPatch = routesPatch;
        this.className = className;
        this.namespaceName = namespaceName;
        this.imports = imports ? imports : [];

    };

    generator.prototype = {
        normalizeKey: function (key) {
            if (key.indexOf("#.") > -1 || key.indexOf("#/") > -1) {
                key = key.substring(2);
            };
            return key;
        },

        writeLine: function (value) {
            this._lines.push(value);
        },
        toString: function () {
            return this._lines.join("\n");
        },

        createSummary: function (description) {
            var result = "";
            result = result.concat("\n" + "        /// <summary>");
            result = result.concat("\n" + "        /// " + this.createDescription(description));
            result = result.concat("\n" + "        /// </summary>");
            return result;
        },
        createDescription: function (description) {

            return description ? description : " [DESCRIPTION MISSING]";

        },
        generate: function () {
            var subClasses = {
                "default": ""
            };
            this.target = this.smd.target;
            var self = this;

            var services = this.smd.services;
            var schema = this.schema;
            if (this.imports) {
                each(this.imports, function (namespaceName) {
                    self.writeLine("using " + namespaceName + ";");
                });

            }
            self.writeLine("namespace " + this.namespaceName);
            self.writeLine("{");
            self.writeLine("    public partial class " + this.className);
            self.writeLine("    {");
            each(services, function (service, key) {
                var serviceText = "";
                serviceText = serviceText.concat("\n" + "        // ***********************************");
                serviceText = serviceText.concat("\n" + "        // " + key);
                serviceText = serviceText.concat("\n" + "        // ***********************************");
                serviceText = serviceText.concat("\n" + "");

                serviceText = serviceText.concat("\n" + self.createSummary(service.description));
                each(service.parameters, function (parameter) {
                    serviceText = serviceText.concat("\n" + "        /// <param name=\"" + parameter.name + "\">" + self.createDescription(parameter.description) + "</param>");

                });

                var paramList = "";
                var firstParam = true;
                each(service.parameters, function (parameter) {
                    var paramType;
                    if (parameter.type) {
                        paramType = self.resolveType(parameter.type);
                    }
                    else if (parameter.$ref) {
                        paramType = self.normalizeKey(parameter.$ref);

                    } else {
                        throw new Error("unsupported property type");

                    }

                    if (!firstParam) {
                        paramList = paramList.concat(", ");
                    }

                    firstParam = false;
                    paramList = paramList.concat(paramType, " ", parameter.name);
                });
                var returnType = self.resolveType(service.returns);
                var target = service.target;
                var uriTemplate = service.uriTemplate;
                var transport = service.transport;
                var cacheDuration = service.cacheDuration || "0";
                var throttleScope = service.throttleScope || "default";

                var requestParamList = "";
                var firstRequestParam = true;
                each(service.parameters, function (parameter) {

                    if (!firstRequestParam) {
                        requestParamList = requestParamList.concat(", \n");
                    }

                    firstRequestParam = false;
                    requestParamList = requestParamList.concat("                { \"" + parameter.name + "\", " + parameter.name + "}");

                });
                var visibility = "public";
                var subClassName = "default";
                if (this.routesPatch) {
                    if (this.routesPatch[key]) {

                        if (this.routesPatch[key].visibility) {
                            visibility = this.routesPatch[key].visibility;
                        }
                        if (this.routesPatch[key]["class"]) {
                            subClassName = this.routesPatch[key]["class"];
                        }
                    }
                }

                if (!subClasses[subClassName]) {
                    subClasses[subClassName] = "";
                }

                serviceText = serviceText.concat("\n" + "        " + visibility + " " + returnType + " " + key + "(" + paramList + ")");
                serviceText = serviceText.concat("\n" + "        {");
                serviceText = serviceText.concat("\n" + "            return _client.Request<" + returnType + ">(\"" + target + "\", \"" + uriTemplate + "\", \"" + transport + "\",");
                serviceText = serviceText.concat("\n" + "            new Dictionary<string, object>");
                serviceText = serviceText.concat("\n" + "            {");
                serviceText = serviceText.concat("\n" + requestParamList);

                serviceText = serviceText.concat("\n" + "            }, TimeSpan.FromMilliseconds(" + cacheDuration + "), \"" + throttleScope + "\");");

                serviceText = serviceText.concat("\n" + "        }");
                serviceText = serviceText.concat("\n" + "");

                serviceText = serviceText.concat("\n" + self.createSummary(service.description));

                each(service.parameters, function (parameter) {
                    serviceText = serviceText.concat("\n" + "        /// <param name=\"" + parameter.name + "\">" + self.createDescription(parameter.description) + "</param>");

                });
                serviceText = serviceText.concat("\n" + "        /// <param name=\"callback\"></param>");
                serviceText = serviceText.concat("\n" + "        /// <param name=\"state\"></param>");
                serviceText = serviceText.concat("\n" + "        " + visibility + " void Begin" + key + "(" + paramList + (paramList ? "," : "") + " ApiAsyncCallback<" + returnType + "> callback, object state)");
                serviceText = serviceText.concat("\n" + "        {");
                serviceText = serviceText.concat("\n" + "            _client.BeginRequest(callback, state, \"" + target + "\", \"" + uriTemplate + "\", \"" + transport + "\",");

                serviceText = serviceText.concat("\n" + "            new Dictionary<string, object>");
                serviceText = serviceText.concat("\n" + "            {");
                serviceText = serviceText.concat("\n" + requestParamList);

                serviceText = serviceText.concat("\n" + "            }, TimeSpan.FromMilliseconds(" + cacheDuration + "), \"" + throttleScope + "\");");

                serviceText = serviceText.concat("\n" + "        }");
                serviceText = serviceText.concat("\n" + "");

                serviceText = serviceText.concat("\n" + "        " + visibility + " " + returnType + " End" + key + "(ApiAsyncResult<" + returnType + "> asyncResult)");

                serviceText = serviceText.concat("\n" + "        {");
                serviceText = serviceText.concat("\n" + "            return _client.EndRequest(asyncResult);");
                serviceText = serviceText.concat("\n" + "        }");
                serviceText = serviceText.concat("\n" + "");

                subClasses[subClassName] = subClasses[subClassName].concat(serviceText, "\n");

            });

            // #TODO: need to emit default constructor that instantiates subclasses and accessors
            var subClassProperties = "";
            var subClassDefinitions = "";
            var subClassInitializer = "";
            each(subClasses, function (subClass, key) {
                if (key != "default") {
                    subClassProperties = subClassProperties.concat("\n      public _" + key + " " + key + "{get; private set;}");
                    subClassInitializer = subClassInitializer.concat("\n            this. " + key + " = new _" + key + "(this);");
                }

            });

            self.writeLine(subClassProperties);

            self.writeLine("        public Client(Uri uri)");
            self.writeLine("            : base(uri, new RequestController(TimeSpan.FromSeconds(0), 2, new RequestFactory(), new ErrorResponseDTOJsonExceptionFactory(), new ThrottedRequestQueue(TimeSpan.FromSeconds(5), 30, 10, \"data\"), new ThrottedRequestQueue(TimeSpan.FromSeconds(3), 1, 3, \"trading\")))");
            self.writeLine("        {");
            self.writeLine(subClassInitializer);
            self.writeLine("        }");
            self.writeLine("        public Client(Uri uri, IRequestController requestController)");
            self.writeLine("            : base(uri, requestController)");
            self.writeLine("        {");
            self.writeLine(subClassInitializer);
            self.writeLine("        }            ");

            each(subClasses, function (subClass, key) {
                if (key != "default") {
                    self.writeLine("        public class _" + key);
                    self.writeLine("        {");
                    self.writeLine("            private " + self.className + " _client;");
                    self.writeLine("            public _" + key + "(" + self.className + " client){ this._client = client;}");
                }

                self.writeLine(subClass);

                if (key != "default") {
                    self.writeLine("        }            ");
                }

            });

            self.writeLine("    }");
            self.writeLine("}");

            return this.toString();
        },
        resolveType: function (type) {

            var resolvedType;

            // does not handle arrays and does not handle nullable - neither of which is unreasonable given the nature
            // of the api
            var self = this;

            if (type.$ref) {

                resolvedType = this.normalizeKey(type.$ref);

            } else {

                resolvedType = this.applyFormat(type);
            }

            return resolvedType;

        },
        applyFormat: function (type) {
            var resolvedType = type;
            switch (type) {
                case "string":
                    // new formats "wcf-date"
                    if (type.format == "wcf-date") {
                        resolvedType = "DateTime";
                    }
                    else {
                        resolvedType = "string";
                    }
                    break;
                case "number":
                    // new formats "decimal[-precision?]"
                    if (type.format == "decimal") {
                        resolvedType = "decimal";
                    }
                    else {
                        resolvedType = "float";
                    }
                    break;
                case "integer":
                    resolvedType = "int";
                    break;
                case "boolean":
                    resolvedType = "bool";
                    break;
                case "object":
                    break;

                case "null":
                    break;
                case "any":
                    break;
                default:
                    break;
            }
            return resolvedType;
        }

    };

    // private lib funcs

    function isArray(obj) {
        return (obj && (typeof (obj) == "object") && obj.length);
    };

    function isDefined(obj) {
        return obj && (typeof (obj) != 'undefined');
    };

    function each(obj, action) {
        var self = this;
        if (isArray(obj)) {
            for (var i = 0; i < obj.length; i++) {
                action.call(self, obj[i], i, obj);
            }
        }
        else if (typeof (obj) == "object") {
            for (var name in obj) {
                if (obj.hasOwnProperty(name)) {
                    action.call(self, obj[name], name, obj);
                };
            };
        }
        else {
            throw new Error("cannot iterate supplied obj");
        };
    };
})();

<commit_msg>added default throttle scope to handle services that are not decorated<commit_after>
function generateRoutes() {

    // for use when rendering the schema out flat
    //    var resolver = new JSchemaInheritanceResolver(schema);
    //    resolver.resolve(true);

    var rpcGenerator = new CSharpRouteGenerator(smd.services.rpc, schema, "CIAPI.Rpc", "Client", ["System", "System.Collections.Generic", "CityIndex.JsonClient", "CIAPI.DTO"], routesPatch);
    var rpcRoutes = rpcGenerator.generate();

    document.getElementById("routes").value = rpcRoutes;
};

(function () {

    var generator = window.CSharpRouteGenerator = function (smd, schema, namespaceName, className, imports, routesPatch) {
        this.smd = smd;
        this.schema = schema;
        this._lines = [];
        this.routesPatch = routesPatch;
        this.className = className;
        this.namespaceName = namespaceName;
        this.imports = imports ? imports : [];

    };

    generator.prototype = {
        normalizeKey: function (key) {
            if (key.indexOf("#.") > -1 || key.indexOf("#/") > -1) {
                key = key.substring(2);
            };
            return key;
        },

        writeLine: function (value) {
            this._lines.push(value);
        },
        toString: function () {
            return this._lines.join("\n");
        },

        createSummary: function (description) {
            var result = "";
            result = result.concat("\n" + "        /// <summary>");
            result = result.concat("\n" + "        /// " + this.createDescription(description));
            result = result.concat("\n" + "        /// </summary>");
            return result;
        },
        createDescription: function (description) {

            return description ? description : " [DESCRIPTION MISSING]";

        },
        generate: function () {
            var subClasses = {
                "default": ""
            };
            this.target = this.smd.target;
            var self = this;

            var services = this.smd.services;
            var schema = this.schema;
            if (this.imports) {
                each(this.imports, function (namespaceName) {
                    self.writeLine("using " + namespaceName + ";");
                });

            }
            self.writeLine("namespace " + this.namespaceName);
            self.writeLine("{");
            self.writeLine("    public partial class " + this.className);
            self.writeLine("    {");
            each(services, function (service, key) {
                var serviceText = "";
                serviceText = serviceText.concat("\n" + "        // ***********************************");
                serviceText = serviceText.concat("\n" + "        // " + key);
                serviceText = serviceText.concat("\n" + "        // ***********************************");
                serviceText = serviceText.concat("\n" + "");

                serviceText = serviceText.concat("\n" + self.createSummary(service.description));
                each(service.parameters, function (parameter) {
                    serviceText = serviceText.concat("\n" + "        /// <param name=\"" + parameter.name + "\">" + self.createDescription(parameter.description) + "</param>");

                });

                var paramList = "";
                var firstParam = true;
                each(service.parameters, function (parameter) {
                    var paramType;
                    if (parameter.type) {
                        paramType = self.resolveType(parameter.type);
                    }
                    else if (parameter.$ref) {
                        paramType = self.normalizeKey(parameter.$ref);

                    } else {
                        throw new Error("unsupported property type");

                    }

                    if (!firstParam) {
                        paramList = paramList.concat(", ");
                    }

                    firstParam = false;
                    paramList = paramList.concat(paramType, " ", parameter.name);
                });
                var returnType = self.resolveType(service.returns);
                var target = service.target;
                var uriTemplate = service.uriTemplate;
                var transport = service.transport;
                var cacheDuration = service.cacheDuration || "0";
                var throttleScope = service.throttleScope || "default";

                var requestParamList = "";
                var firstRequestParam = true;
                each(service.parameters, function (parameter) {

                    if (!firstRequestParam) {
                        requestParamList = requestParamList.concat(", \n");
                    }

                    firstRequestParam = false;
                    requestParamList = requestParamList.concat("                { \"" + parameter.name + "\", " + parameter.name + "}");

                });
                var visibility = "public";
                var subClassName = "default";
                if (this.routesPatch) {
                    if (this.routesPatch[key]) {

                        if (this.routesPatch[key].visibility) {
                            visibility = this.routesPatch[key].visibility;
                        }
                        if (this.routesPatch[key]["class"]) {
                            subClassName = this.routesPatch[key]["class"];
                        }
                    }
                }

                if (!subClasses[subClassName]) {
                    subClasses[subClassName] = "";
                }

                serviceText = serviceText.concat("\n" + "        " + visibility + " " + returnType + " " + key + "(" + paramList + ")");
                serviceText = serviceText.concat("\n" + "        {");
                serviceText = serviceText.concat("\n" + "            return _client.Request<" + returnType + ">(\"" + target + "\", \"" + uriTemplate + "\", \"" + transport + "\",");
                serviceText = serviceText.concat("\n" + "            new Dictionary<string, object>");
                serviceText = serviceText.concat("\n" + "            {");
                serviceText = serviceText.concat("\n" + requestParamList);

                serviceText = serviceText.concat("\n" + "            }, TimeSpan.FromMilliseconds(" + cacheDuration + "), \"" + throttleScope + "\");");

                serviceText = serviceText.concat("\n" + "        }");
                serviceText = serviceText.concat("\n" + "");

                serviceText = serviceText.concat("\n" + self.createSummary(service.description));

                each(service.parameters, function (parameter) {
                    serviceText = serviceText.concat("\n" + "        /// <param name=\"" + parameter.name + "\">" + self.createDescription(parameter.description) + "</param>");

                });
                serviceText = serviceText.concat("\n" + "        /// <param name=\"callback\"></param>");
                serviceText = serviceText.concat("\n" + "        /// <param name=\"state\"></param>");
                serviceText = serviceText.concat("\n" + "        " + visibility + " void Begin" + key + "(" + paramList + (paramList ? "," : "") + " ApiAsyncCallback<" + returnType + "> callback, object state)");
                serviceText = serviceText.concat("\n" + "        {");
                serviceText = serviceText.concat("\n" + "            _client.BeginRequest(callback, state, \"" + target + "\", \"" + uriTemplate + "\", \"" + transport + "\",");

                serviceText = serviceText.concat("\n" + "            new Dictionary<string, object>");
                serviceText = serviceText.concat("\n" + "            {");
                serviceText = serviceText.concat("\n" + requestParamList);

                serviceText = serviceText.concat("\n" + "            }, TimeSpan.FromMilliseconds(" + cacheDuration + "), \"" + throttleScope + "\");");

                serviceText = serviceText.concat("\n" + "        }");
                serviceText = serviceText.concat("\n" + "");

                serviceText = serviceText.concat("\n" + "        " + visibility + " " + returnType + " End" + key + "(ApiAsyncResult<" + returnType + "> asyncResult)");

                serviceText = serviceText.concat("\n" + "        {");
                serviceText = serviceText.concat("\n" + "            return _client.EndRequest(asyncResult);");
                serviceText = serviceText.concat("\n" + "        }");
                serviceText = serviceText.concat("\n" + "");

                subClasses[subClassName] = subClasses[subClassName].concat(serviceText, "\n");

            });

            // #TODO: need to emit default constructor that instantiates subclasses and accessors
            var subClassProperties = "";
            var subClassDefinitions = "";
            var subClassInitializer = "";
            each(subClasses, function (subClass, key) {
                if (key != "default") {
                    subClassProperties = subClassProperties.concat("\n      public _" + key + " " + key + "{get; private set;}");
                    subClassInitializer = subClassInitializer.concat("\n            this. " + key + " = new _" + key + "(this);");
                }

            });

            self.writeLine(subClassProperties);

            self.writeLine("        public Client(Uri uri)");
            self.writeLine("            : base(uri, new RequestController(TimeSpan.FromSeconds(0), 2, new RequestFactory(), new ErrorResponseDTOJsonExceptionFactory(), new ThrottedRequestQueue(TimeSpan.FromSeconds(5), 30, 10, \"data\"), new ThrottedRequestQueue(TimeSpan.FromSeconds(3), 1, 3, \"trading\"),new ThrottedRequestQueue(TimeSpan.FromSeconds(5), 30, 10, \"default\")))");
            self.writeLine("        {");
            self.writeLine(subClassInitializer);
            self.writeLine("        }");
            self.writeLine("        public Client(Uri uri, IRequestController requestController)");
            self.writeLine("            : base(uri, requestController)");
            self.writeLine("        {");
            self.writeLine(subClassInitializer);
            self.writeLine("        }            ");

            each(subClasses, function (subClass, key) {
                if (key != "default") {
                    self.writeLine("        public class _" + key);
                    self.writeLine("        {");
                    self.writeLine("            private " + self.className + " _client;");
                    self.writeLine("            public _" + key + "(" + self.className + " client){ this._client = client;}");
                }

                self.writeLine(subClass);

                if (key != "default") {
                    self.writeLine("        }            ");
                }

            });

            self.writeLine("    }");
            self.writeLine("}");

            return this.toString();
        },
        resolveType: function (type) {

            var resolvedType;

            // does not handle arrays and does not handle nullable - neither of which is unreasonable given the nature
            // of the api
            var self = this;

            if (type.$ref) {

                resolvedType = this.normalizeKey(type.$ref);

            } else {

                resolvedType = this.applyFormat(type);
            }

            return resolvedType;

        },
        applyFormat: function (type) {
            var resolvedType = type;
            switch (type) {
                case "string":
                    // new formats "wcf-date"
                    if (type.format == "wcf-date") {
                        resolvedType = "DateTime";
                    }
                    else {
                        resolvedType = "string";
                    }
                    break;
                case "number":
                    // new formats "decimal[-precision?]"
                    if (type.format == "decimal") {
                        resolvedType = "decimal";
                    }
                    else {
                        resolvedType = "float";
                    }
                    break;
                case "integer":
                    resolvedType = "int";
                    break;
                case "boolean":
                    resolvedType = "bool";
                    break;
                case "object":
                    break;

                case "null":
                    break;
                case "any":
                    break;
                default:
                    break;
            }
            return resolvedType;
        }

    };

    // private lib funcs

    function isArray(obj) {
        return (obj && (typeof (obj) == "object") && obj.length);
    };

    function isDefined(obj) {
        return obj && (typeof (obj) != 'undefined');
    };

    function each(obj, action) {
        var self = this;
        if (isArray(obj)) {
            for (var i = 0; i < obj.length; i++) {
                action.call(self, obj[i], i, obj);
            }
        }
        else if (typeof (obj) == "object") {
            for (var name in obj) {
                if (obj.hasOwnProperty(name)) {
                    action.call(self, obj[name], name, obj);
                };
            };
        }
        else {
            throw new Error("cannot iterate supplied obj");
        };
    };
})();

<|endoftext|>