<commit_before>agidoMockups.controller("EditorCtrl", function ($scope)
{
    $scope.selectedComponent = null;
    $scope.editingSource = false;

    var clipboard;
    var availableFonts = $scope.availableFonts =
            ["Arial", "Bigelow Rules", "Georgia", "Cherry Swash", "Comic Sans MS", "Helvetica", "Lucida Console", "Prosto One", "Stint Ultra Expanded",
                "Times New Roman"];
    var dimensionProperties = [
        {name: "x", hidden: true},
        {name: "y", hidden: true}  ,
        {name: "width", hidden: true},
        {name: "height", hidden: true}
    ];
    var fontProperties = [
        {name: "fontFamily", type: "enum", options: availableFonts},
        {name: "fontSize", type: "number"},
        {name: "fontStyle", type: "enum", options: ["normal", "bold", "italic"]}
    ];
    var components = {
        "Link": {constructor: Kinetic.Link,
            options: {
                color: '#000',
                draggable: true
            },
            multilineSource: false,
            properties: fontProperties.concat(dimensionProperties, [
                {name: "disabled", type: "boolean"}
            ])
        }, "RadioItem": {
            constructor: Kinetic.RadioItem, options: {
                color: '#000', draggable: true
            },
            multilineSource: false,
            properties: fontProperties.concat(dimensionProperties, [
                {name: "selected", type: "boolean"}
            ])
        },
        "RadioGroup": {
            constructor: Kinetic.RadioGroup, options: {
                color: '#000', draggable: true
            },
            multilineSource: true,
            properties: fontProperties.concat(dimensionProperties)
        },
        "Input": {constructor: Kinetic.Input,
            options: {
                color: '#000',
                draggable: true
            },
            multilineSource: false,
            properties: fontProperties.concat(dimensionProperties, [
                {name: "disabled", type: "boolean"},
                {name: "datepicker", type: "boolean"}
            ])
        },
        "Button": {constructor: Kinetic.Button,
            options: {
                color: '#000',
                draggable: true
            },
            multilineSource: false,
            properties: fontProperties.concat(dimensionProperties, [
                {name: "disabled", type: "boolean"}
            ])
        },
        "Select": {constructor: Kinetic.Select,
            options: {
                color: '#000',
                draggable: true
            },
            multilineSource: true,
            properties: fontProperties.concat(dimensionProperties, [
                {name: "disabled", type: "boolean"},
                {name: "opened", type: "boolean"}
            ])
        }
    };

    function addToStage(component)
    {
        $scope.stage.getLayers()[0].add(component);
        $scope.stage.draw();
    }

    $scope.addToStage = function (type)
    {
        var scheme = components[type];
        if (null == scheme) {
            throw new Error("Unsupported type: " + type);
        }
        var component = new scheme.constructor(scheme.options);
        component.mockupComponent = scheme;
        addToStage(component);
    };

    function applyComponentSource(source)
    {
        if (null != $scope.selectedComponent && null != source && "" != source.trim()) {
            $scope.selectedComponent.setText(source);
            $scope.stage.draw();
            return true;
        }
        return false;
    }

    $scope.saveSource = function (source)
    {
        return applyComponentSource(source);

    };

    $scope.mockupComponentSelected = function (component)
    {
        $scope.selectedComponent = component;
        $scope.selectedComponentProperties = {};
        if (null != component) {
            var properties = component.mockupComponent.properties;
            for (var i = 0; null != properties && i < properties.length; i++) {
                var property = properties[i];
                $scope.selectedComponentProperties.__defineGetter__(property.name, function (propertyName)
                {
                    return null == $scope.selectedComponent ? null : $scope.selectedComponent["get" + Kinetic.Util._capitalize(propertyName)]();
                }.bind(null, property.name));
                $scope.selectedComponentProperties.__defineSetter__(property.name, function (propertyName, value)
                {
                    if (null != $scope.selectedComponent) {
                        $scope.selectedComponent["set" + Kinetic.Util._capitalize(propertyName)](value);
                    }
                    $scope.stage.draw();
                }.bind(null, property.name));
            }
        }
    };

    $scope.stageClicked = function (source)
    {
        if (null != $scope.selectedComponent) {
            if ($scope.selectedComponent.mockupComponent.multilineSource) {
                applyComponentSource(source);
            }
            $scope.selectedComponent = null
        }
    };

    $scope.isMockupComponent = function (comopnent)
    {
        return comopnent.mockupComponent != null;
    };

    $scope.downloadImage = function ()
    {
        $scope.stage.toDataURL({callback: function (data)
        {
            var pom = document.createElement('a');
            pom.setAttribute('href', data);
            pom.setAttribute('download', "AgidoMockup.png");
            pom.click();
        }})
    };

    $scope.getComponentType = function (component)
    {
        return null == component ? null : component.className;
    };

    $scope.getProperties = function (component)
    {
        return null == component ? null : component.mockupComponent.properties;
    };

    $scope.undo = function ()
    {
//        TODO implement this method
        alert("Not implemented yet");
    };

    $scope.redo = function ()
    {
//        TODO implement this method
        alert("Not implemented yet");
    };

    $scope.duplicate = function ()
    {
        if (null != $scope.selectedComponent) {
            //noinspection JSValidateTypes
            var clone = new $scope.selectedComponent.mockupComponent.constructor($scope.selectedComponent.attrs);
            clone.setAttr("x", clone.getAttr("x") + 15);
            clone.setAttr("y", clone.getAttr("y") + 15);
            clone.mockupComponent = $scope.selectedComponent.mockupComponent;
            $scope.selectedComponent = clone;
            addToStage(clone);
        }
    };

    $scope.cut = function ()
    {
        if (null != $scope.selectedComponent) {
            clipboard = $scope.selectedComponent;
            clipboard.remove();
            $scope.selectedComponent = null;
            $scope.editingSource = false;
            $scope.stage.draw();
        }
    };

    $scope.isClipboardEmpty = function ()
    {
        return null == clipboard;
    };

    $scope.paste = function ()
    {
        if (null != clipboard) {
            $scope.selectedComponent = clipboard;
            $scope.duplicate();
        }
    };

    $scope.delete = function ()
    {
        if (null != $scope.selectedComponent) {
            $scope.selectedComponent.remove();
            $scope.selectedComponent = null;
            $scope.editingSource = false;
            $scope.stage.draw();
        }
    };

    $scope.lock = function ()
    {
//        TODO implement this method
        alert("Not implemented yet");
    };

    $scope.moveToTop = function ()
    {
        if (null != $scope.selectedComponent) {
            $scope.selectedComponent.moveToTop();
            $scope.stage.draw();
        }
    };

    $scope.moveUp = function ()
    {
        if (null != $scope.selectedComponent) {
            $scope.selectedComponent.moveUp();
            $scope.stage.draw();
        }
    };

    $scope.moveDown = function ()
    {
        if (null != $scope.selectedComponent) {
            $scope.selectedComponent.moveDown();
            $scope.stage.draw();
        }
    };

    $scope.moveToBottom = function ()
    {
        if (null != $scope.selectedComponent) {
            $scope.selectedComponent.moveToBottom();
            $scope.stage.draw();
        }
    };

});
<commit_msg>Property min value validation<commit_after>agidoMockups.controller("EditorCtrl", function ($scope)
{
    $scope.selectedComponent = null;
    $scope.editingSource = false;

    var clipboard;
    var availableFonts = $scope.availableFonts =
            ["Arial", "Bigelow Rules", "Georgia", "Cherry Swash", "Comic Sans MS", "Helvetica", "Lucida Console", "Prosto One", "Stint Ultra Expanded",
                "Times New Roman"];
    var dimensionProperties = [
        {name: "x", hidden: true},
        {name: "y", hidden: true}  ,
        {name: "width", hidden: true},
        {name: "height", hidden: true}
    ];
    var fontProperties = [
        {name: "fontFamily", type: "enum", options: availableFonts},
        {name: "fontSize", type: "number", min: 8},
        {name: "fontStyle", type: "enum", options: ["normal", "bold", "italic"]}
    ];
    var components = {
        "Link": {constructor: Kinetic.Link,
            options: {
                color: '#000',
                draggable: true
            },
            multilineSource: false,
            properties: fontProperties.concat(dimensionProperties, [
                {name: "disabled", type: "boolean"}
            ])
        }, "RadioItem": {
            constructor: Kinetic.RadioItem, options: {
                color: '#000', draggable: true
            },
            multilineSource: false,
            properties: fontProperties.concat(dimensionProperties, [
                {name: "selected", type: "boolean"}
            ])
        },
        "RadioGroup": {
            constructor: Kinetic.RadioGroup, options: {
                color: '#000', draggable: true
            },
            multilineSource: true,
            properties: fontProperties.concat(dimensionProperties)
        },
        "Input": {constructor: Kinetic.Input,
            options: {
                color: '#000',
                draggable: true
            },
            multilineSource: false,
            properties: fontProperties.concat(dimensionProperties, [
                {name: "disabled", type: "boolean"},
                {name: "datepicker", type: "boolean"}
            ])
        },
        "Button": {constructor: Kinetic.Button,
            options: {
                color: '#000',
                draggable: true
            },
            multilineSource: false,
            properties: fontProperties.concat(dimensionProperties, [
                {name: "disabled", type: "boolean"}
            ])
        },
        "Select": {constructor: Kinetic.Select,
            options: {
                color: '#000',
                draggable: true
            },
            multilineSource: true,
            properties: fontProperties.concat(dimensionProperties, [
                {name: "disabled", type: "boolean"},
                {name: "opened", type: "boolean"}
            ])
        }
    };

    function addToStage(component)
    {
        $scope.stage.getLayers()[0].add(component);
        $scope.stage.draw();
    }

    $scope.addToStage = function (type)
    {
        var scheme = components[type];
        if (null == scheme) {
            throw new Error("Unsupported type: " + type);
        }
        var component = new scheme.constructor(scheme.options);
        component.mockupComponent = scheme;
        addToStage(component);
    };

    function applyComponentSource(source)
    {
        if (null != $scope.selectedComponent && null != source && "" != source.trim()) {
            $scope.selectedComponent.setText(source);
            $scope.stage.draw();
            return true;
        }
        return false;
    }

    $scope.saveSource = function (source)
    {
        return applyComponentSource(source);

    };

    $scope.mockupComponentSelected = function (component)
    {
        $scope.selectedComponent = component;
        $scope.selectedComponentProperties = {};
        if (null != component) {
            var properties = component.mockupComponent.properties;
            for (var i = 0; null != properties && i < properties.length; i++) {
                var property = properties[i];
                $scope.selectedComponentProperties.__defineGetter__(property.name, function (propertyName)
                {
                    return null == $scope.selectedComponent ? null : $scope.selectedComponent["get" + Kinetic.Util._capitalize(propertyName)]();
                }.bind(null, property.name));
                $scope.selectedComponentProperties.__defineSetter__(property.name, function (property, value)
                {
                    if (null != $scope.selectedComponent) {
                        if ("number" == property.type && property.min && property.min > value) {
                            return;
                        }
                        $scope.selectedComponent["set" + Kinetic.Util._capitalize(property.name)](value);
                    }
                    $scope.stage.draw();
                }.bind(null, property));
            }
        }
    };

    $scope.stageClicked = function (source)
    {
        if (null != $scope.selectedComponent) {
            if ($scope.selectedComponent.mockupComponent.multilineSource) {
                applyComponentSource(source);
            }
            $scope.selectedComponent = null
        }
    };

    $scope.isMockupComponent = function (comopnent)
    {
        return comopnent.mockupComponent != null;
    };

    $scope.downloadImage = function ()
    {
        $scope.stage.toDataURL({callback: function (data)
        {
            var pom = document.createElement('a');
            pom.setAttribute('href', data);
            pom.setAttribute('download', "AgidoMockup.png");
            pom.click();
        }})
    };

    $scope.getComponentType = function (component)
    {
        return null == component ? null : component.className;
    };

    $scope.getProperties = function (component)
    {
        return null == component ? null : component.mockupComponent.properties;
    };

    $scope.undo = function ()
    {
//        TODO implement this method
        alert("Not implemented yet");
    };

    $scope.redo = function ()
    {
//        TODO implement this method
        alert("Not implemented yet");
    };

    $scope.duplicate = function ()
    {
        if (null != $scope.selectedComponent) {
            //noinspection JSValidateTypes
            var clone = new $scope.selectedComponent.mockupComponent.constructor($scope.selectedComponent.attrs);
            clone.setAttr("x", clone.getAttr("x") + 15);
            clone.setAttr("y", clone.getAttr("y") + 15);
            clone.mockupComponent = $scope.selectedComponent.mockupComponent;
            $scope.selectedComponent = clone;
            addToStage(clone);
        }
    };

    $scope.cut = function ()
    {
        if (null != $scope.selectedComponent) {
            clipboard = $scope.selectedComponent;
            clipboard.remove();
            $scope.selectedComponent = null;
            $scope.editingSource = false;
            $scope.stage.draw();
        }
    };

    $scope.isClipboardEmpty = function ()
    {
        return null == clipboard;
    };

    $scope.paste = function ()
    {
        if (null != clipboard) {
            $scope.selectedComponent = clipboard;
            $scope.duplicate();
        }
    };

    $scope.delete = function ()
    {
        if (null != $scope.selectedComponent) {
            $scope.selectedComponent.remove();
            $scope.selectedComponent = null;
            $scope.editingSource = false;
            $scope.stage.draw();
        }
    };

    $scope.lock = function ()
    {
//        TODO implement this method
        alert("Not implemented yet");
    };

    $scope.moveToTop = function ()
    {
        if (null != $scope.selectedComponent) {
            $scope.selectedComponent.moveToTop();
            $scope.stage.draw();
        }
    };

    $scope.moveUp = function ()
    {
        if (null != $scope.selectedComponent) {
            $scope.selectedComponent.moveUp();
            $scope.stage.draw();
        }
    };

    $scope.moveDown = function ()
    {
        if (null != $scope.selectedComponent) {
            $scope.selectedComponent.moveDown();
            $scope.stage.draw();
        }
    };

    $scope.moveToBottom = function ()
    {
        if (null != $scope.selectedComponent) {
            $scope.selectedComponent.moveToBottom();
            $scope.stage.draw();
        }
    };

});
<|endoftext|>


<commit_before>/**
 * Created by tranthiennhan on 7/4/17.
 */

const _ = require('lodash');
const mm = require('nanomatch');

const hydraExpress = require('hydra-express');
const hydra = hydraExpress.getHydra();

const Promise = require('bluebird');
Promise.promisifyAll(require('redis').RedisClient.prototype);

/* Constants */
const ebPreKey = 'hydra:event-bus';
const registryPreKey = ebPreKey + ':registry';
const config = require('../lib/config-helper');
const registry = {};

const registerPatternsForService = ({
  type,
  patterns,
  serviceTag
}) => {
  if (!type || type != 'register') return;

  const stringifiedPatterns = stringifyPatterns(patterns);

  if (!stringifiedPatterns) return;

  updateLocalRegistry(serviceTag, stringifiedPatterns);

  const addPatternToRedis = (pattern) => hydra.redisdb.saddAsync(`${registryPreKey}:${serviceTag}`, pattern);

  Promise.each(stringifiedPatterns, addPatternToRedis)
  .then(function () {
    hydraExpress.appLogger.info(`Registered ${stringifiedPatterns.length} patterns for ${serviceTag}`);
    notifyUpdate(serviceTag);
  })
  .catch(hydraExpress.appLogger.error);
};

const _buildAddPatternToServiceRedisRegistry = (serviceTag) => (pattern) => hydra.redisdb.saddAsync(`${registryPreKey}:${serviceTag}`, pattern);

const unregisterPatternsForService = ({
  type,
  patterns,
  serviceTag
}) => {
  if (!type || type != 'unregister') return;

  const stringifiedPatterns = stringifyPatterns(patterns);

  if (!stringifiedPatterns || !registry[serviceTag]) return;

  const keepPatterns = filterPatternsToKeepInRegistry(stringifiedPatterns, serviceTag);

  updateLocalRegistry(serviceTag, keepPatterns, true);

  hydra.redisdb.delAsync(`${registryPreKey}:${serviceTag}`).then(() => {
      return Promise.each(keepPatterns, _buildAddPatternToServiceRedisRegistry(serviceTag));
  })
    .then( () => {
      hydra.sendToHealthLog('info', `Unregistered ${stringifiedPatterns.length} patterns, ${keepPatterns.length} patterns left for ${serviceTag}`);
      notifyUpdate(serviceTag);
    }).catch((err) => {
      hydra.sendToHealthLog('error', err);
    });
};

const updatePatterns = ({
  type,
  serviceTag
}) => {
  if (!type || type != 'changed') return;

  return hydra.redisdb.smembersAsync(`${registryPreKey}:${serviceTag}`).then(function (patterns) {
    updateLocalRegistry(serviceTag, patterns, true);
  });
};

const updateAllPatterns = () => {
  const patternStartPos = registryPreKey.length + 1;
  return hydra.redisdb.keysAsync(`${registryPreKey}:*`).map((pattern) => {
    return pattern.substring(patternStartPos);
  }).map((serviceTag) => {
    updatePatterns({
      type: 'changed',
      serviceTag: serviceTag
    });
  });

}
const updateLocalRegistry = (serviceTag, stringifiedPatterns, emptyBeforeUpdate = false) => {
  if (!serviceTag || serviceTag.indexOf(':') == -1 || serviceTag.split(':').length != 2) return;

  hydra.sendToHealthLog('info', `Update local registry for ${serviceTag}`);

  if (!registry[serviceTag] || emptyBeforeUpdate) {
    registry[serviceTag] = new Set();
  }

  const patterns = _.castArray(stringifiedPatterns);

  for (let pattern of patterns) {
    registry[serviceTag].add(pattern);
  }
};

const notifyUpdate = (serviceTag) => {
  const msg = hydra.createUMFMessage({
    frm: `${hydra.instanceID}@${config.hydra.serviceName}:/`,
    to: `${config.hydra.serviceName}:/`,
    typ: 'event-bus',
    bdy: {
      type: 'changed',
      serviceTag: serviceTag
    }
  });

  hydra.sendBroadcastMessage(msg);
};

const dispatchEventUMF = ({
  type,
  eventName,
  payload
}) => {
  if (!type || type != 'event') return;

  return dispatchEvent(eventName, payload);
}

const dispatchEvent = (evt, payload) => {
  Object.keys(registry).forEach((serviceTag) => {

    const dispatchForPattern = (pattern) => dispatchEventToService(serviceTag, evt, pattern, payload);
    const isPatternMatched = (pattern) => mm.isMatch(evt, pattern);

    const patterns = Array.from(registry[serviceTag]);
    patterns
      .filter(isPatternMatched)
      .forEach(dispatchForPattern);
  });
}

const dispatchEventToService = (serviceTag, eventName, pattern, payload) => {
  console.log(`Matched - dispatch to ${serviceTag}`);
  const [to, label] = serviceTag.split(':');
  const msg = hydra.createUMFMessage({
    frm: `${config.hydra.serviceName}:/`,
    to: `${to}:/`,
    typ: 'event-bus',
    bdy: {
      type: 'event',
      serviceTag: serviceTag,
      eventName: eventName,
      pattern: pattern,
      payload: payload
    }
  });

  hydra.sendMessage(msg);
}

const stringifyPattern = (pattern) => {
  try {
    if (typeof pattern == 'string') {
      return pattern;
    } else if (typeof pattern == 'object' && pattern instanceof RegExp) {
      return pattern.source;
    }
  } catch (e) {
    return false;
  }
}

const updatePatternsOnMessageReceived = (umf) => {
  if (umf.typ !== 'event-bus')
    return;

  const body = umf.bdy;

  registerPatternsForService(body);
  unregisterPatternsForService(body);
  dispatchEventUMF(body);

  const frmParts = umf.frm.split('@');
  if (frmParts.length != 2 || frmParts[0] != hydra.instanceID) {
    updatePatterns(body);
  }
};

module.exports = {
  dispatchEventUMF,
  dispatchEvent,
  updateAllPatterns,
  registerPatternsForService,
  unregisterPatternsForService,
  updatePatternsOnMessageReceived
}
function filterPatternsToKeepInRegistry(stringifiedPatterns, serviceTag) {
  const removablePatterns = new Set(stringifiedPatterns);
  return Array.from(registry[serviceTag]).filter((pattern) => !removablePatterns.has(pattern));
}

function stringifyPatterns(patterns) {
  return _.castArray(patterns)
    .map(stringifyPattern)
    .filter((pattern) => pattern !== false);
}<commit_msg>Use yarn for manage dependencies and upgrade the package pino<commit_after>/**
 * Created by tranthiennhan on 7/4/17.
 */

const _ = require('lodash');
const mm = require('nanomatch');

const hydraExpress = require('hydra-express');
const hydra = hydraExpress.getHydra();

const Promise = require('bluebird');
Promise.promisifyAll(require('redis').RedisClient.prototype);

/* Constants */
const ebPreKey = 'hydra:event-bus';
const registryPreKey = ebPreKey + ':registry';
const config = require('../lib/config-helper');
const registry = {};

const registerPatternsForService = ({
  type,
  patterns,
  serviceTag
}) => {
  if (!type || type != 'register') return;

  const stringifiedPatterns = stringifyPatterns(patterns);

  if (!stringifiedPatterns) return;

  updateLocalRegistry(serviceTag, stringifiedPatterns);

  const addPatternToRedis = (pattern) => hydra.redisdb.saddAsync(`${registryPreKey}:${serviceTag}`, pattern);

  Promise.each(stringifiedPatterns, addPatternToRedis)
  .then(function () {
    hydraExpress.appLogger.info(`Registered ${stringifiedPatterns.length} patterns for ${serviceTag}`);
    notifyUpdate(serviceTag);
  })
  .catch(hydraExpress.appLogger.error);
};

const _buildAddPatternToServiceRedisRegistry = (serviceTag) => (pattern) => hydra.redisdb.saddAsync(`${registryPreKey}:${serviceTag}`, pattern);

const unregisterPatternsForService = ({
  type,
  patterns,
  serviceTag
}) => {
  if (!type || type != 'unregister') return;

  const stringifiedPatterns = stringifyPatterns(patterns);

  if (!stringifiedPatterns || !registry[serviceTag]) return;

  const keepPatterns = filterPatternsToKeepInRegistry(stringifiedPatterns, serviceTag);

  updateLocalRegistry(serviceTag, keepPatterns, true);

  hydra.redisdb.delAsync(`${registryPreKey}:${serviceTag}`).then(() => {
      return Promise.each(keepPatterns, _buildAddPatternToServiceRedisRegistry(serviceTag));
  })
    .then( () => {
      hydra.sendToHealthLog('info', `Unregistered ${stringifiedPatterns.length} patterns, ${keepPatterns.length} patterns left for ${serviceTag}`);
      notifyUpdate(serviceTag);
    }).catch((err) => {
      hydra.sendToHealthLog('error', err);
    });
};

const updatePatterns = ({
  type,
  serviceTag
}) => {
  if (!type || type != 'changed') return;

  return hydra.redisdb.smembersAsync(`${registryPreKey}:${serviceTag}`).then(function (patterns) {
    updateLocalRegistry(serviceTag, patterns, true);
  });
};

const updateAllPatterns = () => {
  const patternStartPos = registryPreKey.length + 1;
  return hydra.redisdb.keysAsync(`${registryPreKey}:*`).map((pattern) => {
    return pattern.substring(patternStartPos);
  }).map((serviceTag) => {
    updatePatterns({
      type: 'changed',
      serviceTag: serviceTag
    });
  });

}
const updateLocalRegistry = (serviceTag, stringifiedPatterns, emptyBeforeUpdate = false) => {
  if (!serviceTag || serviceTag.indexOf(':') == -1 || serviceTag.split(':').length != 2) return;

  hydra.sendToHealthLog('info', `Update local registry for ${serviceTag}`);

  if (!registry[serviceTag] || emptyBeforeUpdate) {
    registry[serviceTag] = new Set();
  }

  const patterns = _.castArray(stringifiedPatterns);

  for (let pattern of patterns) {
    registry[serviceTag].add(pattern);
  }
};

const notifyUpdate = (serviceTag) => {
  const msg = hydra.createUMFMessage({
    frm: `${hydra.instanceID}@${config.hydra.serviceName}:/`,
    to: `${config.hydra.serviceName}:/`,
    typ: 'event-bus',
    bdy: {
      type: 'changed',
      serviceTag: serviceTag
    }
  });

  hydra.sendBroadcastMessage(msg);
};

const dispatchEventUMF = ({
  type,
  eventName,
  payload
}) => {
  if (!type || type != 'event') return;

  return dispatchEvent(eventName, payload);
}

const dispatchEvent = (evt, payload) => {
  Object.keys(registry).forEach((serviceTag) => {

    const dispatchForPattern = (pattern) => dispatchEventToService(serviceTag, evt, pattern, payload);
    const isPatternMatched = (pattern) => mm.isMatch(evt, pattern);

    const patterns = Array.from(registry[serviceTag]);
    patterns
      .filter(isPatternMatched)
      .forEach(dispatchForPattern);
  });
}

const dispatchEventToService = (serviceTag, eventName, pattern, payload) => {
  console.log(`Matched - dispatch to ${serviceTag}`);
  const [to, label] = serviceTag.split(':');
  const msg = hydra.createUMFMessage({
    frm: `${config.hydra.serviceName}:/`,
    to: `${to}:/`,
    typ: 'event-bus',
    bdy: {
      type: 'event',
      serviceTag: serviceTag,
      eventName: eventName,
      pattern: pattern,
      payload: payload
    }
  });

  hydra.sendMessage(msg);
}

const stringifyPattern = (pattern) => {
  try {
    if (typeof pattern == 'string') {
      return pattern;
    } else if (typeof pattern == 'object' && pattern instanceof RegExp) {
      return pattern.source;
    }
  } catch (e) {
    return false;
  }
}

const updatePatternsOnMessageReceived = (umf) => {
  if (umf.typ !== 'event-bus')
    return;

  const body = umf.bdy;

  registerPatternsForService(body);
  unregisterPatternsForService(body);
  dispatchEventUMF(body);

  const frmParts = umf.frm.split('@');
  if (frmParts.length != 2 || frmParts[0] != hydra.instanceID) {
    updatePatterns(body);
  }
};

module.exports = {
  dispatchEventUMF,
  dispatchEvent,
  updateAllPatterns,
  registerPatternsForService,
  unregisterPatternsForService,
  updatePatternsOnMessageReceived
}
function filterPatternsToKeepInRegistry(stringifiedPatterns, serviceTag) {
  const removablePatterns = new Set(stringifiedPatterns);
  return Array.from(registry[serviceTag]).filter((pattern) => !removablePatterns.has(pattern));
}

function stringifyPatterns(patterns) {
  return _.castArray(patterns)
    .map(stringifyPattern)
    .filter((pattern) => pattern !== false);
}
<|endoftext|>


<commit_before>var loadChat = function() {
	var $sidebar = $('#context-sidebar');
  // Get references to elements on the page.
  var $form = $sidebar.find('#message-form');
  var $messageInput = $sidebar.find('#message');
  var $messages = $sidebar.find('#messages');
  var $socketStatus = $sidebar.find('#status');
  var url = window.location.host + window.location.pathname;

  // var socket = new WebSocket('ws://104.131.117.55:8080');
  var socket = new WebSocket('ws://localhost:8080');

  socket.onopen = function(event) {
	  $socketStatus.html("");
	  $socketStatus.addClass('open');
    var msg = {url: url, initial: true};
    socket.send(JSON.stringify(msg));
	};

	$form.on("submit", function(e) {
	  e.preventDefault();

	  // Retrieve the message from the textarea.
	  var message = $messageInput.val();

	  var msg = {};
	  msg.url = url;
	  msg.message = message;
	  // Send the message through the WebSocket.
	  socket.send(JSON.stringify(msg));

	  // Clear out the message field.
	  $messageInput.val("");

	  return false;
	});

	socket.onmessage = function(event) {
	  var message = event.data;
	  $messages.append('
Received:' + message + '
');
	};

	// Show a disconnected message when the WebSocket is closed.
	socket.onclose = function(event) {
	  $socketStatus.html('Connection Closed');
	  $socketStatus.removeClass('open');
	  $socketStatus.addClass('closed');
	};
}<commit_msg>changed server from localhost<commit_after>var loadChat = function() {
	var $sidebar = $('#context-sidebar');
  // Get references to elements on the page.
  var $form = $sidebar.find('#message-form');
  var $messageInput = $sidebar.find('#message');
  var $messages = $sidebar.find('#messages');
  var $socketStatus = $sidebar.find('#status');
  var url = window.location.host + window.location.pathname;

  var socket = new WebSocket('ws://104.131.117.55:8080');
  // var socket = new WebSocket('ws://localhost:8080');

  socket.onopen = function(event) {
	  $socketStatus.html("");
	  $socketStatus.addClass('open');
    var msg = {url: url, initial: true};
    socket.send(JSON.stringify(msg));
	};

	$form.on("submit", function(e) {
	  e.preventDefault();

	  // Retrieve the message from the textarea.
	  var message = $messageInput.val();

	  var msg = {};
	  msg.url = url;
	  msg.message = message;
	  // Send the message through the WebSocket.
	  socket.send(JSON.stringify(msg));

	  // Clear out the message field.
	  $messageInput.val("");

	  return false;
	});

	socket.onmessage = function(event) {
	  var message = event.data;
	  $messages.append('
Received:' + message + '
');
	};

	// Show a disconnected message when the WebSocket is closed.
	socket.onclose = function(event) {
	  $socketStatus.html('Connection Closed');
	  $socketStatus.removeClass('open');
	  $socketStatus.addClass('closed');
	};
}<|endoftext|>


<commit_before>var defaultConfig = { iceServers: [{ url: "stun:stun.l.google.com:19302" }] };
var dataCount = 1;

var BinaryPack = require("js-binarypack");
var RTCPeerConnection = require("./adapter").RTCPeerConnection;

var util = {
  noop: function() {},

  CLOUD_HOST: "0.peerjs.com",
  CLOUD_PORT: 9000,

  // Browsers that need chunking:
  chunkedBrowsers: { Chrome: 1 },
  chunkedMTU: 16300, // The original 60000 bytes setting does not work when sending data from Firefox to Chrome, which is "cut off" after 16384 bytes and delivered individually.

  // Logging logic
  logLevel: 0,
  setLogLevel: function(level) {
    var debugLevel = parseInt(level, 10);
    if (!isNaN(parseInt(level, 10))) {
      util.logLevel = debugLevel;
    } else {
      // If they are using truthy/falsy values for debug
      util.logLevel = level ? 3 : 0;
    }
    util.log = util.warn = util.error = util.noop;
    if (util.logLevel > 0) {
      util.error = util._printWith("ERROR");
    }
    if (util.logLevel > 1) {
      util.warn = util._printWith("WARNING");
    }
    if (util.logLevel > 2) {
      util.log = util._print;
    }
  },
  setLogFunction: function(fn) {
    if (fn.constructor !== Function) {
      util.warn(
        "The log function you passed in is not a function. Defaulting to regular logs."
      );
    } else {
      util._print = fn;
    }
  },

  _printWith: function(prefix) {
    return function() {
      var copy = Array.prototype.slice.call(arguments);
      copy.unshift(prefix);
      util._print.apply(util, copy);
    };
  },
  _print: function() {
    var err = false;
    var copy = Array.prototype.slice.call(arguments);
    copy.unshift("PeerJS: ");
    for (var i = 0, l = copy.length; i < l; i++) {
      if (copy[i] instanceof Error) {
        copy[i] = "(" + copy[i].name + ") " + copy[i].message;
        err = true;
      }
    }
    err ? console.error.apply(console, copy) : console.log.apply(console, copy);
  },
  //

  // Returns browser-agnostic default config
  defaultConfig: defaultConfig,
  //

  // Returns the current browser.
  browser: (function() {
    if (window.mozRTCPeerConnection) {
      return "Firefox";
    } else if (window.webkitRTCPeerConnection) {
      return "Chrome";
    } else if (window.RTCPeerConnection) {
      return "Supported";
    } else {
      return "Unsupported";
    }
  })(),
  //

  // Lists which features are supported
  supports: (function() {
    if (typeof RTCPeerConnection === "undefined") {
      return {};
    }

    var data = true;
    var audioVideo = true;

    var binaryBlob = false;
    var sctp = false;
    var onnegotiationneeded = !!window.webkitRTCPeerConnection;

    var pc, dc;
    try {
      pc = new RTCPeerConnection(defaultConfig, {
        optional: [{ RtpDataChannels: true }]
      });
    } catch (e) {
      data = false;
      audioVideo = false;
    }

    if (data) {
      try {
        dc = pc.createDataChannel("_PEERJSTEST");
      } catch (e) {
        data = false;
      }
    }

    if (data) {
      // Binary test
      try {
        dc.binaryType = "blob";
        binaryBlob = true;
      } catch (e) {}

      // Reliable test.
      // Unfortunately Chrome is a bit unreliable about whether or not they
      // support reliable.
      var reliablePC = new RTCPeerConnection(defaultConfig, {});
      try {
        var reliableDC = reliablePC.createDataChannel(
          "_PEERJSRELIABLETEST",
          {}
        );
        sctp = reliableDC.reliable;
      } catch (e) {}
      reliablePC.close();
    }

    // FIXME: not really the best check...
    if (audioVideo) {
      audioVideo = !!pc.addStream;
    }

    // FIXME: this is not great because in theory it doesn't work for
    // av-only browsers (?).
    /*
    if (!onnegotiationneeded && data) {
      // sync default check.
      var negotiationPC = new RTCPeerConnection(defaultConfig, {optional: [{RtpDataChannels: true}]});
      negotiationPC.onnegotiationneeded = function() {
        onnegotiationneeded = true;
        // async check.
        if (util && util.supports) {
          util.supports.onnegotiationneeded = true;
        }
      };
      negotiationPC.createDataChannel('_PEERJSNEGOTIATIONTEST');

      setTimeout(function() {
        negotiationPC.close();
      }, 1000);
    }
    */

    if (pc) {
      pc.close();
    }

    return {
      audioVideo: audioVideo,
      data: data,
      binaryBlob: binaryBlob,
      binary: sctp, // deprecated; sctp implies binary support.
      reliable: sctp, // deprecated; sctp implies reliable data.
      sctp: sctp,
      onnegotiationneeded: onnegotiationneeded
    };
  })(),
  //

  // Ensure alphanumeric ids
  validateId: function(id) {
    // Allow empty ids
    return !id || /^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.exec(id);
  },

  validateKey: function(key) {
    // Allow empty keys
    return !key || /^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.exec(key);
  },

  debug: false,

  inherits: function(ctor, superCtor) {
    ctor.super_ = superCtor;
    ctor.prototype = Object.create(superCtor.prototype, {
      constructor: {
        value: ctor,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
  },
  extend: function(dest, source) {
    for (var key in source) {
      if (source.hasOwnProperty(key)) {
        dest[key] = source[key];
      }
    }
    return dest;
  },
  pack: BinaryPack.pack,
  unpack: BinaryPack.unpack,

  log: function() {
    if (util.debug) {
      var err = false;
      var copy = Array.prototype.slice.call(arguments);
      copy.unshift("PeerJS: ");
      for (var i = 0, l = copy.length; i < l; i++) {
        if (copy[i] instanceof Error) {
          copy[i] = "(" + copy[i].name + ") " + copy[i].message;
          err = true;
        }
      }
      err
        ? console.error.apply(console, copy)
        : console.log.apply(console, copy);
    }
  },

  setZeroTimeout: (function(global) {
    var timeouts = [];
    var messageName = "zero-timeout-message";

    // Like setTimeout, but only takes a function argument.	 There's
    // no time argument (always zero) and no arguments (you have to
    // use a closure).
    function setZeroTimeoutPostMessage(fn) {
      timeouts.push(fn);
      global.postMessage(messageName, "*");
    }

    function handleMessage(event) {
      if (event.source == global && event.data == messageName) {
        if (event.stopPropagation) {
          event.stopPropagation();
        }
        if (timeouts.length) {
          timeouts.shift()();
        }
      }
    }
    if (global.addEventListener) {
      global.addEventListener("message", handleMessage, true);
    } else if (global.attachEvent) {
      global.attachEvent("onmessage", handleMessage);
    }
    return setZeroTimeoutPostMessage;
  })(window),

  // Binary stuff

  // chunks a blob.
  chunk: function(bl) {
    var chunks = [];
    var size = bl.size;
    var start = (index = 0);
    var total = Math.ceil(size / util.chunkedMTU);
    while (start < size) {
      var end = Math.min(size, start + util.chunkedMTU);
      var b = bl.slice(start, end);

      var chunk = {
        __peerData: dataCount,
        n: index,
        data: b,
        total: total
      };

      chunks.push(chunk);

      start = end;
      index += 1;
    }
    dataCount += 1;
    return chunks;
  },

  blobToArrayBuffer: function(blob, cb) {
    var fr = new FileReader();
    fr.onload = function(evt) {
      cb(evt.target.result);
    };
    fr.readAsArrayBuffer(blob);
  },
  blobToBinaryString: function(blob, cb) {
    var fr = new FileReader();
    fr.onload = function(evt) {
      cb(evt.target.result);
    };
    fr.readAsBinaryString(blob);
  },
  binaryStringToArrayBuffer: function(binary) {
    var byteArray = new Uint8Array(binary.length);
    for (var i = 0; i < binary.length; i++) {
      byteArray[i] = binary.charCodeAt(i) & 0xff;
    }
    return byteArray.buffer;
  },
  randomToken: function() {
    return Math.random()
      .toString(36)
      .substr(2);
  },
  //

  isSecure: function() {
    return location.protocol === "https:";
  }
};

module.exports = util;
<commit_msg>changes RTCPeerConnection iceServers url property to urls<commit_after>var defaultConfig = {'iceServers': [{ 'urls': 'stun:stun.l.google.com:19302' }]};
var dataCount = 1;

var BinaryPack = require("js-binarypack");
var RTCPeerConnection = require("./adapter").RTCPeerConnection;

var util = {
  noop: function() {},

  CLOUD_HOST: "0.peerjs.com",
  CLOUD_PORT: 9000,

  // Browsers that need chunking:
  chunkedBrowsers: { Chrome: 1 },
  chunkedMTU: 16300, // The original 60000 bytes setting does not work when sending data from Firefox to Chrome, which is "cut off" after 16384 bytes and delivered individually.

  // Logging logic
  logLevel: 0,
  setLogLevel: function(level) {
    var debugLevel = parseInt(level, 10);
    if (!isNaN(parseInt(level, 10))) {
      util.logLevel = debugLevel;
    } else {
      // If they are using truthy/falsy values for debug
      util.logLevel = level ? 3 : 0;
    }
    util.log = util.warn = util.error = util.noop;
    if (util.logLevel > 0) {
      util.error = util._printWith("ERROR");
    }
    if (util.logLevel > 1) {
      util.warn = util._printWith("WARNING");
    }
    if (util.logLevel > 2) {
      util.log = util._print;
    }
  },
  setLogFunction: function(fn) {
    if (fn.constructor !== Function) {
      util.warn(
        "The log function you passed in is not a function. Defaulting to regular logs."
      );
    } else {
      util._print = fn;
    }
  },

  _printWith: function(prefix) {
    return function() {
      var copy = Array.prototype.slice.call(arguments);
      copy.unshift(prefix);
      util._print.apply(util, copy);
    };
  },
  _print: function() {
    var err = false;
    var copy = Array.prototype.slice.call(arguments);
    copy.unshift("PeerJS: ");
    for (var i = 0, l = copy.length; i < l; i++) {
      if (copy[i] instanceof Error) {
        copy[i] = "(" + copy[i].name + ") " + copy[i].message;
        err = true;
      }
    }
    err ? console.error.apply(console, copy) : console.log.apply(console, copy);
  },
  //

  // Returns browser-agnostic default config
  defaultConfig: defaultConfig,
  //

  // Returns the current browser.
  browser: (function() {
    if (window.mozRTCPeerConnection) {
      return "Firefox";
    } else if (window.webkitRTCPeerConnection) {
      return "Chrome";
    } else if (window.RTCPeerConnection) {
      return "Supported";
    } else {
      return "Unsupported";
    }
  })(),
  //

  // Lists which features are supported
  supports: (function() {
    if (typeof RTCPeerConnection === "undefined") {
      return {};
    }

    var data = true;
    var audioVideo = true;

    var binaryBlob = false;
    var sctp = false;
    var onnegotiationneeded = !!window.webkitRTCPeerConnection;

    var pc, dc;
    try {
      pc = new RTCPeerConnection(defaultConfig, {
        optional: [{ RtpDataChannels: true }]
      });
    } catch (e) {
      data = false;
      audioVideo = false;
    }

    if (data) {
      try {
        dc = pc.createDataChannel("_PEERJSTEST");
      } catch (e) {
        data = false;
      }
    }

    if (data) {
      // Binary test
      try {
        dc.binaryType = "blob";
        binaryBlob = true;
      } catch (e) {}

      // Reliable test.
      // Unfortunately Chrome is a bit unreliable about whether or not they
      // support reliable.
      var reliablePC = new RTCPeerConnection(defaultConfig, {});
      try {
        var reliableDC = reliablePC.createDataChannel(
          "_PEERJSRELIABLETEST",
          {}
        );
        sctp = reliableDC.reliable;
      } catch (e) {}
      reliablePC.close();
    }

    // FIXME: not really the best check...
    if (audioVideo) {
      audioVideo = !!pc.addStream;
    }

    // FIXME: this is not great because in theory it doesn't work for
    // av-only browsers (?).
    /*
    if (!onnegotiationneeded && data) {
      // sync default check.
      var negotiationPC = new RTCPeerConnection(defaultConfig, {optional: [{RtpDataChannels: true}]});
      negotiationPC.onnegotiationneeded = function() {
        onnegotiationneeded = true;
        // async check.
        if (util && util.supports) {
          util.supports.onnegotiationneeded = true;
        }
      };
      negotiationPC.createDataChannel('_PEERJSNEGOTIATIONTEST');

      setTimeout(function() {
        negotiationPC.close();
      }, 1000);
    }
    */

    if (pc) {
      pc.close();
    }

    return {
      audioVideo: audioVideo,
      data: data,
      binaryBlob: binaryBlob,
      binary: sctp, // deprecated; sctp implies binary support.
      reliable: sctp, // deprecated; sctp implies reliable data.
      sctp: sctp,
      onnegotiationneeded: onnegotiationneeded
    };
  })(),
  //

  // Ensure alphanumeric ids
  validateId: function(id) {
    // Allow empty ids
    return !id || /^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.exec(id);
  },

  validateKey: function(key) {
    // Allow empty keys
    return !key || /^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.exec(key);
  },

  debug: false,

  inherits: function(ctor, superCtor) {
    ctor.super_ = superCtor;
    ctor.prototype = Object.create(superCtor.prototype, {
      constructor: {
        value: ctor,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
  },
  extend: function(dest, source) {
    for (var key in source) {
      if (source.hasOwnProperty(key)) {
        dest[key] = source[key];
      }
    }
    return dest;
  },
  pack: BinaryPack.pack,
  unpack: BinaryPack.unpack,

  log: function() {
    if (util.debug) {
      var err = false;
      var copy = Array.prototype.slice.call(arguments);
      copy.unshift("PeerJS: ");
      for (var i = 0, l = copy.length; i < l; i++) {
        if (copy[i] instanceof Error) {
          copy[i] = "(" + copy[i].name + ") " + copy[i].message;
          err = true;
        }
      }
      err
        ? console.error.apply(console, copy)
        : console.log.apply(console, copy);
    }
  },

  setZeroTimeout: (function(global) {
    var timeouts = [];
    var messageName = "zero-timeout-message";

    // Like setTimeout, but only takes a function argument.	 There's
    // no time argument (always zero) and no arguments (you have to
    // use a closure).
    function setZeroTimeoutPostMessage(fn) {
      timeouts.push(fn);
      global.postMessage(messageName, "*");
    }

    function handleMessage(event) {
      if (event.source == global && event.data == messageName) {
        if (event.stopPropagation) {
          event.stopPropagation();
        }
        if (timeouts.length) {
          timeouts.shift()();
        }
      }
    }
    if (global.addEventListener) {
      global.addEventListener("message", handleMessage, true);
    } else if (global.attachEvent) {
      global.attachEvent("onmessage", handleMessage);
    }
    return setZeroTimeoutPostMessage;
  })(window),

  // Binary stuff

  // chunks a blob.
  chunk: function(bl) {
    var chunks = [];
    var size = bl.size;
    var start = (index = 0);
    var total = Math.ceil(size / util.chunkedMTU);
    while (start < size) {
      var end = Math.min(size, start + util.chunkedMTU);
      var b = bl.slice(start, end);

      var chunk = {
        __peerData: dataCount,
        n: index,
        data: b,
        total: total
      };

      chunks.push(chunk);

      start = end;
      index += 1;
    }
    dataCount += 1;
    return chunks;
  },

  blobToArrayBuffer: function(blob, cb) {
    var fr = new FileReader();
    fr.onload = function(evt) {
      cb(evt.target.result);
    };
    fr.readAsArrayBuffer(blob);
  },
  blobToBinaryString: function(blob, cb) {
    var fr = new FileReader();
    fr.onload = function(evt) {
      cb(evt.target.result);
    };
    fr.readAsBinaryString(blob);
  },
  binaryStringToArrayBuffer: function(binary) {
    var byteArray = new Uint8Array(binary.length);
    for (var i = 0; i < binary.length; i++) {
      byteArray[i] = binary.charCodeAt(i) & 0xff;
    }
    return byteArray.buffer;
  },
  randomToken: function() {
    return Math.random()
      .toString(36)
      .substr(2);
  },
  //

  isSecure: function() {
    return location.protocol === "https:";
  }
};

module.exports = util;
<|endoftext|>


<commit_before>/*
	BigEval extension for MikeMcl's decimal.js
	https://github.com/MikeMcl/decimal.js
*/

// function to remove prefixed + . see https://github.com/aviaryan/BigEval.js/issues/8
function p(s){
	return s[0] == '+' ? s.substr(1) : s;
}

var _decimal, _bigeval;

// import decimal module in case of node
if (typeof module !== 'undefined' && typeof exports !== 'undefined'){
	_decimal = require('decimal.js');
	_bigeval = require('bigeval');
} else {
	_decimal = Decimal;
	_bigeval = BigEval;
}

// override methods

_bigeval.prototype.number = function(str){
	return (str instanceof Decimal) ? str : new Decimal(str);
};

_bigeval.prototype.add = function(a, b){
	return new _decimal(p(a)).plus(p(b));
};

_bigeval.prototype.sub = function(a, b){
	return new _decimal(p(a)).minus(p(b));
};

_bigeval.prototype.mul = function(a, b){
	return new _decimal(p(a)).times(p(b));
};

_bigeval.prototype.div = function(a, b){
	return new _decimal(p(a)).dividedBy(p(b));
};

_bigeval.prototype.pow = function(a, b){
	return new _decimal(p(a)).pow(p(b));
};

_bigeval.prototype.lessThan = function(a, b){
	return a.lessThan(b);
};

_bigeval.prototype.lessThanOrEqualsTo = function(a, b){
	return a.lessThanOrEqualTo(b);
};

_bigeval.prototype.greaterThan = function(a, b){
	return a.greaterThan(b);
};

_bigeval.prototype.greaterThanOrEqualsTo = function(a, b){
	return a.greaterThanOrEqualTo(b);
};

_bigeval.prototype.equalsTo = function(a, b){
	return a.equals(b);
};

_bigeval.prototype.notEqualsTo = function(a, b){
	return !a.equals(b);
};

_bigeval.prototype.logicalAnd = function(a, b){
    if (!a || ((a instanceof Decimal) && a.equals(0)))
        return a;

    return b;
};

_bigeval.prototype.logicalOr = function(a, b){
    if (!a || ((a instanceof Decimal) && a.equals(0)))
        return b;

    return a;
};

_bigeval.prototype.mod = function(a, b){
	return new _decimal(p(a)).modulo(p(b));
};

_bigeval.prototype.shiftLeft = function(a, b){
	return a << b;
};

_bigeval.prototype.shiftRight = function(a, b){
	return a >> b;
};

_bigeval.prototype.and = function(a, b){
	return a & b;
};

_bigeval.prototype.xor = function(a, b){
	return a ^ b;
};

_bigeval.prototype.or = function(a, b){
	return a | b;
};

// Extra methods

_bigeval.prototype.sqrt = function(a){
	return new _decimal(p(a)).sqrt();
};

_bigeval.prototype.log = function(a){
	return new _decimal(p(a)).log();
};

_bigeval.prototype.ln = function(a){
	return new _decimal(p(a)).ln();
};

_bigeval.prototype.exp = function(a){
	return new _decimal(p(a)).exp();
};

/*
 * Export module
 */
if (typeof module !== 'undefined' && module.exports && typeof exports !== 'undefined'){
	module.exports = _bigeval;
}<commit_msg>Implemented isTruthy in MikeMcl-decimal.js<commit_after>/*
	BigEval extension for MikeMcl's decimal.js
	https://github.com/MikeMcl/decimal.js
*/

// function to remove prefixed + . see https://github.com/aviaryan/BigEval.js/issues/8
function p(s){
	return s[0] == '+' ? s.substr(1) : s;
}

var _decimal, _bigeval;

// import decimal module in case of node
if (typeof module !== 'undefined' && typeof exports !== 'undefined'){
	_decimal = require('decimal.js');
	_bigeval = require('bigeval');
} else {
	_decimal = Decimal;
	_bigeval = BigEval;
}

// override methods

_bigeval.prototype.number = function(str){
	return (str instanceof Decimal) ? str : new Decimal(str);
};

_bigeval.prototype.add = function(a, b){
	return new _decimal(p(a)).plus(p(b));
};

_bigeval.prototype.sub = function(a, b){
	return new _decimal(p(a)).minus(p(b));
};

_bigeval.prototype.mul = function(a, b){
	return new _decimal(p(a)).times(p(b));
};

_bigeval.prototype.div = function(a, b){
	return new _decimal(p(a)).dividedBy(p(b));
};

_bigeval.prototype.pow = function(a, b){
	return new _decimal(p(a)).pow(p(b));
};

_bigeval.prototype.lessThan = function(a, b){
	return a.lessThan(b);
};

_bigeval.prototype.lessThanOrEqualsTo = function(a, b){
	return a.lessThanOrEqualTo(b);
};

_bigeval.prototype.greaterThan = function(a, b){
	return a.greaterThan(b);
};

_bigeval.prototype.greaterThanOrEqualsTo = function(a, b){
	return a.greaterThanOrEqualTo(b);
};

_bigeval.prototype.equalsTo = function(a, b){
	return a.equals(b);
};

_bigeval.prototype.notEqualsTo = function(a, b){
	return !a.equals(b);
};

_bigeval.prototype.isTruthy = function(a){
	return !a.equals(0);
};

_bigeval.prototype.logicalAnd = function(a, b){
    if (!a || ((a instanceof Decimal) && a.equals(0)))
        return a;

    return b;
};

_bigeval.prototype.logicalOr = function(a, b){
    if (!a || ((a instanceof Decimal) && a.equals(0)))
        return b;

    return a;
};

_bigeval.prototype.mod = function(a, b){
	return new _decimal(p(a)).modulo(p(b));
};

_bigeval.prototype.shiftLeft = function(a, b){
	return a << b;
};

_bigeval.prototype.shiftRight = function(a, b){
	return a >> b;
};

_bigeval.prototype.and = function(a, b){
	return a & b;
};

_bigeval.prototype.xor = function(a, b){
	return a ^ b;
};

_bigeval.prototype.or = function(a, b){
	return a | b;
};

// Extra methods

_bigeval.prototype.sqrt = function(a){
	return new _decimal(p(a)).sqrt();
};

_bigeval.prototype.log = function(a){
	return new _decimal(p(a)).log();
};

_bigeval.prototype.ln = function(a){
	return new _decimal(p(a)).ln();
};

_bigeval.prototype.exp = function(a){
	return new _decimal(p(a)).exp();
};

/*
 * Export module
 */
if (typeof module !== 'undefined' && module.exports && typeof exports !== 'undefined'){
	module.exports = _bigeval;
}
<|endoftext|>


<commit_before>'use strict'

const fs = require('fs')
const path = require('path')
const { promisify } = require('util')
const { spawn } = require('child_process')
const which = require('which')
const debug = require('debug')('0x')
const execSpawn = require('execspawn')
const envString = require('env-string')
const makeDir = require('make-dir')

module.exports = {
  getTargetFolder, tidy, pathTo, isSudo, noop, spawnOnPort, when
}

function when (ee, evt) {
  return promisify((cb) => ee.once(evt, (...args) => cb(null, ...args)))()
}

function spawnOnPort (cmd, port) {
  if (typeof cmd === 'function') {
    return new Promise((resolve, reject) => {
      cmd(port, err => {
        if (err) reject(err)
        else resolve(0, null)
      })
    })
  }

  const sp = execSpawn(envString(cmd, {PORT: port + ''}), {stdio: 'inherit'})
  return new Promise((resolve, reject) => {
    sp.on('exit', (code, signal) => {
      if (code === 0 || code === null) resolve(code, signal)
      else reject(Object.assign(Error(`onPort command failed with code: ${code}`), { code }))
    })
  })
}

function getTargetFolder ({outputDir, workingDir, name, pid}) {
  name = (outputDir || '{pid}.0x').replace('{pid}', pid || 'UNKNOWN_PID')
    .replace('{timestamp}', Date.now())
    .replace('{cwd}', workingDir)
    .replace('{name}', name)

  const folder = path.resolve(workingDir, name)
  makeDir.sync(folder)

  return folder
}

function tidy () {
  debug('tidying up')

  fs.readdirSync('.')
    .filter(function (f) {
      return /isolate-(0x[0-9A-Fa-f]{2,12})-v8\.log/.test(f)
    })
    .forEach(function (f) {
      fs.unlinkSync(f)
    })
}

function pathTo (bin) {
  if (fs.existsSync(bin)) { return bin }
  return which.sync(bin)
}

function isSudo () {
  var check = spawn('sudo', ['-n', 'true'])
  return new Promise((resolve, reject) => {
    check.on('error', reject)
    check.on('exit', function (code) {
      if (!code) return resolve(true)
      resolve(false)
    })
  })
}

function noop () {}
<commit_msg>Replace all placeholders, not just first<commit_after>'use strict'

const fs = require('fs')
const path = require('path')
const { promisify } = require('util')
const { spawn } = require('child_process')
const which = require('which')
const debug = require('debug')('0x')
const execSpawn = require('execspawn')
const envString = require('env-string')
const makeDir = require('make-dir')

module.exports = {
  getTargetFolder, tidy, pathTo, isSudo, noop, spawnOnPort, when
}

function when (ee, evt) {
  return promisify((cb) => ee.once(evt, (...args) => cb(null, ...args)))()
}

function spawnOnPort (cmd, port) {
  if (typeof cmd === 'function') {
    return new Promise((resolve, reject) => {
      cmd(port, err => {
        if (err) reject(err)
        else resolve(0, null)
      })
    })
  }

  const sp = execSpawn(envString(cmd, {PORT: port + ''}), {stdio: 'inherit'})
  return new Promise((resolve, reject) => {
    sp.on('exit', (code, signal) => {
      if (code === 0 || code === null) resolve(code, signal)
      else reject(Object.assign(Error(`onPort command failed with code: ${code}`), { code }))
    })
  })
}

function getTargetFolder ({outputDir, workingDir, name, pid}) {
  name = (outputDir || '{pid}.0x').replace(/{pid}/g, pid || 'UNKNOWN_PID')
    .replace(/{timestamp}/g, Date.now())
    .replace(/{cwd}/g, workingDir)
    .replace(/{name}/g, name)

  const folder = path.resolve(workingDir, name)
  makeDir.sync(folder)

  return folder
}

function tidy () {
  debug('tidying up')

  fs.readdirSync('.')
    .filter(function (f) {
      return /isolate-(0x[0-9A-Fa-f]{2,12})-v8\.log/.test(f)
    })
    .forEach(function (f) {
      fs.unlinkSync(f)
    })
}

function pathTo (bin) {
  if (fs.existsSync(bin)) { return bin }
  return which.sync(bin)
}

function isSudo () {
  var check = spawn('sudo', ['-n', 'true'])
  return new Promise((resolve, reject) => {
    check.on('error', reject)
    check.on('exit', function (code) {
      if (!code) return resolve(true)
      resolve(false)
    })
  })
}

function noop () {}
<|endoftext|>


<commit_before>(function (g, factory) {
    /* globals module:0, define:0 */

    'use strict';

    /* istanbul ignore next */
    if (typeof exports === 'object') {
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        define('ceb', [], factory);
    } else {
        g.ceb = factory();
    }

}(this, function () {

    'use strict';

    var testing = {};

    /* TOOLS */

    function emptyFn() {
        return function () {};
    }
    testing.emptyFn = emptyFn;

    function listValues(o) {
        return Object.getOwnPropertyNames(o).map(function (propName) {
            return o[propName];
        });
    }
    testing.listValues = listValues;

    // transform property notation to attribute notation
    function fromCamelCaseToHyphenCase(value) {
        return value.split(/(?=[A-Z])/).map(function (part) {
            return part.charAt(0).toLowerCase() + part.slice(1);
        }).join('-');
    }
    testing.fromCamelCaseToHyphenCase = fromCamelCaseToHyphenCase;

    function compareLevels(a, b) {
        return a.level - b.level;
    }
    testing.compareLevels = compareLevels;

    function applyAttributeValue(el, attName, value, isBoolean) {
        if (isBoolean) {
            if (value && !el.hasAttribute(attName)) {
                el.setAttribute(attName, '');
            } else if (!value && el.hasAttribute(attName)) {
                el.removeAttribute(attName);
            }
        } else {
            if ((value === null || value === undefined) && el.hasAttribute(attName)) {
                el.removeAttribute(attName);
            } else if ((value !== null && value !== undefined) && el.getAttribute(attName) !== value) {
                el.setAttribute(attName, value);
            }
        }
    }
    testing.applyAttributeValue = applyAttributeValue;

    function accessorFactory(wrappers, wrapped) {
        var stack = wrappers.sort(compareLevels);
        return function () {
            var el = this;
            return stack.reduce(function (previous, current) {
                return current.bind(el, previous, el);
            }, wrapped.bind(el, el)).apply(el, arguments);
        };
    }
    testing.accessorFactory = accessorFactory;

    function attributeAccessorSetFactory(attName, setter, isBoolean) {
        return function (el, value) {
            var attValue = value;
            if (setter) {
                attValue = setter.call(el, el, value);
            }
            applyAttributeValue(el, attName, attValue, isBoolean);
        };
    }
    testing.attributeAccessorSetFactory = attributeAccessorSetFactory;

    function attributeAccessorGetFactory(attName, getter, isBoolean) {
        return function (el) {
            var value = isBoolean ? el.hasAttribute(attName) : el.getAttribute(attName);
            if (getter) {
                value = getter.call(el, el, value);
            }
            return value;
        };
    }
    testing.attributeAccessorGetFactory = attributeAccessorGetFactory;

    function methodFactory(wrappers, wrapped) {
        var stack = wrappers.sort(compareLevels);
        return function () {
            var el = this;
            return stack.reduce(function (previous, current) {
                return current.bind(el, function next(args) {
                    return previous.apply(el, Array.prototype.slice.call(args).slice(2, args.length));
                }, el);
            }, wrapped.bind(el, el)).apply(el, arguments);
        };
    }
    testing.methodFactory = methodFactory;

    /* BUILD LIFE CYCLE */

    function sanitizeStructure(struct) {
        struct.prototype = struct.prototype || Object.create(HTMLElement.prototype);
        struct.features = struct.features || [];
        struct.interceptors = struct.interceptors || [];
        struct.wrappers = struct.wrappers || [];
        struct.properties = struct.properties || {};
        struct.methods = Object.assign({
            createdCallback: emptyFn(),
            attachedCallback: emptyFn(),
            detachedCallback: emptyFn(),
            attributeChangedCallback: emptyFn()
        }, struct.methods);
        return struct;
    }
    testing.sanitizeStructure = sanitizeStructure;

    function setupFeatures(struct) {
        var b = builder(struct.tagName, {
            struct: struct,
            registered: true
        });
        struct.features.sort(compareLevels).forEach(function (feature) {
            if (feature.fn && feature.fn.setup) {
                feature.fn.setup(struct, b, feature.options);
            }
        });
    }
    testing.setupFeatures = setupFeatures;

    function createAttributesHash(struct) {
        return listValues(struct.properties).filter(function (property) {
            return property.attName;
        }).reduce(function (previous, current) {
            previous[current.attName] = current;
            return previous;
        }, {});
    }
    testing.createAttributesHash = createAttributesHash;

    function createDefinedPropertiesHash(struct) {
        return listValues(struct.properties).map(function (property) {
            // default parameters
            var definedProperty = {
                configurable: false,
                enumerable: true
            };

            if (property.attribute) {
                // handle properties linked to an attribute
                property.set = attributeAccessorSetFactory(property.attName, property.setter, !!property.attribute.boolean);
                property.get = attributeAccessorGetFactory(property.attName, property.getter, !!property.attribute.boolean);
            } else if (property.hasOwnProperty('value') && property.hasOwnProperty('writable') && !property.writable) {
                // handle constants
                definedProperty.value = property.value;
                definedProperty.writable = false;
            } else if (!property.set && !property.get) {
                definedProperty.writable = true;
            }

            if (!definedProperty.hasOwnProperty('writable')) {
                // handle setter and getter
                var interceptors = struct.interceptors[property.propName] || {};
                if (property.set) {
                    var setStack = interceptors.set || [];
                    definedProperty.set = accessorFactory(setStack, property.set);
                }
                if (property.get) {
                    var getStack = interceptors.get || [];
                    definedProperty.get = accessorFactory(getStack, property.get);
                }
            }

            return Object.assign(property, {
                property: definedProperty
            });
        }).reduce(function (previous, current) {
            previous[current.propName] = current.property;
            return previous;
        }, {});
    }
    testing.createDefinedPropertiesHash = createDefinedPropertiesHash;

    function createMethodsHash(struct) {
        return Object.getOwnPropertyNames(struct.methods).map(function (methName) {
            var stack = struct.wrappers[methName] || [];
            var fn = struct.methods[methName];
            return {
                methName: methName,
                fn: methodFactory(stack, fn)
            };
        }).reduce(function (previous, current) {
            previous[current.methName] = current.fn;
            return previous;
        }, {});
    }
    testing.createMethodsHash = createMethodsHash;

    /* BUILD */

    var build = function build(struct) {
        sanitizeStructure(struct);
        setupFeatures(struct);

        struct.definedProperties = createDefinedPropertiesHash(struct);
        struct.attributes = createAttributesHash(struct);
        struct.methods = createMethodsHash(struct);

        Object.defineProperties(struct.prototype, struct.definedProperties);
        Object.assign(struct.prototype, struct.methods);

        return document.registerElement(struct.tagName, struct);
    };
    testing.build = build;

    /* FEATURES */

    var builtInFeatures = {};
    testing.builtInFeatures = builtInFeatures;

    builtInFeatures.delegate = emptyFn();
    builtInFeatures.delegate.delegableSetAccessorInterceptor = function (property, next, el, value) {
        next(value);
        var target = el.querySelector(property.delegate.target);
        /* istanbul ignore else  */
        if (target) {
            var targetPropName = property.delegate.property;
            var targetAttName = property.delegate.attribute;
            if (!targetPropName && !targetAttName) {
                targetPropName = property.propName;
                targetAttName = property.attName;
            }
            var isBoolean = property.attribute && !!property.attribute.boolean;
            if (property.delegate.hasOwnProperty('boolean')) {
                isBoolean = property.delegate.boolean;
            }
            if (targetAttName) {
                applyAttributeValue(target, targetAttName, value, isBoolean);
            } else {
                target[targetPropName] = value;
            }
        }
    };
    builtInFeatures.delegate.delegableGetAccessorInterceptor = function (property, next, el, value) {
        var result = next(value);
        var target = el.querySelector(property.delegate.target);
        /* istanbul ignore else  */
        if (target) {
            var targetPropName = property.delegate.property;
            var targetAttName = property.delegate.attribute;
            if (!targetPropName && !targetAttName) {
                targetPropName = property.propName;
                targetAttName = property.attName;
            }
            var isBoolean = property.attribute && !!property.attribute.boolean;
            if (property.delegate.hasOwnProperty('boolean')) {
                isBoolean = property.delegate.boolean;
            }
            if (targetAttName) {
                result = isBoolean ? target.hasAttribute(targetAttName) : target.getAttribute(targetAttName);
            } else {
                result = target[targetPropName];
            }
        }
        return result;
    };
    builtInFeatures.delegate.setup = function (struct, builder) {
        var delegableSetAccessorInterceptor = builtInFeatures.delegate.delegableSetAccessorInterceptor;
        var delegableGetAccessorInterceptor = builtInFeatures.delegate.delegableGetAccessorInterceptor;
        // keep only properties configured for delegation
        listValues(struct.properties).filter(function (property) {
            return property.delegate;
        }).forEach(function (property) {
            // intercept the setter
            if (!property.attName) {
                property.set = property.set || emptyFn();
                property.get = property.get || emptyFn();
            }
            builder.intercept(
                property.propName,
                delegableSetAccessorInterceptor.bind(builtInFeatures.delegate, property),
                delegableGetAccessorInterceptor.bind(builtInFeatures.delegate, property)
            );
        });
    };

    builtInFeatures.valueInitializer = emptyFn();
    builtInFeatures.valueInitializer.createdCallbackWrapper = function (struct, next, el) {
        next(arguments);
        listValues(struct.properties).forEach(function (property) {
            if (property.attName) {
                if (el.hasAttribute(property.attName)) {
                    el[property.propName] = property.attribute.boolean ? true : el.getAttribute(property.attName);
                } else if (property.hasOwnProperty('value')) {
                    applyAttributeValue(el, property.attName, property.value, property.attribute.boolean);
                }
            } else if (property.hasOwnProperty('value') && property.writable) {
                el[property.propName] = property.value;
            }
        });
    };
    builtInFeatures.valueInitializer.attributeChangedCallbackWrapper = function (struct, next, el, attName, oldVal, newVal) {
        var property = struct.attributes[attName];
        if (property) {
            var value = newVal;
            if (property.attribute.boolean) {
                value = typeof newVal === 'string' ? true : false;
            }
            el[property.propName] = value;
        }
        next(arguments);
    };
    builtInFeatures.valueInitializer.setup = function (struct, builder) {
        var createdCallbackWrapper = builtInFeatures.valueInitializer.createdCallbackWrapper;
        var attributeChangedCallbackWrapper = builtInFeatures.valueInitializer.attributeChangedCallbackWrapper;
        builder.wrap('createdCallback', createdCallbackWrapper.bind(builtInFeatures.valueInitializer, struct));
        builder.wrap('attributeChangedCallback', attributeChangedCallbackWrapper.bind(builtInFeatures.valueInitializer, struct));
    };

    /* BUILDER */

    function baseStructFactory() {
        return {
            properties: {},
            methods: {},
            wrappers: [],
            interceptors: [],
            features: [{
                fn: builtInFeatures.delegate,
                level: -2
            }, {
                fn: builtInFeatures.valueInitializer,
                level: -1
            }]
        };
    }
    testing.baseStructFactory = baseStructFactory;

    function sanitizeProperty(property) {
        if (property.attribute) {
            property.attName = property.attribute.name || fromCamelCaseToHyphenCase(property.propName);
        }
        property.writable = property.hasOwnProperty('writable') ? property.writable : true;
        return property;
    }
    testing.sanitizeProperty = sanitizeProperty;

    var builder = function builder(tagName, params) {
        var struct = params && params.struct ? sanitizeStructure(params.struct) : baseStructFactory();
        struct.tagName = tagName;
        var registered = params && params.hasOwnProperty('registered') ? params.registered : false;
        var api = {};
        // WRAPPER
        api.wrap = function (methName, fn, level) {
            if (!struct.wrappers[methName]) {
                struct.wrappers[methName] = [];
            }
            fn.level = isNaN(level) ? 0 : level;
            struct.wrappers[methName].push(fn);
            return api;
        };
        api.intercept = function (propName, setFn, getFn, level) {
            if (!struct.interceptors[propName]) {
                struct.interceptors[propName] = {
                    set: [],
                    get: []
                };
            }
            if (setFn) {
                setFn.level = isNaN(level) ? 0 : level;
                struct.interceptors[propName].set.push(setFn);
            }
            if (getFn) {
                getFn.level = isNaN(level) ? 0 : level;
                struct.interceptors[propName].get.push(getFn);
            }
            return api;
        };
        // INTEGRATION
        api['extends'] = function (anExtend) {
            struct['extends'] = anExtend;
            return api;
        };
        api.prototype = function (aProto) {
            struct.prototype = aProto;
            return api;
        };
        // FELDS
        api.properties = function (someProperties) {

            var sanitizedProperties = Object.getOwnPropertyNames(someProperties).map(function (propName) {
                return Object.assign(someProperties[propName], {
                    propName: propName
                });
            }).map(sanitizeProperty).reduce(function (previous, current) {
                previous[current.propName] = current;
                return previous;
            }, {});

            Object.assign(struct.properties, sanitizedProperties);

            return api;
        };
        api.methods = function (someMethods) {
            Object.assign(struct.methods, someMethods);
            return api;
        };
        // FEATURES
        api.feature = function (fn, options, level) {
            struct.features.push({
                fn: fn,
                options: options,
                level: isNaN(level) ? 0 : level
            });
            return api;
        };
        api.register = function () {
            if (!registered) {
                registered = true;
                return build(struct);
            }
        };
        api.get = function () {
            return struct;
        };
        return api;
    };
    testing.builder = builder;

    function factory(params) {
        var api = {};
        api.name = function (tagName) {
            return builder(tagName, params);
        };
        return api;
    }
    factory._testing = testing;

    return factory;
}));
<commit_msg>name anonymous function<commit_after>(function (g, factory) {
    /* globals module:0, define:0 */

    'use strict';

    /* istanbul ignore next */
    if (typeof exports === 'object') {
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        define('ceb', [], factory);
    } else {
        g.ceb = factory();
    }

}(this, function () {

    'use strict';

    var testing = {};

    /* TOOLS */

    function emptyFn() {
        return function () {};
    }
    testing.emptyFn = emptyFn;

    function listValues(o) {
        return Object.getOwnPropertyNames(o).map(function (propName) {
            return o[propName];
        });
    }
    testing.listValues = listValues;

    // transform property notation to attribute notation
    function fromCamelCaseToHyphenCase(value) {
        return value.split(/(?=[A-Z])/).map(function (part) {
            return part.charAt(0).toLowerCase() + part.slice(1);
        }).join('-');
    }
    testing.fromCamelCaseToHyphenCase = fromCamelCaseToHyphenCase;

    function compareLevels(a, b) {
        return a.level - b.level;
    }
    testing.compareLevels = compareLevels;

    function applyAttributeValue(el, attName, value, isBoolean) {
        if (isBoolean) {
            if (value && !el.hasAttribute(attName)) {
                el.setAttribute(attName, '');
            } else if (!value && el.hasAttribute(attName)) {
                el.removeAttribute(attName);
            }
        } else {
            if ((value === null || value === undefined) && el.hasAttribute(attName)) {
                el.removeAttribute(attName);
            } else if ((value !== null && value !== undefined) && el.getAttribute(attName) !== value) {
                el.setAttribute(attName, value);
            }
        }
    }
    testing.applyAttributeValue = applyAttributeValue;

    function accessorFactory(wrappers, wrapped) {
        var stack = wrappers.sort(compareLevels);
        return function accessor() {
            var el = this;
            return stack.reduce(function (previous, current) {
                return current.bind(el, previous, el);
            }, wrapped.bind(el, el)).apply(el, arguments);
        };
    }
    testing.accessorFactory = accessorFactory;

    function attributeAccessorSetFactory(attName, setter, isBoolean) {
        return function attributeAccessorSet(el, value) {
            var attValue = value;
            if (setter) {
                attValue = setter.call(el, el, value);
            }
            applyAttributeValue(el, attName, attValue, isBoolean);
        };
    }
    testing.attributeAccessorSetFactory = attributeAccessorSetFactory;

    function attributeAccessorGetFactory(attName, getter, isBoolean) {
        return function attributeAccessorGet(el) {
            var value = isBoolean ? el.hasAttribute(attName) : el.getAttribute(attName);
            if (getter) {
                value = getter.call(el, el, value);
            }
            return value;
        };
    }
    testing.attributeAccessorGetFactory = attributeAccessorGetFactory;

    function methodFactory(wrappers, wrapped) {
        var stack = wrappers.sort(compareLevels);
        return function () {
            var el = this;
            return stack.reduce(function (previous, current) {
                return current.bind(el, function next(args) {
                    return previous.apply(el, Array.prototype.slice.call(args).slice(2, args.length));
                }, el);
            }, wrapped.bind(el, el)).apply(el, arguments);
        };
    }
    testing.methodFactory = methodFactory;

    /* BUILD LIFE CYCLE */

    function sanitizeStructure(struct) {
        struct.prototype = struct.prototype || Object.create(HTMLElement.prototype);
        struct.features = struct.features || [];
        struct.interceptors = struct.interceptors || [];
        struct.wrappers = struct.wrappers || [];
        struct.properties = struct.properties || {};
        struct.methods = Object.assign({
            createdCallback: emptyFn(),
            attachedCallback: emptyFn(),
            detachedCallback: emptyFn(),
            attributeChangedCallback: emptyFn()
        }, struct.methods);
        return struct;
    }
    testing.sanitizeStructure = sanitizeStructure;

    function setupFeatures(struct) {
        var b = builder(struct.tagName, {
            struct: struct,
            registered: true
        });
        struct.features.sort(compareLevels).forEach(function (feature) {
            if (feature.fn && feature.fn.setup) {
                feature.fn.setup(struct, b, feature.options);
            }
        });
    }
    testing.setupFeatures = setupFeatures;

    function createAttributesHash(struct) {
        return listValues(struct.properties).filter(function (property) {
            return property.attName;
        }).reduce(function (previous, current) {
            previous[current.attName] = current;
            return previous;
        }, {});
    }
    testing.createAttributesHash = createAttributesHash;

    function createDefinedPropertiesHash(struct) {
        return listValues(struct.properties).map(function (property) {
            // default parameters
            var definedProperty = {
                configurable: false,
                enumerable: true
            };

            if (property.attribute) {
                // handle properties linked to an attribute
                property.set = attributeAccessorSetFactory(property.attName, property.setter, !!property.attribute.boolean);
                property.get = attributeAccessorGetFactory(property.attName, property.getter, !!property.attribute.boolean);
            } else if (property.hasOwnProperty('value') && property.hasOwnProperty('writable') && !property.writable) {
                // handle constants
                definedProperty.value = property.value;
                definedProperty.writable = false;
            } else if (!property.set && !property.get) {
                definedProperty.writable = true;
            }

            if (!definedProperty.hasOwnProperty('writable')) {
                // handle setter and getter
                var interceptors = struct.interceptors[property.propName] || {};
                if (property.set) {
                    var setStack = interceptors.set || [];
                    definedProperty.set = accessorFactory(setStack, property.set);
                }
                if (property.get) {
                    var getStack = interceptors.get || [];
                    definedProperty.get = accessorFactory(getStack, property.get);
                }
            }

            return Object.assign(property, {
                property: definedProperty
            });
        }).reduce(function (previous, current) {
            previous[current.propName] = current.property;
            return previous;
        }, {});
    }
    testing.createDefinedPropertiesHash = createDefinedPropertiesHash;

    function createMethodsHash(struct) {
        return Object.getOwnPropertyNames(struct.methods).map(function (methName) {
            var stack = struct.wrappers[methName] || [];
            var fn = struct.methods[methName];
            return {
                methName: methName,
                fn: methodFactory(stack, fn)
            };
        }).reduce(function (previous, current) {
            previous[current.methName] = current.fn;
            return previous;
        }, {});
    }
    testing.createMethodsHash = createMethodsHash;

    /* BUILD */

    var build = function build(struct) {
        sanitizeStructure(struct);
        setupFeatures(struct);

        struct.definedProperties = createDefinedPropertiesHash(struct);
        struct.attributes = createAttributesHash(struct);
        struct.methods = createMethodsHash(struct);

        Object.defineProperties(struct.prototype, struct.definedProperties);
        Object.assign(struct.prototype, struct.methods);

        return document.registerElement(struct.tagName, struct);
    };
    testing.build = build;

    /* FEATURES */

    var builtInFeatures = {};
    testing.builtInFeatures = builtInFeatures;

    builtInFeatures.delegate = emptyFn();
    builtInFeatures.delegate.delegableSetAccessorInterceptor = function (property, next, el, value) {
        next(value);
        var target = el.querySelector(property.delegate.target);
        /* istanbul ignore else  */
        if (target) {
            var targetPropName = property.delegate.property;
            var targetAttName = property.delegate.attribute;
            if (!targetPropName && !targetAttName) {
                targetPropName = property.propName;
                targetAttName = property.attName;
            }
            var isBoolean = property.attribute && !!property.attribute.boolean;
            if (property.delegate.hasOwnProperty('boolean')) {
                isBoolean = property.delegate.boolean;
            }
            if (targetAttName) {
                applyAttributeValue(target, targetAttName, value, isBoolean);
            } else {
                target[targetPropName] = value;
            }
        }
    };
    builtInFeatures.delegate.delegableGetAccessorInterceptor = function (property, next, el, value) {
        var result = next(value);
        var target = el.querySelector(property.delegate.target);
        /* istanbul ignore else  */
        if (target) {
            var targetPropName = property.delegate.property;
            var targetAttName = property.delegate.attribute;
            if (!targetPropName && !targetAttName) {
                targetPropName = property.propName;
                targetAttName = property.attName;
            }
            var isBoolean = property.attribute && !!property.attribute.boolean;
            if (property.delegate.hasOwnProperty('boolean')) {
                isBoolean = property.delegate.boolean;
            }
            if (targetAttName) {
                result = isBoolean ? target.hasAttribute(targetAttName) : target.getAttribute(targetAttName);
            } else {
                result = target[targetPropName];
            }
        }
        return result;
    };
    builtInFeatures.delegate.setup = function (struct, builder) {
        var delegableSetAccessorInterceptor = builtInFeatures.delegate.delegableSetAccessorInterceptor;
        var delegableGetAccessorInterceptor = builtInFeatures.delegate.delegableGetAccessorInterceptor;
        // keep only properties configured for delegation
        listValues(struct.properties).filter(function (property) {
            return property.delegate;
        }).forEach(function (property) {
            // intercept the setter
            if (!property.attName) {
                property.set = property.set || emptyFn();
                property.get = property.get || emptyFn();
            }
            builder.intercept(
                property.propName,
                delegableSetAccessorInterceptor.bind(builtInFeatures.delegate, property),
                delegableGetAccessorInterceptor.bind(builtInFeatures.delegate, property)
            );
        });
    };

    builtInFeatures.valueInitializer = emptyFn();
    builtInFeatures.valueInitializer.createdCallbackWrapper = function (struct, next, el) {
        next(arguments);
        listValues(struct.properties).forEach(function (property) {
            if (property.attName) {
                if (el.hasAttribute(property.attName)) {
                    el[property.propName] = property.attribute.boolean ? true : el.getAttribute(property.attName);
                } else if (property.hasOwnProperty('value')) {
                    applyAttributeValue(el, property.attName, property.value, property.attribute.boolean);
                }
            } else if (property.hasOwnProperty('value') && property.writable) {
                el[property.propName] = property.value;
            }
        });
    };
    builtInFeatures.valueInitializer.attributeChangedCallbackWrapper = function (struct, next, el, attName, oldVal, newVal) {
        var property = struct.attributes[attName];
        if (property) {
            var value = newVal;
            if (property.attribute.boolean) {
                value = typeof newVal === 'string' ? true : false;
            }
            el[property.propName] = value;
        }
        next(arguments);
    };
    builtInFeatures.valueInitializer.setup = function (struct, builder) {
        var createdCallbackWrapper = builtInFeatures.valueInitializer.createdCallbackWrapper;
        var attributeChangedCallbackWrapper = builtInFeatures.valueInitializer.attributeChangedCallbackWrapper;
        builder.wrap('createdCallback', createdCallbackWrapper.bind(builtInFeatures.valueInitializer, struct));
        builder.wrap('attributeChangedCallback', attributeChangedCallbackWrapper.bind(builtInFeatures.valueInitializer, struct));
    };

    /* BUILDER */

    function baseStructFactory() {
        return {
            properties: {},
            methods: {},
            wrappers: [],
            interceptors: [],
            features: [{
                fn: builtInFeatures.delegate,
                level: -2
            }, {
                fn: builtInFeatures.valueInitializer,
                level: -1
            }]
        };
    }
    testing.baseStructFactory = baseStructFactory;

    function sanitizeProperty(property) {
        if (property.attribute) {
            property.attName = property.attribute.name || fromCamelCaseToHyphenCase(property.propName);
        }
        property.writable = property.hasOwnProperty('writable') ? property.writable : true;
        return property;
    }
    testing.sanitizeProperty = sanitizeProperty;

    var builder = function builder(tagName, params) {
        var struct = params && params.struct ? sanitizeStructure(params.struct) : baseStructFactory();
        struct.tagName = tagName;
        var registered = params && params.hasOwnProperty('registered') ? params.registered : false;
        var api = {};
        // WRAPPER
        api.wrap = function (methName, fn, level) {
            if (!struct.wrappers[methName]) {
                struct.wrappers[methName] = [];
            }
            fn.level = isNaN(level) ? 0 : level;
            struct.wrappers[methName].push(fn);
            return api;
        };
        api.intercept = function (propName, setFn, getFn, level) {
            if (!struct.interceptors[propName]) {
                struct.interceptors[propName] = {
                    set: [],
                    get: []
                };
            }
            if (setFn) {
                setFn.level = isNaN(level) ? 0 : level;
                struct.interceptors[propName].set.push(setFn);
            }
            if (getFn) {
                getFn.level = isNaN(level) ? 0 : level;
                struct.interceptors[propName].get.push(getFn);
            }
            return api;
        };
        // INTEGRATION
        api['extends'] = function (anExtend) {
            struct['extends'] = anExtend;
            return api;
        };
        api.prototype = function (aProto) {
            struct.prototype = aProto;
            return api;
        };
        // FELDS
        api.properties = function (someProperties) {

            var sanitizedProperties = Object.getOwnPropertyNames(someProperties).map(function (propName) {
                return Object.assign(someProperties[propName], {
                    propName: propName
                });
            }).map(sanitizeProperty).reduce(function (previous, current) {
                previous[current.propName] = current;
                return previous;
            }, {});

            Object.assign(struct.properties, sanitizedProperties);

            return api;
        };
        api.methods = function (someMethods) {
            Object.assign(struct.methods, someMethods);
            return api;
        };
        // FEATURES
        api.feature = function (fn, options, level) {
            struct.features.push({
                fn: fn,
                options: options,
                level: isNaN(level) ? 0 : level
            });
            return api;
        };
        api.register = function () {
            if (!registered) {
                registered = true;
                return build(struct);
            }
        };
        api.get = function () {
            return struct;
        };
        return api;
    };
    testing.builder = builder;

    function factory(params) {
        var api = {};
        api.name = function (tagName) {
            return builder(tagName, params);
        };
        return api;
    }
    factory._testing = testing;

    return factory;
}));
<|endoftext|>


<commit_before>/**
 * Provides --phone and --tabled options to force given device viewport and user agent
 *
 * @see https://github.com/macbre/phantomas/issues/213
 */
'use strict';

module.exports = function(phantomas) {
	var device,
		// @see https://developers.google.com/chrome/mobile/docs/user-agent?hl=pl
		// @see http://viewportsizes.com/
		devices = {
			// pretend we're iPhone
			phone: {
				viewport: '320x568',
				'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_0_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13A452 Safari/601.1'
			},
			// pretend we're iPad
			tablet: {
				viewport: '768x1024',
				'user-agent': 'Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B5110e Safari/601.1'
			}
		},
		availableDevices = Object.keys(devices);

	// check if --phone or --tablet option was passed
	availableDevices.forEach(function(item) {
		if (phantomas.getParam(item) === true) {
			device = item;
			return false;
		}
	});

	// no profile selected, add a hint to the logs
	if (typeof device === 'undefined') {
		phantomas.log('Devices: no profile selected (available: %s)', availableDevices.join(', '));
		return;
	}

	// apply the profile
	phantomas.log('Devices: using "%s" profile', device);

	Object.keys(devices[device]).forEach(function(key) {
		phantomas.setParam(key, devices[device][key]);
	});
};
<commit_msg>devices: read descriptors from puppeteer/DeviceDescriptors<commit_after>/**
 * Provides --phone, --phone-landscape, --tablet and --table-landscape options to force given device viewport and user agent.
 *
 * @see https://github.com/macbre/phantomas/issues/213
 * @see https://github.com/GoogleChrome/puppeteer/blob/v1.11.0/docs/api.md#pageemulateoptions
 */
'use strict';

module.exports = function(phantomas) {
	const devices = require('puppeteer/DeviceDescriptors'),
		// @see https://github.com/GoogleChrome/puppeteer/blob/master/DeviceDescriptors.js
		availableDevices = {
			'phone': 'Galaxy S5', // 360x640
			'phone-landscape': 'Galaxy S5 landscape', // 640x360
			'tablet': 'Kindle Fire HDX', // 800x1200
			'tablet-landscape': 'Kindle Fire HDX landscape', // 1280x800
		};

	var device;

	// check if --phone or --tablet option was passed
	Object.keys(availableDevices).forEach(function(item) {
		if (phantomas.getParam(item) === true) {
			device = item;
			return false;
		}
	});

	// no profile selected, add a hint to the logs
	if (typeof device === 'undefined') {
		phantomas.log('No profile selected (available: %s)', Object.keys(availableDevices).join(', '));
		return;
	}

	// apply the profile
	const profileName = availableDevices[device];

	phantomas.log('Devices: %s provided - using "%s" profile: %j', device, profileName, devices[profileName]);

	phantomas.on('init', async (_, page) => {
		await page.emulate(devices[profileName]);
		phantomas.log('page.emulate() called');
	});
};
<|endoftext|>