<commit_before>var _ = require('lodash').noConflict(),
    iconvlite = require('iconv-lite'),
    util,

    ASCII_SOURCE = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
    ASCII_SOURCE_LENGTH = ASCII_SOURCE.length,
    EMPTY = '';

/**
 * @module util
 * @private
 */
_.mixin(/** @lends util */ {

    /**
     * Creates an inheritance relation between the child and the parent, adding a 'super_' attribute to the
     * child, and setting up the child prototype.
     *
     * @param {Function} child - The target object to create parent references for,.
     * @param {Function} base - The parent association to assign to the provided child definition.
     * @returns {*}
     */
    inherit (child, base) {
        Object.defineProperty(child, 'super_', {
            value: _.isFunction(base) ? base : _.noop,
            configurable: false,
            enumerable: false,
            writable: false
        });

        child.prototype = Object.create((_.isFunction(base) ? base.prototype : base), {
            constructor: {
                value: child,
                enumerable: false,
                writable: true,
                configurable: true
            }
        });

        return child;
    },

    /**
     * Creates an array from a Javascript "arguments" object.
     * https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/arguments
     *
     * @param {Array} args -
     * @returns {Array.<T>}
     */
    args (args) {
        return Array.prototype.slice.call(args);
    },

    /**
     * Makes sure the given string is encoded only once.
     *
     * @param {String} string -
     * @returns {String}
     */
    ensureEncoded (string) {
        // Takes care of the case where the string is already encoded.
        try {
            string = decodeURIComponent(string);
        }
        catch (e) {} // eslint-disable-line no-empty

        try {
            return encodeURIComponent(string);
        }
        // handle malformed URI sequence
        // refer: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Malformed_URI
        catch (error) {
            return string;
        }
    },

    /**
     * Creates a locked property on an object, which is not writable or enumerable.
     *
     * @param {Object} obj -
     * @param {String} name -
     * @param {*} prop -
     * @returns {*}
     */
    assignLocked (obj, name, prop) {
        Object.defineProperty(obj, name, {
            value: prop,
            configurable: false,
            enumerable: false,
            writable: false
        });

        return obj;
    },

    /**
     * Creates a hidden property on an object, which can be changed, but is not enumerable.
     *
     * @param {Object} obj -
     * @param {String} name -
     * @param {*} prop -
     * @returns {*}
     */
    assignHidden (obj, name, prop) {
        Object.defineProperty(obj, name, {
            value: prop,
            configurable: true,
            enumerable: false,
            writable: true
        });

        return obj;
    },

    /**
     * Creates a property on an object, with the given type.
     *
     * @param {Object} obj -
     * @param {String} name -
     * @param {Property} Prop -
     * @param {*} [fallback] -
     * @returns {Prop|undefined}
     */
    createDefined (obj, name, Prop, fallback) {
        return _.has(obj, name) ? (new Prop(obj[name])) : fallback;
    },

    /**
     * Merges defined keys from the target object onto the source object.
     *
     * @param {Object} target -
     * @param {Object} source -
     * @returns {Object}
     */
    mergeDefined (target, source) {
        var key;

        for (key in source) {
            if (_.has(source, key) && !_.isUndefined(source[key])) {
                target[key] = source[key];
            }
        }

        return target;
    },

    /**
     * Returns the value of a property if defined in object, else the default
     *
     * @param {Object} obj -
     * @param {String} prop -
     * @param {*=} def -
     *
     * @returns {*}
     */
    getOwn (obj, prop, def) {
        return _.has(obj, prop) ? obj[prop] : def;
    },

    /**
     * Creates a clone of an object, but uses the toJSON method if available.
     *
     * @param {Object} obj -
     * @returns {*}
     */
    cloneElement (obj) {
        return _.cloneDeepWith(obj, function (value) {
            // falls back to default deepclone if object does not have explicit toJSON().
            if (value && _.isFunction(value.toJSON)) {
                return value.toJSON();
            }
        });
    },

    /**
     * Returns the match of a value of a property by traversing the prototype
     *
     * @param {Object} obj -
     * @param {String} key -
     * @param {*} value -
     *
     * @returns {Boolean}
     */
    inSuperChain (obj, key, value) {
        return obj ? ((obj[key] === value) || _.inSuperChain(obj.super_, key, value)) : false;
    },

    /**
     * Generates a random string of given length (useful for nonce generation, etc).
     *
     * @param {Number} length -
     */
    randomString (length) {
        length = length || 6;

        var result = [],
            i;

        for (i = 0; i < length; i++) {
            result[i] = ASCII_SOURCE[(Math.random() * ASCII_SOURCE_LENGTH) | 0];
        }

        return result.join(EMPTY);
    },

    choose () {
        for (var i = 0, ii = arguments.length; i < ii; i++) {
            if (!_.isEmpty(arguments[i])) {
                return arguments[i];
            }
        }
    }
});

util = {
    lodash: _,

    /**
     *
     * @param {String} data -
     * @returns {String} [description]
     */
    btoa: ((typeof btoa !== 'function' && typeof Buffer === 'function') ? function (data) {
        return Buffer.from(data).toString('base64');
    } : function (data) {
        return btoa(data);
    }), // @todo use browserify to normalise this

    /**
     * ArrayBuffer to String
     *
     * @param {ArrayBuffer} buffer -
     * @returns {String}
     */
    arrayBufferToString: function (buffer) {
        var str = '',
            uArrayVal = new Uint8Array(buffer),

            i,
            ii;

        for (i = 0, ii = uArrayVal.length; i < ii; i++) {
            str += String.fromCharCode(uArrayVal[i]);
        }

        return str;
    },

    bufferOrArrayBufferToString: function (buffer, charset) {
        if (!buffer || _.isString(buffer)) {
            return buffer || '';
        }

        if (Buffer.isBuffer(buffer)) {
            if (iconvlite.encodingExists(charset)) {
                return iconvlite.decode(buffer, charset);
            }

            return buffer.toString(); // Default to utf8 if iconvlite also not supporting the charset
        }

        return util.arrayBufferToString(buffer);
    },

    bufferOrArrayBufferToBase64: function (buffer) {
        if (!buffer) {
            return '';
        }

        // handle when buffer is pure string
        if (_.isString(buffer)) {
            return util.btoa(buffer);
        }

        // check if tostring works
        var base64 = buffer.toString('base64') || '';

        if (base64 === '[object ArrayBuffer]') {
            return util.btoa(util.arrayBufferToString(buffer));
        }

        return base64;
    },

    /**
     * Check whether a value is number-like
     * https://github.com/lodash/lodash/issues/1148#issuecomment-141139153
     *
     * @param {*} n - The candidate to be checked for numeric compliance.
     * @returns {Boolean}
     */
    isNumeric: function (n) {
        return !isNaN(parseFloat(n)) && isFinite(n);
    }
};

module.exports = util;
<commit_msg>Ignore code coverage for btoa for Node v16<commit_after>var _ = require('lodash').noConflict(),
    iconvlite = require('iconv-lite'),
    util,

    ASCII_SOURCE = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
    ASCII_SOURCE_LENGTH = ASCII_SOURCE.length,
    EMPTY = '';

/**
 * @module util
 * @private
 */
_.mixin(/** @lends util */ {

    /**
     * Creates an inheritance relation between the child and the parent, adding a 'super_' attribute to the
     * child, and setting up the child prototype.
     *
     * @param {Function} child - The target object to create parent references for,.
     * @param {Function} base - The parent association to assign to the provided child definition.
     * @returns {*}
     */
    inherit (child, base) {
        Object.defineProperty(child, 'super_', {
            value: _.isFunction(base) ? base : _.noop,
            configurable: false,
            enumerable: false,
            writable: false
        });

        child.prototype = Object.create((_.isFunction(base) ? base.prototype : base), {
            constructor: {
                value: child,
                enumerable: false,
                writable: true,
                configurable: true
            }
        });

        return child;
    },

    /**
     * Creates an array from a Javascript "arguments" object.
     * https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/arguments
     *
     * @param {Array} args -
     * @returns {Array.<T>}
     */
    args (args) {
        return Array.prototype.slice.call(args);
    },

    /**
     * Makes sure the given string is encoded only once.
     *
     * @param {String} string -
     * @returns {String}
     */
    ensureEncoded (string) {
        // Takes care of the case where the string is already encoded.
        try {
            string = decodeURIComponent(string);
        }
        catch (e) {} // eslint-disable-line no-empty

        try {
            return encodeURIComponent(string);
        }
        // handle malformed URI sequence
        // refer: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Malformed_URI
        catch (error) {
            return string;
        }
    },

    /**
     * Creates a locked property on an object, which is not writable or enumerable.
     *
     * @param {Object} obj -
     * @param {String} name -
     * @param {*} prop -
     * @returns {*}
     */
    assignLocked (obj, name, prop) {
        Object.defineProperty(obj, name, {
            value: prop,
            configurable: false,
            enumerable: false,
            writable: false
        });

        return obj;
    },

    /**
     * Creates a hidden property on an object, which can be changed, but is not enumerable.
     *
     * @param {Object} obj -
     * @param {String} name -
     * @param {*} prop -
     * @returns {*}
     */
    assignHidden (obj, name, prop) {
        Object.defineProperty(obj, name, {
            value: prop,
            configurable: true,
            enumerable: false,
            writable: true
        });

        return obj;
    },

    /**
     * Creates a property on an object, with the given type.
     *
     * @param {Object} obj -
     * @param {String} name -
     * @param {Property} Prop -
     * @param {*} [fallback] -
     * @returns {Prop|undefined}
     */
    createDefined (obj, name, Prop, fallback) {
        return _.has(obj, name) ? (new Prop(obj[name])) : fallback;
    },

    /**
     * Merges defined keys from the target object onto the source object.
     *
     * @param {Object} target -
     * @param {Object} source -
     * @returns {Object}
     */
    mergeDefined (target, source) {
        var key;

        for (key in source) {
            if (_.has(source, key) && !_.isUndefined(source[key])) {
                target[key] = source[key];
            }
        }

        return target;
    },

    /**
     * Returns the value of a property if defined in object, else the default
     *
     * @param {Object} obj -
     * @param {String} prop -
     * @param {*=} def -
     *
     * @returns {*}
     */
    getOwn (obj, prop, def) {
        return _.has(obj, prop) ? obj[prop] : def;
    },

    /**
     * Creates a clone of an object, but uses the toJSON method if available.
     *
     * @param {Object} obj -
     * @returns {*}
     */
    cloneElement (obj) {
        return _.cloneDeepWith(obj, function (value) {
            // falls back to default deepclone if object does not have explicit toJSON().
            if (value && _.isFunction(value.toJSON)) {
                return value.toJSON();
            }
        });
    },

    /**
     * Returns the match of a value of a property by traversing the prototype
     *
     * @param {Object} obj -
     * @param {String} key -
     * @param {*} value -
     *
     * @returns {Boolean}
     */
    inSuperChain (obj, key, value) {
        return obj ? ((obj[key] === value) || _.inSuperChain(obj.super_, key, value)) : false;
    },

    /**
     * Generates a random string of given length (useful for nonce generation, etc).
     *
     * @param {Number} length -
     */
    randomString (length) {
        length = length || 6;

        var result = [],
            i;

        for (i = 0; i < length; i++) {
            result[i] = ASCII_SOURCE[(Math.random() * ASCII_SOURCE_LENGTH) | 0];
        }

        return result.join(EMPTY);
    },

    choose () {
        for (var i = 0, ii = arguments.length; i < ii; i++) {
            if (!_.isEmpty(arguments[i])) {
                return arguments[i];
            }
        }
    }
});

util = {
    lodash: _,

    /**
     *
     * @param {String} data -
     * @returns {String} [description]
     */
    btoa: (/* istanbul ignore next */
        (typeof btoa !== 'function' && typeof Buffer === 'function') ? function (data) {
            return Buffer.from(data).toString('base64');
        } : function (data) {
            return btoa(data);
        }
    ), // @todo use browserify to normalise this

    /**
     * ArrayBuffer to String
     *
     * @param {ArrayBuffer} buffer -
     * @returns {String}
     */
    arrayBufferToString: function (buffer) {
        var str = '',
            uArrayVal = new Uint8Array(buffer),

            i,
            ii;

        for (i = 0, ii = uArrayVal.length; i < ii; i++) {
            str += String.fromCharCode(uArrayVal[i]);
        }

        return str;
    },

    bufferOrArrayBufferToString: function (buffer, charset) {
        if (!buffer || _.isString(buffer)) {
            return buffer || '';
        }

        if (Buffer.isBuffer(buffer)) {
            if (iconvlite.encodingExists(charset)) {
                return iconvlite.decode(buffer, charset);
            }

            return buffer.toString(); // Default to utf8 if iconvlite also not supporting the charset
        }

        return util.arrayBufferToString(buffer);
    },

    bufferOrArrayBufferToBase64: function (buffer) {
        if (!buffer) {
            return '';
        }

        // handle when buffer is pure string
        if (_.isString(buffer)) {
            return util.btoa(buffer);
        }

        // check if tostring works
        var base64 = buffer.toString('base64') || '';

        if (base64 === '[object ArrayBuffer]') {
            return util.btoa(util.arrayBufferToString(buffer));
        }

        return base64;
    },

    /**
     * Check whether a value is number-like
     * https://github.com/lodash/lodash/issues/1148#issuecomment-141139153
     *
     * @param {*} n - The candidate to be checked for numeric compliance.
     * @returns {Boolean}
     */
    isNumeric: function (n) {
        return !isNaN(parseFloat(n)) && isFinite(n);
    }
};

module.exports = util;
<|endoftext|>


<commit_before>var db = require('./db');
var moment = require('moment');
var r = require('./redis');
var redis = r.client;
var utility = require('./utility');
var getData = utility.getData;
module.exports = function getReplayUrl(match, cb) {
    db.matches.findOne({
        match_id: match.match_id
    }, function(err, doc) {
        if (match.start_time < moment().subtract(7, 'days').format('X')) {
            console.log("replay expired, not getting replay url");
            //set status to 1 if this match isn't parsed already
            //this ensures we don't mark formerly parsed matches as unavailable on reparses
            match.parse_status = (doc.parse_status === 2) ? doc.parse_status : 1;
            return cb(err);
        }
        if (!err && doc && doc.url) {
            console.log("replay url in db");
            match.url = doc.url;
            return cb(err);
        }
        else {
            redis.get("retrievers", function(err, result) {
                if (err) {
                    return cb(err);
                }
                result = JSON.parse(result);
                //make array of retriever urls and use a random one on each retry
                var urls = result.map(function(r) {
                    return r + "&match_id=" + match.match_id;
                });
                getData(urls, function(err, body) {
                    if (err || !body || !body.match) {
                        //non-retryable error
                        return cb("invalid body or error");
                    }
                    var url = "http://replay" + body.match.cluster + ".valve.net/570/" + match.match_id + "_" + body.match.replaySalt + ".dem.bz2";
                    match.url = url;
                    //save replay url in db
                    db.matches.update({
                        match_id: match.match_id
                    }, {
                        $set: match
                    }, {
                        upsert: true
                    }, function(err) {
                        cb(err);
                    });
                });
            });
        }
    });
}<commit_msg>don't get url if we already gave it one<commit_after>var db = require('./db');
var moment = require('moment');
var r = require('./redis');
var redis = r.client;
var utility = require('./utility');
var getData = utility.getData;
module.exports = function getReplayUrl(match, cb) {
    db.matches.findOne({
        match_id: match.match_id
    }, function(err, doc) {
        if (match.url) { //if there's already a url, for custom jobs!
            return cb(err);
        }
        if (match.start_time < moment().subtract(7, 'days').format('X')) {
            console.log("replay expired, not getting replay url");
            //set status to 1 if this match isn't parsed already
            //this ensures we don't mark formerly parsed matches as unavailable on reparses
            match.parse_status = (doc.parse_status === 2) ? doc.parse_status : 1;
            return cb(err);
        }
        if (!err && doc && doc.url) {
            console.log("replay url in db");
            match.url = doc.url;
            return cb(err);
        }
        else {
            redis.get("retrievers", function(err, result) {
                if (err) {
                    return cb(err);
                }
                result = JSON.parse(result);
                //make array of retriever urls and use a random one on each retry
                var urls = result.map(function(r) {
                    return r + "&match_id=" + match.match_id;
                });
                getData(urls, function(err, body) {
                    if (err || !body || !body.match) {
                        //non-retryable error
                        return cb("invalid body or error");
                    }
                    var url = "http://replay" + body.match.cluster + ".valve.net/570/" + match.match_id + "_" + body.match.replaySalt + ".dem.bz2";
                    match.url = url;
                    //save replay url in db
                    db.matches.update({
                        match_id: match.match_id
                    }, {
                        $set: match
                    }, {
                        upsert: true
                    }, function(err) {
                        cb(err);
                    });
                });
            });
        }
    });
}<|endoftext|>


<commit_before>//----------------------------------------------------------------------
// AdalJS v1.0.4
// @preserve Copyright (c) Microsoft Open Technologies, Inc.
// All Rights Reserved
// Apache License 2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//----------------------------------------------------------------------
'use strict';

if (typeof module !== 'undefined' && module.exports) {
    module.exports.inject = function (conf) {
        return new AuthenticationContext(conf);
    };
}

(function () {
    // ============= Angular modules- Start =============
    if (angular) {

        var AdalModule = angular.module('AdalAngular', []);

        AdalModule.provider('adalAuthenticationService', function () {
            var _adal = null;
            var _oauthData = { isAuthenticated: false, userName: '', loginError: '', profile: '' };
            var _acquiringIdToken = false;

            var updateDataFromCache = function (resource) {
                // only cache lookup here to not interrupt with events
                var token = _adal.getCachedToken(resource);
                _oauthData.isAuthenticated = token !== null && token.length > 0;
                var user = _adal.getCachedUser() || { userName: '' };
                _oauthData.userName = user.userName;
                _oauthData.profile = user.profile;
                _oauthData.loginError = _adal.getLoginError();
            };

            this.init = function (configOptions, httpProvider) {
                if (configOptions) {
                    // redirect and logout_redirect are set to current location by default
                    var existingHash = window.location.hash;
                    var pathDefault = window.location.href;
                    if (existingHash) {
                        pathDefault = pathDefault.replace(existingHash, '');
                    }
                    configOptions.redirectUri = configOptions.redirectUri || pathDefault;
                    configOptions.postLogoutRedirectUri = configOptions.postLogoutRedirectUri || pathDefault;

                    if (httpProvider && httpProvider.interceptors) {
                        httpProvider.interceptors.push('ProtectedResourceInterceptor');
                    }

                    // create instance with given config
                    _adal = new AuthenticationContext(configOptions);
                } else {
                    throw new Error('You must set configOptions, when calling init');
                }

                // loginresource is used to set authenticated status
                updateDataFromCache(_adal.config.loginResource);
            };

            // special function that exposes methods in Angular controller
            // $rootScope, $window, $q, $location, $timeout are injected by Angular
            this.$get = ['$rootScope', '$window', '$q', '$location', '$timeout', 'HttpAuthenticationBuffer', function ($rootScope, $window, $q, $location, $timeout, httpAuthenticationBuffer) {

                var locationChangeHandler = function () {
                    var hash = $window.location.hash;

                    if (_adal.isCallback(hash)) {
                        // callback can come from login or iframe request

                        var requestInfo = _adal.getRequestInfo(hash);
                        _adal.saveTokenFromHash(requestInfo);

                        if ($location.$$html5) {
                            $window.location = $window.location.origin + $window.location.pathname;
                        } else {
                            $window.location.hash = '';
                        }

                        if (requestInfo.requestType !== _adal.REQUEST_TYPE.LOGIN) {
                            _adal.callback = $window.parent.AuthenticationContext().callback;
                            if (requestInfo.requestType === _adal.REQUEST_TYPE.RENEW_TOKEN) {
                                _adal.callback = $window.parent.callBackMappedToRenewStates[requestInfo.stateResponse];
                            }
                        }

                        // Return to callback if it is send from iframe
                        if (requestInfo.stateMatch) {
                            if (typeof _adal.callback === 'function') {
                                // Call within the same context without full page redirect keeps the callback
                                if (requestInfo.requestType === _adal.REQUEST_TYPE.RENEW_TOKEN) {
                                    // Idtoken or Accestoken can be renewed
                                    if (requestInfo.parameters['access_token']) {
                                        _adal.callback(_adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['access_token']);
                                        return;
                                    } else if (requestInfo.parameters['id_token']) {
                                        _adal.callback(_adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['id_token']);
                                        return;
                                    }
                                }
                            } else {
                                // normal full login redirect happened on the page
                                updateDataFromCache(_adal.config.loginResource);
                                if (_oauthData.userName) {
                                    //IDtoken is added as token for the app
                                    $timeout(function () {
                                        updateDataFromCache(_adal.config.loginResource);
                                        $rootScope.userInfo = _oauthData;
                                        // redirect to login requested page
                                        var loginStartPage = _adal._getItem(_adal.CONSTANTS.STORAGE.START_PAGE);
                                        if (loginStartPage) {
                                            $location.path(loginStartPage);
                                        }
                                    }, 1);
                                    $rootScope.$broadcast('adal:loginSuccess');
                                } else {
                                    $rootScope.$broadcast('adal:loginFailure', _adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION));
                                }
                            }
                        }
                    } else {
                        // No callback. App resumes after closing or moving to new page.
                        // Check token and username
                        updateDataFromCache(_adal.config.loginResource);
                        if (!_adal._renewActive && !_oauthData.isAuthenticated && _oauthData.userName) {
                            if (!_adal._getItem(_adal.CONSTANTS.STORAGE.FAILED_RENEW)) {
                                // Idtoken is expired or not present
                                _acquiringIdToken = true;
                                _adal.acquireToken(_adal.config.loginResource, function (error, tokenOut) {
                                    _acquiringIdToken = false;
                                    if (error) {
                                        $rootScope.$broadcast('adal:loginFailure', 'auto renew failure');
                                    } else {
                                        if (tokenOut) {
                                            _oauthData.isAuthenticated = true;
                                        }
                                    }
                                    httpAuthenticationBuffer.flushRequestBuffer(error || !_oauthData.isAuthenticated);
                                });
                            }
                        }
                    }

                    $timeout(function () {
                        updateDataFromCache(_adal.config.loginResource);
                        $rootScope.userInfo = _oauthData;
                    }, 1);
                };

                var loginHandler = function () {
                    _adal._logstatus('Login event for:' + $location.$$path);
                    if (_adal.config && _adal.config.localLoginUrl) {
                        $location.path(_adal.config.localLoginUrl);
                    } else {
                        // directly start login flow
                        _adal._saveItem(_adal.CONSTANTS.STORAGE.START_PAGE, $location.$$path);
                        _adal._logstatus('Start login at:' + window.location.href);
                        $rootScope.$broadcast('adal:loginRedirect');
                        _adal.login();
                    }
                };

                function isADLoginRequired(route, global) {
                    return global.requireADLogin ? route.requireADLogin !== false : !!route.requireADLogin;
                }

                var routeChangeHandler = function (e, nextRoute) {
                    if (nextRoute && nextRoute.$$route && isADLoginRequired(nextRoute.$$route, _adal.config)) {
                        if (!_oauthData.isAuthenticated) {
                            _adal._logstatus('Route change event for:' + $location.$$path);
                            loginHandler();
                        }
                    }
                };

                var stateChangeHandler = function (e, nextRoute) {
                    if (nextRoute && isADLoginRequired(nextRoute, _adal.config)) {
                        if (!_oauthData.isAuthenticated) {
                            _adal._logstatus('State change event for:' + $location.$$path);
                            loginHandler();
                        }
                    }
                };

                // Route change event tracking to receive fragment and also auto renew tokens
                $rootScope.$on('$routeChangeStart', routeChangeHandler);

                $rootScope.$on('$stateChangeStart', stateChangeHandler);

                $rootScope.$on('$locationChangeStart', locationChangeHandler);

                updateDataFromCache(_adal.config.loginResource);
                $rootScope.userInfo = _oauthData;

                return {
                    // public methods will be here that are accessible from Controller
                    config: _adal.config,
                    login: function () {
                        _adal.login();
                    },
                    loginInProgress: function () {
                        return _adal.loginInProgress();
                    },
                    logOut: function () {
                        _adal.logOut();
                        //call signout related method
                    },
                    getCachedToken: function (resource) {
                        return _adal.getCachedToken(resource);
                    },
                    userInfo: _oauthData,
                    acquireToken: function (resource) {
                        // automated token request call
                        var deferred = $q.defer();
                        _adal.acquireToken(resource, function (error, tokenOut) {
                            if (error) {
                                _adal._logstatus('err :' + error);
                                deferred.reject(error);
                            } else {
                                deferred.resolve(tokenOut);
                            }
                        });

                        return deferred.promise;
                    },
                    getUser: function () {
                        var deferred = $q.defer();
                        _adal.getUser(function (error, user) {
                            if (error) {
                                _adal._logstatus('err :' + error);
                                deferred.reject(error);
                            } else {
                                deferred.resolve(user);
                            }
                        });

                        return deferred.promise;
                    },
                    getResourceForEndpoint: function (endpoint) {
                        return _adal.getResourceForEndpoint(endpoint);
                    },
                    clearCache: function () {
                        _adal.clearCache();
                    },
                    clearCacheForResource: function (resource) {
                        _adal.clearCacheForResource(resource);
                    },
                    acquiringIdToken: function () {
                        return _acquiringIdToken;
                    }
                };
            }];
        });

        AdalModule.factory('HttpAuthenticationBuffer', ['$q', '$injector', function ($q, $injector) {
            var _requestBuffer = [];
            var $http;

            return {
                bufferRequest: function (response) {
                    var defer = $q.defer();
                    _requestBuffer.push({
                        response: response,
                        defer: defer
                    });
                    return defer.promise;
                },
                flushRequestBuffer: function (error) {
                    var bufferedRequest;
                    $http = $http || $injector.get('$http');

                    while (bufferedRequest = _requestBuffer.shift()) {
                        (function () {
                            var defer = bufferedRequest.defer;
                            if (error) {
                                defer.reject(error);
                            } else {
                                $http(bufferedRequest.response.config).then(function (data) {
                                    defer.resolve(data);
                                }, function (error) {
                                    defer.reject(error);
                                });
                            }
                        })();
                    }
                }
            }
        }]);

        // Interceptor for http if needed
<<<<<<< HEAD
        AdalModule.factory('ProtectedResourceInterceptor', ['adalAuthenticationService', '$q', '$rootScope', function (authService, $q, $rootScope) {
=======
        AdalModule.factory('ProtectedResourceInterceptor', ['adalAuthenticationService', 'HttpAuthenticationBuffer', '$q', '$rootScope', '$window', '$interval', function (authService, httpAuthenticationBuffer, $q, $rootScope, $window, $interval) {
>>>>>>> 8a2131e0cdef27506ecd3629c6da1510ddf32f70

            return {
                request: function (config) {
                    if (config) {

                        // This interceptor needs to load service, but dependeny definition causes circular reference error.
                        // Loading with injector is suggested at github. https://github.com/angular/angular.js/issues/2367

                        config.headers = config.headers || {};

                        var resource = authService.getResourceForEndpoint(config.url);
                        var tokenStored = authService.getCachedToken(resource);
                        var isEndpoint = false;
                        if (tokenStored) {
                            // check endpoint mapping if provided
                            config.headers.Authorization = 'Bearer ' + tokenStored;
                            return config;
                        } else {

                            if (authService.config) {
                                for (var endpointUrl in authService.config.endpoints) {
                                    if (config.url.indexOf(endpointUrl) > -1) {
                                        isEndpoint = true;
                                    }
                                }
                            }

                            // Cancel request if login is starting or if within an ADAL frame (to prevent recursive spawning of adal frames. We don't need to load the app completely in the iframe)
                            if (authService.loginInProgress() || ($window.self.frameElement && /^adal\w+Frame/i.test($window.self.frameElement.id))) {
                                return $q.reject();
                            } else if (authService.config && isEndpoint) {
                                // external endpoints
                                // delayed request to return after iframe completes
                                var delayedRequest = $q.defer();
                                authService.acquireToken(resource).then(function (token) {
                                config.headers.Authorization = 'Bearer ' + token;
                                delayedRequest.resolve(config);
                            }, function (err) {
                                delayedRequest.reject(err);
                            });

                                return delayedRequest.promise;
                            }
                        }

                        return config;
                    }
                },
                responseError: function (rejection) {
                    if (rejection && rejection.status === 401) {
<<<<<<< HEAD
                        var resource = authService.getResourceForEndpoint(rejection.config.url);
                        authService.clearCacheForResource(resource);
                        $rootScope.$broadcast('adal:notAuthorized', rejection, resource);
=======
						var resource = authService.getResourceForEndpoint(rejection.config.url);

						if(!authService.loginInProgress($window.location.hash)) {
							if (authService.acquiringIdToken()) {
                                return httpAuthenticationBuffer.bufferRequest(rejection);
                            }

                            authService.clearCacheForResource(resource);
                            $rootScope.$broadcast('adal:notAuthorized', rejection, resource);
						}
>>>>>>> 8a2131e0cdef27506ecd3629c6da1510ddf32f70
                    }

                    return $q.reject(rejection);
                }
            };
        }]);
    } else {
        console.error('Angular.JS is not included');
    }
}());
<commit_msg>Clean up<commit_after>//----------------------------------------------------------------------
// AdalJS v1.0.4
// @preserve Copyright (c) Microsoft Open Technologies, Inc.
// All Rights Reserved
// Apache License 2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//----------------------------------------------------------------------
'use strict';

if (typeof module !== 'undefined' && module.exports) {
    module.exports.inject = function (conf) {
        return new AuthenticationContext(conf);
    };
}

(function () {
    // ============= Angular modules- Start =============
    if (angular) {

        var AdalModule = angular.module('AdalAngular', []);

        AdalModule.provider('adalAuthenticationService', function () {
            var _adal = null;
            var _oauthData = { isAuthenticated: false, userName: '', loginError: '', profile: '' };
            var _acquiringIdToken = false;

            var updateDataFromCache = function (resource) {
                // only cache lookup here to not interrupt with events
                var token = _adal.getCachedToken(resource);
                _oauthData.isAuthenticated = token !== null && token.length > 0;
                var user = _adal.getCachedUser() || { userName: '' };
                _oauthData.userName = user.userName;
                _oauthData.profile = user.profile;
                _oauthData.loginError = _adal.getLoginError();
            };

            this.init = function (configOptions, httpProvider) {
                if (configOptions) {
                    // redirect and logout_redirect are set to current location by default
                    var existingHash = window.location.hash;
                    var pathDefault = window.location.href;
                    if (existingHash) {
                        pathDefault = pathDefault.replace(existingHash, '');
                    }
                    configOptions.redirectUri = configOptions.redirectUri || pathDefault;
                    configOptions.postLogoutRedirectUri = configOptions.postLogoutRedirectUri || pathDefault;

                    if (httpProvider && httpProvider.interceptors) {
                        httpProvider.interceptors.push('ProtectedResourceInterceptor');
                    }

                    // create instance with given config
                    _adal = new AuthenticationContext(configOptions);
                } else {
                    throw new Error('You must set configOptions, when calling init');
                }

                // loginresource is used to set authenticated status
                updateDataFromCache(_adal.config.loginResource);
            };

            // special function that exposes methods in Angular controller
            // $rootScope, $window, $q, $location, $timeout are injected by Angular
            this.$get = ['$rootScope', '$window', '$q', '$location', '$timeout', 'HttpAuthenticationBuffer', function ($rootScope, $window, $q, $location, $timeout, httpAuthenticationBuffer) {

                var locationChangeHandler = function () {
                    var hash = $window.location.hash;

                    if (_adal.isCallback(hash)) {
                        // callback can come from login or iframe request

                        var requestInfo = _adal.getRequestInfo(hash);
                        _adal.saveTokenFromHash(requestInfo);

                        if ($location.$$html5) {
                            $window.location = $window.location.origin + $window.location.pathname;
                        } else {
                            $window.location.hash = '';
                        }

                        if (requestInfo.requestType !== _adal.REQUEST_TYPE.LOGIN) {
                            _adal.callback = $window.parent.AuthenticationContext().callback;
                            if (requestInfo.requestType === _adal.REQUEST_TYPE.RENEW_TOKEN) {
                                _adal.callback = $window.parent.callBackMappedToRenewStates[requestInfo.stateResponse];
                            }
                        }

                        // Return to callback if it is send from iframe
                        if (requestInfo.stateMatch) {
                            if (typeof _adal.callback === 'function') {
                                // Call within the same context without full page redirect keeps the callback
                                if (requestInfo.requestType === _adal.REQUEST_TYPE.RENEW_TOKEN) {
                                    // Idtoken or Accestoken can be renewed
                                    if (requestInfo.parameters['access_token']) {
                                        _adal.callback(_adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['access_token']);
                                        return;
                                    } else if (requestInfo.parameters['id_token']) {
                                        _adal.callback(_adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION), requestInfo.parameters['id_token']);
                                        return;
                                    }
                                }
                            } else {
                                // normal full login redirect happened on the page
                                updateDataFromCache(_adal.config.loginResource);
                                if (_oauthData.userName) {
                                    //IDtoken is added as token for the app
                                    $timeout(function () {
                                        updateDataFromCache(_adal.config.loginResource);
                                        $rootScope.userInfo = _oauthData;
                                        // redirect to login requested page
                                        var loginStartPage = _adal._getItem(_adal.CONSTANTS.STORAGE.START_PAGE);
                                        if (loginStartPage) {
                                            $location.path(loginStartPage);
                                        }
                                    }, 1);
                                    $rootScope.$broadcast('adal:loginSuccess');
                                } else {
                                    $rootScope.$broadcast('adal:loginFailure', _adal._getItem(_adal.CONSTANTS.STORAGE.ERROR_DESCRIPTION));
                                }
                            }
                        }
                    } else {
                        // No callback. App resumes after closing or moving to new page.
                        // Check token and username
                        updateDataFromCache(_adal.config.loginResource);
                        if (!_adal._renewActive && !_oauthData.isAuthenticated && _oauthData.userName) {
                            if (!_adal._getItem(_adal.CONSTANTS.STORAGE.FAILED_RENEW)) {
                                // Idtoken is expired or not present
                                _acquiringIdToken = true;
                                _adal.acquireToken(_adal.config.loginResource, function (error, tokenOut) {
                                    _acquiringIdToken = false;
                                    if (error) {
                                        $rootScope.$broadcast('adal:loginFailure', 'auto renew failure');
                                    } else {
                                        if (tokenOut) {
                                            _oauthData.isAuthenticated = true;
                                        }
                                    }
                                    httpAuthenticationBuffer.flushRequestBuffer(error || !_oauthData.isAuthenticated);
                                });
                            }
                        }
                    }

                    $timeout(function () {
                        updateDataFromCache(_adal.config.loginResource);
                        $rootScope.userInfo = _oauthData;
                    }, 1);
                };

                var loginHandler = function () {
                    _adal._logstatus('Login event for:' + $location.$$path);
                    if (_adal.config && _adal.config.localLoginUrl) {
                        $location.path(_adal.config.localLoginUrl);
                    } else {
                        // directly start login flow
                        _adal._saveItem(_adal.CONSTANTS.STORAGE.START_PAGE, $location.$$path);
                        _adal._logstatus('Start login at:' + window.location.href);
                        $rootScope.$broadcast('adal:loginRedirect');
                        _adal.login();
                    }
                };

                function isADLoginRequired(route, global) {
                    return global.requireADLogin ? route.requireADLogin !== false : !!route.requireADLogin;
                }

                var routeChangeHandler = function (e, nextRoute) {
                    if (nextRoute && nextRoute.$$route && isADLoginRequired(nextRoute.$$route, _adal.config)) {
                        if (!_oauthData.isAuthenticated) {
                            _adal._logstatus('Route change event for:' + $location.$$path);
                            loginHandler();
                        }
                    }
                };

                var stateChangeHandler = function (e, nextRoute) {
                    if (nextRoute && isADLoginRequired(nextRoute, _adal.config)) {
                        if (!_oauthData.isAuthenticated) {
                            _adal._logstatus('State change event for:' + $location.$$path);
                            loginHandler();
                        }
                    }
                };

                // Route change event tracking to receive fragment and also auto renew tokens
                $rootScope.$on('$routeChangeStart', routeChangeHandler);

                $rootScope.$on('$stateChangeStart', stateChangeHandler);

                $rootScope.$on('$locationChangeStart', locationChangeHandler);

                updateDataFromCache(_adal.config.loginResource);
                $rootScope.userInfo = _oauthData;

                return {
                    // public methods will be here that are accessible from Controller
                    config: _adal.config,
                    login: function () {
                        _adal.login();
                    },
                    loginInProgress: function () {
                        return _adal.loginInProgress();
                    },
                    logOut: function () {
                        _adal.logOut();
                        //call signout related method
                    },
                    getCachedToken: function (resource) {
                        return _adal.getCachedToken(resource);
                    },
                    userInfo: _oauthData,
                    acquireToken: function (resource) {
                        // automated token request call
                        var deferred = $q.defer();
                        _adal.acquireToken(resource, function (error, tokenOut) {
                            if (error) {
                                _adal._logstatus('err :' + error);
                                deferred.reject(error);
                            } else {
                                deferred.resolve(tokenOut);
                            }
                        });

                        return deferred.promise;
                    },
                    getUser: function () {
                        var deferred = $q.defer();
                        _adal.getUser(function (error, user) {
                            if (error) {
                                _adal._logstatus('err :' + error);
                                deferred.reject(error);
                            } else {
                                deferred.resolve(user);
                            }
                        });

                        return deferred.promise;
                    },
                    getResourceForEndpoint: function (endpoint) {
                        return _adal.getResourceForEndpoint(endpoint);
                    },
                    clearCache: function () {
                        _adal.clearCache();
                    },
                    clearCacheForResource: function (resource) {
                        _adal.clearCacheForResource(resource);
                    },
                    acquiringIdToken: function () {
                        return _acquiringIdToken;
                    }
                };
            }];
        });

        // Interceptor for http if needed
        AdalModule.factory('ProtectedResourceInterceptor', ['adalAuthenticationService', '$q', '$rootScope', '$window', function (authService, $q, $rootScope, $window) {
            return {
                request: function (config) {
                    if (config) {

                        // This interceptor needs to load service, but dependeny definition causes circular reference error.
                        // Loading with injector is suggested at github. https://github.com/angular/angular.js/issues/2367

                        config.headers = config.headers || {};

                        var resource = authService.getResourceForEndpoint(config.url);
                        var tokenStored = authService.getCachedToken(resource);
                        var isEndpoint = false;
                        if (tokenStored) {
                            // check endpoint mapping if provided
                            config.headers.Authorization = 'Bearer ' + tokenStored;
                            return config;
                        } else {

                            if (authService.config) {
                                for (var endpointUrl in authService.config.endpoints) {
                                    if (config.url.indexOf(endpointUrl) > -1) {
                                        isEndpoint = true;
                                    }
                                }
                            }

                            // Cancel request if login is starting or if within an ADAL frame (to prevent recursive spawning of adal frames. We don't need to load the app completely in the iframe)
                            if (authService.loginInProgress() || ($window.self.frameElement && /^adal\w+Frame/i.test($window.self.frameElement.id))) {
                                return $q.reject();
                            } else if (authService.config && isEndpoint) {
                                // external endpoints
                                // delayed request to return after iframe completes
                                var delayedRequest = $q.defer();
                                authService.acquireToken(resource).then(function (token) {
                                config.headers.Authorization = 'Bearer ' + token;
                                delayedRequest.resolve(config);
                            }, function (err) {
                                delayedRequest.reject(err);
                            });

                                return delayedRequest.promise;
                            }
                        }

                        return config;
                    }
                },
                responseError: function (rejection) {
                    if (rejection && rejection.status === 401) {
                        var resource = authService.getResourceForEndpoint(rejection.config.url);
                        authService.clearCacheForResource(resource);
                        $rootScope.$broadcast('adal:notAuthorized', rejection, resource);
                    }

                    return $q.reject(rejection);
                }
            };
        }]);
    } else {
        console.error('Angular.JS is not included');
    }
}());
<|endoftext|>


<commit_before>'use strict';

let juttle_utils = require('../runtime/juttle-utils');

//
// The AdapterAPI is the exported interface to the juttle compiler / runtime
// that is expected to be used by all adapters.
//
// The version field corresponds to the juttle version in which the latest
// changes were made to the adapter API.
//
let AdapterAPI = {
    version: '0.5.0',
    AdapterRead: require('./adapter-read'),
    AdapterWrite: require('./adapter-write'),
    compiler: {
        ASTVisitor: require('../compiler/ast-visitor'),
        ASTTransformer: require('../compiler/ast-transformer'),
        StaticFilterCompiler: require('../compiler/filters/static-filter-compiler'),
        FilterJSCompiler: require('../compiler/filters/filter-js-compiler'),
    },
    errors: require('../errors'),
    getLogger: require('../logger').getLogger,
    runtime: {
        values: require('../runtime/values'),
        toNative: juttle_utils.toNative,
        parseTime: juttle_utils.parseTime,
        reducerDefaultValue: require('../runtime/reducers').default_value
    },
    types: require('../runtime/types')
};

module.exports = AdapterAPI;
<commit_msg>Adapter API: add parsers/serializers<commit_after>'use strict';

let juttle_utils = require('../runtime/juttle-utils');

//
// The AdapterAPI is the exported interface to the juttle compiler / runtime
// that is expected to be used by all adapters.
//
// The version field corresponds to the juttle version in which the latest
// changes were made to the adapter API.
//
let AdapterAPI = {
    version: '0.5.2',
    AdapterRead: require('./adapter-read'),
    AdapterWrite: require('./adapter-write'),
    compiler: {
        ASTVisitor: require('../compiler/ast-visitor'),
        ASTTransformer: require('../compiler/ast-transformer'),
        StaticFilterCompiler: require('../compiler/filters/static-filter-compiler'),
        FilterJSCompiler: require('../compiler/filters/filter-js-compiler'),
    },
    parsers: require('./parsers'),
    serializers: require('./serializers'),
    errors: require('../errors'),
    getLogger: require('../logger').getLogger,
    runtime: {
        values: require('../runtime/values'),
        toNative: juttle_utils.toNative,
        parseTime: juttle_utils.parseTime,
        reducerDefaultValue: require('../runtime/reducers').default_value
    },
    types: require('../runtime/types')
};

module.exports = AdapterAPI;
<|endoftext|>


<commit_before>function Civet(){
  this.data = {};
  this.id = 1;
};

Civet.prototype.create = function(entity, callback){
  var error = null;

  if((entity instanceof Object) && !Array.isArray(entity)) {
    entity.id = this.id;
    this.data[entity.id] = Object.create({}, entity);
    this.id += 1;
  } else {
    error = "You need to pass in an object!";
  }

  callback(error);
}

Civet.prototype.find = function(callback){
  var error = null;

  if(Object.keys(this.data).length === 0){
    error = "No records found!";
  }

  var entities = [];
  for (entity in this.data) {
    if(this.data.hasOwnProperty(entity)){
      entities.push(this.data[entity])
    }
  }
  callback(error, entities);
}

Civet.prototype.findById = function(id, callback) {
  var entity = this.data[id];
  var error = entity ? null : "No record found!";

  callback(error, entity);
}

Civet.prototype.remove = function(id, callback){
  var entity = Object.create({}, this.data[id]);
  var error = null;

  if(entity){
    delete this.data[id]
  } else {
    error = "No record found!";
  }

  callback(error, entity);
}

module.exports = new Civet();
<commit_msg>Never mind.<commit_after>function Civet(){
  this.data = {};
  this.id = 1;
};

Civet.prototype.create = function(entity, callback){
  var error = null;

  if((entity instanceof Object) && !Array.isArray(entity)) {
    entity.id = this.id;
    this.data[entity.id] = Object.assign({}, entity);
    this.id += 1;
  } else {
    error = "You need to pass in an object!";
  }

  callback(error);
}

Civet.prototype.find = function(callback){
  var error = null;

  if(Object.keys(this.data).length === 0){
    error = "No records found!";
  }

  var entities = [];
  for (entity in this.data) {
    if(this.data.hasOwnProperty(entity)){
      entities.push(this.data[entity])
    }
  }
  callback(error, entities);
}

Civet.prototype.findById = function(id, callback) {
  var entity = this.data[id];
  var error = entity ? null : "No record found!";

  callback(error, entity);
}

Civet.prototype.remove = function(id, callback){
  var entity = Object.assign({}, this.data[id]);
  var error = null;

  if(entity){
    delete this.data[id]
  } else {
    error = "No record found!";
  }

  callback(error, entity);
}

module.exports = new Civet();
<|endoftext|>


<commit_before>//jQuery.Class
// This is a modified version of John Resig's class
// http://ejohn.org/blog/simple-javascript-inheritance/
// It provides class level inheritance and callbacks.

(function( $ ) {

    var PropertyHelper =
        {
            isPrivatePropertyRegEx: /^_[a-z]/,

            _init: function()
            {
                this.privates = {};
                this.publics = {};
                this.statics = {};
                this.parentClass = null;
                this.parentPrototype = {};
                this.implement = [];
            },

            determineProperties: function(properties)
            {
                this._init();
                this._setInheritance(properties);
                this._setInterfaces(properties);

                var name;

                for (name in properties) {
                    if (name[0] == '$') {
                        this.statics[name.substr(1,name.length)] = properties[name];
                        continue;
                    }
                    if (this.isPrivatePropertyRegEx.test(name)) {
                        this.privates[name.substr(1,name.length)] = properties[name];
                        continue;
                    }

                    this.publics[name] = properties[name];
                }
            },

            _setInheritance: function(properties)
            {
                if (properties.extend === undefined) {
                    return;
                }

                if (!$.isFunction(properties.extend)) {
                    return;
                }

                this.parentClass = properties.extend;
                this.parentPrototype = this.parentClass['prototype'];
                delete properties.extend;
            },

            _setInterfaces: function(properties)
            {
                if (properties.implement === undefined) {
                    return;
                }

                this.implement = $.isArray(properties.implement) ? properties.implement : [properties.implement];

                this.publics.___interfaces = this.implement;

                delete properties.implement;
            }
        },

		concatArgs = function(arr, args){
			return arr.concat($.makeArray(args));
		},

		isSuperCalledInFunctionRegEx = /xyz/.test(function() {
			xyz;
		}) ? /\b_super\b/ : /.*/,

        isPrivateCalledInFunctionRegEx = /xyz/.test(function() {
			xyz;
        }) ? /\bthis\.privates\.\b/ : /.*/;

    Logger.log('fntest: ');
    Logger.log(isSuperCalledInFunctionRegEx);

    /**
     * @param reference object
     */
    function implementInterfaces(reference)
    {
        if (arguments.length < 2) {
            throw new Error('function requires more then one param.');
        }

        var validInterfaces = [];

        for (var i = 1; i < arguments.length; i++) {
            if (!(arguments[i] instanceof Sys.base.Interface)) {
                throw new Error('Object should be instance of Sys.base.Interface');
            }
            validInterfaces.push(arguments[i]);
        }

        var newClass = function() {
            reference.apply(this, arguments);
            Sys.base.Interface.ensureImplementation(this, this.___interfaces);
        };

        extend(reference, newClass);

        newClass.prototype['___interfaces'] = validInterfaces;

        console.log(validInterfaces);

        return newClass;
    }

    /**
     * overwrites an object with methods
     *
     * @param newProps object (new properties)
     * @param oldProps object (where the old properties might be)
     * @param addTo object (what we are adding to)
     */
    function inheritProps( newProps, oldProps, addTo ) {
        Logger.log('inherit props');
        Logger.log("old props");
        Logger.log(oldProps);
        Logger.log("new props");
        Logger.log(newProps);
        addTo = addTo || newProps;
        Logger.log("add to");
        Logger.log(addTo);
        for ( var name in newProps ) {
            // Check if we're overwriting an existing function
            Logger.log(isSuperCalledInFunctionRegEx);
            Logger.log('test property: ' + name);
            Logger.log(isSuperCalledInFunctionRegEx.test(newProps[name]));

            Logger.log('isFunction(newProps[name])');
            Logger.log($.isFunction(newProps[name]));
            Logger.log('isFunction(oldProps[name])');
            Logger.log($.isFunction(oldProps[name]));
            Logger.log('fnTest.test(newProps[name])');
            Logger.log(isSuperCalledInFunctionRegEx.test(newProps[name]));

            if ($.isFunction(newProps[name])
                && $.isFunction(oldProps[name])
                && isSuperCalledInFunctionRegEx.test(newProps[name]))
            {

                Logger.log('overwritten prop detected!!!: ' + name);
                Logger.log('overwrite existing function / property: ' + name);

                Logger.log(name);

                addTo[name] = getOverriddenMethodWithSuper(newProps[name], oldProps[name]);
            }
            else {
                Logger.log('is not super: '+ name);
                addTo[name] = newProps[name];
            }
        }
    }

    /**
     * @param newMethod function()
     * @param oldMethod function()
     */
    function getOverriddenMethodWithSuper( newMethod, oldMethod )
    {
        return function() {
            var tmp = this._super,
                ret;

            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = oldMethod;

            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            ret = newMethod.apply(this, arguments);
            delete this._super;
            return ret;
        };
    }

    /**
     * copied from $.String helper to remove dependency
     *
     * @param {String} name the name of the object to look for
     * @param {Array} [roots] an array of root objects to look for the
     *   name.  If roots is not provided, the window is used.
     * @param {Boolean} [add] true to add missing objects to
     *  the path. false to remove found properties. undefined to
     *  not modify the root object
     * @return {Object} The object.
     */
    function getObject( name, roots, add )
    {
        // the parts of the name we are looking up
        // ['App','Models','Recipe']
        var regs = {
                undHash: /_|-/,
                colons: /::/,
                words: /([A-Z]+)([A-Z][a-z])/g,
                lowUp: /([a-z\d])([A-Z])/g,
                dash: /([a-z\d])([A-Z])/g,
                replacer: /\{([^\}]+)\}/g,
                dot: /\./
            },
            isContainer = function(current){
                var type = typeof current;
                return current && ( type == 'function' || type == 'object' );
            },
            getNext = function(current, nextPart, add){
                return current[nextPart] !== undefined ? current[nextPart] : ( add && (current[nextPart] = {}) );
            },
            parts = name ? name.split(regs.dot) : [],
            length =  parts.length,
            current,
            ret,
            i,
            r = 0,
            type;

        // make sure roots is an array
        roots = $.isArray(roots) ? roots : [roots || window];

        if(length == 0){
            return roots[0];
        }
        // for each root, mark it as current
        while( current = roots[r++] ) {
            // walk current to the 2nd to last object
            // or until there is not a container
            for (i =0; i < length - 1 && isContainer(current); i++ ) {
                current = getNext(current, parts[i], add);
            }
            // if we can get a property from the 2nd to last object
            if( isContainer(current) ) {

                // get (and possibly set) the property
                ret = getNext(current, parts[i], add);

                // if there is a value, we exit
                if( ret !== undefined ) {
                    // if add is false, delete the property
                    if ( add === false ) {
                        delete current[parts[i]];
                    }
                    return ret;

                }
            }
        }
    }

    /**
     * register class in dom namespace
     * @param fullName string
     */
    function registerClassInWindowNamespace(Class, fullName)
    {
        var parts = fullName.split(/\./),
            shortName = parts.pop(),
            current = getObject(parts.join('.'), window, true),
            namespace = current;

            Logger.log('fullName: ' + fullName);

        current[shortName] = Class;

        Logger.log('current: ');
            Logger.log(current);
        Logger.log('curre[shortName]: ');
            Logger.log(current[shortName]);
            Logger.log('shortName '
             + shortName);
    }

    /**
     * @function newInstance
     * Creates a new instance of the class.  This method is useful for creating new instances
     * with arbitrary parameters.
     * @return {class} instance of the class
     */
    function newInstance(instance, arguments)
    {
        ensureInterfaces(instance);

        // call init if there is an init, if setup returned args, use those as the arguments
        if ( instance.init ) {
            instance.init.apply(instance, arguments);
        }

        return instance;
    }

    function ensureInterfaces(object)
    {
        console.log(object);
        if (!object.___interfaces) {
            return;
        }

        for (i in object.___interfaces) {
            if (!(object.___interfaces[i] instanceof $.Interface)) {
                throw new Error('Object should be instance of $.Interface');
            }
        }
    }

    /**
     * @param {String} [fullName]  the classes name (used for classes w/ introspection)
     * @param {Object} [properties]  the new classes prototype functions
     *
     * @return {jQuery.Class} returns the new class
     */
    function createClass(fullName, properties)
    {
        Logger.log('extend was called');

        PropertyHelper.determineProperties(properties);

        var statics = PropertyHelper.statics,
            privates = PropertyHelper.privates,
            publics = PropertyHelper.publics,
            parentClass = PropertyHelper.parentClass,
            parentPrototype = PropertyHelper.parentPrototype,
            name;

        Logger.log('statics');
        Logger.log(statics);

        Logger.log('publics');
        Logger.log(publics);

        Logger.log('privates');
        Logger.log(privates);

         // The dummy class constructor
        function Class() {
            return newInstance(this, arguments);
        }

        // @todo: separate from this function ?
        if (parentClass) {
            var parent = function() {};
            parent.prototype = parentClass.prototype;
            Class.prototype = new parent();

            for (name in parentClass) {
                statics[name] = parentClass[name];
            }
        }

        $.extend(Class.prototype, parentPrototype, publics);

        // Copy the properties over onto the new prototype
        inheritProps(publics, parentPrototype, Class['prototype']);

        // copy new static props on class
        Logger.log('inherit static properties');
        inheritProps(statics, parentClass || function() {}, Class);

        registerClassInWindowNamespace(Class, fullName);

        // call the class setup
        Logger.log('call the class setup');
        // var args = Class.setup.apply(Class, concatArgs([_super_class],arguments));

        // call the class init static constructor
        Logger.log('call init class static constructor');
        // if ( Class.init ) {
        //     Class.init.apply(Class, args || concatArgs([_super_class],arguments));
        // }

        // @todo: separate from this function ?
        for (name in Class.prototype) {
            if (publics.hasOwnProperty(name)
                && isPrivateCalledInFunctionRegEx.test(Class.prototype[name])
                && $.isFunction(Class.prototype[name]))
            {
                Class.prototype[name] = (function() {
                    var originalProto = Class.prototype;
                    var original = Class.prototype[name];
                    return function() {
                        originalProto.privates = privates;
                        var value = original.apply(this, arguments);
                        delete originalProto.privates;
                        return value;
                    }
                })();
            }
        }

        /* @Prototype*/
        return Class;
    }

    clss = $.Class = function(fullName, properties) {
        createClass(fullName, properties);
	};

})(jQuery);
<commit_msg>fixed bug on inherit<commit_after>//jQuery.Class
// This is a modified version of John Resig's class
// http://ejohn.org/blog/simple-javascript-inheritance/
// It provides class level inheritance and callbacks.

(function( $ ) {

    var PropertyHelper =
        {
            isPrivatePropertyRegEx: /^_[a-z]/,

            _init: function()
            {
                this.privates = {};
                this.publics = {};
                this.statics = {};
                this.parentClass = null;
                this.parentPrototype = {};
                this.implement = [];
            },

            determineProperties: function(properties)
            {
                this._init();
                this._setInheritance(properties);
                this._setInterfaces(properties);

                var name;

                for (name in properties) {
                    if (name[0] == '$') {
                        this.statics[name.substr(1,name.length)] = properties[name];
                        continue;
                    }
                    if (this.isPrivatePropertyRegEx.test(name)) {
                        this.privates[name.substr(1,name.length)] = properties[name];
                        continue;
                    }

                    this.publics[name] = properties[name];
                }
            },

            _setInheritance: function(properties)
            {
                if (properties.extend === undefined) {
                    return;
                }

                if (!$.isFunction(properties.extend)) {
                    return;
                }

                this.parentClass = properties.extend;
                this.parentPrototype = this.parentClass['prototype'];
                delete properties.extend;
            },

            _setInterfaces: function(properties)
            {
                if (properties.implement === undefined) {
                    return;
                }

                this.implement = $.isArray(properties.implement) ? properties.implement : [properties.implement];

                this.publics.___interfaces = this.implement;

                delete properties.implement;
            }
        },

		concatArgs = function(arr, args){
			return arr.concat($.makeArray(args));
		},

		isSuperCalledInFunctionRegEx = /xyz/.test(function() {
			xyz;
		}) ? /\b_super\b/ : /.*/,

        isPrivateCalledInFunctionRegEx = /xyz/.test(function() {
			xyz;
        }) ? /\bthis\.privates\.\b/ : /.*/;

    Logger.log('fntest: ');
    Logger.log(isSuperCalledInFunctionRegEx);

    /**
     * @param reference object
     */
    function implementInterfaces(reference)
    {
        if (arguments.length < 2) {
            throw new Error('function requires more then one param.');
        }

        var validInterfaces = [];

        for (var i = 1; i < arguments.length; i++) {
            if (!(arguments[i] instanceof Sys.base.Interface)) {
                throw new Error('Object should be instance of Sys.base.Interface');
            }
            validInterfaces.push(arguments[i]);
        }

        var newClass = function() {
            reference.apply(this, arguments);
            Sys.base.Interface.ensureImplementation(this, this.___interfaces);
        };

        extend(reference, newClass);

        newClass.prototype['___interfaces'] = validInterfaces;

        console.log(validInterfaces);

        return newClass;
    }

    /**
     * overwrites an object with methods
     *
     * @param newProps object (new properties)
     * @param oldProps object (where the old properties might be)
     * @param addTo object (what we are adding to)
     */
    function inheritProps( newProps, oldProps, addTo ) {
        Logger.log('inherit props');
        Logger.log("old props");
        Logger.log(oldProps);
        Logger.log("new props");
        Logger.log(newProps);
        addTo = addTo || newProps;
        Logger.log("add to");
        Logger.log(addTo);
        for ( var name in newProps ) {
            // Check if we're overwriting an existing function
            Logger.log(isSuperCalledInFunctionRegEx);
            Logger.log('test property: ' + name);
            Logger.log(isSuperCalledInFunctionRegEx.test(newProps[name]));

            Logger.log('isFunction(newProps[name])');
            Logger.log($.isFunction(newProps[name]));
            Logger.log('isFunction(oldProps[name])');
            Logger.log($.isFunction(oldProps[name]));
            Logger.log('fnTest.test(newProps[name])');
            Logger.log(isSuperCalledInFunctionRegEx.test(newProps[name]));

            if ($.isFunction(newProps[name])
                && $.isFunction(oldProps[name])
                && isSuperCalledInFunctionRegEx.test(newProps[name]))
            {

                Logger.log('overwritten prop detected!!!: ' + name);
                Logger.log('overwrite existing function / property: ' + name);

                Logger.log(name);

                addTo[name] = getOverriddenMethodWithSuper(newProps[name], oldProps[name]);
            }
            else {
                Logger.log('is not super: '+ name);
                addTo[name] = newProps[name];
            }
        }
    }

    /**
     * @param newMethod function()
     * @param oldMethod function()
     */
    function getOverriddenMethodWithSuper( newMethod, oldMethod )
    {
        return function() {
            var tmp = this._super,
                ret;

            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = oldMethod;

            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            ret = newMethod.apply(this, arguments);
            delete this._super;
            return ret;
        };
    }

    /**
     * copied from $.String helper to remove dependency
     *
     * @param {String} name the name of the object to look for
     * @param {Array} [roots] an array of root objects to look for the
     *   name.  If roots is not provided, the window is used.
     * @param {Boolean} [add] true to add missing objects to
     *  the path. false to remove found properties. undefined to
     *  not modify the root object
     * @return {Object} The object.
     */
    function getObject( name, roots, add )
    {
        // the parts of the name we are looking up
        // ['App','Models','Recipe']
        var regs = {
                undHash: /_|-/,
                colons: /::/,
                words: /([A-Z]+)([A-Z][a-z])/g,
                lowUp: /([a-z\d])([A-Z])/g,
                dash: /([a-z\d])([A-Z])/g,
                replacer: /\{([^\}]+)\}/g,
                dot: /\./
            },
            isContainer = function(current){
                var type = typeof current;
                return current && ( type == 'function' || type == 'object' );
            },
            getNext = function(current, nextPart, add){
                return current[nextPart] !== undefined ? current[nextPart] : ( add && (current[nextPart] = {}) );
            },
            parts = name ? name.split(regs.dot) : [],
            length =  parts.length,
            current,
            ret,
            i,
            r = 0,
            type;

        // make sure roots is an array
        roots = $.isArray(roots) ? roots : [roots || window];

        if(length == 0){
            return roots[0];
        }
        // for each root, mark it as current
        while( current = roots[r++] ) {
            // walk current to the 2nd to last object
            // or until there is not a container
            for (i =0; i < length - 1 && isContainer(current); i++ ) {
                current = getNext(current, parts[i], add);
            }
            // if we can get a property from the 2nd to last object
            if( isContainer(current) ) {

                // get (and possibly set) the property
                ret = getNext(current, parts[i], add);

                // if there is a value, we exit
                if( ret !== undefined ) {
                    // if add is false, delete the property
                    if ( add === false ) {
                        delete current[parts[i]];
                    }
                    return ret;

                }
            }
        }
    }

    /**
     * register class in dom namespace
     * @param fullName string
     */
    function registerClassInWindowNamespace(Class, fullName)
    {
        var parts = fullName.split(/\./),
            shortName = parts.pop(),
            current = getObject(parts.join('.'), window, true),
            namespace = current;

            Logger.log('fullName: ' + fullName);

        current[shortName] = Class;

        Logger.log('current: ');
            Logger.log(current);
        Logger.log('curre[shortName]: ');
            Logger.log(current[shortName]);
            Logger.log('shortName '
             + shortName);
    }

    /**
     * @function newInstance
     * Creates a new instance of the class.  This method is useful for creating new instances
     * with arbitrary parameters.
     * @return {class} instance of the class
     */
    function newInstance(instance, arguments)
    {
        ensureInterfaces(instance);

        // call init if there is an init, if setup returned args, use those as the arguments
        if ( instance.init ) {
            instance.init.apply(instance, arguments);
        }

        return instance;
    }

    function ensureInterfaces(object)
    {
        console.log(object);
        if (!object.___interfaces) {
            return;
        }

        for (i in object.___interfaces) {
            if (!(object.___interfaces[i] instanceof $.Interface)) {
                throw new Error('Object should be instance of $.Interface');
            }
        }
    }

    /**
     * @param {String} [fullName]  the classes name (used for classes w/ introspection)
     * @param {Object} [properties]  the new classes prototype functions
     *
     * @return {jQuery.Class} returns the new class
     */
    function createClass(fullName, properties)
    {
        Logger.log('extend was called');

        PropertyHelper.determineProperties(properties);

        var statics = PropertyHelper.statics,
            privates = PropertyHelper.privates,
            publics = PropertyHelper.publics,
            parentClass = PropertyHelper.parentClass,
            parentPrototype = PropertyHelper.parentPrototype,
            name;

        Logger.log('statics');
        Logger.log(statics);

        Logger.log('publics');
        Logger.log(publics);

        Logger.log('privates');
        Logger.log(privates);

         // The dummy class constructor
        function Class() {
            return newInstance(this, arguments);
        }

        // @todo: separate from this function ?
        if (parentClass) {
            var parent = function() {};
            parent.prototype = parentClass.prototype;
            Class.prototype = new parent();

            for (name in parentClass) {
                statics[name] = parentClass[name];
            }
        }

        $.extend(Class.prototype, publics);

        // Copy the properties over onto the new prototype
        inheritProps(publics, parentPrototype, Class['prototype']);

        // copy new static props on class
        Logger.log('inherit static properties');
        inheritProps(statics, parentClass || function() {}, Class);

        registerClassInWindowNamespace(Class, fullName);

        // call the class setup
        Logger.log('call the class setup');
        // var args = Class.setup.apply(Class, concatArgs([_super_class],arguments));

        // call the class init static constructor
        Logger.log('call init class static constructor');
        // if ( Class.init ) {
        //     Class.init.apply(Class, args || concatArgs([_super_class],arguments));
        // }

        // @todo: separate from this function ?
        for (name in Class.prototype) {
            if (publics.hasOwnProperty(name)
                && isPrivateCalledInFunctionRegEx.test(Class.prototype[name])
                && $.isFunction(Class.prototype[name]))
            {
                Class.prototype[name] = (function() {
                    var originalProto = Class.prototype;
                    var original = Class.prototype[name];
                    return function() {
                        originalProto.privates = privates;
                        var value = original.apply(this, arguments);
                        delete originalProto.privates;
                        return value;
                    }
                })();
            }
        }

        /* @Prototype*/
        return Class;
    }

    clss = $.Class = function(fullName, properties) {
        createClass(fullName, properties);
	};

})(jQuery);
<|endoftext|>


<commit_before>var msg = require('../locale');
var utils = require('../utils');

/**
 * @fileoverview Representation of a droplet function/block's tooltip
 */

var DROPLET_BLOCK_I18N_PREFIX = "dropletBlock_";

/**
 * @typedef {Object} parameterInfo
 * @property {String} name
 * @property {?String} description
 */

/**
 * Stores a block's tooltip information and helps render it
 * Grabs much of the tooltip's information from either app-specific locale
 * file (passed in as appMsg) or, if not present, the 'common' locale file,
 * (apps/i18n/common/en_us.json), keyed by the function name.
 *
 * e.g.,
 *
 * "dropletBlock_readRecords_description": "Reads records [...].",
 * "dropletBlock_readRecords_param0": "table",
 * "dropletBlock_readRecords_param1": "searchParams",
 * "dropletBlock_readRecords_param2": "onSuccess",
 *
 * Will result in a tooltip with the contents:
 *
 *    readRecords(table, searchParams, onSuccess)
 *    Reads records [...].
 *    [Read More] (links to `readRecords` doc file)
 *
 * Blocks which have functionNames that should not be user-visible can define
 * their own signature override.
 *
 * e.g.,
 *
 * "dropletBlock_functionParams_n_description": "Define a function with a given parameter",
 * "dropletBlock_functionParams_n_signatureOverride": "Function with a Parameter",
 *
 * Will result in a tooltip with the contents:
 *
 *    Function with a Parameter <-- note, no ()s
 *    Define a function with a given parameter.
 *    [Read More] (links to `functionParams_n` doc file)
 *
 * @constructor
 */
var DropletFunctionTooltip = function (appMsg, definition) {
  /** @type {String} */
  this.functionName = definition.func;

  /** @type {String} */
  var description = appMsg[this.descriptionKey()] || msg[this.descriptionKey()];
  if (description) {
    this.description = description();
  }

  var signatureOverride = appMsg[this.signatureOverrideKey()] ||
                            msg[this.signatureOverrideKey()];
  if (signatureOverride) {
    this.signatureOverride = signatureOverride();
  }

  /** @type {Array.<parameterInfo>} */
  this.parameterInfos = [];

  for (var paramId = 0; ; paramId++) {
    var nameKey = this.parameterNameKey(paramId);
    var paramName = appMsg[nameKey] || msg[nameKey];
    if (!paramName) {
      break;
    }

    var paramInfo = {};
    paramInfo.name = paramName();
    var paramDesc = appMsg[this.parameterDescriptionKey(paramId)] ||
                              msg[this.parameterDescriptionKey(paramId)];
    if (paramDesc) {
      paramInfo.description = paramDesc();
    }
    if (definition.assetTooltip) {
      paramInfo.assetTooltip = definition.assetTooltip[paramId];
    }
    this.parameterInfos.push(paramInfo);
  }
};

/**
 * @returns {string}
 */
DropletFunctionTooltip.prototype.descriptionKey = function () {
  return this.i18nPrefix() + "_description";
};

/**
 * @returns {string}
 */
DropletFunctionTooltip.prototype.signatureOverrideKey = function () {
  return this.i18nPrefix() + "_signatureOverride";
};

/**
 * @param {Number} paramIndex
 * @returns {string}
 */
DropletFunctionTooltip.prototype.parameterNameKey = function (paramIndex) {
  return this.i18nPrefix() + "_param" + paramIndex;
};

/**
 * @param {Number} paramIndex
 * @returns {string}
 */
DropletFunctionTooltip.prototype.parameterDescriptionKey = function (paramIndex) {
  return this.i18nPrefix() + "_param" + paramIndex + '_description';
};

/**
 * @returns {string} i18n file prefix for this function
 */
DropletFunctionTooltip.prototype.i18nPrefix = function () {
  return DROPLET_BLOCK_I18N_PREFIX + this.functionName;
};

/**
 * @returns {string} URL for full doc about this function
 */
DropletFunctionTooltip.prototype.getFullDocumentationURL = function () {
  return '//' + utils.getPegasusHost() + '/applab/docs/' + this.functionName + '?embedded';
};

module.exports = DropletFunctionTooltip;
<commit_msg>Refactor out `appMsg || msg` localization [ci skip]<commit_after>var msg = require('../locale');
var utils = require('../utils');

/**
 * @fileoverview Representation of a droplet function/block's tooltip
 */

var DROPLET_BLOCK_I18N_PREFIX = "dropletBlock_";

/**
 * @typedef {Object} parameterInfo
 * @property {String} name
 * @property {?String} description
 */

/**
 * Stores a block's tooltip information and helps render it
 * Grabs much of the tooltip's information from either app-specific locale
 * file (passed in as appMsg) or, if not present, the 'common' locale file,
 * (apps/i18n/common/en_us.json), keyed by the function name.
 *
 * e.g.,
 *
 * "dropletBlock_readRecords_description": "Reads records [...].",
 * "dropletBlock_readRecords_param0": "table",
 * "dropletBlock_readRecords_param1": "searchParams",
 * "dropletBlock_readRecords_param2": "onSuccess",
 *
 * Will result in a tooltip with the contents:
 *
 *    readRecords(table, searchParams, onSuccess)
 *    Reads records [...].
 *    [Read More] (links to `readRecords` doc file)
 *
 * Blocks which have functionNames that should not be user-visible can define
 * their own signature override.
 *
 * e.g.,
 *
 * "dropletBlock_functionParams_n_description": "Define a function with a given parameter",
 * "dropletBlock_functionParams_n_signatureOverride": "Function with a Parameter",
 *
 * Will result in a tooltip with the contents:
 *
 *    Function with a Parameter <-- note, no ()s
 *    Define a function with a given parameter.
 *    [Read More] (links to `functionParams_n` doc file)
 *
 * @constructor
 */
var DropletFunctionTooltip = function (appMsg, definition) {
  this.appMsg = appMsg;

  /** @type {String} */
  this.functionName = definition.func;

  /** @type {String} */
  var description = getLocalization(this.descriptionKey());
  if (description) {
    this.description = description();
  }

  var signatureOverride = getLocalization(this.signatureOverrideKey());
  if (signatureOverride) {
    this.signatureOverride = signatureOverride();
  }

  /** @type {Array.<parameterInfo>} */
  this.parameterInfos = [];

  for (var paramId = 0; ; paramId++) {
    var paramName = getLocalization(this.parameterNameKey(paramId));
    if (!paramName) {
      break;
    }

    var paramInfo = {};
    paramInfo.name = paramName();
    var paramDesc = getLocalization(this.parameterDescriptionKey(paramId));
    if (paramDesc) {
      paramInfo.description = paramDesc();
    }
    if (definition.assetTooltip) {
      paramInfo.assetTooltip = definition.assetTooltip[paramId];
    }
    this.parameterInfos.push(paramInfo);
  }
};

function getLocalization(key) {
  return this.appMsg[key] || msg[key];
}

/**
 * @returns {string}
 */
DropletFunctionTooltip.prototype.descriptionKey = function () {
  return this.i18nPrefix() + "_description";
};

/**
 * @returns {string}
 */
DropletFunctionTooltip.prototype.signatureOverrideKey = function () {
  return this.i18nPrefix() + "_signatureOverride";
};

/**
 * @param {Number} paramIndex
 * @returns {string}
 */
DropletFunctionTooltip.prototype.parameterNameKey = function (paramIndex) {
  return this.i18nPrefix() + "_param" + paramIndex;
};

/**
 * @param {Number} paramIndex
 * @returns {string}
 */
DropletFunctionTooltip.prototype.parameterDescriptionKey = function (paramIndex) {
  return this.i18nPrefix() + "_param" + paramIndex + '_description';
};

/**
 * @returns {string} i18n file prefix for this function
 */
DropletFunctionTooltip.prototype.i18nPrefix = function () {
  return DROPLET_BLOCK_I18N_PREFIX + this.functionName;
};

/**
 * @returns {string} URL for full doc about this function
 */
DropletFunctionTooltip.prototype.getFullDocumentationURL = function () {
  return '//' + utils.getPegasusHost() + '/applab/docs/' + this.functionName + '?embedded';
};

module.exports = DropletFunctionTooltip;
<|endoftext|>