<commit_before>var smilOnline = smilOnline || {};

var guid = (function () {
    function s4() {
        return Math.floor((1 + Math.random()) * 0x10000)
                   .toString(16)
                   .substring(1);
    }
    return function () {
        return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
               s4() + '-' + s4() + s4() + s4();
    };
})();

var smilOnline = function () {

    var siteUrl = function () {
        var url = document.location.origin + SP.ClientContext.get_current().get_url();
        return url;
    };

    var loadConfig = function (callback) {
        var req = new XMLHttpRequest();
        var requestUrl = siteUrl() + "/SmilOnlineAssets/smilOnline.jsn";
        req.open("GET", requestUrl);

        req.setRequestHeader("accept", "application/json; odata=verbose");
        req.onreadystatechange = function () {
            if (req.readyState == req.DONE) {
                var config = JSON.parse(req.response);
                callback(config);
            }
        }
        req.send();

    };

    var registerEditFormCallBack = function (formContext) {
        var element = document.getElementById(formContext.fieldSchema.Id + '_' + formContext.fieldName);
        var val = element.value;
        return val;
    };

    // is this really needed
    var getQueryStringParameter = function (param) {
        var params = document.URL.split("?")[1].split("&");
        var strParams = "";
        for (var i = 0; i < params.length; i++) {
            var singleParam = params[i].split("=");
            if (singleParam[0] == param)
                return singleParam[1];
        }
    };

    var displayForm = function (ctx) {
        smilOnline.state = "view";
        var mapElem = createMapElement(ctx);
        return mapElem;
    };

    var editForm = function (ctx) {
        smilOnline.state = "edit";
        var mapElem = createMapElement(ctx);
        return mapElem;
    };

    var createMapElement = function (ctx) {
        var elemID = this.guid();
        var geom = ctx.CurrentItem[ctx.CurrentFieldSchema.Name];
        if (geom === '') {
            return '';
        }
        var guid = this.guid();

        var elem = geom;
        elem += '

';
        smilOnline.renderElemId = elemID;
        return elem;
    };

    renderMap = function () {
        var intervalId = setInterval(function () {
            if (smilOnline.bingMaps && Microsoft && Microsoft.Maps && Microsoft.Maps.Map) {
                loadModules(function () {
                    clearInterval(intervalId);
                    loadConfig(function (config) {
                        var mapOptions = smilOnline.configParser.getMapOptions(config);
                        switch (smilOnline.state) {
                            case "edit":
                                renderEditMap(mapOptions);
                                break;
                            case "new":
                                renderNewMap(mapOptions);
                                break;
                            case "list":
                                renderListMap(mapOptions);
                                break;
                            default:
                                renderViewMap(mapOptions);
                                break;
                        }
                    });
                });
            }
        }, 50);
    };

    renderViewMap = function (mapOptions) {
        var elem = document.getElementById(smilOnline.renderElemId);
        smilOnline.map = new Microsoft.Maps.Map(elem, mapOptions);
        var wktValue = elem.previousSibling.innerHTML;
        elem.previousSibling.style.display = "none";
        var geom = WKTModule.Read(wktValue);
        smilOnline.map.entities.push(geom);
        zoomToEntity(geom);
    };

    zoomToEntity = function (entity) {
        var locations = getLocations(entity);
        if (locations.length > 0) {
            var locationRect = Microsoft.Maps.LocationRect.fromLocations(locations);
            smilOnline.map.setView({ bounds: locationRect });
        }
    };

    getLocations = function (entity) {
        var locations = [];

        if (entity instanceof Microsoft.Maps.Pushpin) {
            var location = entity.getLocation();
            locations.push(location);
        }
        return locations;
    };

    renderNewMap = function () {
        var elem = document.getElementById(smilOnline.renderElemId);
    };

    renderEditMap = function () {
        var elem = document.getElementById(smilOnline.renderElemId);
        smilOnline.map = new Microsoft.Maps.Map(elem, mapOptions);
        var wktValue = elem.previousSibling.innerHTML;
        elem.previousSibling.style.display = "none";
        var geom = WKTModule.Read(wktValue);
        smilOnline.map.entities.push(geom);
        zoomToEntity(geom);
    };

    loadModule = function (module, callback) {

        if (module === "wkt") {
            Microsoft.Maps.registerModule("WKTModule", (smilOnline.getSiteUrl() + "/SmilOnlineAssets/WKTModule-min.js"));
            Microsoft.Maps.loadModule("WKTModule", {
                callback: function () {
                    callback();
                }
            });
        }
        else if (module === "drawingtools") {

        }
    };

    var addScript = function (urls, callback) {

        var processQueue = function (urls) {
            urls.length === 0 ? callback() : addScript(urls, callback);
        };

        var url = urls.pop();

        var script = document.createElement("script");
        script.type = "text/javascript";

        if (script.readyState) {
            script.onreadystatechange = function () {
                if (script.readyState == "loaded" || script.readyState == "complete") { //IE will hit here
                    script.onreadystatechange = null;
                    processQueue(urls);
                }
            };
        } else {
            script.onload = function () {//chrome will hit here
                processQueue(urls);
            };
        }
        script.src = url;
        document.body.appendChild(script);
    };

    return {
        addScript: addScript,
        displayForm: displayForm,
        editForm: editForm,
        renderMap: renderMap,
        getSiteUrl: siteUrl
    };

}();

document.onreadystatechange = function () {
    var state = document.readyState;
    if (state == 'complete') {
        var scriptsToAdd = ["http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0",
                           (smilOnline.getSiteUrl() + "/SmilOnlineAssets/config.js"),
                           (smilOnline.getSiteUrl() + "/SmilOnlineAssets/configParser.js")];

        smilOnline.addScript(scriptsToAdd, function scriptsLoaded() {
            smilOnline.bingMaps = true;
            smilOnline.renderMap();
        });
    }
};

(function () {

    var geometryContext = {};
    geometryContext.Templates = {};
    geometryContext.Templates.Fields = {
        'Geometry': {
            'View': smilOnline.viewList,
            'DisplayForm': smilOnline.displayForm,
            'EditForm': smilOnline.editForm,
            'NewForm': smilOnline.newForm
        }
    };

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(
        geometryContext
    );
})();<commit_msg>started edit map view<commit_after>var smilOnline = smilOnline || {};

var guid = (function () {
    function s4() {
        return Math.floor((1 + Math.random()) * 0x10000)
                   .toString(16)
                   .substring(1);
    }
    return function () {
        return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
               s4() + '-' + s4() + s4() + s4();
    };
})();

var smilOnline = function () {

    var siteUrl = function () {
        var url = document.location.origin + SP.ClientContext.get_current().get_url();
        return url;
    };

    var loadConfig = function (callback) {
        var req = new XMLHttpRequest();
        var requestUrl = siteUrl() + "/SmilOnlineAssets/smilOnline.jsn";
        req.open("GET", requestUrl);

        req.setRequestHeader("accept", "application/json; odata=verbose");
        req.onreadystatechange = function () {
            if (req.readyState == req.DONE) {
                var config = JSON.parse(req.response);
                callback(config);
            }
        }
        req.send();

    };

    var registerEditFormCallBack = function (formContext) {
        var element = document.getElementById(formContext.fieldSchema.Id + '_' + formContext.fieldName);
        var val = element.value;
        return val;
    };

    // is this really needed
    var getQueryStringParameter = function (param) {
        var params = document.URL.split("?")[1].split("&");
        var strParams = "";
        for (var i = 0; i < params.length; i++) {
            var singleParam = params[i].split("=");
            if (singleParam[0] == param)
                return singleParam[1];
        }
    };

    var displayForm = function (ctx) {
        smilOnline.state = "view";
        var mapElem = createMapElement(ctx);
        return mapElem;
    };

    var editForm = function (ctx) {
        smilOnline.state = "edit";
        var geoElem = createToolbar();
        geoElem += createMapElement(ctx);
        return geoElem;
    };

    var createToolbar = function () {
        var elemID = this.guid();
        var elem = '

';
        return elem;
    };

    var createMapElement = function (ctx) {
        var elemID = this.guid();
        var geom = ctx.CurrentItem[ctx.CurrentFieldSchema.Name];
        if (geom === '') {
            return '';
        }
        var guid = this.guid();

        var elem = geom;
        elem += '

';
        smilOnline.renderElemId = elemID;
        return elem;
    };

    renderMap = function () {
        var intervalId = setInterval(function () {
            if (smilOnline.bingMaps && Microsoft && Microsoft.Maps && Microsoft.Maps.Map) {

                clearInterval(intervalId);
                loadConfig(function (config) {
                    var mapOptions = smilOnline.configParser.getMapOptions(config);
                    switch (smilOnline.state) {
                        case "edit":
                            loadModule("wkt", function () {
                                loadModule("drawingtools", function () {
                                    renderEditMap(mapOptions);
                                });
                            });

                            break;
                        case "new":
                            renderNewMap(mapOptions);
                            break;
                        case "list":
                            renderListMap(mapOptions);
                            break;
                        default:
                            loadModule("wkt", function () {
                                renderViewMap(mapOptions);
                            });
                            break;
                    }
                });
            }
        }, 50);
    };

    renderViewMap = function (mapOptions) {
        var elem = document.getElementById(smilOnline.renderElemId);
        smilOnline.map = new Microsoft.Maps.Map(elem, mapOptions);
        var wktValue = elem.previousSibling.innerHTML;
        elem.previousSibling.style.display = "none";
        var geom = WKTModule.Read(wktValue);
        smilOnline.map.entities.push(geom);
        zoomToEntity(geom);
    };

    zoomToEntity = function (entity) {
        var locations = getLocations(entity);
        if (locations.length > 0) {
            var locationRect = Microsoft.Maps.LocationRect.fromLocations(locations);
            smilOnline.map.setView({ bounds: locationRect });
        }
    };

    getLocations = function (entity) {
        var locations = [];

        if (entity instanceof Microsoft.Maps.Pushpin) {
            var location = entity.getLocation();
            locations.push(location);
        }
        return locations;
    };

    renderNewMap = function () {
        var elem = document.getElementById(smilOnline.renderElemId);
    };

    renderEditMap = function (mapOptions) {
        var elem = document.getElementById(smilOnline.renderElemId);
        smilOnline.map = new Microsoft.Maps.Map(elem, mapOptions);
        var wktValue = elem.previousSibling;
        var geom = WKTModule.Read(wktValue.data);
        wktValue.remove();
        smilOnline.map.entities.push(geom);
        zoomToEntity(geom);

        var toolbarID = elem.parentNode.firstElementChild.id;
        debugger;
        var drawingTools = new DrawingTools.DrawingManager(smilOnline.map);
    };

    //refactor to be able to send in module[]
    loadModule = function (module, callback) {

        if (module === "wkt") {
            Microsoft.Maps.registerModule("WKTModule", (smilOnline.getSiteUrl() + "/SmilOnlineAssets/WKTModule-min.js"));
            Microsoft.Maps.loadModule("WKTModule", {
                callback: function () {
                    callback();
                }
            });
        }
        else if (module === "drawingtools") {
            Microsoft.Maps.registerModule("DrawingToolsModule", (smilOnline.getSiteUrl() + "/SmilOnlineAssets/DrawingToolsModule.js"));
            Microsoft.Maps.loadModule("DrawingToolsModule", {
                callback: function () {
                    callback();
                }
            });
        }
    };

    var addScript = function (urls, callback) {

        var processQueue = function (urls) {
            urls.length === 0 ? callback() : addScript(urls, callback);
        };

        var url = urls.pop();

        var script = document.createElement("script");
        script.type = "text/javascript";

        if (script.readyState) {
            script.onreadystatechange = function () {
                if (script.readyState == "loaded" || script.readyState == "complete") { //IE will hit here
                    script.onreadystatechange = null;
                    processQueue(urls);
                }
            };
        } else {
            script.onload = function () {//chrome will hit here
                processQueue(urls);
            };
        }
        script.src = url;
        document.body.appendChild(script);
    };

    return {
        addScript: addScript,
        displayForm: displayForm,
        editForm: editForm,
        renderMap: renderMap,
        getSiteUrl: siteUrl
    };

}();

document.onreadystatechange = function () {
    var state = document.readyState;
    if (state == 'complete') {
        var scriptsToAdd = ["http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0",
                           (smilOnline.getSiteUrl() + "/SmilOnlineAssets/config.js"),
                           (smilOnline.getSiteUrl() + "/SmilOnlineAssets/configParser.js")];

        smilOnline.addScript(scriptsToAdd, function scriptsLoaded() {
            smilOnline.bingMaps = true;
            smilOnline.renderMap();
        });
    }
};

(function () {

    var geometryContext = {};
    geometryContext.Templates = {};
    geometryContext.Templates.Fields = {
        'Geometry': {
            'View': smilOnline.viewList,
            'DisplayForm': smilOnline.displayForm,
            'EditForm': smilOnline.editForm,
            'NewForm': smilOnline.newForm
        }
    };

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(
        geometryContext
    );
})();<|endoftext|>


<commit_before>'use strict';

var url = require('url');
var _ = require('lodash');
var Promise = require('bluebird');
var downloader = require('../downloader');

module.exports.apiConfig = {};
module.exports.searchConfig = {};
module.exports.osExplorerUrl = null;
module.exports.osConductorUrl = null;
module.exports.defaultSettingsUrl = 'settings.json';

function loadConfig(settingsUrl) {
  var url = settingsUrl || module.exports.defaultSettingsUrl;
  return downloader.getJson(url).then(function(config) {
    module.exports.apiConfig = config.api;
    module.exports.searchConfig = config.search;
    module.exports.dataMineConfig = config.dataMine;
    module.exports.osExplorerUrl = config.osExplorerUrl;
    module.exports.osConductorUrl = config.osConductorUrl;
    return config;
  });
}

function getDataPackages(authToken, packageId, userId) {
  return loadConfig().then(function() {
    var searchConfig = module.exports.searchConfig;
    var url = searchConfig.url + '?size=10000';
    if (authToken) {
      url += '&jwt=' + encodeURIComponent(authToken);
    }
    if (packageId) {
      url += '&id=' + encodeURIComponent(JSON.stringify(packageId));
    }
    if (userId) {
      url += '&package.owner=' + encodeURIComponent(JSON.stringify(userId));
    }
    return downloader.getJson(url).then(function(packages) {
      return _.chain(packages)
        .filter(function(dataPackage) {
          var result = true;
          if (packageId && (dataPackage.id != packageId)) {
            result = false;
          }
          if (userId && (dataPackage.package.owner != userId)) {
            result = false;
          }
          return result;
        })
        .map(function(dataPackage) {
          dataPackage.author = _.chain(dataPackage.package.author)
            .split(' ')
            .dropRight(1)
            .join(' ')
            .value();
          return {
            id: dataPackage.id,
            author: dataPackage.author,
            title: dataPackage.package.title,
            description: dataPackage.package.description
          };
        })
        .value();
    });
  });
}

function getDataPackageMetadata(dataPackage, model) {
  // jscs:disable
  var originUrl = dataPackage.__origin_url ? dataPackage.__origin_url :
    [
      'http://datastore.openspending.org',
      dataPackage.owner,
      dataPackage.name,
      'datapackage.json'
    ].join('/');
  // jscs:enable

  var defaultParams = {};
  if (dataPackage.defaultParams &&
      _.isString(dataPackage.defaultParams.params)) {
    defaultParams = JSON.parse(dataPackage.defaultParams.params);
  }

  return {
    defaultParams: defaultParams,
    name: dataPackage.name,
    title: dataPackage.title,
    description: dataPackage.description,
    owner: dataPackage.owner,
    author: dataPackage.author,
    countryCode: (function(countryCode) {
      var result = _.isArray(countryCode) ? _.first(countryCode) : countryCode;
      return _.isString(result) ? result.toUpperCase() : undefined;
    })(dataPackage.countryCode),
    // jscs:disable
    factTable: model ? model.fact_table : null,
    // jscs:enable
    url: originUrl,
    resources: _.chain(dataPackage.resources)
      .map(function(resource) {
        var resourceUrl = null;
        if (resource.url) {
          resourceUrl = resource.url;
        }
        if (resource.path) {
          resourceUrl = url.resolve(originUrl, resource.path);
        }

        if (resourceUrl) {
          return {
            name: resource.name,
            url: resourceUrl
          };
        }
      })
      .filter()
      .value()
  };
}

function getMeasuresFromModel(dataPackage, model) {
  // Populate some additional model properties
  var measureMappings = null;
  if (_.isObject(dataPackage.model)) {
    if (_.isObject(dataPackage.model.measures)) {
      measureMappings = dataPackage.model.measures;
    }
  }

  return _.chain(model.aggregates)
    .filter(function(aggregate) {
      return aggregate.measure && model.measures[aggregate.measure];
    })
    .map(function(aggregate) {
      var result = {};
      result.id = aggregate.measure;
      result.key = aggregate.ref;
      result.label = aggregate.label;

      if (measureMappings) {
        var measure = model.measures[aggregate.measure];
        // jscs:disable
        var originalMeasure = measureMappings[measure.orig_measure];
        // jscs:enable
        if (originalMeasure) {
          result.currency = originalMeasure.currency;
        }
      }

      return result;
    })
    .sortBy(function(item) {
      return item.label;
    })
    .value();
}

function getDimensionsFromModel(dataPackage, model) {
  // Populate some additional model properties
  var dimensionMappings = null;
  if (_.isObject(dataPackage.model)) {
    if (_.isObject(dataPackage.model.dimensions)) {
      dimensionMappings = dataPackage.model.dimensions;
    }
  }

  return _.chain(model.dimensions)
    .map(function(dimension, index) {
      var result = {};

      result.id = index;
      // jscs:disable
      result.key = dimension.key_ref;
      result.label = dimension.label;
      result.valueRef = dimension.label_ref || dimension.key_ref;
      result.sortKey = dimension.label_ref || dimension.key_ref;
      // jscs:enable
      result.hierarchy = dimension.hierarchy;

      if (dimensionMappings) {
        // jscs:disable
        var originalDimension = dimensionMappings[dimension.orig_dimension];
        // jscs:enable

        if (originalDimension) {
          result.dimensionType = originalDimension.dimensionType;
        }
      }
      return result;
    })
    .sortBy(function(item) {
      return item.label;
    })
    .value();
}

function loadDimensionValues(packageId, dimension, filters) {
  return loadConfig().then(function() {
    var apiConfig = module.exports.apiConfig;

    var cut = _.extend({}, filters);
    delete cut[dimension.key];
    cut = serializeCut(cut).join('|');
    if (cut != '') {
      cut = '?cut=' + encodeURIComponent(cut);
    }

    var url = apiConfig.url + '/cubes/' +
      encodeURIComponent(packageId) + '/members/' +
      encodeURIComponent(dimension.id) + cut;

    return downloader.getJson(url).then(function(results) {
      return _.chain(results.data)
        .map(function(value) {
          var key = value[dimension.key];
          var label = value[dimension.valueRef];
          if (!!key) {
            return {
              key: key,
              label: (label && label != key) ? key + ' - ' + label : key
            };
          }
        })
        .filter()
        .value();
    });
  });
}

function mapDimensionValues(dimension, rawValues) {
  return _.chain(rawValues)
    .map(function(value) {
      var key = value[dimension.key];
      var label = value[dimension.valueRef];
      if (!!key) {
        return {
          key: key,
          label: (label && label != key) ? key + ' - ' + label : key
        };
      }
    })
    .filter()
    .sortBy('label')
    .value();
}

// `dimensions` is optional; if omitted - all dimensions will be populated
function loadDimensionsValues(packageModel, dimensions, filters) {
  dimensions = _.isArray(dimensions) ? dimensions : packageModel.dimensions;
  if (dimensions.length == 0) {
    return Promise.resolve(packageModel);
  }
  filters = _.extend({}, filters);
  var apiConfig = null;

  return loadConfig()
    .then(function() {
      apiConfig = module.exports.apiConfig;

      // Prepare dimensions that are mentioned in filters but
      // have no values yet
      var promises = _.chain(dimensions)
        .map(function(dimension) {
          var isFiltered = (filters[dimension.key] || []).length > 0;
          var hasValues = _.isArray(dimension.values);
          if (isFiltered && !hasValues) {
            var url = apiConfig.url + '/cubes/' +
              encodeURIComponent(packageModel.id) + '/members/' +
              encodeURIComponent(dimension.id) + '/';
            return downloader.getJson(url).then(function(result) {
              dimension.values = mapDimensionValues(dimension, result.data);
              return result;
            });
          }
        })
        .filter()
        .value();

      return Promise.all(promises);
    })
    .then(function() {
      var promises = _.map(dimensions, function(dimension) {
        var cut = _.clone(filters);
        delete cut[dimension.key];
        cut = serializeCut(cut).join('|');
        if (cut != '') {
          cut = '?cut=' + encodeURIComponent(cut);
        }

        var url = apiConfig.url + '/cubes/' +
          encodeURIComponent(packageModel.id) + '/members/' +
          encodeURIComponent(dimension.id) + cut;
        return downloader.getJson(url).then(function(result) {
          // Save current values; after loading new values, some of selected
          // values may be missed in the new set, so we'll need to add them
          result.savedValues = dimension.values;
          result.filters = filters[dimension.key] || [];
          result.dimension = dimension;
          return result;
        });
      });

      return Promise.all(promises).then(function(results) {
        _.each(results, function(result) {
          var dimension = result.dimension;
          dimension.values = mapDimensionValues(dimension, result.data);

          // Add missing selected values
          _.chain(result.filters)
            .difference(_.map(dimension.values, function(value) {
              return value.key;
            }))
            .each(function(key) {
              var value = _.find(result.savedValues, {key: key});
              if (value) {
                dimension.values.push(value);
              }
            })
            .value();

          dimension.values = _.sortBy(dimension.values, 'label');
        });
        return packageModel;
      });
    });
}

function getHierarchiesFromModel(dataPackage, model, packageModel) {
  return _.chain(model.hierarchies)
    .map(function(hierarchy, index) {
      return {
        id: index,
        key: index,
        label: hierarchy.label,
        dimensions: _.map(hierarchy.levels, function(dimensionId) {
          return _.find(packageModel.dimensions, function(dimension) {
            return dimension.id == dimensionId;
          });
        })
      };
    })
    .sortBy(function(item) {
      return item.label;
    })
    .value();
}

function filterHierarchiesByType(hierarchies, type) {
  return _.chain(hierarchies)
    .map(function(hierarchy) {
      var result = _.extend({}, hierarchy);
      result.dimensions = _.filter(hierarchy.dimensions,
        function(item) {
          return item.dimensionType == type;
        });
      if (result.dimensions.length > 0) {
        return result;
      }
    })
    .filter()
    .value();
}

function createPackageModel(packageId, dataPackage, model) {
  var packageModel = {
    id: packageId,
    meta: getDataPackageMetadata(dataPackage, model),
    measures: getMeasuresFromModel(dataPackage, model),
    dimensions: getDimensionsFromModel(dataPackage, model)
  };

  packageModel.hierarchies = getHierarchiesFromModel(dataPackage,
    model, packageModel);
  packageModel.columnHierarchies = packageModel.hierarchies;
  packageModel.locationHierarchies = filterHierarchiesByType(
    packageModel.hierarchies, 'location');
  packageModel.dateTimeHierarchies = filterHierarchiesByType(
    packageModel.hierarchies, 'datetime');

  return packageModel;
}

// If loadBareModel == true, this function will load only
// minimal amount of data required to build model structure.
// Data like dimension values will not be loaded.
function getDataPackage(packageId, loadBareModel) {
  return loadConfig().then(function() {
    var apiConfig = module.exports.apiConfig;

    var promises = [
      downloader.getJson(apiConfig.url + '/info/' +
        encodeURIComponent(packageId) + '/package'),
      downloader.getJson(apiConfig.url + '/cubes/' +
        encodeURIComponent(packageId) + '/model/')
    ];

    return Promise.all(promises)
      .then(function(results) {
        return createPackageModel(packageId, results[0], results[1].model);
      })
      .then(function(packageModel) {
        if (loadBareModel) {
          return packageModel;
        }
        return loadDimensionsValues(packageModel);
      });
  });
}

function serializeCut(filters, drilldown) {
  // Add filters from drilldown, if any
  if (_.isArray(drilldown)) {
    filters = _.cloneDeep(filters);
    _.each(drilldown, function(item) {
      // When drilldown - replace filters for all drilldown
      // dimensions: they cannot be selected by user, but ensure
      // that there are no any garbage
      filters[item.dimension] = [item.filter];
    });
  }

  return _.chain(filters)
    .map(function(values, key) {
      return key + ':' + _.chain(values)
        .map(function(value) {
          return JSON.stringify(value);
        })
        .join(';')
        .value();
    })
    .value();
}

function setDefaultParams(token, packageId, params) {
  return loadConfig().then(function() {
    var url = module.exports.osConductorUrl + '/package/update_params';

    var data = _.chain({
      jwt: token,
      id: packageId
    })
    .map(function(value, key) {
      return encodeURIComponent(key) + '=' + encodeURIComponent(value);
    })
    .join('&')
    .value();

    var options = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({params: JSON.stringify(params)})
    };
    return downloader.getJson(url + '?' + data, options, true)
      .then(function(result) {
        if (!result.success) {
          throw new Error(result.error);
        }
        return result.json;
      });
  });
}

module.exports.serializeCut = serializeCut;
module.exports.loadConfig = loadConfig;
module.exports.getDataPackages = getDataPackages;
module.exports.getDataPackage = getDataPackage;
module.exports.loadDimensionValues = loadDimensionValues;
module.exports.loadDimensionsValues = loadDimensionsValues;
module.exports.createPackageModel = createPackageModel;
module.exports.setDefaultParams = setDefaultParams;
<commit_msg>More trailing slash twiddling<commit_after>'use strict';

var url = require('url');
var _ = require('lodash');
var Promise = require('bluebird');
var downloader = require('../downloader');

module.exports.apiConfig = {};
module.exports.searchConfig = {};
module.exports.osExplorerUrl = null;
module.exports.osConductorUrl = null;
module.exports.defaultSettingsUrl = 'settings.json';

function loadConfig(settingsUrl) {
  var url = settingsUrl || module.exports.defaultSettingsUrl;
  return downloader.getJson(url).then(function(config) {
    module.exports.apiConfig = config.api;
    module.exports.searchConfig = config.search;
    module.exports.dataMineConfig = config.dataMine;
    module.exports.osExplorerUrl = config.osExplorerUrl;
    module.exports.osConductorUrl = config.osConductorUrl;
    return config;
  });
}

function getDataPackages(authToken, packageId, userId) {
  return loadConfig().then(function() {
    var searchConfig = module.exports.searchConfig;
    var url = searchConfig.url + '?size=10000';
    if (authToken) {
      url += '&jwt=' + encodeURIComponent(authToken);
    }
    if (packageId) {
      url += '&id=' + encodeURIComponent(JSON.stringify(packageId));
    }
    if (userId) {
      url += '&package.owner=' + encodeURIComponent(JSON.stringify(userId));
    }
    return downloader.getJson(url).then(function(packages) {
      return _.chain(packages)
        .filter(function(dataPackage) {
          var result = true;
          if (packageId && (dataPackage.id != packageId)) {
            result = false;
          }
          if (userId && (dataPackage.package.owner != userId)) {
            result = false;
          }
          return result;
        })
        .map(function(dataPackage) {
          dataPackage.author = _.chain(dataPackage.package.author)
            .split(' ')
            .dropRight(1)
            .join(' ')
            .value();
          return {
            id: dataPackage.id,
            author: dataPackage.author,
            title: dataPackage.package.title,
            description: dataPackage.package.description
          };
        })
        .value();
    });
  });
}

function getDataPackageMetadata(dataPackage, model) {
  // jscs:disable
  var originUrl = dataPackage.__origin_url ? dataPackage.__origin_url :
    [
      'http://datastore.openspending.org',
      dataPackage.owner,
      dataPackage.name,
      'datapackage.json'
    ].join('/');
  // jscs:enable

  var defaultParams = {};
  if (dataPackage.defaultParams &&
      _.isString(dataPackage.defaultParams.params)) {
    defaultParams = JSON.parse(dataPackage.defaultParams.params);
  }

  return {
    defaultParams: defaultParams,
    name: dataPackage.name,
    title: dataPackage.title,
    description: dataPackage.description,
    owner: dataPackage.owner,
    author: dataPackage.author,
    countryCode: (function(countryCode) {
      var result = _.isArray(countryCode) ? _.first(countryCode) : countryCode;
      return _.isString(result) ? result.toUpperCase() : undefined;
    })(dataPackage.countryCode),
    // jscs:disable
    factTable: model ? model.fact_table : null,
    // jscs:enable
    url: originUrl,
    resources: _.chain(dataPackage.resources)
      .map(function(resource) {
        var resourceUrl = null;
        if (resource.url) {
          resourceUrl = resource.url;
        }
        if (resource.path) {
          resourceUrl = url.resolve(originUrl, resource.path);
        }

        if (resourceUrl) {
          return {
            name: resource.name,
            url: resourceUrl
          };
        }
      })
      .filter()
      .value()
  };
}

function getMeasuresFromModel(dataPackage, model) {
  // Populate some additional model properties
  var measureMappings = null;
  if (_.isObject(dataPackage.model)) {
    if (_.isObject(dataPackage.model.measures)) {
      measureMappings = dataPackage.model.measures;
    }
  }

  return _.chain(model.aggregates)
    .filter(function(aggregate) {
      return aggregate.measure && model.measures[aggregate.measure];
    })
    .map(function(aggregate) {
      var result = {};
      result.id = aggregate.measure;
      result.key = aggregate.ref;
      result.label = aggregate.label;

      if (measureMappings) {
        var measure = model.measures[aggregate.measure];
        // jscs:disable
        var originalMeasure = measureMappings[measure.orig_measure];
        // jscs:enable
        if (originalMeasure) {
          result.currency = originalMeasure.currency;
        }
      }

      return result;
    })
    .sortBy(function(item) {
      return item.label;
    })
    .value();
}

function getDimensionsFromModel(dataPackage, model) {
  // Populate some additional model properties
  var dimensionMappings = null;
  if (_.isObject(dataPackage.model)) {
    if (_.isObject(dataPackage.model.dimensions)) {
      dimensionMappings = dataPackage.model.dimensions;
    }
  }

  return _.chain(model.dimensions)
    .map(function(dimension, index) {
      var result = {};

      result.id = index;
      // jscs:disable
      result.key = dimension.key_ref;
      result.label = dimension.label;
      result.valueRef = dimension.label_ref || dimension.key_ref;
      result.sortKey = dimension.label_ref || dimension.key_ref;
      // jscs:enable
      result.hierarchy = dimension.hierarchy;

      if (dimensionMappings) {
        // jscs:disable
        var originalDimension = dimensionMappings[dimension.orig_dimension];
        // jscs:enable

        if (originalDimension) {
          result.dimensionType = originalDimension.dimensionType;
        }
      }
      return result;
    })
    .sortBy(function(item) {
      return item.label;
    })
    .value();
}

function loadDimensionValues(packageId, dimension, filters) {
  return loadConfig().then(function() {
    var apiConfig = module.exports.apiConfig;

    var cut = _.extend({}, filters);
    delete cut[dimension.key];
    cut = serializeCut(cut).join('|');
    if (cut != '') {
      cut = '/?cut=' + encodeURIComponent(cut);
    } else {
      cut = '/';
    }

    var url = apiConfig.url + '/cubes/' +
      encodeURIComponent(packageId) + '/members/' +
      encodeURIComponent(dimension.id) + cut;

    return downloader.getJson(url).then(function(results) {
      return _.chain(results.data)
        .map(function(value) {
          var key = value[dimension.key];
          var label = value[dimension.valueRef];
          if (!!key) {
            return {
              key: key,
              label: (label && label != key) ? key + ' - ' + label : key
            };
          }
        })
        .filter()
        .value();
    });
  });
}

function mapDimensionValues(dimension, rawValues) {
  return _.chain(rawValues)
    .map(function(value) {
      var key = value[dimension.key];
      var label = value[dimension.valueRef];
      if (!!key) {
        return {
          key: key,
          label: (label && label != key) ? key + ' - ' + label : key
        };
      }
    })
    .filter()
    .sortBy('label')
    .value();
}

// `dimensions` is optional; if omitted - all dimensions will be populated
function loadDimensionsValues(packageModel, dimensions, filters) {
  dimensions = _.isArray(dimensions) ? dimensions : packageModel.dimensions;
  if (dimensions.length == 0) {
    return Promise.resolve(packageModel);
  }
  filters = _.extend({}, filters);
  var apiConfig = null;

  return loadConfig()
    .then(function() {
      apiConfig = module.exports.apiConfig;

      // Prepare dimensions that are mentioned in filters but
      // have no values yet
      var promises = _.chain(dimensions)
        .map(function(dimension) {
          var isFiltered = (filters[dimension.key] || []).length > 0;
          var hasValues = _.isArray(dimension.values);
          if (isFiltered && !hasValues) {
            var url = apiConfig.url + '/cubes/' +
              encodeURIComponent(packageModel.id) + '/members/' +
              encodeURIComponent(dimension.id) + '/';
            return downloader.getJson(url).then(function(result) {
              dimension.values = mapDimensionValues(dimension, result.data);
              return result;
            });
          }
        })
        .filter()
        .value();

      return Promise.all(promises);
    })
    .then(function() {
      var promises = _.map(dimensions, function(dimension) {
        var cut = _.clone(filters);
        delete cut[dimension.key];
        cut = serializeCut(cut).join('|');
        if (cut != '') {
          cut = '/?cut=' + encodeURIComponent(cut);
        } else {
          cut = '/';
        }

        var url = apiConfig.url + '/cubes/' +
          encodeURIComponent(packageModel.id) + '/members/' +
          encodeURIComponent(dimension.id) + cut;
        return downloader.getJson(url).then(function(result) {
          // Save current values; after loading new values, some of selected
          // values may be missed in the new set, so we'll need to add them
          result.savedValues = dimension.values;
          result.filters = filters[dimension.key] || [];
          result.dimension = dimension;
          return result;
        });
      });

      return Promise.all(promises).then(function(results) {
        _.each(results, function(result) {
          var dimension = result.dimension;
          dimension.values = mapDimensionValues(dimension, result.data);

          // Add missing selected values
          _.chain(result.filters)
            .difference(_.map(dimension.values, function(value) {
              return value.key;
            }))
            .each(function(key) {
              var value = _.find(result.savedValues, {key: key});
              if (value) {
                dimension.values.push(value);
              }
            })
            .value();

          dimension.values = _.sortBy(dimension.values, 'label');
        });
        return packageModel;
      });
    });
}

function getHierarchiesFromModel(dataPackage, model, packageModel) {
  return _.chain(model.hierarchies)
    .map(function(hierarchy, index) {
      return {
        id: index,
        key: index,
        label: hierarchy.label,
        dimensions: _.map(hierarchy.levels, function(dimensionId) {
          return _.find(packageModel.dimensions, function(dimension) {
            return dimension.id == dimensionId;
          });
        })
      };
    })
    .sortBy(function(item) {
      return item.label;
    })
    .value();
}

function filterHierarchiesByType(hierarchies, type) {
  return _.chain(hierarchies)
    .map(function(hierarchy) {
      var result = _.extend({}, hierarchy);
      result.dimensions = _.filter(hierarchy.dimensions,
        function(item) {
          return item.dimensionType == type;
        });
      if (result.dimensions.length > 0) {
        return result;
      }
    })
    .filter()
    .value();
}

function createPackageModel(packageId, dataPackage, model) {
  var packageModel = {
    id: packageId,
    meta: getDataPackageMetadata(dataPackage, model),
    measures: getMeasuresFromModel(dataPackage, model),
    dimensions: getDimensionsFromModel(dataPackage, model)
  };

  packageModel.hierarchies = getHierarchiesFromModel(dataPackage,
    model, packageModel);
  packageModel.columnHierarchies = packageModel.hierarchies;
  packageModel.locationHierarchies = filterHierarchiesByType(
    packageModel.hierarchies, 'location');
  packageModel.dateTimeHierarchies = filterHierarchiesByType(
    packageModel.hierarchies, 'datetime');

  return packageModel;
}

// If loadBareModel == true, this function will load only
// minimal amount of data required to build model structure.
// Data like dimension values will not be loaded.
function getDataPackage(packageId, loadBareModel) {
  return loadConfig().then(function() {
    var apiConfig = module.exports.apiConfig;

    var promises = [
      downloader.getJson(apiConfig.url + '/info/' +
        encodeURIComponent(packageId) + '/package'),
      downloader.getJson(apiConfig.url + '/cubes/' +
        encodeURIComponent(packageId) + '/model/')
    ];

    return Promise.all(promises)
      .then(function(results) {
        return createPackageModel(packageId, results[0], results[1].model);
      })
      .then(function(packageModel) {
        if (loadBareModel) {
          return packageModel;
        }
        return loadDimensionsValues(packageModel);
      });
  });
}

function serializeCut(filters, drilldown) {
  // Add filters from drilldown, if any
  if (_.isArray(drilldown)) {
    filters = _.cloneDeep(filters);
    _.each(drilldown, function(item) {
      // When drilldown - replace filters for all drilldown
      // dimensions: they cannot be selected by user, but ensure
      // that there are no any garbage
      filters[item.dimension] = [item.filter];
    });
  }

  return _.chain(filters)
    .map(function(values, key) {
      return key + ':' + _.chain(values)
        .map(function(value) {
          return JSON.stringify(value);
        })
        .join(';')
        .value();
    })
    .value();
}

function setDefaultParams(token, packageId, params) {
  return loadConfig().then(function() {
    var url = module.exports.osConductorUrl + '/package/update_params';

    var data = _.chain({
      jwt: token,
      id: packageId
    })
    .map(function(value, key) {
      return encodeURIComponent(key) + '=' + encodeURIComponent(value);
    })
    .join('&')
    .value();

    var options = {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({params: JSON.stringify(params)})
    };
    return downloader.getJson(url + '?' + data, options, true)
      .then(function(result) {
        if (!result.success) {
          throw new Error(result.error);
        }
        return result.json;
      });
  });
}

module.exports.serializeCut = serializeCut;
module.exports.loadConfig = loadConfig;
module.exports.getDataPackages = getDataPackages;
module.exports.getDataPackage = getDataPackage;
module.exports.loadDimensionValues = loadDimensionValues;
module.exports.loadDimensionsValues = loadDimensionsValues;
module.exports.createPackageModel = createPackageModel;
module.exports.setDefaultParams = setDefaultParams;
<|endoftext|>


<commit_before>import PropTypes from 'prop-types';

export default {
  disableMouseEvents: PropTypes.bool,
  seriesKey: PropTypes.string,
  onClick: PropTypes.func,
  onMouseMove: PropTypes.func,
  onMouseLeave: PropTypes.func,
  xScale: PropTypes.func,
  yScale: PropTypes.func,
};
<commit_msg>[xy-chart] add margin to sharedSeriesProps<commit_after>import PropTypes from 'prop-types';
import { marginShape } from './propShapes';

export default {
  disableMouseEvents: PropTypes.bool,
  seriesKey: PropTypes.string,
  onClick: PropTypes.func,
  onMouseMove: PropTypes.func,
  onMouseLeave: PropTypes.func,
  xScale: PropTypes.func,
  yScale: PropTypes.func,
  margin: marginShape,
};
<|endoftext|>


<commit_before>import React, {Component} from 'react'
import bus from 'bus'
import t from 't-component'
import user from 'lib/user/user'
import urlBuilder from 'lib/url-builder'
import Header from './header/component'
import Content from './content/component'
import Footer from './footer/component'
import Participants from './participants/component'
import DecisionMaker from './decision-maker/component'

export default class TopicArticle extends Component {
  constructor (props) {
    super(props)

    this.state = {
      showSidebar: false
    }
  }

  componentWillMount () {
    bus.on('sidebar:show', this.toggleSidebar)
  }

  componentWillUnmount () {
    bus.off('sidebar:show', this.toggleSidebar)
  }

  toggleSidebar = (bool) => {
    this.setState({
      showSidebar: bool
    })
  }

  handleCreateTopic = () => {
    window.location = urlBuilder.for('admin.topics.create', {
      forum: this.props.forum.name
    })
  }

  render () {
    const topic = this.props.topic
    const forum = this.props.forum
    const canCreateTopics = user.privileges &&
      user.privileges.canManage &&
      forum &&
      forum.privileges &&
      forum.privileges.canChangeTopics

    if (!topic) {
      return (

{t('homepage.no-topics')}

          {
            canCreateTopics && (
              <button
                className='btn btn-primary'
                onClick={this.handleCreateTopic} >
                {t('homepage.create-debate')}
              </button>
            )
          }

      )
    }

    const votes = {
      positive: topic.upvotes || [],
      negative: topic.downvotes || [],
      neutral: topic.abstentions || []
    }

    return (

        {
          this.state.showSidebar &&

        }

        {topic.clauses && <Content clauses={topic.clauses} />}
        {topic.links && (

        )}
        {topic.clauses && topic.participants && (
          <Participants participants={topic.participants} />
        )}
        {
          topic.votable &&
            <DecisionMaker
              votes={votes}
              closed={topic.closed}
              id={topic.id}
              url={topic.url}
              closingAt={topic.closingAt}
              cantVote={!forum.privileges.canVoteAndComment} />
        }

    )
  }
}

function hideSidebar () {
  bus.emit('sidebar:show', false)
}
<commit_msg>fix js styles<commit_after>import React, {Component} from 'react'
import bus from 'bus'
import t from 't-component'
import user from 'lib/user/user'
import urlBuilder from 'lib/url-builder'
import Header from './header/component'
import Content from './content/component'
import Footer from './footer/component'
import Participants from './participants/component'
import DecisionMaker from './decision-maker/component'

export default class TopicArticle extends Component {
  constructor (props) {
    super(props)

    this.state = {
      showSidebar: false
    }
  }

  componentWillMount () {
    bus.on('sidebar:show', this.toggleSidebar)
  }

  componentWillUnmount () {
    bus.off('sidebar:show', this.toggleSidebar)
  }

  toggleSidebar = (bool) => {
    this.setState({
      showSidebar: bool
    })
  }

  handleCreateTopic = () => {
    window.location = urlBuilder.for('admin.topics.create', {
      forum: this.props.forum.name
    })
  }

  render () {
    const topic = this.props.topic
    const forum = this.props.forum
    const canCreateTopics = user.privileges &&
      user.privileges.canManage &&
      forum &&
      forum.privileges &&
      forum.privileges.canChangeTopics

    if (!topic) {
      return (

{t('homepage.no-topics')}

          {
            canCreateTopics && (
              <button
                className='btn btn-primary'
                onClick={this.handleCreateTopic} >
                {t('homepage.create-debate')}
              </button>
            )
          }

      )
    }

    const votes = {
      positive: topic.upvotes || [],
      negative: topic.downvotes || [],
      neutral: topic.abstentions || []
    }

    return (

        {
          this.state.showSidebar &&

        }

        {topic.clauses && <Content clauses={topic.clauses} />}
        {
          topic.links && (

          )
        }
        {
          topic.clauses && topic.participants && (
            <Participants participants={topic.participants} />
          )
        }
        {
          topic.votable && (
            <DecisionMaker
              votes={votes}
              closed={topic.closed}
              id={topic.id}
              url={topic.url}
              closingAt={topic.closingAt}
              cantVote={!forum.privileges.canVoteAndComment} />
          )
        }

    )
  }
}

function hideSidebar () {
  bus.emit('sidebar:show', false)
}
<|endoftext|>


<commit_before>/**
 * * [add](#add)
 * * [get](#get)
 * * [getAll](#getall)
 * * [remove](#remove)
 * * [store](#store)
 * * [load](#load)
 * * [render](#render)
 *
 * Before using methods you should get first the module from the editor instance, in this way:
 *
 * ```js
 * var assetManager = editor.AssetManager;
 * ```
 *
 * @module AssetManager
 */
define(function(require) {

	return function() {
		var c = {},
			Assets = require('./model/Assets'),
			AssetsView = require('./view/AssetsView'),
			FileUpload = require('./view/FileUploader'),
			assets, am, fu;

	  return {

	  	/**
	  	 * Name of the module
	  	 * @type {String}
	  	 * @private
	  	 */
	  	name: 'AssetManager',

	  	/**
	  	 * Mandatory for the storage manager
	  	 * @type {String}
	  	 * @private
	  	 */
	  	storageKey: 'assets',

	  	/**
	  	 * Initialize module
	  	 * @param {Object} config Configurations
			 * @param {Array<Object>} [config.assets=[]] Default assets
			 * @param {String} [config.uploadText='Drop files here or click to upload'] Upload text
			 * @param {String} [config.upload=''] Where to send upload data. Expects as return a JSON with asset/s object
			 * as: {data: [{src:'...'}, {src:'...'}]}
			 * @return {this}
			 * @example
			 * ...
			 * {
			 * 	assets: [
			 *  	{src:'path/to/image.png'},
			 *     ...
			 *  ],
			 *  upload: 'http://dropbox/path', // Set to false to disable it
			 *  uploadText: 'Drop files here or click to upload',
			 * }
	  	 */
	  	init: function(config){
	  		c = config || {};
	  		var defaults = require('./config/config');

	  		for (var name in defaults) {
					if (!(name in c))
						c[name] = defaults[name];
				}

				var ppfx = c.pStylePrefix;
				if(ppfx)
					c.stylePrefix = ppfx + c.stylePrefix;

	  		assets = new Assets(c.assets);
				var obj = {
					collection: assets,
					config: c,
				};
				am = new AssetsView(obj);
	  		fu = new FileUpload(obj);
	  		return this;
	  	},

			/**
			 * Add new asset/s to the collection. URLs are supposed to be unique
			 * @param {string|Object|Array<string>|Array<Object>} asset URL strings or an objects representing the resource.
			 * @return {Model}
			 * @example
			 * // In case of strings, would be interpreted as images
			 * assetManager.add('http://img.jpg');
			 * assetManager.add(['http://img.jpg', './path/to/img.png']);
			 *
			 * // Using objects you could indicate the type and other meta informations
			 * assetManager.add({
			 * 	src: 'http://img.jpg',
			 * 	//type: 'image',	//image is default
			 * 	height: 300,
			 *	width: 200,
			 * });
			 * assetManager.add([{
			 * 	src: 'http://img.jpg',
			 * },{
			 * 	src: './path/to/img.png',
			 * }]);
			 */
			add: function(asset){
				return assets.add(asset);
			},

			/**
			 * Return the asset by URL
			 * @param  {string} src URL of the asset
			 * @return {Object} Object representing the asset
			 * @example
			 * var asset = assetManager.get('http://img.jpg');
			 */
			get: function(src){
				return assets.where({src: src})[0];
			},

			/**
			 * Return all assets
			 * @return {Collection}
			 */
			getAll: function(){
				return assets;
			},

			/**
			 * Remove asset by URL
			 * @param  {string} src URL of the asset
			 * @return {this}
			 * @example
			 * assetManager.remove('http://img.jpg');
			 */
			remove: function(src){
				var asset = this.get(src);
				this.getAll().remove(asset);
				return this;
			},

			/**
			 * Store assets data to the selected storage
			 * @param {Boolean} noStore If true, won't store
			 * @return {Object} Data to store
			 * @example
			 * var assets = assetManager.store();
			 */
			store: function(noStore){
				var obj = {};
				var assets = JSON.stringify(this.getAll().toJSON());
				obj[this.storageKey] = assets;
				if(!noStore && c.stm)
					c.stm.store(obj);
				return obj;
			},

			/**
			 * Load data from the passed object, if the object is empty will try to fetch them
			 * autonomously from the storage manager.
			 * The fetched data will be added to the collection
			 * @param {Object} data Object of data to load
			 * @return {Object} Loaded assets
			 * @example
			 * var assets = assetManager.load();
			 * // The format below will be used by the editor model
			 * // to load automatically all the stuff
			 * var assets = assetManager.load({
			 * 	assets: [...]
			 * });
			 *
			 */
			load: function(data){
				var d = data || '';
				var name = this.storageKey;
				if(!d && c.stm)
					d = c.stm.load(name);
				var assets = [];
				try{
					assets = JSON.parse(d[name]);
				}catch(err){}
				this.getAll().add(assets);
				return assets;
			},

			/**
			 * Render assets
			 * @param  {Boolean} f 	Force to render, otherwise cached version will be returned
			 * @return {HTMLElement}
			 */
			render: function(f){
				if(!this.rendered || f)
					this.rendered	= am.render().$el.add(fu.render().$el);
				return	this.rendered;
			},

			//-------

			/**
			 * Set new target
			 * @param	{Object}	m Model
			 * @private
			 * */
			setTarget: function(m){
				am.collection.target = m;
			},

			/**
			 * Set callback after asset was selected
			 * @param	{Object}	f Callback function
			 * @private
			 * */
			onSelect: function(f){
				am.collection.onSelect = f;
			},

		};
	};
});<commit_msg>Update AssetManager JSDoc<commit_after>/**
 * * [add](#add)
 * * [get](#get)
 * * [getAll](#getall)
 * * [remove](#remove)
 * * [store](#store)
 * * [load](#load)
 *
 * Before using this methods you should get first the module from the editor instance, in this way:
 *
 * ```js
 * var assetManager = editor.AssetManager;
 * ```
 *
 * @module AssetManager
 * @param {Object} config Configurations
 * @param {Array<Object>} [config.assets=[]] Default assets
 * @param {String} [config.uploadText='Drop files here or click to upload'] Upload text
 * @param {String} [config.upload=''] Where to send upload data. Expects as return a JSON with asset/s object
 * as: {data: [{src:'...'}, {src:'...'}]}
 * @return {this}
 * @example
 * ...
 * {
 * 	assets: [
 *  	{src:'path/to/image.png'},
 *     ...
 *  ],
 *  upload: 'http://dropbox/path', // Set to false to disable it
 *  uploadText: 'Drop files here or click to upload',
 * }
 */
define(function(require) {

	return function() {
		var c = {},
			Assets = require('./model/Assets'),
			AssetsView = require('./view/AssetsView'),
			FileUpload = require('./view/FileUploader'),
			assets, am, fu;

	  return {

	  	/**
	  	 * Name of the module
	  	 * @type {String}
	  	 * @private
	  	 */
	  	name: 'AssetManager',

	  	/**
	  	 * Mandatory for the storage manager
	  	 * @type {String}
	  	 * @private
	  	 */
	  	storageKey: 'assets',

	  	/**
	  	 * Initialize module
	  	 * @param {Object} config Configurations
	  	 * @private
	  	 */
	  	init: function(config){
	  		c = config || {};
	  		var defaults = require('./config/config');

	  		for (var name in defaults) {
					if (!(name in c))
						c[name] = defaults[name];
				}

				var ppfx = c.pStylePrefix;
				if(ppfx)
					c.stylePrefix = ppfx + c.stylePrefix;

	  		assets = new Assets(c.assets);
				var obj = {
					collection: assets,
					config: c,
				};
				am = new AssetsView(obj);
	  		fu = new FileUpload(obj);
	  		return this;
	  	},

			/**
			 * Add new asset/s to the collection. URLs are supposed to be unique
			 * @param {string|Object|Array<string>|Array<Object>} asset URL strings or an objects representing the resource.
			 * @return {Model}
			 * @example
			 * // In case of strings, would be interpreted as images
			 * assetManager.add('http://img.jpg');
			 * assetManager.add(['http://img.jpg', './path/to/img.png']);
			 *
			 * // Using objects you could indicate the type and other meta informations
			 * assetManager.add({
			 * 	src: 'http://img.jpg',
			 * 	//type: 'image',	//image is default
			 * 	height: 300,
			 *	width: 200,
			 * });
			 * assetManager.add([{
			 * 	src: 'http://img.jpg',
			 * },{
			 * 	src: './path/to/img.png',
			 * }]);
			 */
			add: function(asset){
				return assets.add(asset);
			},

			/**
			 * Returns the asset by URL
			 * @param  {string} src URL of the asset
			 * @return {Object} Object representing the asset
			 * @example
			 * var asset = assetManager.get('http://img.jpg');
			 */
			get: function(src){
				return assets.where({src: src})[0];
			},

			/**
			 * Return all assets
			 * @return {Collection}
			 */
			getAll: function(){
				return assets;
			},

			/**
			 * Remove the asset by its URL
			 * @param  {string} src URL of the asset
			 * @return {this}
			 * @example
			 * assetManager.remove('http://img.jpg');
			 */
			remove: function(src){
				var asset = this.get(src);
				this.getAll().remove(asset);
				return this;
			},

			/**
			 * Store assets data to the selected storage
			 * @param {Boolean} noStore If true, won't store
			 * @return {Object} Data to store
			 * @example
			 * var assets = assetManager.store();
			 */
			store: function(noStore){
				var obj = {};
				var assets = JSON.stringify(this.getAll().toJSON());
				obj[this.storageKey] = assets;
				if(!noStore && c.stm)
					c.stm.store(obj);
				return obj;
			},

			/**
			 * Load data from the passed object, if the object is empty will try to fetch them
			 * autonomously from the storage manager.
			 * The fetched data will be added to the collection
			 * @param {Object} data Object of data to load
			 * @return {Object} Loaded assets
			 * @example
			 * var assets = assetManager.load();
			 * // The format below will be used by the editor model
			 * // to load automatically all the stuff
			 * var assets = assetManager.load({
			 * 	assets: [...]
			 * });
			 *
			 */
			load: function(data){
				var d = data || '';
				var name = this.storageKey;
				if(!d && c.stm)
					d = c.stm.load(name);
				var assets = [];
				try{
					assets = JSON.parse(d[name]);
				}catch(err){}
				this.getAll().add(assets);
				return assets;
			},

			/**
			 * Render assets
			 * @param  {Boolean} f 	Force to render, otherwise cached version will be returned
			 * @return {HTMLElement}
			 * @private
			 */
			render: function(f){
				if(!this.rendered || f)
					this.rendered	= am.render().$el.add(fu.render().$el);
				return	this.rendered;
			},

			//-------

			/**
			 * Set new target
			 * @param	{Object}	m Model
			 * @private
			 * */
			setTarget: function(m){
				am.collection.target = m;
			},

			/**
			 * Set callback after asset was selected
			 * @param	{Object}	f Callback function
			 * @private
			 * */
			onSelect: function(f){
				am.collection.onSelect = f;
			},

		};
	};
});<|endoftext|>


<commit_before>import React from "react";
import ReactDOM from "react-dom";
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
import RC2 from "react-chartjs2";
import * as diagram from "../Diagram";
import { units, cycles } from "../Setup";
import { FlowType } from "../Flow";
import ComboBox from "./components/ComboBox";
import dispatcher from "../Dispatcher";

let chartItems = [
    { name: "Temperature", prop: "t", unit: units.t[0] },
    { name: "Pressure", prop: "p", unit: units.p[0] },
    { name: "Mass Flow Rate", prop: "m", unit: units.m[0] },
    { name: "Specific Enthalpy", prop: "h", unit: units.x[0] },
    { name: "Specific Entropy", prop: "s", unit: units.x[0] },
    { name: "Specific Exergy", prop: "x", unit: units.x[0] }
];

let chartUnit;
let chartOptions = {
    legend: { display: false },
    title: { display: true, text: 'Temperature', position: "left" },
    scales: {
        yAxes: [{
            type: 'linear',
            ticks: {
                callback: function (value, index, values) {
                    return (chartUnit) ? chartUnit.print(value) : value;
                }
            }
        }]
    }
};

let chartData = {
    labels: ["Stream"],
    datasets: [{
        label: "Temperature",
        lineTension: 0,
        borderColor: 'rgb(255, 99, 132)',
        data: [],
    }]
};

export default class ResultsPanel extends React.Component {

    componentDidMount(){
        this.windowResized();
        $(window).resize(this.windowResized.bind(this));
    }

    windowResized(e){
        let node = ReactDOM.findDOMNode(this);
        let height = $(window).height();
        let mh = Math.max(100, height - 200);
        $(".results-content", node).css("max-height", mh);
    }

    componentWillUnmount(){

        $(window).off("resize", this.windowResized);
    }

    componentWillMount() {

        let pathNames = constructPathNames(diagram.flowPaths);
        this.pathItems = diagram.flowPaths.map((path, i) => {
            return { name: pathNames[i], path };
        });

        if (this.pathItems.length == 0) {
            this.pathItems.push({ name: "N/A", path: [] });
        }

        let pathItem = this.pathItems[0];
        let item = chartItems[0];

        this.prepareData(pathItem.path, item);
        this.setState({ chartItem: item, pathItem });

        this.regId = dispatcher.register(this.handleActions.bind(this));
    }

    componentWillUnmount() {
        dispatcher.unregister(this.regId);
    }

    handleActions(action) {
        switch (action.type) {
            case "MODEL_CALCULATED":
                this.prepareData(this.state.chartItem);
                this.forceUpdate();
                break;
        }
    }

    prepareData(path, item) {

        chartUnit = item.unit;
        chartOptions.title.text = item.name + " [" + item.unit.label + "]";

        var labels = [];
        var dataList = [];
        path.slice().sort((a, b) => {
            return a.number > b.number;
        }).map(flow => {

            let res = flow.results;
            if (flow.getType() == FlowType.Pipe) {
                res = res.inlet;
            }

            if (res && res[item.prop]) {

                let val = Number(chartUnit.print(res[item.prop]));
                labels.push(flow.number + "");
                dataList.push(val);
            }
        });

        chartData.labels = labels;
        chartData.datasets[0].data = dataList;
    }

    closePanel() {
        let node = ReactDOM.findDOMNode(this);
        let elm = $(node).parent()[0];
        ReactDOM.unmountComponentAtNode(elm);
    }

    chartItemChanged(item) {

        let { path } = this.state.pathItem;
        this.prepareData(path, item);
        this.setState({ chartItem: item });
    }

    pathItemChanged(item) {

        let { path } = item;
        this.prepareData(path, this.state.chartItem);
        this.setState({ pathItem: item })
    }

    render() {

        let type = diagram.cycleInfo.type;
        let results = diagram.cycleInfo.results;
        let cycle = cycles[type];

        let cycleTable;
        if (cycle && results) {

            let rows = [];
            for (var p in cycle) {
                let prop = cycle[p];

                let title = prop.title;
                let unit = prop.units[0];
                let value = results[p];
                value = unit.printWithLabel(value);
                rows.push(

                        {value}

                );
            }

            cycleTable = rows.length > 0 ? (

                      > Performance

{rows}

            ) : null;
        }

        return (

Results
                    <button class="close-btn btn btn-link" onClick={this.closePanel.bind(this)}>

                    </button>

                    {cycleTable}

                          > Charts

Flow Path

                        <ComboBox value={this.state.pathItem} items={this.pathItems} onChange={this.pathItemChanged.bind(this)} />

Property

                        <ComboBox value={this.state.chartItem} items={chartItems} onChange={this.chartItemChanged.bind(this)} />

                    <RC2 data={chartData} options={chartOptions} type='line' />

        );
    }
}

function constructPathNames(paths) {

    let names = [];
    paths.map(path => {

        let groups = [];
        let num_s = path[0].number;
        let num_e = path[path.length - 1].number;

        var start = num_s, num = num_s;
        var last = null;
        for (var i = 1; i < path.length; i++) {

            let flow = path[i];
            if (flow.number != (num + 1)) {

                groups.push([start, num])
                start = flow.number;
                num = flow.number;
            } else {

                num += 1;
            }

            if (i == path.length - 1 && num == flow.number) {
                groups.push([start, num]);
                start = null;
            }
        }

        var name = "";
        for (var g in groups) {
            let group = groups[g];
            groups[g] = group.join(" .. ");
        }

        name += groups.join(" > ");
        name += (start) ? ">" + start : "";

        names.push(name);
    });

    return names;
}<commit_msg>HS diagram<commit_after>import React from "react";
import ReactDOM from "react-dom";
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
import RC2 from "react-chartjs2";
import * as diagram from "../Diagram";
import { units, cycles } from "../Setup";
import { FlowType } from "../Flow";
import ComboBox from "./components/ComboBox";
import dispatcher from "../Dispatcher";

let chartItems = [
    { name: "Temperature", prop: "t", unit: units.t[0] },
    { name: "Pressure", prop: "p", unit: units.p[0] },
    { name: "Mass Flow Rate", prop: "m", unit: units.m[0] },
    { name: "Specific Enthalpy", prop: "h", unit: units.x[0] },
    { name: "Specific Entropy", prop: "s", unit: units.x[0] },
    { name: "Specific Exergy", prop: "x", unit: units.x[0] }
];

let chartUnit;
let chartOptions = {
    legend: { display: false },
    title: { display: true, text: 'Temperature', position: "left" },
    scales: {
        yAxes: [{
            type: 'linear',
            ticks: {
                callback: function (value, index, values) {
                    return (chartUnit) ? chartUnit.print(value) : value;
                }
            }
        }]
    }
};

let chartData = {
    labels: ["Stream"],
    datasets: [{
        label: "Temperature",
        lineTension: 0,
        borderColor: 'rgb(255, 99, 132)',
        data: [],
    }]
};

let cycleOptions = {
    legend: { display: false },
    title: { display: true, text: 'HS Diagram', position: "top" },
    scales: {
        xAxes: [{ scaleLabel: {display: true, labelString: 'Entropy (s) - kJ/kg'},
                type: 'linear', min: 0, max: 6 }],
        yAxes: [{ scaleLabel: {display: true, labelString: 'Enthalpy (h) - kJ/kg'},
                type: 'linear', min: 0, max: 6 }]
    }
};

let cycleData = {
    labels: ["Stream"],
    datasets: [{
        label: "Enthalpy",
        lineTension: 0,
        fill: false,
        borderColor: 'rgb(255, 99, 132)',
        data: [],
    }]
};

export default class ResultsPanel extends React.Component {

    componentDidMount() {
        this.windowResized();
        $(window).resize(this.windowResized.bind(this));
    }

    windowResized(e) {
        let node = ReactDOM.findDOMNode(this);
        let height = $(window).height();
        let mh = Math.max(100, height - 200);
        $(".results-content", node).css("max-height", mh);
    }

    componentWillUnmount() {

        $(window).off("resize", this.windowResized);
    }

    componentWillMount() {

        let pathNames = constructPathNames(diagram.flowPaths);
        this.pathItems = diagram.flowPaths.map((path, i) => {
            return { name: pathNames[i], path };
        });

        if (this.pathItems.length == 0) {
            this.pathItems.push({ name: "N/A", path: [] });
        }

        let pathItem = this.pathItems[0];
        let item = chartItems[0];

        this.prepareData(pathItem.path, item);
        this.setState({ chartItem: item, pathItem });

        this.regId = dispatcher.register(this.handleActions.bind(this));
    }

    componentWillUnmount() {
        dispatcher.unregister(this.regId);
    }

    handleActions(action) {
        switch (action.type) {
            case "MODEL_CALCULATED":
                this.prepareData(this.state.chartItem);
                this.forceUpdate();
                break;
        }
    }

    prepareData(path, item) {

        chartUnit = item.unit;
        chartOptions.title.text = item.name + " [" + item.unit.label + "]";

        var processData = [];
        var labels = [];
        var dataList = [];
        path.slice().sort((a, b) => {
            return a.number > b.number;
        }).map(flow => {

            let res = flow.results;
            if (flow.getType() == FlowType.Pipe) {
                res = res.inlet;
            }

            if (res && res[item.prop]) {

                let val = Number(chartUnit.print(res[item.prop]));
                labels.push(flow.number + "");
                dataList.push(val);
            }

            let hVal = Number( units.x[0].print(res.h) );
            let sVal = Number( units.x[0].print(res.s) );

            processData.push({x: sVal, y: hVal});
        });

        chartData.labels = labels;
        chartData.datasets[0].data = dataList;
        cycleData.datasets[0].data = processData;
    }

    closePanel() {
        let node = ReactDOM.findDOMNode(this);
        let elm = $(node).parent()[0];
        ReactDOM.unmountComponentAtNode(elm);
    }

    chartItemChanged(item) {

        let { path } = this.state.pathItem;
        this.prepareData(path, item);
        this.setState({ chartItem: item });
    }

    pathItemChanged(item) {

        let { path } = item;
        this.prepareData(path, this.state.chartItem);
        this.setState({ pathItem: item })
    }

    render() {

        let type = diagram.cycleInfo.type;
        let results = diagram.cycleInfo.results;
        let cycle = cycles[type];

        let cycleTable;
        if (cycle && results) {

            let rows = [];
            for (var p in cycle) {
                let prop = cycle[p];

                let title = prop.title;
                let unit = prop.units[0];
                let value = results[p];
                value = unit.printWithLabel(value);
                rows.push(

                        {value}

                );
            }

            cycleTable = rows.length > 0 ? (

                      > Performance

{rows}

            ) : null;
        }

        return (

Results
                    <button class="close-btn btn btn-link" onClick={this.closePanel.bind(this)}>

                    </button>

                    {cycleTable}

                          > Charts

Flow Path

                        <ComboBox value={this.state.pathItem} items={this.pathItems} onChange={this.pathItemChanged.bind(this)} />

Property

                        <ComboBox value={this.state.chartItem} items={chartItems} onChange={this.chartItemChanged.bind(this)} />

                    <RC2 data={chartData} options={chartOptions} type='line' />

                    <RC2 data={cycleData} options={cycleOptions} type='line' />

        );
    }
}

function constructPathNames(paths) {

    let names = [];
    paths.map(path => {

        let groups = [];
        let num_s = path[0].number;
        let num_e = path[path.length - 1].number;

        var start = num_s, num = num_s;
        var last = null;
        for (var i = 1; i < path.length; i++) {

            let flow = path[i];
            if (flow.number != (num + 1)) {

                groups.push([start, num])
                start = flow.number;
                num = flow.number;
            } else {

                num += 1;
            }

            if (i == path.length - 1 && num == flow.number) {
                groups.push([start, num]);
                start = null;
            }
        }

        var name = "";
        for (var g in groups) {
            let group = groups[g];
            groups[g] = group.join(" .. ");
        }

        name += groups.join(" > ");
        name += (start) ? ">" + start : "";

        names.push(name);
    });

    return names;
}<|endoftext|>


<commit_before>var task = function(gulp, config) {
  'use strict';

  var gulpif = require('gulp-if');
  var cachebust = require('gulp-cache-bust');
  var changed = require('gulp-changed');
  var minifyCss = require('gulp-minify-css');
  var preprocess = require('gulp-preprocess');
  var concat = require('gulp-concat');
  var git = require('gulp-git');
  var rename = require('gulp-rename');

  gulp.task('copy-html', function() {
    return gulp.src(config.src.html)
      .pipe(changed(config.dist.approot))
      .pipe(preprocess({
        context: {
          VERSION: config.version()
        }
      }))
      .pipe(gulpif(global.isProd, cachebust()))
      .pipe(gulp.dest(config.dist.approot));
  });

  gulp.task('copy-css', function(cb) {
    git.revParse({
      args: '--abbrev-ref HEAD'
    }, function(err, ref) {
      gulp.src([].concat(config.deps.css, config.src.css))
        .pipe(concat(config.pkgname + '-' + config.version() + '.css'))
        .pipe(changed(config.dist.approot))
        .pipe(gulpif(global.isProd, minifyCss()))
        .pipe(gulp.dest(config.dist.approot))
        .pipe(rename(config.pkgname + '-' + ref + '-latest.css'))
        .pipe(gulp.dest(config.dist.approot));
        cb();
    });

  });

  gulp.task('copy-static', function() {
    return gulp.src([].concat(config.src.config, config.src.img))
      .pipe(changed(config.dist.approot))
      .pipe(gulp.dest(config.dist.approot));
  });

  gulp.task('copy-deps-assets', function() {
    return gulp.src(config.deps.assets)
      .pipe(changed(config.dist.assets))
      .pipe(gulp.dest(config.dist.assets));
  });

  gulp.task('copy-all', ['copy-html', 'copy-css', 'copy-static', 'copy-deps-assets']);
};

module.exports = task;
<commit_msg>Muted git revParse<commit_after>var task = function(gulp, config) {
  'use strict';

  var gulpif = require('gulp-if');
  var cachebust = require('gulp-cache-bust');
  var changed = require('gulp-changed');
  var minifyCss = require('gulp-minify-css');
  var preprocess = require('gulp-preprocess');
  var concat = require('gulp-concat');
  var git = require('gulp-git');
  var rename = require('gulp-rename');

  gulp.task('copy-html', function() {
    return gulp.src(config.src.html)
      .pipe(changed(config.dist.approot))
      .pipe(preprocess({
        context: {
          VERSION: config.version()
        }
      }))
      .pipe(gulpif(global.isProd, cachebust()))
      .pipe(gulp.dest(config.dist.approot));
  });

  gulp.task('copy-css', function(cb) {
    git.revParse({
      args: '--abbrev-ref HEAD', quiet: true
    }, function(err, ref) {
      gulp.src([].concat(config.deps.css, config.src.css))
        .pipe(concat(config.pkgname + '-' + config.version() + '.css'))
        .pipe(changed(config.dist.approot))
        .pipe(gulpif(global.isProd, minifyCss()))
        .pipe(gulp.dest(config.dist.approot))
        .pipe(rename(config.pkgname + '-' + ref + '-latest.css'))
        .pipe(gulp.dest(config.dist.approot));
        cb();
    });

  });

  gulp.task('copy-static', function() {
    return gulp.src([].concat(config.src.config, config.src.img))
      .pipe(changed(config.dist.approot))
      .pipe(gulp.dest(config.dist.approot));
  });

  gulp.task('copy-deps-assets', function() {
    return gulp.src(config.deps.assets)
      .pipe(changed(config.dist.assets))
      .pipe(gulp.dest(config.dist.assets));
  });

  gulp.task('copy-all', ['copy-html', 'copy-css', 'copy-static', 'copy-deps-assets']);
};

module.exports = task;
<|endoftext|>


<commit_before>import {
  sort, highlight
} from 'reactabular';
import * as resizable from 'reactabular-resizable';
import * as tree from 'reactabular-tree';

function bindHighlightCell() {
  return {
    match({ cell }) {
      return cell.highlight;
    },
    evaluate() {
      return {
        cell: {
          formatters: [
            highlight.cell
          ]
        }
      };
    }
  };
}

function bindToggleChildrenCell({
  idField,
  parentField,
  toggleChildrenProps,
  onToggleShowingChildren,
  rows
}) {
  return {
    match({ cell }) {
      return cell.toggleChildren;
    },
    evaluate() {
      return {
        cell: {
          formatters: [
            tree.toggleChildren({
              getRows: () => rows,
              getShowingChildren: ({ rowData }) => rowData.showingChildren,
              toggleShowingChildren: onToggleShowingChildren,
              // Without this it will perform checks against default id
              idField,
              parentField,
              props: toggleChildrenProps
            })
          ]
        }
      };
    }
  };
}

function bindDraggableHeader({
  onMoveColumns
}) {
  return {
    match({ header }) {
      return header.draggable;
    },
    evaluate({ header }) {
      if (!header.label) {
        console.warn('bind.draggableHeader - missing header.label!');
      }

      return {
        header: {
          props: {
            // DnD needs this to tell header cells apart.
            // TODO: It might be a good idea to model this as an id instead.
            label: header.label,
            onMove: onMoveColumns
          }
        }
      };
    }
  };
}

function bindResizableHeader({
  window,
  onDragColumn,
  props
}) {
  return {
    match({ header }) {
      return header.resizable;
    },
    evaluate() {
      return {
        header: {
          formatters: [
            resizable.column({
              onDrag: onDragColumn,
              parent: window,
              props
            })
          ]
        }
      };
    }
  };
}

function bindSortableHeader({
  sortingColumns,
  onSort,
  props
}) {
  return {
    match({ header }) {
      return header.sortable;
    },
    evaluate() {
      const getSortingColumns = () => sortingColumns || {};
      const sortable = sort.sort({
        getSortingColumns,
        onSort: (selectedColumn) => {
          onSort(
            sort.byColumns({
              sortingColumns,
              selectedColumn
            })
          );
        },
        strategy: sort.strategies.byProperty,
        props
      });

      return {
        header: {
          formatters: [
            sort.header({
              sortable,
              getSortingColumns,
              strategy: sort.strategies.byProperty
            })
          ],
          transforms: [
            sort.reset({
              event: 'onDoubleClick',
              getSortingColumns,
              strategy: sort.strategies.byProperty,
              onReset: params => onSort(params.sortingColumns)
            })
          ]
        }
      };
    }
  };
}

export {
  bindHighlightCell as highlightCell,
  bindToggleChildrenCell as toggleChildrenCell,
  bindDraggableHeader as draggableHeader,
  bindResizableHeader as resizableHeader,
  bindSortableHeader as sortableHeader
};
<commit_msg>chore(easy) - Lint<commit_after>import {
  sort, highlight
} from 'reactabular';
import * as resizable from 'reactabular-resizable';
import * as tree from 'reactabular-tree';

function bindHighlightCell() {
  return {
    match({ cell }) {
      return cell.highlight;
    },
    evaluate() {
      return {
        cell: {
          formatters: [
            highlight.cell
          ]
        }
      };
    }
  };
}

function bindToggleChildrenCell({
  idField,
  parentField,
  toggleChildrenProps,
  onToggleShowingChildren,
  rows
}) {
  return {
    match({ cell }) {
      return cell.toggleChildren;
    },
    evaluate() {
      return {
        cell: {
          formatters: [
            tree.toggleChildren({
              getRows: () => rows,
              getShowingChildren: ({ rowData }) => rowData.showingChildren,
              toggleShowingChildren: onToggleShowingChildren,
              // Without this it will perform checks against default id
              idField,
              parentField,
              props: toggleChildrenProps
            })
          ]
        }
      };
    }
  };
}

function bindDraggableHeader({
  onMoveColumns
}) {
  return {
    match({ header }) {
      return header.draggable;
    },
    evaluate({ header }) {
      if (!header.label) {
        console.warn('bind.draggableHeader - missing header.label!'); // eslint-disable-line no-console
      }

      return {
        header: {
          props: {
            // DnD needs this to tell header cells apart.
            // TODO: It might be a good idea to model this as an id instead.
            label: header.label,
            onMove: onMoveColumns
          }
        }
      };
    }
  };
}

function bindResizableHeader({
  window,
  onDragColumn,
  props
}) {
  return {
    match({ header }) {
      return header.resizable;
    },
    evaluate() {
      return {
        header: {
          formatters: [
            resizable.column({
              onDrag: onDragColumn,
              parent: window,
              props
            })
          ]
        }
      };
    }
  };
}

function bindSortableHeader({
  sortingColumns,
  onSort,
  props
}) {
  return {
    match({ header }) {
      return header.sortable;
    },
    evaluate() {
      const getSortingColumns = () => sortingColumns || {};
      const sortable = sort.sort({
        getSortingColumns,
        onSort: (selectedColumn) => {
          onSort(
            sort.byColumns({
              sortingColumns,
              selectedColumn
            })
          );
        },
        strategy: sort.strategies.byProperty,
        props
      });

      return {
        header: {
          formatters: [
            sort.header({
              sortable,
              getSortingColumns,
              strategy: sort.strategies.byProperty
            })
          ],
          transforms: [
            sort.reset({
              event: 'onDoubleClick',
              getSortingColumns,
              strategy: sort.strategies.byProperty,
              onReset: params => onSort(params.sortingColumns)
            })
          ]
        }
      };
    }
  };
}

export {
  bindHighlightCell as highlightCell,
  bindToggleChildrenCell as toggleChildrenCell,
  bindDraggableHeader as draggableHeader,
  bindResizableHeader as resizableHeader,
  bindSortableHeader as sortableHeader
};
<|endoftext|>


<commit_before>module.exports = (async () => {
const Sequelize = require('sequelize');
const fs = require('fs');
const path = require('path');
    const config = await require("../config");

    const sequelize = new Sequelize(config.databaseURL, {
        operatorsAliases: Sequelize.Op.Aliases
});

    const db = {};
const modelsDir = path.join(__dirname, 'models');

    fs
        .readdirSync(modelsDir)
        .filter(file => {
            return (file.indexOf('.') !== 0);
        })
        .forEach(file => {
            const model = sequelize['import'](path.join(modelsDir, file));
            db[model.name] = model;
        });

    Object.keys(db).forEach(modelName => {
        if (db[modelName].associate) {
            db[modelName].associate(db);
        }
});

    db.sequelize = sequelize;
db.Sequelize = Sequelize;

    return db;

})();<commit_msg>Sodding docker compose<commit_after>module.exports = (async () => {
const Sequelize = require('sequelize');
const fs = require('fs');
const path = require('path');
    const config = await require("../config");

    console.log(config);

    const sequelize = new Sequelize(config.databaseURL, {
        operatorsAliases: Sequelize.Op.Aliases
});

    const db = {};
const modelsDir = path.join(__dirname, 'models');

    fs
        .readdirSync(modelsDir)
        .filter(file => {
            return (file.indexOf('.') !== 0);
        })
        .forEach(file => {
            const model = sequelize['import'](path.join(modelsDir, file));
            db[model.name] = model;
        });

    Object.keys(db).forEach(modelName => {
        if (db[modelName].associate) {
            db[modelName].associate(db);
        }
});

    db.sequelize = sequelize;
db.Sequelize = Sequelize;

    return db;

})();<|endoftext|>


<commit_before>angular.module('MyModule')
    .controller('circlecontroller', function ($scope, $window, $timeout, KineticService, UtilityService, AgentService) {
       'use strict';
       $scope.windowWidth = function () {
          return $window.innerWidth;
       };

       //$scope.windowHeight = function () {
       //   return $window.innerHeight;
       //}

       $scope.$watch($scope.windowWidth, function (newValue, oldValue) {
          stage.setWidth(newValue);
       });

       //$scope.$watch($scope.windowHeight, function (newValue, oldValue) {
       //   stage.setHeight(newValue < 300 ? 300 : newValue);
       //});

       var stage = {};
       function init() {
          $scope.pageName = "CIRCLES";
          stage = KineticService.createStage('container', $scope.windowWidth(), 700);
          AgentService.clear();

          for (var i = 0; i < 10; i++) {
             var v1 = new Vec2(UtilityService.randomInt( -10, 10), UtilityService.randomInt( -10, 10));
             v1 = vMath.normalize(v1);
             v1 = vMath.mulS(v1,UtilityService.randomInt(1, 5));
             AgentService.createAgent(stage, null, v1, 15);
          }

          for (var i = 0; i < 10; i++) {
              var v1 = new Vec2(UtilityService.randomInt(-10, 10), UtilityService.randomInt(-10, 10));
              v1 = vMath.normalize(v1);
              v1 = vMath.mulS(v1, UtilityService.randomInt(1, 5));
              AgentService.createAgent(stage, null, v1, 20);
          }

          for (var i = 0; i < 10; i++) {
              var v1 = new Vec2(UtilityService.randomInt(-10, 10), UtilityService.randomInt(-10, 10));
              v1 = vMath.normalize(v1);
              v1 = vMath.mulS(v1, UtilityService.randomInt(1, 8));
              AgentService.createAgent(stage, null, v1, 25);
          }

       }

       init();

       $scope.onTimeout = function () {
          mytimeout = $timeout($scope.onTimeout, 20);

          AgentService.checkAllBoundaries(stage.getWidth(), stage.getHeight());

          AgentService.checkAllCollisions();

          AgentService.moveAllAgents();

          AgentService.drawAllLayers();
       };

       var mytimeout = $timeout($scope.onTimeout, 20);

       $scope.$on("$destroy", function () {

          $timeout.cancel(mytimeout);
       });

    });<commit_msg>Tweak starting positions and sizes.<commit_after>angular.module('MyModule')
    .controller('circlecontroller', function ($scope, $window, $timeout, KineticService, UtilityService, AgentService) {
       'use strict';
       $scope.windowWidth = function () {
          return $window.innerWidth;
       };

       //$scope.windowHeight = function () {
       //   return $window.innerHeight;
       //}

       $scope.$watch($scope.windowWidth, function (newValue, oldValue) {
          stage.setWidth(newValue);
       });

       //$scope.$watch($scope.windowHeight, function (newValue, oldValue) {
       //   stage.setHeight(newValue < 300 ? 300 : newValue);
       //});

       var stage = {};
       function init() {
          $scope.pageName = "CIRCLES";
          stage = KineticService.createStage('container', $scope.windowWidth(), 700);
          AgentService.clear();

          for (var i = 0; i < 8; i++) {
             var v1 = new Vec2(UtilityService.randomInt( -10, 10), UtilityService.randomInt( -10, 10));
             v1 = vMath.normalize(v1);
             v1 = vMath.mulS(v1,UtilityService.randomInt(1, 8));
             AgentService.createAgent(stage, null, v1, 15);
          }

          for (var i = 0; i < 8; i++) {
              var v1 = new Vec2(UtilityService.randomInt(-10, 10), UtilityService.randomInt(-10, 10));
              v1 = vMath.normalize(v1);
              v1 = vMath.mulS(v1, UtilityService.randomInt(1, 8));
              AgentService.createAgent(stage, null, v1, 20);
          }

          for (var i = 0; i < 8; i++) {
              var v1 = new Vec2(UtilityService.randomInt(-10, 10), UtilityService.randomInt(-10, 10));
              v1 = vMath.normalize(v1);
              v1 = vMath.mulS(v1, UtilityService.randomInt(1, 8));
              AgentService.createAgent(stage, null, v1, 25);
          }

          for (var i = 0; i < 3; i++) {
              var v1 = new Vec2(UtilityService.randomInt(-10, 10), UtilityService.randomInt(-10, 10));
              v1 = vMath.normalize(v1);
              v1 = vMath.mulS(v1, UtilityService.randomInt(1, 2));
              AgentService.createAgent(stage, null, v1, 70);
          }
      }

       init();

       $scope.onTimeout = function () {
          mytimeout = $timeout($scope.onTimeout, 20);

          AgentService.checkAllBoundaries(stage.getWidth(), stage.getHeight());

          AgentService.checkAllCollisions();

          AgentService.moveAllAgents();

          AgentService.drawAllLayers();
       };

       var mytimeout = $timeout($scope.onTimeout, 20);

       $scope.$on("$destroy", function () {

          $timeout.cancel(mytimeout);
       });

    });<|endoftext|>


<commit_before>import React, {Component} from 'react';
import PropTypes from 'prop-types';

import EditableField from '../EditableField';

import Util from '../_vendors/Util';
import CharSize from '../_vendors/CharSize';

import './TagField.css';

export default class TagField extends Component {

    constructor(props) {

        super(props);

        this.inputSymbol = Symbol('input');

        this.state = {
            data: props.data,
            inputValue: '',
            inputIndex: props.data.length
        };

        this.mouseDownHandler = this::this.mouseDownHandler;
        this.inputChangeHandler = this::this.inputChangeHandler;
        this.inputKeyDownHandler = this::this.inputKeyDownHandler;

    }

    mouseDownHandler(e) {
        if (e.target == this.refs.wrapper) {
            setTimeout(() => {
                this.refs.input.focus();
            }, 0);
        }
    }

    inputChangeHandler(e) {

        const inputValue = e.target.value;

        this.setState({
            inputValue
        }, () => {
            const width = CharSize.calculateStringWidth(inputValue, this.refs.test);
            this.refs.input.style.width = `${width + 1}px`;
        });

    }

    inputKeyDownHandler(e) {

        if (e.keyCode === 13) {

            const {data, inputValue, inputIndex} = this.state;

            data.splice(inputIndex, 0, {
                value: inputValue
            });

            this.setState({
                data,
                inputValue: '',
                inputIndex: inputIndex + 1
            }, () => {
                const {onChange} = this.props;
                onChange && onChange(data);
            });

        }
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.data !== this.state.data) {
            this.setState({
                data: nextProps.data
            });
        }
    }

    render() {

        const {className, style, valueField, displayField} = this.props,
            {data, inputValue, inputIndex} = this.state,

            tagFieldClassName = (className ? ' ' + className : '');

        const indexData = Util.genIndexArray(data.length);
        indexData.splice(inputIndex, 0, this.inputSymbol);

        return (

                {
                    indexData.map(index => {
                        return index === this.inputSymbol ?
                            (
                                <input key="input"
                                       ref="input"
                                       className="tag-field-input"
                                       autoFocus="true"
                                       value={inputValue}
                                       onChange={this.inputChangeHandler}
                                       onKeyDown={this.inputKeyDownHandler}/>
                            )
                            :
                            (

                                    <EditableField className="tag-field-item-field"
                                                   value={Util.getTextByDisplayField(data[index], displayField, valueField)}/>
                                    {', '}

                            );
                    })
                }

        );

    }
};

TagField.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     *
     */
    data: PropTypes.array,

    /**
     *
     */
    valueField: PropTypes.string,

    /**
     *
     */
    displayField: PropTypes.string,

    /**
     *
     */
    onChange: PropTypes.func

};

TagField.defaultProps = {

    className: '',
    style: null,

    data: [],

    valueField: 'value',
    displayField: 'text'

};<commit_msg>update TagField<commit_after>import React, {Component} from 'react';
import PropTypes from 'prop-types';

import EditableField from '../EditableField';

import Util from '../_vendors/Util';
import CharSize from '../_vendors/CharSize';

import './TagField.css';

export default class TagField extends Component {

    constructor(props) {

        super(props);

        this.inputSymbol = Symbol('input');

        this.state = {
            data: props.data,
            inputValue: '',
            inputIndex: props.data.length
        };

        this.mouseDownHandler = this::this.mouseDownHandler;
        this.inputChangeHandler = this::this.inputChangeHandler;
        this.inputKeyDownHandler = this::this.inputKeyDownHandler;
        this.inputPasteHandler = this::this.inputPasteHandler;

    }

    mouseDownHandler(e) {
        if (e.target == this.refs.wrapper) {
            setTimeout(() => {
                this.refs.input.focus();
            }, 0);
        }
    }

    inputChangeHandler(e) {

        const inputValue = e.target.value;

        this.setState({
            inputValue
        }, () => {
            const width = CharSize.calculateStringWidth(inputValue, this.refs.test);
            this.refs.input.style.width = `${width + 1}px`;
        });

    }

    inputKeyDownHandler(e) {

        if (e.keyCode === 13) {

            const {data, inputValue, inputIndex} = this.state;

            if (!inputValue) {
                return;
            }

            const splitedValue = inputValue.split(',').map(value => ({
                value
            }));

            data.splice(inputIndex, 0, ...splitedValue);

            this.setState({
                data,
                inputValue: '',
                inputIndex: inputIndex + splitedValue.length
            }, () => {
                const {onChange} = this.props;
                onChange && onChange(data);
            });

        }
    }

    inputPasteHandler(e) {
        console.log(e);
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.data !== this.state.data) {
            this.setState({
                data: nextProps.data
            });
        }
    }

    render() {

        const {className, style, valueField, displayField} = this.props,
            {data, inputValue, inputIndex} = this.state,

            tagFieldClassName = (className ? ' ' + className : '');

        const indexData = Util.genIndexArray(data.length);
        indexData.splice(inputIndex, 0, this.inputSymbol);

        return (

                {
                    indexData.map(index => {
                        return index === this.inputSymbol ?
                            (
                                <input key="input"
                                       ref="input"
                                       className="tag-field-input"
                                       autoFocus="true"
                                       value={inputValue}
                                       onChange={this.inputChangeHandler}
                                       onKeyDown={this.inputKeyDownHandler}
                                       onPaste={this.inputPasteHandler}/>
                            )
                            :
                            (

                                    <EditableField className="tag-field-item-field"
                                                   value={Util.getTextByDisplayField(data[index], displayField, valueField)}/>
                                    {', '}

                            );
                    })
                }

        );

    }
};

TagField.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     *
     */
    data: PropTypes.array,

    /**
     *
     */
    valueField: PropTypes.string,

    /**
     *
     */
    displayField: PropTypes.string,

    /**
     *
     */
    onChange: PropTypes.func

};

TagField.defaultProps = {

    className: '',
    style: null,

    data: [],

    valueField: 'value',
    displayField: 'text'

};<|endoftext|>