<commit_before>"use strict";

define(['logManager',
    'clientUtil'], function (logManager,
    util) {

    var PropertyEditorWidgetController;

    PropertyEditorWidgetController = function (myClient, myView) {
        this._client = myClient;
        this._widget = myView;

        this._initEventHandlers();

        this._logger = logManager.create("PropertyEditorWidgetController");
        this._logger.debug("Created");
    };

    PropertyEditorWidgetController.prototype._initEventHandlers = function () {
        var self = this;

        if (this._client) {
            this._client.addEventListener(this._client.events.PROPERTY_EDITOR_SELECTION_CHANGED, function (__project, idList) {
                self._selectedObjectsChanged(idList);
            });
        }

        this._widget.propertyGrid.onFinishChange(function (args) {
            self._onPropertyChanged(args);
        });
    };

    PropertyEditorWidgetController.prototype._selectedObjectsChanged = function (idList) {
        var patterns = {},
            i;

        this._idList = idList;

        if (this._territoryId) {
            this._client.removeUI(this._territoryId);
        }

        if (idList.length > 0) {
            i = idList.length;
            while (i--) {
                patterns[idList[i]] = { "children": 0 };
            }

            this._territoryId = this._client.addUI(this, true);
            this._client.updateTerritory(this._territoryId, patterns);
        }
    };

    PropertyEditorWidgetController.prototype.onOneEvent = function (/*events*/) {
        this._refreshPropertyList();
    };

    PropertyEditorWidgetController.prototype._refreshPropertyList = function () {
        var propList = this._getCommonPropertiesForSelection(this._idList);
        this._widget.propertyGrid.setPropertyList(propList);
    };

    PropertyEditorWidgetController.prototype._getCommonPropertiesForSelection = function (selectedObjIDs) {
        var propList = {},
            selectionLength = selectedObjIDs.length,
            cNode,
            i,
            flattenedAttrs,
            flattenedRegs,
            commonAttrs = {},
            commonRegs = {},
            noCommonValueColor = "#f89406",
            _getNodePropertyValues, //fn
            _filterCommon, //fn
            _addItemsToResultList; //fn

        _getNodePropertyValues = function (node, propNameFn, propValueFn) {
            var result =  {},
                attrNames = node[propNameFn](),
                len = attrNames.length;

            while (--len >= 0) {
                result[attrNames[len]] = node[propValueFn](attrNames[len]);
            }

            return util.flattenObject(result);
        };

        _filterCommon = function (resultList, otherList, initPhase) {
            var it;

            if (initPhase === true) {
                for (it in otherList) {
                    if (otherList.hasOwnProperty(it)) {
                        resultList[it] = { "value": otherList[it],
                            "valueType": typeof otherList[it],
                            "isCommon": true };
                    }
                }
            } else {
                for (it in resultList) {
                    if (resultList.hasOwnProperty(it)) {
                        if (otherList.hasOwnProperty(it)) {
                            if (resultList[it].isCommon) {
                                resultList[it].isCommon = resultList[it].value === otherList[it];
                            }
                        } else {
                            delete resultList[it];
                        }
                    }
                }
            }
        };

        if (selectionLength > 0) {
            //get all attributes
            //get all registry elements
            i = selectionLength;
            while (--i >= 0) {
                cNode = this._client.getNode(selectedObjIDs[i]);

                if (cNode) {
                    flattenedAttrs = _getNodePropertyValues(cNode, "getAttributeNames", "getAttribute");

                    _filterCommon(commonAttrs, flattenedAttrs, i === selectionLength - 1);

                    flattenedRegs = _getNodePropertyValues(cNode, "getRegistryNames", "getRegistry");

                    _filterCommon(commonRegs, flattenedRegs, i === selectionLength - 1);
                }
            }

            _addItemsToResultList = function (srcList, prefix, dstList) {
                var i,
                    extKey,
                    keyParts;

                if (prefix !== "") {
                    prefix += ".";
                }

                for (i in srcList) {
                    if (srcList.hasOwnProperty(i)) {
                        extKey = prefix + i;
                        keyParts = i.split(".");
                        dstList[extKey] = { "name": keyParts[keyParts.length - 1],
                            "value": srcList[i].value,
                            "valueType": srcList[i].valueType};

                        if (i === "position.x" || i === "position.y") {
                            dstList[extKey].minValue = 0;
                            dstList[extKey].stepValue = 10;
                        }

                        if (srcList[i].readOnly === false || srcList[i].readOnly === true) {
                            dstList[extKey].readOnly = srcList[i].readOnly;
                        }

                        if (srcList[i].isCommon === false) {
                            dstList[extKey].value = "";
                            dstList[extKey].options = {"textColor": noCommonValueColor};
                        }

                        if (extKey.indexOf(".x") > -1) {
                            //let's say its inherited, make it italic
                            dstList[extKey].options = dstList[extKey].options || {};
                            dstList[extKey].options.textItalic = true;
                            dstList[extKey].options.textBold = true;
                        }
                    }
                }
            };

            if (selectedObjIDs.length === 1) {
                _addItemsToResultList({"ID": { "value": selectedObjIDs[0],
                    "valueType": typeof selectedObjIDs[0],
                    "isCommon": true,
                    "readOnly": true}}, "", propList);
            }

            _addItemsToResultList(commonAttrs, "Attributes", propList);
            _addItemsToResultList(commonRegs, "Registry", propList);
        }

        return propList;
    };

    PropertyEditorWidgetController.prototype._onPropertyChanged = function (args) {
        var selectedObjIDs = this._idList,
            i = selectedObjIDs.length,
            keyArr,
            setterFn,
            getterFn,
            propObject,
            propPointer,
            gmeID,
            path;

        this._client.startTransaction();
        while (--i >= 0) {
            gmeID = selectedObjIDs[i];

            keyArr = args.id.split(".");
            if (keyArr[0] === "Attributes") {
                setterFn = "setAttributes";
                getterFn = "getAttribute";
            } else {
                setterFn = "setRegistry";
                getterFn = "getRegistry";
            }

            keyArr.splice(0, 1);

            //get property object from node
            path = keyArr[0];
            propObject = this._client.getNode(gmeID)[getterFn](path);

            //get root object
            propPointer = propObject;
            keyArr.splice(0, 1);

            if(keyArr.length < 1){
                //simple value so just set it
                propObject = args.newValue;
            } else {
                //dig down to leaf property
                while (keyArr.length > 1) {
                    propPointer = propPointer[keyArr[0]];
                    keyArr.splice(0, 1);
                }

                //set value
                propPointer[keyArr[0]] = args.newValue;
            }

            //save back object
            this._client[setterFn](gmeID, path, propObject);
        }
        this._client.completeTransaction();
    };

    return PropertyEditorWidgetController;
});<commit_msg>provide 'text' for propertyDesc<commit_after>"use strict";

define(['logManager',
    'clientUtil'], function (logManager,
    util) {

    var PropertyEditorWidgetController;

    PropertyEditorWidgetController = function (myClient, myView) {
        this._client = myClient;
        this._widget = myView;

        this._initEventHandlers();

        this._logger = logManager.create("PropertyEditorWidgetController");
        this._logger.debug("Created");
    };

    PropertyEditorWidgetController.prototype._initEventHandlers = function () {
        var self = this;

        if (this._client) {
            this._client.addEventListener(this._client.events.PROPERTY_EDITOR_SELECTION_CHANGED, function (__project, idList) {
                self._selectedObjectsChanged(idList);
            });
        }

        this._widget.propertyGrid.onFinishChange(function (args) {
            self._onPropertyChanged(args);
        });
    };

    PropertyEditorWidgetController.prototype._selectedObjectsChanged = function (idList) {
        var patterns = {},
            i;

        this._idList = idList;

        if (this._territoryId) {
            this._client.removeUI(this._territoryId);
        }

        if (idList.length > 0) {
            i = idList.length;
            while (i--) {
                patterns[idList[i]] = { "children": 0 };
            }

            this._territoryId = this._client.addUI(this, true);
            this._client.updateTerritory(this._territoryId, patterns);
        }
    };

    PropertyEditorWidgetController.prototype.onOneEvent = function (/*events*/) {
        this._refreshPropertyList();
    };

    PropertyEditorWidgetController.prototype._refreshPropertyList = function () {
        var propList = this._getCommonPropertiesForSelection(this._idList);
        this._widget.propertyGrid.setPropertyList(propList);
    };

    PropertyEditorWidgetController.prototype._getCommonPropertiesForSelection = function (selectedObjIDs) {
        var propList = {},
            selectionLength = selectedObjIDs.length,
            cNode,
            i,
            flattenedAttrs,
            flattenedRegs,
            commonAttrs = {},
            commonRegs = {},
            noCommonValueColor = "#f89406",
            _getNodePropertyValues, //fn
            _filterCommon, //fn
            _addItemsToResultList; //fn

        _getNodePropertyValues = function (node, propNameFn, propValueFn) {
            var result =  {},
                attrNames = node[propNameFn](),
                len = attrNames.length;

            while (--len >= 0) {
                result[attrNames[len]] = node[propValueFn](attrNames[len]);
            }

            return util.flattenObject(result);
        };

        _filterCommon = function (resultList, otherList, initPhase) {
            var it;

            if (initPhase === true) {
                for (it in otherList) {
                    if (otherList.hasOwnProperty(it)) {
                        resultList[it] = { "value": otherList[it],
                            "valueType": typeof otherList[it],
                            "isCommon": true };
                    }
                }
            } else {
                for (it in resultList) {
                    if (resultList.hasOwnProperty(it)) {
                        if (otherList.hasOwnProperty(it)) {
                            if (resultList[it].isCommon) {
                                resultList[it].isCommon = resultList[it].value === otherList[it];
                            }
                        } else {
                            delete resultList[it];
                        }
                    }
                }
            }
        };

        if (selectionLength > 0) {
            //get all attributes
            //get all registry elements
            i = selectionLength;
            while (--i >= 0) {
                cNode = this._client.getNode(selectedObjIDs[i]);

                if (cNode) {
                    flattenedAttrs = _getNodePropertyValues(cNode, "getAttributeNames", "getAttribute");

                    _filterCommon(commonAttrs, flattenedAttrs, i === selectionLength - 1);

                    flattenedRegs = _getNodePropertyValues(cNode, "getRegistryNames", "getRegistry");

                    _filterCommon(commonRegs, flattenedRegs, i === selectionLength - 1);
                }
            }

            _addItemsToResultList = function (srcList, prefix, dstList) {
                var i,
                    extKey,
                    keyParts;

                if (prefix !== "") {
                    prefix += ".";
                }

                for (i in srcList) {
                    if (srcList.hasOwnProperty(i)) {
                        extKey = prefix + i;
                        keyParts = i.split(".");
                        dstList[extKey] = { "name": keyParts[keyParts.length - 1],
                            "value": srcList[i].value,
                            "valueType": srcList[i].valueType};

                        if (i === "position.x" || i === "position.y") {
                            dstList[extKey].minValue = 0;
                            dstList[extKey].stepValue = 10;
                        }

                        if (srcList[i].readOnly === false || srcList[i].readOnly === true) {
                            dstList[extKey].readOnly = srcList[i].readOnly;
                        }

                        if (srcList[i].isCommon === false) {
                            dstList[extKey].value = "";
                            dstList[extKey].options = {"textColor": noCommonValueColor};
                        }

                        if (extKey.indexOf(".x") > -1) {
                            //let's say its inherited, make it italic
                            dstList[extKey].options = dstList[extKey].options || {};
                            dstList[extKey].options.textItalic = true;
                            dstList[extKey].options.textBold = true;
                        }
                    }
                }
            };

            if (selectedObjIDs.length === 1) {
                propList["ID"] = { "name": 'ID',
                    "value": selectedObjIDs[0],
                    "valueType": typeof selectedObjIDs[0],
                    "isCommon": true,
                    "readOnly": true};
            }

            propList["Attributes"] = { "name": 'Attributes',
                "text": "Attributes",
                "value": undefined};

            propList["Registry"] = { "name": 'Registry',
                "text": "Registry",
                "value": undefined};

            _addItemsToResultList(commonAttrs, "Attributes", propList);
            _addItemsToResultList(commonRegs, "Registry", propList);
        }

        return propList;
    };

    PropertyEditorWidgetController.prototype._onPropertyChanged = function (args) {
        var selectedObjIDs = this._idList,
            i = selectedObjIDs.length,
            keyArr,
            setterFn,
            getterFn,
            propObject,
            propPointer,
            gmeID,
            path;

        this._client.startTransaction();
        while (--i >= 0) {
            gmeID = selectedObjIDs[i];

            keyArr = args.id.split(".");
            if (keyArr[0] === "Attributes") {
                setterFn = "setAttributes";
                getterFn = "getAttribute";
            } else {
                setterFn = "setRegistry";
                getterFn = "getRegistry";
            }

            keyArr.splice(0, 1);

            //get property object from node
            path = keyArr[0];
            propObject = this._client.getNode(gmeID)[getterFn](path);

            //get root object
            propPointer = propObject;
            keyArr.splice(0, 1);

            if(keyArr.length < 1){
                //simple value so just set it
                propObject = args.newValue;
            } else {
                //dig down to leaf property
                while (keyArr.length > 1) {
                    propPointer = propPointer[keyArr[0]];
                    keyArr.splice(0, 1);
                }

                //set value
                propPointer[keyArr[0]] = args.newValue;
            }

            //save back object
            this._client[setterFn](gmeID, path, propObject);
        }
        this._client.completeTransaction();
    };

    return PropertyEditorWidgetController;
});<|endoftext|>


<commit_before>import angular from "angular";
import { attach, delay } from "../../../utils.js";
import { DomCache } from "../../../cstm-ng-utils.js";

import "style/_datetimepicker.scss";

const serviceDependencies = ["$scope", "$element"];
function genComponentConf() {
  let template = `

         <svg class="datetimep__input__icon clickable"
            style="--local-primary:var(--won-primary-color);"
            ng-if="self.showResetButton"
            ng-click="self.resetDatetime()">
            <use xlink:href="#ico36_close" href="#ico36_close"></use>
          </svg>
          <input
              type="datetime-local"
              class="datetimep__input__inner"
              placeholder="{{self.detail.placeholder}}"
              ng-model="self.value"
              ng-change="::self.updateDatetime()"
              ng-class="{'datetimep__input__inner--withreset' : self.showResetButton}"/>

    `;

  class Controller {
    constructor() {
      attach(this, serviceDependencies, arguments);
      this.domCache = new DomCache(this.$element);

      window.datetimep4dbg = this;

      this.addedDatetime = this.initialValue;
      this.showResetButton = false;

      delay(0).then(() => this.showInitialDatetime());
    }

    /**
     * Checks validity and uses callback method
     */
    update(datetime) {
      const xsdDatetime = datetime + ":00"; // seconds need to be specified
      if (datetime) {
        this.onUpdate({ value: xsdDatetime });
      } else {
        this.onUpdate({ value: undefined });
      }
    }

    showInitialDatetime() {
      this.addedDatetime = this.initialValue;

      if (this.initialValue && this.initialValue.trim().length > 0) {
        this.textfield().value = this.initialValue.trim();
        this.showResetButton = true;
      }

      this.$scope.$apply();
    }

    updateDatetime() {
      const text = this.textfield().value;

      if (text && text.trim().length > 0) {
        this.addedDatetime = text.trim();
        this.update(this.addedDatetime);
        this.showResetButton = true;
      } else {
        this.resetDatetime();
      }
    }

    resetDatetime() {
      this.addedDatetime = undefined;
      this.textfield().value = "";
      this.update(undefined);
      this.showResetButton = false;
    }

    // textfieldNg() {
    //   return this.domCache.ng(".datetimep__input__inner");
    // }

    // textfield() {
    //   return this.domCache.dom(".datetimep__input__inner");
    // } // TODO: why is this done differently for number than for any other picker?

    textfieldNg() {
      return angular.element(this.textfield());
    }
    textfield() {
      if (!this._datetimeInput) {
        this._datetimeInput = this.$element[0].querySelector(
          ".datetimep__input__inner"
        );
      }
      return this._datetimeInput;
    }
  }
  Controller.$inject = serviceDependencies;

  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl
    scope: {
      onUpdate: "&",
      initialValue: "=",
      detail: "=",
    },
    template: template,
  };
}

export default angular
  .module("won.owner.components.datetimePicker", [])
  .directive("wonDatetimePicker", genComponentConf).name;
<commit_msg>Made datetime-picker timezone-aware. It picks with the local timezone in mind.<commit_after>import angular from "angular";
import { attach, delay } from "../../../utils.js";
import { DomCache } from "../../../cstm-ng-utils.js";

import "style/_datetimepicker.scss";

const serviceDependencies = ["$scope", "$element"];
function genComponentConf() {
  let template = `

         <svg class="datetimep__input__icon clickable"
            style="--local-primary:var(--won-primary-color);"
            ng-if="self.showResetButton"
            ng-click="self.resetDatetime()">
            <use xlink:href="#ico36_close" href="#ico36_close"></use>
          </svg>
          <input
              type="datetime-local"
              class="datetimep__input__inner"
              placeholder="{{self.detail.placeholder}}"
              ng-model="self.value"
              ng-change="::self.updateDatetime()"
              ng-class="{'datetimep__input__inner--withreset' : self.showResetButton}"/>

    `;

  class Controller {
    constructor() {
      attach(this, serviceDependencies, arguments);
      this.domCache = new DomCache(this.$element);

      window.datetimep4dbg = this;

      this.addedDatetime = this.initialValue;
      this.showResetButton = false;

      delay(0).then(() => this.showInitialDatetime());
    }

    /**
     * Checks validity and uses callback method
     */
    update(datetime) {
      const d = new Date(datetime);
      if (datetime) {
        // this.onUpdate({ value: d }); // TODO return raw date
        this.onUpdate({ value: d.toISOString() });
      } else {
        this.onUpdate({ value: undefined });
      }
    }

    showInitialDatetime() {
      this.addedDatetime = this.initialValue;

      if (this.initialValue && this.initialValue.trim().length > 0) {
        this.textfield().value = this.initialValue.trim();
        this.showResetButton = true;
      }

      this.$scope.$apply();
    }

    updateDatetime() {
      const text = this.textfield().value;

      if (text && text.trim().length > 0) {
        this.addedDatetime = text.trim();
        this.update(this.addedDatetime);
        this.showResetButton = true;
      } else {
        this.resetDatetime();
      }
    }

    resetDatetime() {
      this.addedDatetime = undefined;
      this.textfield().value = "";
      this.update(undefined);
      this.showResetButton = false;
    }

    // textfieldNg() {
    //   return this.domCache.ng(".datetimep__input__inner");
    // }

    // textfield() {
    //   return this.domCache.dom(".datetimep__input__inner");
    // } // TODO: why is this done differently for number than for any other picker?

    textfieldNg() {
      return angular.element(this.textfield());
    }
    textfield() {
      if (!this._datetimeInput) {
        this._datetimeInput = this.$element[0].querySelector(
          ".datetimep__input__inner"
        );
      }
      return this._datetimeInput;
    }
  }
  Controller.$inject = serviceDependencies;

  return {
    restrict: "E",
    controller: Controller,
    controllerAs: "self",
    bindToController: true, //scope-bindings -> ctrl
    scope: {
      onUpdate: "&",
      initialValue: "=",
      detail: "=",
    },
    template: template,
  };
}

export default angular
  .module("won.owner.components.datetimePicker", [])
  .directive("wonDatetimePicker", genComponentConf).name;
<|endoftext|>


<commit_before>module.exports = {
}
<commit_msg>remove postcss.config.js<commit_after><|endoftext|>


<commit_before>/**
 * Copyright (c) 2013-2017 Memba Sarl. All rights reserved.
 * Sources at https://github.com/Memba
 */

/* jshint node: true */

'use strict';

var util = require('util');
var logger = require('./lib/logger');
var closingInProgress = false;

/**
 * Handle uncaught exceptions
 * @see http://stackoverflow.com/questions/7310521/node-js-best-practice-exception-handling
 */
process.on('uncaughtException', function (exception) {

    closingInProgress = true;

    logger.critical({
        // message = exception.message
        module: 'server',
        method: 'process.onuncaughtException',
        error: exception
    });

    if (typeof server !== 'undefined') {
        // stop taking new requests
        server.close();
        // make sure we close down within 5 seconds
        // which should give enough time for any pending request to complete
        var killtimer = setTimeout(function () {
            process.exit(1);
        }, 5 * 1000);
        // see https://nodejs.org/api/domain.html
        killtimer.unref();
    } else {
        process.exit(1);
    }

});

/**
 * Ensure we exit properly when interrupted by a kill
 */
process.on('SIGTERM', function () {
    // TODO pass exit code 0
    throw new Error('Process killed.');
});

/**
 * Ensure we exit properly when interrupting by Ctrl+C
 */
process.on('SIGINT', function () {
    // TODO pass exit code 0
    throw new Error('Process interrupted by Ctrl+C.');
});

/**
 * This event handler is called after process.exit
 * Therefore it closes the mongoose connection before exiting
 * either from an uncaughtException or from Ctrl+C
 */
process.on('exit', function (code) {
    // We use a try/catch block here because we might have reached here from an uncaughtException
    try {
        logger.warn({
            message: 'exiting with code ' + code,
            module: 'server',
            method: 'process.onexit'
        });
    } catch (ex) {
        // We use console.log because logger might not be available
        console.error(ex);
    }
});

var express = require('express');
var app = express();
var compression = require('compression');
var cors = require('cors');
var helmet = require('helmet');
var http = require('http');
var i18n = require('i18n');
var path = require('path');
var config = require('./config');
var pkg = require('../package.json');
var server;

logger.info({
    message: 'nconf environment is ' + config.environment,
    module: 'server'
});

config.load(function (error/*, store*/) {

    if (error instanceof Error) {
        throw error;
    }

    // set version (to invalidate cache when loading new versions of scripts)
    config.set('application:version', pkg.version);

    // handle requests while closing
    app.use(function (req, res, next) {
        if (closingInProgress) {
            res.setHeader('Connection', 'close');
            res.status(503).send('A webapp server is in the process of restarting');
        } else {
            return next();
        }
    });

    // Secure expressJS with helmet from https://github.com/helmetjs/helmet
    // app.disable('x-powered-by');
    app.use(helmet());

    // @see https://helmetjs.github.io/docs/csp/
    // @see https://content-security-policy.com/
    var cdnRoot = config.get('uris:cdn:root');
    var connectSrc = [
            '\'self\'',
            cdnRoot,                                // Required to load index.json on CDN
            'https://s3.amazonaws.com',             // Required to upload images to Amazon S3
            'https://js.leadin.com',                // Hubspot
            'https://forms.hubspot.com'             // Hubspot
            // 'https://api.getsidekick.com'
        ];
    if (typeof config.get('uris:rapi:root') === 'string' && config.get('uris:rapi:root') !== config.get('uris:webapp:root')) {
        // Note: config.get('uris:webapp:root') is covered by 'self'
        connectSrc.push(config.get('uris:rapi:root'));
    }
    app.use(helmet.contentSecurityPolicy({
        directives: {
            defaultSrc: [
                '\'self\'',
                'blob:'                             // This is for web workers as workerSrc is not supported by helmet.contentSecurityPolicy
            ],
            connectSrc: connectSrc,
            fontSrc: [
                '\'self\'',
                'data:',
                cdnRoot,
                'https://fonts.gstatic.com'         // Google fonts
            ],
            frameSrc: [
                'https://accounts.google.com',      // Google classroom button
                'https://www.gstatic.com'           // Google classroom button
            ],
            imgSrc: [
                'data:',
                '*'
            ],
            mediaSrc: [
                '*'
            ],
            scriptSrc: [
                '\'self\'',
                '\'unsafe-eval\'',
                '\'unsafe-inline\'',
                cdnRoot,
                'https://code.jquery.com',
                'https://cdnjs.cloudflare.com',     // Promise polyfill for webpack
                'https://www.googletagmanager.com', // GTM
                'https://apis.google.com',          // Google classroom button
                'www.google-analytics.com',         // Google Analytics (Loaded via http on http://localhost)
                'js.hs-analytics.net',              // Hubspot (Loaded via http on http://localhost)
                'https://js.hscollectedforms.net',  // Hubspot
                'https://js.hsleadflows.net',       // Hubspot
                'https://js.hsleadflowsqa.net',     // Hubspot
                'https://js.hs-scripts.com',        // Hubspot
                'https://js.leadin.com'             // Hubspot
            ],
            styleSrc: [
                '\'self\'',
                '\'unsafe-inline\'',
                cdnRoot,
                'https://fonts.googleapis.com'      // Google fonts
            ],
            // sandbox: ['allow-forms', 'allow-scripts'],
            // reportUri: '/report-violation',
            objectSrc: [
                '\'none\''
            ]
        },
        browserSniff: false
    }));

    // i18n
    i18n.configure({
        locales: config.get('locales'), // ['en', 'fr'],
        directory: path.join(__dirname, 'locales'),
        objectNotation: true, // Use hierarchies in locales.json files
        updateFiles: false,
        syncFiles: false
    });
    // Use __() in templates
    app.use(i18n.init);

    // Template engine
    app.engine('.ejs', require('ejs').__express);
    // Optional since express defaults to CWD/views
    app.set('views', path.join(__dirname, 'views'));
    // Without this one would need to supply the extension to res.render(), ex: res.render('users.html').
    app.set('view engine', 'ejs');

    // compression (before static files otherwise they are not compressed)
    app.use(compression({ filter: function (req, res) {
            if (req.headers['x-no-compression']) {
                // don't compress responses with this request header
                return false;
            }
            // fallback to standard filter function
            return compression.filter(req, res);
        }
    }));

    // Static files (before routing)
    // Cache-Control maxAge requires a string in MS format - see https://www.npmjs.com/package/ms
    app.use(
        util.format(config.get('uris:webapp:public'), ''),
        cors({ origin: config.get('uris:webapp:root') }),
        express.static(path.join(__dirname, 'public'), { maxAge: '1d' })
    );

    // Routing
    var router = require('./routes');
    app.use(router);

    // Configure expressJS and launch server
    var port = process.env.PORT || config.get('express:port');
    app.set('port', port);
    app.set('trust proxy', 'uniquelocal');
    server = app.listen(port);

    // Logging
    logger.info({
        message: 'expressJS server listening on port ' + port,
        module: 'server',
        method: 'config.load'
    });

});

// Export app for unit tests
// It is fine, because app does not accept requests
// until it has been fully configured here above
module.exports = app;
<commit_msg>Added https://api.usemessages.com to CSP<commit_after>/**
 * Copyright (c) 2013-2017 Memba Sarl. All rights reserved.
 * Sources at https://github.com/Memba
 */

/* jshint node: true */

'use strict';

var util = require('util');
var logger = require('./lib/logger');
var closingInProgress = false;

/**
 * Handle uncaught exceptions
 * @see http://stackoverflow.com/questions/7310521/node-js-best-practice-exception-handling
 */
process.on('uncaughtException', function (exception) {

    closingInProgress = true;

    logger.critical({
        // message = exception.message
        module: 'server',
        method: 'process.onuncaughtException',
        error: exception
    });

    if (typeof server !== 'undefined') {
        // stop taking new requests
        server.close();
        // make sure we close down within 5 seconds
        // which should give enough time for any pending request to complete
        var killtimer = setTimeout(function () {
            process.exit(1);
        }, 5 * 1000);
        // see https://nodejs.org/api/domain.html
        killtimer.unref();
    } else {
        process.exit(1);
    }

});

/**
 * Ensure we exit properly when interrupted by a kill
 */
process.on('SIGTERM', function () {
    // TODO pass exit code 0
    throw new Error('Process killed.');
});

/**
 * Ensure we exit properly when interrupting by Ctrl+C
 */
process.on('SIGINT', function () {
    // TODO pass exit code 0
    throw new Error('Process interrupted by Ctrl+C.');
});

/**
 * This event handler is called after process.exit
 * Therefore it closes the mongoose connection before exiting
 * either from an uncaughtException or from Ctrl+C
 */
process.on('exit', function (code) {
    // We use a try/catch block here because we might have reached here from an uncaughtException
    try {
        logger.warn({
            message: 'exiting with code ' + code,
            module: 'server',
            method: 'process.onexit'
        });
    } catch (ex) {
        // We use console.log because logger might not be available
        console.error(ex);
    }
});

var express = require('express');
var app = express();
var compression = require('compression');
var cors = require('cors');
var helmet = require('helmet');
var http = require('http');
var i18n = require('i18n');
var path = require('path');
var config = require('./config');
var pkg = require('../package.json');
var server;

logger.info({
    message: 'nconf environment is ' + config.environment,
    module: 'server'
});

config.load(function (error/*, store*/) {

    if (error instanceof Error) {
        throw error;
    }

    // set version (to invalidate cache when loading new versions of scripts)
    config.set('application:version', pkg.version);

    // handle requests while closing
    app.use(function (req, res, next) {
        if (closingInProgress) {
            res.setHeader('Connection', 'close');
            res.status(503).send('A webapp server is in the process of restarting');
        } else {
            return next();
        }
    });

    // Secure expressJS with helmet from https://github.com/helmetjs/helmet
    // app.disable('x-powered-by');
    app.use(helmet());

    // @see https://helmetjs.github.io/docs/csp/
    // @see https://content-security-policy.com/
    var cdnRoot = config.get('uris:cdn:root');
    var connectSrc = [
            '\'self\'',
            cdnRoot,                                // Required to load index.json on CDN
            'https://s3.amazonaws.com',             // Required to upload images to Amazon S3
            'https://js.leadin.com',                // Hubspot
            'https://forms.hubspot.com'             // Hubspot
            // 'https://api.getsidekick.com'
        ];
    if (typeof config.get('uris:rapi:root') === 'string' && config.get('uris:rapi:root') !== config.get('uris:webapp:root')) {
        // Note: config.get('uris:webapp:root') is covered by 'self'
        connectSrc.push(config.get('uris:rapi:root'));
    }
    app.use(helmet.contentSecurityPolicy({
        directives: {
            defaultSrc: [
                '\'self\'',
                'blob:'                             // This is for web workers as workerSrc is not supported by helmet.contentSecurityPolicy
            ],
            connectSrc: connectSrc,
            fontSrc: [
                '\'self\'',
                'data:',
                cdnRoot,
                'https://fonts.gstatic.com'         // Google fonts
            ],
            frameSrc: [
                'https://accounts.google.com',      // Google classroom button
                'https://www.gstatic.com'           // Google classroom button
            ],
            imgSrc: [
                'data:',
                '*'
            ],
            mediaSrc: [
                '*'
            ],
            scriptSrc: [
                '\'self\'',
                '\'unsafe-eval\'',
                '\'unsafe-inline\'',
                cdnRoot,
                'https://code.jquery.com',
                'https://cdnjs.cloudflare.com',     // Promise polyfill for webpack
                'https://www.googletagmanager.com', // GTM
                'https://apis.google.com',          // Google classroom button
                'www.google-analytics.com',         // Google Analytics (Loaded via http on http://localhost)
                'js.hs-analytics.net',              // Hubspot (Loaded via http on http://localhost)
                'https://api.usemessages.com',      // Hubspot
                'https://js.hscollectedforms.net',  // Hubspot
                'https://js.hsleadflows.net',       // Hubspot
                'https://js.hsleadflowsqa.net',     // Hubspot
                'https://js.hs-scripts.com',        // Hubspot
                'https://js.leadin.com'             // Hubspot
            ],
            styleSrc: [
                '\'self\'',
                '\'unsafe-inline\'',
                cdnRoot,
                'https://fonts.googleapis.com'      // Google fonts
            ],
            // sandbox: ['allow-forms', 'allow-scripts'],
            // reportUri: '/report-violation',
            objectSrc: [
                '\'none\''
            ]
        },
        browserSniff: false
    }));

    // i18n
    i18n.configure({
        locales: config.get('locales'), // ['en', 'fr'],
        directory: path.join(__dirname, 'locales'),
        objectNotation: true, // Use hierarchies in locales.json files
        updateFiles: false,
        syncFiles: false
    });
    // Use __() in templates
    app.use(i18n.init);

    // Template engine
    app.engine('.ejs', require('ejs').__express);
    // Optional since express defaults to CWD/views
    app.set('views', path.join(__dirname, 'views'));
    // Without this one would need to supply the extension to res.render(), ex: res.render('users.html').
    app.set('view engine', 'ejs');

    // compression (before static files otherwise they are not compressed)
    app.use(compression({ filter: function (req, res) {
            if (req.headers['x-no-compression']) {
                // don't compress responses with this request header
                return false;
            }
            // fallback to standard filter function
            return compression.filter(req, res);
        }
    }));

    // Static files (before routing)
    // Cache-Control maxAge requires a string in MS format - see https://www.npmjs.com/package/ms
    app.use(
        util.format(config.get('uris:webapp:public'), ''),
        cors({ origin: config.get('uris:webapp:root') }),
        express.static(path.join(__dirname, 'public'), { maxAge: '1d' })
    );

    // Routing
    var router = require('./routes');
    app.use(router);

    // Configure expressJS and launch server
    var port = process.env.PORT || config.get('express:port');
    app.set('port', port);
    app.set('trust proxy', 'uniquelocal');
    server = app.listen(port);

    // Logging
    logger.info({
        message: 'expressJS server listening on port ' + port,
        module: 'server',
        method: 'config.load'
    });

});

// Export app for unit tests
// It is fine, because app does not accept requests
// until it has been fully configured here above
module.exports = app;
<|endoftext|>


<commit_before>angular.module('materialscommons').directive('processSettings', processSettingsDirective);
function processSettingsDirective() {
    return {
        restrict: 'E',
        scope: {
            settings: '=',
            taskId: '=',
            templateId: '=',
            attribute: '='
        },
        controller: ProcessSettingsDirectiveController,
        controllerAs: 'ctrl',
        bindToController: true,
        templateUrl: 'app/project/processes/process/create/components/process-settings.html'
    }
}

/*@ngInject*/
function ProcessSettingsDirectiveController(experimentsService, toast, $stateParams) {
    var ctrl = this;
    ctrl.datePickerOptions = {
        formatYear: 'yy',
        startingDay: 1
    };
    ctrl.openDatePicker = openDatePicker;

    // Set default value on selections to first choice.
    ctrl.settings.forEach(function(setting) {
        // selection type
        if (setting.property._type === 'selection') {
            setting.property.value = setting.property.choices[0];
        } else if (setting.property._type === 'date') {
            setting.property.opened = false;
        }

        // unit selections
        if (setting.property.units.length !== 0) {
            setting.property.unit = setting.property.units[0];
        }
    });

    ctrl.updateSettingProperty = (property) => {
        if (!property.value) {
            return;
        }

        property.setup_attribute = ctrl.attribute;
        let propertyArgs = {
            template_id: ctrl.templateId,
            properties: [property]
        };
        experimentsService.updateTaskTemplateProperties($stateParams.project_id, $stateParams.experiment_id, ctrl.taskId, propertyArgs)
            .then(
                () => null,
                () => toast.error('Unable to update property')
            );
    };

    ///////////////////////////////////////

    function openDatePicker($event, prop) {
        $event.preventDefault();
        $event.stopPropagation();
        prop.opened = true;
    }
}<commit_msg>md-select works with ng-model so we don't have to specify a default value.<commit_after>angular.module('materialscommons').directive('processSettings', processSettingsDirective);
function processSettingsDirective() {
    return {
        restrict: 'E',
        scope: {
            settings: '=',
            taskId: '=',
            templateId: '=',
            attribute: '='
        },
        controller: ProcessSettingsDirectiveController,
        controllerAs: 'ctrl',
        bindToController: true,
        templateUrl: 'app/project/processes/process/create/components/process-settings.html'
    }
}

/*@ngInject*/
function ProcessSettingsDirectiveController(experimentsService, toast, $stateParams) {
    var ctrl = this;
    ctrl.datePickerOptions = {
        formatYear: 'yy',
        startingDay: 1
    };
    ctrl.openDatePicker = openDatePicker;

    ctrl.updateSettingProperty = (property) => {
        if (!property.value) {
            return;
        }

        property.setup_attribute = ctrl.attribute;
        let propertyArgs = {
            template_id: ctrl.templateId,
            properties: [property]
        };
        experimentsService.updateTaskTemplateProperties($stateParams.project_id, $stateParams.experiment_id, ctrl.taskId, propertyArgs)
            .then(
                () => null,
                () => toast.error('Unable to update property')
            );
    };

    ///////////////////////////////////////

    function openDatePicker($event, prop) {
        $event.preventDefault();
        $event.stopPropagation();
        prop.opened = true;
    }
}<|endoftext|>


<commit_before>var http = require('http');
var fs = require('fs');
var index = fs.readFileSync('index.html');

var testvals = [
        [45.507, -73.556, 3],
        [45.508, -73.556, 3],
        [45.509, -73.556, 2],
        [45.510, -73.556, 1],
        [45.511, -73.556, 2],
        [45.512, -73.556, 4],
        [45.513, -73.556, 2],
        [45.514, -73.513, 1]
];
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.write(testvals);
    res.end(index);
}).listen(9615);

<commit_msg>update to express app<commit_after>var express = require('express');
var app = express();

var testvals = [
        [45.507, -73.556, 3],
        [45.508, -73.556, 3],
        [45.509, -73.556, 2],
        [45.510, -73.556, 1],
        [45.511, -73.556, 2],
        [45.512, -73.556, 4],
        [45.513, -73.556, 2],
        [45.514, -73.513, 1]
];
app.get('/data', function(req, res){
      res.send(testvals);
});

var server = app.listen(3000, function() {
        console.log('Listening on port %d', server.address().port);
});
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { translate } from '../../../common/i18n';
import * as style from '../style';
import Dialog from './Dialog';
import { restrictInputCharacter } from '../shared';

class LimitsContent extends PureComponent {
    constructor() {
        super();
        this.state = {
            error    : '',
            maxLoss  : '',
            maxTrades: '',
        };
    }
    submit() {
        const maxLoss = parseFloat(this.state.maxLoss || 0);
        const maxTrades = parseInt(this.state.maxTrades || 0);
        this.setState({ error: '' });
        if (maxTrades <= 0 || maxTrades > 100) {
            this.setState({ error: 'Maximum number of trades should be between 1 and 100.' });
            return;
        }
        if (!maxLoss) {
            this.setState({ error: 'Please enter a Maximum Loss amount greater than zero.' });
            return;
        }
        this.props.onSave({
            maxLoss,
            maxTrades,
        });
    }
    componentDidMount() {
        const cleanupLayout = () => {
            this.setState({
                maxTrades: '',
                maxLoss  : '',
                error    : '',
            });
        };
        $('#limits-dialog-component').dialog({
            close   : cleanupLayout,
            autoOpen: false,
        });
    }
    onMaxTradeChange(e) {
        if (restrictInputCharacter({ input: e.target.value, whitelistRegEx: '^[\\d]*$' })) {
            this.setState({ maxTrades: e.target.value });
        }
    }
    onMaxLossChange(e) {
        if (restrictInputCharacter({ input: e.target.value, whitelistRegEx: '^\\d*\\.?\\d*$' })) {
            this.setState({ maxLoss: e.target.value });
        }
    }
    render() {
        return (
            <form
                action="javascript:;" // eslint-disable-line no-script-url
                onSubmit={() => this.submit()}
                className="dialog-content"
                style={style.content}
            >

                            <input
                                style={style.input}
                                ref={el => {
                                    this.maxTradesDiv = el;
                                }}
                                type="text"
                                id="limitation-max-trades"
                                step="1"
                                maxLength="3"
                                value={this.state.maxTrades}
                                onChange={(...args) => this.onMaxTradeChange(...args)}
                            />
                            {translate('Maximum number of trades')}

                            <input
                                style={style.input}
                                ref={el => {
                                    this.maxLossDiv = el;
                                }}
                                value={this.state.maxLoss}
                                type="text"
                                id="limitation-max-loss"
                                step="any"
                                onChange={(...args) => this.onMaxLossChange(...args)}
                            />
                            {translate('Maximum loss amount')}

                    {this.state.error ?
{this.state.error}
 : null}

                    {translate(
                        'Trade limitations are required by our regulators. Your bot will conclude trading when one or both of the conditions are met.'
                    )}

                    <button type="submit">{translate('Start')}</button>

            </form>
        );
    }
    static props = {
        onSave: PropTypes.func,
    };
}

export default class Limits extends Dialog {
    constructor() {
        const onSave = limits => {
            this.limitsPromise(limits);
            this.close();
        };
        super('limits-dialog', translate('Trade Limitations'), <LimitsContent onSave={onSave} />, style.dialogLayout);
    }
    getLimits() {
        this.open();
        return new Promise(resolve => {
            this.limitsPromise = resolve;
        });
    }
}
<commit_msg>Revamp Limits-dialog to enforce self-exclusion limits<commit_after>import { LiveApi } from 'binary-live-api';
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import Dialog from './Dialog';
import { restrictInputCharacter } from '../shared';
import * as style from '../style';
import { getToken } from '../../../common/utils/storageManager';
import { showSpinnerInButton, removeSpinnerInButton, createUrl, translate } from '../../../common/utils/tools';

class LimitsContent extends PureComponent {
    constructor() {
        super();
        this.state = {
            error    : '',
            maxTrades: 0,
            maxLosses: null,
        };
    }

    submit() {
        this.setState({ error: '' });

        if (!this.state.maxLosses) {
            this.updateMaxLosses()
                .then(() => {
                    this.props.onSave({ maxTrades: this.state.maxTrades });
                })
                .catch(() => {
                    this.setState({
                        error: translate(
                            'Please set your daily loss limit in the Self-Exclusion Facilities page to allow trading.'
                        ),
                    });
                });
            return;
        }

        if (this.state.maxTrades <= 0 || this.state.maxTrades > 100) {
            this.setState({ error: translate('Maximum consecutive trades should be between 1 and 100') });
            return;
        }

        this.props.onSave({ maxTrades: this.state.maxTrades });
    }

    updateMaxLosses() {
        return new Promise((resolve, reject) => {
            const { api } = this.props;
            const $startButton = $('#submit-trade-limits');
            const initialText = $startButton.text();

            showSpinnerInButton($startButton);

            api.getSelfExclusion()
                .then(response => {
                    const { max_losses: maxLosses } = response.get_self_exclusion;
                    let callback;

                    if (maxLosses) {
                        this.setState({ maxLosses });
                        callback = resolve;
                    } else {
                        callback = reject;
                    }

                    removeSpinnerInButton($startButton, initialText);
                    callback();
                })
                .catch(() => {
                    removeSpinnerInButton($startButton, initialText);
                    reject();
                });
        });
    }

    componentDidMount() {
        const cleanupLayout = () => {
            this.setState({
                maxTrades: 0,
                error    : '',
            });
        };

        const onDialogOpen = () => {
            this.updateMaxLosses().catch(() => {});
        };

        $('#limits-dialog-component').dialog({
            open    : onDialogOpen,
            close   : cleanupLayout,
            autoOpen: false,
        });
    }

    onMaxTradeChange(e) {
        if (restrictInputCharacter({ input: e.target.value, whitelistRegEx: '^[\\d]*$' })) {
            this.setState({ maxTrades: e.target.value });
        }
    }

    getDailyLossesLimit() {
        if (this.state.maxLosses) {
            const token = $('.account-id')
                .first()
                .attr('value');
            const tokenObj = getToken(token);
            const currency = tokenObj && tokenObj.loginInfo.currency;
            return currency ? `${this.state.maxLosses} ${currency}` : `${this.state.maxLosses}`;
        }
        return translate('Not set');
    }

    render() {
        return (
            <form
                action="javascript:;" // eslint-disable-line no-script-url
                onSubmit={() => this.submit()}
                className="dialog-content"
                style={style.content}
            >

                    {translate(
                        'We require you to set trade limitations in compliance with business regulations. Please note that your bot will only stop trading if any or both of the conditions below are met.'
                    )}

                        {translate('Daily limit on losses:')} {this.getDailyLossesLimit()}

                        {translate([
                            'This is the threshold that limits your potential losses for the day in all Binary.com platforms. Once your total loss reaches or exceeds this amount, your bot will stop trading. Please set a value in the [_1]Self-Exclusion Facilities page[_2].',
                            ``,
                            '',
                        ])}

                    {translate('Maximum consecutive trades')}

                        {translate(
                            'This is the maximum number of trades that you allow your bot to execute for this run.'
                        )}

                    <input
                        ref={el => {
                            this.maxTradesDiv = el;
                        }}
                        type="text"
                        id="limitation-max-trades"
                        step="1"
                        maxLength="3"
                        value={this.state.maxTrades}
                        onChange={(...args) => this.onMaxTradeChange(...args)}
                        data-lpignore={true}
                    />

                {this.state.error &&
{this.state.error}
}

                    <button id="submit-trade-limits" type="submit">
                        {translate('Start')}
                    </button>

            </form>
        );
    }
    static props = {
        onSave: PropTypes.func,
        api   : PropTypes.instanceOf(LiveApi),
    };
}

export default class Limits extends Dialog {
    constructor(api) {
        const onSave = limits => {
            this.limitsPromise(limits);
            this.close();
        };
        super(
            'limits-dialog',
            translate('Trade Limitations'),
            <LimitsContent onSave={onSave} api={api} />,
            style.dialogLayout
        );
        this.registerCloseOnOtherDialog();
    }
    getLimits() {
        this.open();
        return new Promise(resolve => {
            this.limitsPromise = resolve;
        });
    }
}
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { compose } from 'redux';

import LanguagePicker from 'amo/components/LanguagePicker';
import Link from 'amo/components/Link';
import translate from 'core/i18n/translate';
import Icon from 'ui/components/Icon';
import { sanitizeHTML } from 'core/utils';

import './styles.scss';

export class FooterBase extends React.Component {
  static propTypes = {
    handleViewDesktop: PropTypes.func.isRequired,
    i18n: PropTypes.object.isRequired,
    location: PropTypes.object.isRequired,
  }

  render() {
    const { handleViewDesktop, i18n, location } = this.props;
    const homepageText = i18n.gettext("Go to Mozilla's homepage");

    return (

              <Icon
                alt={homepageText}
                className="Footer-mozilla-logo"
                name="mozilla"
              />

<Link href="/">{i18n.gettext('Add-ons')}</Link>

                <Link
                  to="/about"
                  prependClientApp={false}
                >
                  {i18n.gettext('About')}
                </Link>

                {i18n.gettext('Blog')}

                <Link
                  href="/developers/"
                  prependClientApp={false}
                >
                  {i18n.gettext('Developer Hub')}
                </Link>

                {i18n.gettext('Forum')}

                {i18n.gettext('Report a bug')}

                <Link
                  to="/review_guide"
                  prependClientApp={false}
                >
                  {i18n.gettext('Review Guide')}
                </Link>

{i18n.gettext('Site Status')}

                 { this.desktopLink = ref; }}
                >
                  {i18n.gettext('View classic desktop site')}

Firefox

                  {i18n.gettext('Download Firefox')}

                  {i18n.gettext('Android Browser')}

                  {i18n.gettext('iOS Browser')}

                  {i18n.gettext('Focus Browser')}

                  {i18n.gettext('Desktop Browser')}

                  {i18n.gettext('Beta, Nightly, Developer Edition')}

                  <Icon name="twitter" alt="Twitter (@firefox)" />

                  <Icon name="facebook" alt="Facebook (Firefox)" />

                  <Icon name="youtube" alt="YouTube (firefoxchannel)" />

{i18n.gettext('Privacy')}

{i18n.gettext('Cookies')}

{i18n.gettext('Legal')}

{i18n.gettext('Report Trademark Abuse')}

          <p
            className="Footer-copyright"
            // eslint-disable-next-line react/no-danger
            dangerouslySetInnerHTML={
              sanitizeHTML(
                i18n.sprintf(
                  i18n.gettext(`Except where otherwise %(startNotedLink)snoted%(endNotedLink)s,
                  content on this site is licensed under the %(startLicenseLink)sCreative Commons
                  Attribution Share-Alike License v3.0%(endLicenseLink)s or any later version.`),
                  { startNotedLink: '',
                    endNotedLink: '',
                    startLicenseLink: '',
                    endLicenseLink: '' }
                ), ['a'])
            }
          />

            <LanguagePicker
              location={location}
              ref={(ref) => { this.languagePicker = ref; }}
            />

    );
  }
}

export default compose(
  translate({ withRef: true }),
)(FooterBase);
<commit_msg>Link to the root of the status site<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { compose } from 'redux';

import LanguagePicker from 'amo/components/LanguagePicker';
import Link from 'amo/components/Link';
import translate from 'core/i18n/translate';
import Icon from 'ui/components/Icon';
import { sanitizeHTML } from 'core/utils';

import './styles.scss';

export class FooterBase extends React.Component {
  static propTypes = {
    handleViewDesktop: PropTypes.func.isRequired,
    i18n: PropTypes.object.isRequired,
    location: PropTypes.object.isRequired,
  }

  render() {
    const { handleViewDesktop, i18n, location } = this.props;
    const homepageText = i18n.gettext("Go to Mozilla's homepage");

    return (

              <Icon
                alt={homepageText}
                className="Footer-mozilla-logo"
                name="mozilla"
              />

<Link href="/">{i18n.gettext('Add-ons')}</Link>

                <Link
                  to="/about"
                  prependClientApp={false}
                >
                  {i18n.gettext('About')}
                </Link>

                {i18n.gettext('Blog')}

                <Link
                  href="/developers/"
                  prependClientApp={false}
                >
                  {i18n.gettext('Developer Hub')}
                </Link>

                {i18n.gettext('Forum')}

                {i18n.gettext('Report a bug')}

                <Link
                  to="/review_guide"
                  prependClientApp={false}
                >
                  {i18n.gettext('Review Guide')}
                </Link>

{i18n.gettext('Site Status')}

                 { this.desktopLink = ref; }}
                >
                  {i18n.gettext('View classic desktop site')}

Firefox

                  {i18n.gettext('Download Firefox')}

                  {i18n.gettext('Android Browser')}

                  {i18n.gettext('iOS Browser')}

                  {i18n.gettext('Focus Browser')}

                  {i18n.gettext('Desktop Browser')}

                  {i18n.gettext('Beta, Nightly, Developer Edition')}

                  <Icon name="twitter" alt="Twitter (@firefox)" />

                  <Icon name="facebook" alt="Facebook (Firefox)" />

                  <Icon name="youtube" alt="YouTube (firefoxchannel)" />

{i18n.gettext('Privacy')}

{i18n.gettext('Cookies')}

{i18n.gettext('Legal')}

{i18n.gettext('Report Trademark Abuse')}

          <p
            className="Footer-copyright"
            // eslint-disable-next-line react/no-danger
            dangerouslySetInnerHTML={
              sanitizeHTML(
                i18n.sprintf(
                  i18n.gettext(`Except where otherwise %(startNotedLink)snoted%(endNotedLink)s,
                  content on this site is licensed under the %(startLicenseLink)sCreative Commons
                  Attribution Share-Alike License v3.0%(endLicenseLink)s or any later version.`),
                  { startNotedLink: '',
                    endNotedLink: '',
                    startLicenseLink: '',
                    endLicenseLink: '' }
                ), ['a'])
            }
          />

            <LanguagePicker
              location={location}
              ref={(ref) => { this.languagePicker = ref; }}
            />

    );
  }
}

export default compose(
  translate({ withRef: true }),
)(FooterBase);
<|endoftext|>


<commit_before>import {
  createUser,
  authenticate,
  removeUser
} from './backend-interface'
import assert from 'assert'
const BACKEND_URL = 'http://localhost:3033/'
let TOKEN = ''

describe('backend-interface', () => {
  describe('createUser', () => {
    it('Should be able to create user', async () => {
      try {
        const result = await createUser(BACKEND_URL)('test', 'password')
        assert(result.success, 'should have created user')
      } catch (error) {
        assert(false,
        `Threw an error while trying to create user` + error)
      }
    })
  })
  describe('authenticate', () => {
    it('authenticates user', async () => {
      try {
        const result = await authenticate(BACKEND_URL)('test', 'password')
        TOKEN = result.token
        assert(result.success, 'should have authenticated user')
      } catch (error) {
        assert(false,
        'Threw an error while trying to authenticate user')
      }
    })
  })
  describe('removeUser', () => {
    it('should delete user', async () => {
      try {
        const result = await removeUser(BACKEND_URL)(TOKEN)
        assert(result.success, 'should have deleted user')
      } catch (error) {
        assert(false,
        'Threw an error while trying to delete user')
      }
    })
  })
})
<commit_msg>warning for integrated test potental issues<commit_after>import {
  createUser,
  authenticate,
  removeUser
} from './backend-interface'
import assert from 'assert'
const BACKEND_URL = 'http://localhost:3033/'
let TOKEN = ''

/*------------ WARNING --------------
These test have a temporal coupling meaning some of them
have to be in order.*/

context('Warning -- temporal coupling', () => {
  describe('backend-interface', () => {
    describe('createUser', () => {
      it('Should be able to create user', async () => {
        try {
          const result = await createUser(BACKEND_URL)('test', 'password')
          assert(result.success, 'should have created user')
        } catch (error) {
          assert(false,
          `Threw an error while trying to create user` + error)
        }
      })
    })
    describe('authenticate', () => {
      it('authenticates user', async () => {
        try {
          const result = await authenticate(BACKEND_URL)('test', 'password')
          TOKEN = result.token
          assert(result.success, 'should have authenticated user')
        } catch (error) {
          assert(false,
          'Threw an error while trying to authenticate user')
        }
      })
    })
    describe('removeUser', () => {
      it('should delete user', async () => {
        try {
          const result = await removeUser(BACKEND_URL)(TOKEN)
          assert(result.success, 'should have deleted user')
        } catch (error) {
          assert(false,
          'Threw an error while trying to delete user')
        }
      })
    })
  })
})
<|endoftext|>


<commit_before>/**
 * This file contains the readily availbile functions which interact with the
 * ITSLanguage choice challenge API.
 */

import { authorisedRequest } from '../../communication';

/**
 * The URL for the choice challenge handler(s).
 * @type {string}
 */
const url = '/challenges/choice';

/**
 * Create a new choice challenge.
 *
 * @param {Object} challenge - The challenge to create.
 *
 * @returns {Promise} - The challenge creation promise.
 */
export function create(challenge) {
  return authorisedRequest('POST', url, challenge);
}

/**
 * Get a single choice challenge by its ID.
 *
 * @param {string} id - The ID of the desired choice challenge.
 *
 * @returns {Promise} - The promise for the choice challenge.
 */
export function getByID(id) {
  return authorisedRequest('GET', `${url}/${id}`);
}

/**
 * Get a all choice challenges.
 *
 * By default all choice challenges are fetched though it is allowed to pass
 * filters as a `URLSearchParams` object.
 *
 * @param {URLSearchParams} [filters] - The filters to apply to the category
 *                                      list.
 *
 * @throws {Promise.<string>} - If the given optional filters are not an
 *                              instance of `URLSearchParams`.
 *
 * @returns {Promise} - The promise for the choice challenges.
 */
export function getAll(filters) {
  let urlWithFilters = url;

  if (filters) {
    if (!(filters instanceof URLSearchParams)) {
      return Promise.reject(new Error('The filters should be a `URLSearchParams` object.'));
    }

    urlWithFilters += `?${filters.toString()}`;
  }

  return authorisedRequest('GET', urlWithFilters);
}
<commit_msg>refactor: getByID to getById consistency<commit_after>/**
 * This file contains the readily availbile functions which interact with the
 * ITSLanguage choice challenge API.
 */

import { authorisedRequest } from '../../communication';

/**
 * The URL for the choice challenge handler(s).
 * @type {string}
 */
const url = '/challenges/choice';

/**
 * Create a new choice challenge.
 *
 * @param {Object} challenge - The challenge to create.
 *
 * @returns {Promise} - The challenge creation promise.
 */
export function create(challenge) {
  return authorisedRequest('POST', url, challenge);
}

/**
 * Get a single choice challenge by its ID.
 *
 * @param {string} id - The ID of the desired choice challenge.
 *
 * @returns {Promise} - The promise for the choice challenge.
 */
export function getById(id) {
  return authorisedRequest('GET', `${url}/${id}`);
}

/**
 * Get a all choice challenges.
 *
 * By default all choice challenges are fetched though it is allowed to pass
 * filters as a `URLSearchParams` object.
 *
 * @param {URLSearchParams} [filters] - The filters to apply to the category
 *                                      list.
 *
 * @throws {Promise.<string>} - If the given optional filters are not an
 *                              instance of `URLSearchParams`.
 *
 * @returns {Promise} - The promise for the choice challenges.
 */
export function getAll(filters) {
  let urlWithFilters = url;

  if (filters) {
    if (!(filters instanceof URLSearchParams)) {
      return Promise.reject(new Error('The filters should be a `URLSearchParams` object.'));
    }

    urlWithFilters += `?${filters.toString()}`;
  }

  return authorisedRequest('GET', urlWithFilters);
}
<|endoftext|>


<commit_before>'use strict'

module.exports = (sources, opts) => {
  return JSON.stringify({
    language: 'Solidity',
    sources: sources,
    settings: {
      optimizer: {
        enabled: opts.optimize === true,
        runs: 500
      }
    },
    libraries: opts.libraries,
    outputSelection: {
      '*': {
        '': [ 'legacyAST' ],
        '*': [ 'abi', 'metadata', 'evm.legacyAssembly', 'evm.bytecode', 'evm.deployedBytecode', 'evm.methodIdentifiers', 'evm.gasEstimates' ]
      }
    }
  })
}
<commit_msg>jsonio: both libraries and outputSelection is part of settings<commit_after>'use strict'

module.exports = (sources, opts) => {
  return JSON.stringify({
    language: 'Solidity',
    sources: sources,
    settings: {
      optimizer: {
        enabled: opts.optimize === true,
        runs: 500
      },
      libraries: opts.libraries,
      outputSelection: {
        '*': {
          '': [ 'legacyAST' ],
          '*': [ 'abi', 'metadata', 'evm.legacyAssembly', 'evm.bytecode', 'evm.deployedBytecode', 'evm.methodIdentifiers', 'evm.gasEstimates' ]
        }
      }
    }
  })
}
<|endoftext|>