<commit_before>define(function(require) {
  'use strict';

  var q = require('q');
  var validator = require('validator');

  var PF = require('js/app/obj');
  var logger = PF.logger.get('root/js/apps/user/entities');

  PF.module('UserApp.Entities', function(Entities, PF, Backbone, Marionette, $, _) {
    require('js/common/base_entities');

    Entities.User = PF.Entities.PFDatabaseModel.extend({
      __name: 'User',
      urlRoot: '/api/user/user',
      validate: function(attrs, options) {
        var errors = {};
        if(!validator.isEmail(attrs.email)) {
          attrs['email'] = "'" + attrs.email + "' - invalid email address format";
        }

        if(attrs.password && !validators.isAlphanumeric(attrs.password)) {
          attrs["password"] = "Passwords must be letters and numbers only";
        }

        return errors;
      }
    });

    var API = {
      get_promise: function(user_id) {
        logger.trace('API.get_promise -- enter');
        var deferred = q.defer();
        var user = new Entities.User({ id: user_id });
        user.fetch({
          success: function(user_model) { deferred.resolve(user_model); },
          error: function() { deferred.resolve(undefined); }
        });
        return deferred.promise;
      }
    };

    PF.reqres.setHandler('userapp:entities:user', function() {
      return API.get_promise();
    });
  });
});
<commit_msg>client/js/apps/user/entities.js - tweaked validators, return PF.UserApp.Entities from module define call<commit_after>define(function(require) {
  'use strict';

  var q = require('q');
  var validator = require('validator');

  var PF = require('js/app/obj');
  var logger = PF.logger.get('root/js/apps/user/entities');

  PF.module('UserApp.Entities', function(Entities, PF, Backbone, Marionette, $, _) {
    require('js/common/base_entities');

    Entities.User = PF.Entities.PFDatabaseModel.extend({
      __name: 'User',
      urlRoot: '/api/user/user',
      validate: function(attrs, options) {
        var errors = {};
        if(!validator.isEmail(attrs.email)) {
          attrs['email'] = '"' + attrs.email + '" - invalid email address format';
        }

        if(attrs.password && !validator.isAlphanumeric(attrs.password)) {
          attrs['password'] = 'Passwords must be letters and numbers only (and at least 8 characters long)';
        }
        else if(attrs.password && !validator.isLength(attrs.password, 8)) {
          attrs['password'] = 'Passwords must be at least 8 characters long (letters and numbers only)';
        }

        return errors;
      }
    });

    var API = {
      get_promise: function(user_id) {
        logger.trace('API.get_promise -- enter');
        var deferred = q.defer();
        var user = new Entities.User({ id: user_id });
        user.fetch({
          success: function(user_model) { deferred.resolve(user_model); },
          error: function() { deferred.resolve(undefined); }
        });
        return deferred.promise;
      }
    };

    PF.reqres.setHandler('userapp:entities:user', function() {
      return API.get_promise();
    });
  });

  return PF.UserApp.Entities;
});
<|endoftext|>


<commit_before>var q = require('q');
var Jasmine = require('jasmine');
var SpecReporter = require('jasmine-spec-reporter');
var jrunner = new Jasmine();
jrunner.exitCodeReporter = new (require('./exit-code-reporter.js'))(jrunner);
var ermrestUtils = require(process.env.PWD + "/../ErmrestDataUtils/import.js");

// Util function to create a catalog before running all specs
// Returns a promise
var createCatalog = function() {
	var defer = q.defer();

	// make http request to create a catalog to be used across all specs
	ermrestUtils.importData({
        setup: { catalog: {} },
        url: process.env.ERMREST_URL,
        authCookie: process.env.AUTH_COOKIE
    }).then(function (data) {
    	process.env.DEFAULT_CATALOG = data.catalogId;
	    defer.resolve(data.catalogId);
    }, function (err) {
	    defer.reject(err);
    });

	return defer.promise;
};
exports.createCatalog = createCatalog;

// Util function to delete a catalog if provided or uses process.env.DEFAULT_CATALOG after running all specs
// Returns a promise
var deleteCatalog = function(catalogId) {
	var defer = q.defer();
	catalogId = catalogId || process.env.DEFAULT_CATALOG;
	if (catalogId) {
		ermrestUtils.tear({
	        setup: { catalog : { } },
	        catalogId: catalogId,
	        url:  process.env.ERMREST_URL ,
	        authCookie : process.env.AUTH_COOKIE
	    }).then(function(data) {
		  	defer.resolve();
	    }, function(err) {
	        console.log("Unable to delete catalog");
		    defer.reject(err);
	    });
	} else {
		defer.resolve("no catalogId found");
	}

	return defer.promise;
};
exports.deleteCatalog = deleteCatalog

// Start running the test specs
// Accepts a config json
// Creates a catalog and then runs the specs as mentioned in the config file
// Deletes the created catalog once all specs have been executed
exports.run = function(config) {

	// Load the configuration
	jrunner.loadConfig(config);

	// Remove default reporter logs
	jrunner.configureDefaultReporter({ print: function() { } });

	// Add Jasmine  specReporter
	jrunner.addReporter(new SpecReporter());

	// Set timeout to a large value
	jrunner.jasmine.DEFAULT_TIMEOUT_INTERVAL = 25000;

	jrunner.onComplete(function(passed) {
		console.log("Test suite " + (passed ? "passed" : "failed"));
		deleteCatalog().done(function() {
			if (!passed) process.exit(1);
		});
	});

	// Create a catalog and then
	// Execute the specs mentioned in the config file jasmine.json in /support folder
	createCatalog().then(function() {
		jrunner.execute();
	}, function(err) {
		console.log("Unable to create default catalog");
		process.exit(1);
	}).catch(function(err) {
		process.exit(1);
	});
};<commit_msg>Increased Jasmine timeout to 100000 seconds<commit_after>var q = require('q');
var Jasmine = require('jasmine');
var SpecReporter = require('jasmine-spec-reporter');
var jrunner = new Jasmine();
jrunner.exitCodeReporter = new (require('./exit-code-reporter.js'))(jrunner);
var ermrestUtils = require(process.env.PWD + "/../ErmrestDataUtils/import.js");

// Util function to create a catalog before running all specs
// Returns a promise
var createCatalog = function() {
	var defer = q.defer();

	// make http request to create a catalog to be used across all specs
	ermrestUtils.importData({
        setup: { catalog: {} },
        url: process.env.ERMREST_URL,
        authCookie: process.env.AUTH_COOKIE
    }).then(function (data) {
    	process.env.DEFAULT_CATALOG = data.catalogId;
	    defer.resolve(data.catalogId);
    }, function (err) {
	    defer.reject(err);
    });

	return defer.promise;
};
exports.createCatalog = createCatalog;

// Util function to delete a catalog if provided or uses process.env.DEFAULT_CATALOG after running all specs
// Returns a promise
var deleteCatalog = function(catalogId) {
	var defer = q.defer();
	catalogId = catalogId || process.env.DEFAULT_CATALOG;
	if (catalogId) {
		ermrestUtils.tear({
	        setup: { catalog : { } },
	        catalogId: catalogId,
	        url:  process.env.ERMREST_URL ,
	        authCookie : process.env.AUTH_COOKIE
	    }).then(function(data) {
		  	defer.resolve();
	    }, function(err) {
	        console.log("Unable to delete catalog");
		    defer.reject(err);
	    });
	} else {
		defer.resolve("no catalogId found");
	}

	return defer.promise;
};
exports.deleteCatalog = deleteCatalog

// Start running the test specs
// Accepts a config json
// Creates a catalog and then runs the specs as mentioned in the config file
// Deletes the created catalog once all specs have been executed
exports.run = function(config) {

	// Load the configuration
	jrunner.loadConfig(config);

	// Remove default reporter logs
	jrunner.configureDefaultReporter({ print: function() { } });

	// Add Jasmine  specReporter
	jrunner.addReporter(new SpecReporter());

	// Set timeout to a large value
	jrunner.jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000;

	jrunner.onComplete(function(passed) {
		console.log("Test suite " + (passed ? "passed" : "failed"));
		deleteCatalog().done(function() {
			if (!passed) process.exit(1);
		});
	});

	// Create a catalog and then
	// Execute the specs mentioned in the config file jasmine.json in /support folder
	createCatalog().then(function() {
		jrunner.execute();
	}, function(err) {
		console.log("Unable to create default catalog");
		process.exit(1);
	}).catch(function(err) {
		process.exit(1);
	});
};<|endoftext|>


<commit_before>function whiteline() {
	document.getElementById('handle-line').style.background='#fff';
}
function destroywhite() {
	document.getElementById('handle-line').style.background='rgba(255, 255, 255, 0.5)';
}

$(document).ready(function(){
	/*---------------------------------
		Tabs system from 99Lime.com HTML KickStart by Joshua Gatcke
	-----------------------------------*/
	// tab setup
	$('.tab-content').addClass('clearfix').not(':first').hide();
	$('ul.tabs').each(function(){
		var current = $(this).find('li.current');
		if(current.length < 1) { $(this).find('li:first').addClass('current'); }
		current = $(this).find('li.current a').attr('href');
		$(current).show();
	});

	// tab click
	$(document).on('click', 'ul.tabs a[href^="#"]', function(e){
		e.preventDefault();
		var tabs = $(this).parents('ul.tabs').find('li');
		var tab_next = $(this).attr('href');
		var tab_current = tabs.filter('.current').find('a').attr('href');
		$(tab_current).hide();
		tabs.removeClass('current');
		$(this).parent().addClass('current');
		$(tab_next).show();
		history.pushState( null, null, window.location.search + $(this).attr('href') );
		return false;
	});

 	// tab hashtag identification and auto-focus
  	var wantedTag = window.location.hash;
	if (wantedTag != "") {
	// This code can and does fail, hard, killing the entire app.
	// Esp. when used with the jQuery.Address project.
		try {
			var allTabs = $("ul.tabs a[href^=" + wantedTag + "]").parents('ul.tabs').find('li');
			var defaultTab = allTabs.filter('.current').find('a').attr('href');
			$(defaultTab).hide();
			allTabs.removeClass('current');
			$("ul.tabs a[href^=" + wantedTag + "]").parent().addClass('current');
			$("#" + wantedTag.replace('#','')).show();
		}
		catch(e) {
			// I have no idea what to do here, so I'm leaving this for the maintainer.
		}
	}
});
<commit_msg>Update script.js<commit_after>$(document).ready(function(){
	/*---------------------------------
		Tabs system from 99Lime.com HTML KickStart by Joshua Gatcke
	-----------------------------------*/
	// tab setup
	$('.tab-content').addClass('clearfix').not(':first').hide();
	$('ul.tabs').each(function(){
		var current = $(this).find('li.current');
		if(current.length < 1) { $(this).find('li:first').addClass('current'); }
		current = $(this).find('li.current a').attr('href');
		$(current).show();
	});

	// tab click
	$(document).on('click', 'ul.tabs a[href^="#"]', function(e){
		e.preventDefault();
		var tabs = $(this).parents('ul.tabs').find('li');
		var tab_next = $(this).attr('href');
		var tab_current = tabs.filter('.current').find('a').attr('href');
		$(tab_current).hide();
		tabs.removeClass('current');
		$(this).parent().addClass('current');
		$(tab_next).show();
		history.pushState( null, null, window.location.search + $(this).attr('href') );
		return false;
	});

 	// tab hashtag identification and auto-focus
  	var wantedTag = window.location.hash;
	if (wantedTag != "") {
	// This code can and does fail, hard, killing the entire app.
	// Esp. when used with the jQuery.Address project.
		try {
			var allTabs = $("ul.tabs a[href^=" + wantedTag + "]").parents('ul.tabs').find('li');
			var defaultTab = allTabs.filter('.current').find('a').attr('href');
			$(defaultTab).hide();
			allTabs.removeClass('current');
			$("ul.tabs a[href^=" + wantedTag + "]").parent().addClass('current');
			$("#" + wantedTag.replace('#','')).show();
		}
		catch(e) {
			// I have no idea what to do here, so I'm leaving this for the maintainer.
		}
	}
});
<|endoftext|>


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

function onRequest(context) {
    var log = new Log("stats.js");
    var carbonServer = require("carbon").server;
    var device = context.unit.params.device;
    var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
    var constants = require("/app/modules/constants.js");

    var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss");
    var jwtService = carbonServer.osgiService(
        'org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService');
    var jwtClient = jwtService.getJWTClient();
    var encodedClientKeys = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
    if (encodedClientKeys) {
        var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"];
        var resp = tokenUtil.decode(encodedClientKeys).split(":");
        var deviceParam = "{\"scope\":\"stats\",\"deviceIdentifiers\":[{\"id\":\"" + device.deviceIdentifier
                          + " \", \"type\":\"" + device.type + "\"}]}";
        var encodedScope = tokenUtil.encode(deviceParam);
        var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,
                                                 "{\"device\": \"" + encodedScope + "\"}");
        var token = "";
        if (tokenPair) {
            token = tokenPair.accessToken;
        }
        websocketEndpoint = websocketEndpoint + "/secured-outputui/org.wso2.iot.devices.temperature/1.0.0?" +
                            "token=" + token + "&deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type;
    }
    return {"device": device, "websocketEndpoint": websocketEndpoint};
}<commit_msg>Fixing JWT token issue for realtime analytics<commit_after>/*
 * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 *
 * WSO2 Inc. licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

function onRequest(context) {
    var log = new Log("stats.js");
    var carbonServer = require("carbon").server;
    var device = context.unit.params.device;
    var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"];
    var constants = require("/app/modules/constants.js");

    var websocketEndpoint = devicemgtProps["wssURL"].replace("https", "wss");
    var jwtService = carbonServer.osgiService(
        'org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService');
    var jwtClient = jwtService.getJWTClient();
    var encodedClientKeys = session.get(constants["ENCODED_TENANT_BASED_CLIENT_APP_CREDENTIALS"]);
    if (encodedClientKeys) {
        var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"];
        var resp = tokenUtil.decode(encodedClientKeys).split(":");
        var deviceParam = "{\"scope\":\"stats\",\"deviceIdentifiers\":[{\"id\":\"" + device.deviceIdentifier
                          + "\", \"type\":\"" + device.type + "\"}]}";
        var encodedScope = tokenUtil.encode(deviceParam);
        var tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default",
                                                 {"device": encodedScope});
        var token = "";
        if (tokenPair) {
            token = tokenPair.accessToken;
        }
        websocketEndpoint = websocketEndpoint + "/secured-outputui/org.wso2.iot.devices.temperature/1.0.0?" +
                            "token=" + token + "&deviceId=" + device.deviceIdentifier + "&deviceType=" + device.type;
    }
    return {"device": device, "websocketEndpoint": websocketEndpoint};
}<|endoftext|>


<commit_before>/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};

/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {

/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}

/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;

/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";

/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var Countdown = __webpack_require__(1);

	document.addEventListener('DOMContentLoaded', function () {
	  new Countdown({
	    id: "ds-Countdown",
	    targetTime: '2017-01-01 00:00:00',
	    separator: ':',
	    afterEnd: function afterEnd() {
	      alert("Time over !");
	    }
	  });
	}, false);

/***/ },
/* 1 */
/***/ function(module, exports) {

	"use strict";

	var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

	var Countdown = function () {
	  function Countdown(options) {
	    var _this = this;

	    _classCallCheck(this, Countdown);

	    if (!options.targetTime || !options.id) {
	      console.error("Countdown : Date is not defined");
	    }

	    this.el = document.getElementById(options.id);
	    this.now = new Date().getTime();
	    this.targetTime = new Date(options.targetTime).getTime();
	    this.afterEnd = options.afterEnd;
	    if (options.separator === false) {
	      this.separator = "";
	    } else {
	      this.separator = options.separator && typeof options.separator == "string" ? options.separator : ":";
	    }
	    this.hideDayAtZeroOpts = options.hideDayAtZero || false;
	    this.noDay = options.noDay || false;

	    if (this.now > this.targetTime) {
	      console.warn("Countdown : Date defined > Date now");
	      return;
	    }

	    this.refresh();
	    this.interval = setInterval(function () {
	      _this.refresh();
	    }, 1000);
	  }

	  _createClass(Countdown, [{
	    key: "refresh",
	    value: function refresh() {
	      this.now = new Date().getTime();

	      if (this.now > this.targetTime) {
	        clearInterval(this.interval);
	        if (this.afterEnd) this.afterEnd();
	        return;
	      }

	      this.defineTimer();
	      this.render();
	    }
	  }, {
	    key: "hideDayAtZero",
	    value: function hideDayAtZero() {
	      if (this.hideDayAtZeroOpts && this.timer.day == 0) {
	        return true;
	      }
	    }
	  }, {
	    key: "defineTimer",
	    value: function defineTimer() {
	      this.timer = {};
	      var tmp = this.targetTime - this.now;
	      tmp = Math.floor(tmp / 1000);
	      this.timer.sec = tmp % 60;
	      this.timer.sec = this.timer.sec < 10 ? "0" + this.timer.sec : this.timer.sec;

	      tmp = Math.floor((tmp - this.timer.sec) / 60);
	      this.timer.min = tmp % 60;
	      this.timer.min = this.timer.min < 10 ? "0" + this.timer.min : this.timer.min;

	      tmp = Math.floor((tmp - this.timer.min) / 60);
	      this.timer.hour = this.noDay ? tmp : tmp % 24;
	      this.timer.hour = this.timer.hour < 10 ? "0" + this.timer.hour : this.timer.hour;

	      if (this.noDay) return;
	      tmp = Math.floor((tmp - this.timer.hour) / 24);
	      this.timer.day = tmp;
	      if (this.hideDayAtZero()) return;
	      this.timer.day = this.timer.day < 10 ? "0" + this.timer.day : this.timer.day;
	    }
	  }, {
	    key: "render",
	    value: function render() {
	      var tplDay = "" + this.timer.day + "" + this.separator;
	      var tpl = "" + this.timer.hour + "" + this.separator + "" + this.timer.min + "" + this.separator + "" + this.timer.sec + "";

	      this.el.innerHTML = this.hideDayAtZero() || this.noDay ? tpl : tplDay + tpl;
	    }
	  }]);

	  return Countdown;
	}();

	module.exports = Countdown;

/***/ }
/******/ ]);<commit_msg>build bundle demo<commit_after>/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};

/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {

/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}

/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;

/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";

/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

	'use strict';

	var Countdown = __webpack_require__(1);

	document.addEventListener('DOMContentLoaded', function () {
	  new Countdown({
	    id: "ds-Countdown",
	    targetTime: '2017-01-01 00:00:00',
	    separator: ':',
	    afterEnd: function afterEnd() {
	      alert("Time over !");
	    }
	  });
	}, false);

/***/ }),
/* 1 */
/***/ (function(module, exports) {

	'use strict';

	var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

	var Countdown = function () {
	  function Countdown() {
	    var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

	    _classCallCheck(this, Countdown);

	    this.options = options;
	    this.targetTime = new Date(this.options.targetTime).getTime();
	    this.afterEnd = this.options.afterEnd;
	    this.hideDayAtZero = this.options.hideDayAtZero || false;
	    this.noDay = this.options.noDay || false;

	    this.checkExceptions();
	    this.defineSeparatorTpl();
	    this.run();
	  }

	  _createClass(Countdown, [{
	    key: 'checkExceptions',
	    value: function checkExceptions() {
	      this.optionsAreCorrectlyDefined();
	      this.checkDateIsOutOfTargetDate();
	    }
	  }, {
	    key: 'optionsAreCorrectlyDefined',
	    value: function optionsAreCorrectlyDefined() {
	      var targetTimeOptionExist = this.options.hasOwnProperty('targetTime');
	      var idOptionExist = this.options.hasOwnProperty('id');

	      if (!targetTimeOptionExist || !idOptionExist) {
	        throw new Error("Countdown : Date is not defined");
	      }
	    }
	  }, {
	    key: 'checkDateIsOutOfTargetDate',
	    value: function checkDateIsOutOfTargetDate() {
	      if (this.now > this.targetTime) {
	        throw new Error("Countdown : Date defined > Date now");
	      }
	    }
	  }, {
	    key: 'defineSeparatorTpl',
	    value: function defineSeparatorTpl() {
	      var separatorOptionSetToFalse = this.options.separator === false;
	      if (separatorOptionSetToFalse) {
	        this.separator = "";
	      } else {
	        this.separator = this.options.separator || ':';
	      }
	    }
	  }, {
	    key: 'run',
	    value: function run() {
	      var _this = this;

	      this.refresh();
	      this.intervalRender = setInterval(function () {
	        _this.refresh();
	      }, 1000);
	    }
	  }, {
	    key: 'refresh',
	    value: function refresh() {
	      this.now = new Date().getTime();
	      this.checkTimeOutOrNot();
	    }
	  }, {
	    key: 'checkTimeOutOrNot',
	    value: function checkTimeOutOrNot() {
	      if (this.now > this.targetTime) {
	        this.clearAndRunCallback();
	      } else {
	        this.defineTimer();
	        this.render();
	      }
	    }
	  }, {
	    key: 'clearAndRunCallback',
	    value: function clearAndRunCallback() {
	      clearInterval(this.intervalRender);
	      if (this.afterEnd) this.afterEnd();
	    }
	  }, {
	    key: 'hideDay',
	    value: function hideDay() {
	      return !!(this.hideDayAtZero && (this.timer.day === 0 || this.timer.day === '00'));
	    }
	  }, {
	    key: 'defineTimer',
	    value: function defineTimer() {
	      this.timer = {};
	      var diffTime = this.targetTime - this.now;

	      diffTime = Math.floor(diffTime / 1000);
	      this.setTimerToSec(diffTime);

	      diffTime = Math.floor((diffTime - this.timer.sec) / 60);
	      this.setTimerToMin(diffTime);

	      diffTime = Math.floor((diffTime - this.timer.min) / 60);
	      this.setTimeToHours(diffTime);

	      if (this.noDay) return;
	      var remainingDay = Math.floor((diffTime - this.timer.hour) / 24);
	      this.timer.day = remainingDay;
	      this.addPadStartZero(remainingDay, "day");
	    }
	  }, {
	    key: 'addPadStartZero',
	    value: function addPadStartZero(time, timer) {
	      if (time < 10) {
	        this.timer[timer] = time.toString().padStart(2, '0');
	      }
	    }
	  }, {
	    key: 'setTimeToHours',
	    value: function setTimeToHours(tmp) {
	      var remainingHours = this.noDay ? tmp : tmp % 24;
	      this.timer.hour = remainingHours;
	      this.addPadStartZero(remainingHours, "hour");
	    }
	  }, {
	    key: 'setTimerToMin',
	    value: function setTimerToMin(tmp) {
	      var remainingMin = tmp % 60;
	      this.timer.min = remainingMin;
	      this.addPadStartZero(remainingMin, "min");
	    }
	  }, {
	    key: 'setTimerToSec',
	    value: function setTimerToSec(tmp) {
	      var remainingSec = tmp % 60;
	      this.timer.sec = remainingSec;
	      this.addPadStartZero(remainingSec, "sec");
	    }
	  }, {
	    key: 'render',
	    value: function render() {
	      var _createTemplate = this.createTemplate(),
	          tplDay = _createTemplate.tplDay,
	          tpl = _createTemplate.tpl;

	      this.el = document.getElementById(this.options.id);
	      this.el.innerHTML = this.hideDay() || this.noDay ? tpl : tplDay + tpl;
	    }
	  }, {
	    key: 'createItem',
	    value: function createItem(timer, modifier) {
	      return '' + timer + '';
	    }
	  }, {
	    key: 'createTemplate',
	    value: function createTemplate() {
	      var tplDay = this.createItem(this.timer.day, 'day') + this.separator;
	      var tpl = this.createItem(this.timer.hour, 'hour') + this.separator + this.createItem(this.timer.min, 'min') + this.separator + this.createItem(this.timer.sec, 'sec');
	      return { tplDay: tplDay, tpl: tpl };
	    }
	  }]);

	  return Countdown;
	}();

	module.exports = Countdown;

/***/ })
/******/ ]);<|endoftext|>


<commit_before>( function( root, factory ) {
    // Set up appropriately for the environment.
    // Start with AMD.
    if ( typeof define === 'function' && define.amd ) {
        define(
            [
                'underscore',
                'exports'
            ],
            function( _, exports ) {
                root.ExoSuit = root.ExoSuit || {};
                root.ExoSuit.Mixins = root.ExoSuit.Mixins || {};
                root.ExoSuit.Mixins.ExcludeFromJSONMixin = factory( root, exports, _ );
            }
        );
    // Next for Node.js or CommonJS.
    } else if ( typeof exports !== 'undefined' ) {
        var _ = require( 'underscore' );

        module.exports = factory( root, exports, _ );
    // Finally, as a browser global.
    } else {
        root.ExoSuit = root.ExoSuit || {};
        root.ExoSuit.Mixins = root.ExoSuit.Mixins || {};
        root.ExoSuit.Mixins.ExcludeFromJSONMixin = factory( root, {}, root._ );
    }
}( this, function( root, ExcludeFromJSONMixin, _ ) {
    // Flatten a nested object to flat single depth object
    //
    // {
    //   "main" : {
    //      "childKey": "value",
    //      "myArray": [ "good", "bye" ],
    //      "arrayObjects": [ { "key": "value" } ]
    //   }
    // }
    //
    // to
    //
    // {
    //   "main.childKey" : "value",
    //   "main.myArray.0" : "good",
    //   "main.myArray.1" : "bye",
    //   "main.arrayObjects.0.key" : "value"
    // }
    function flatten( object, scope, prefix ) {
        prefix = prefix || '';
        scope = scope || {};

        // Reduce object into new object
        return _( object ).reduce( function( result, value, key ) {
            if ( _.isObject( value ) ) {
                // If value is an object/array, run it through flatten again with a set prefix
                flatten( value, result, prefix + key + '.' );
            } else {
                // If just a primitive value then set on result object
                result[ prefix + key ] = value;
            }

            return result;
        }, scope );
    }

    // Unflatten a single depth object with dot notation keys to a multi level object
    // Opposite of above flatten method
    function unflatten( object ) {
        return _.chain( object ).reduce( function( result, value, key ) {
            // Get parts information of flattened key
            var parts = key.split( "." ),
                partsLength = parts.length;

            // Reduce parts into unflattened object
            result = _.reduce( parts, function( partResult, part, index ) {
                var current = partResult,
                    idx = 0;

                // Get currently constructed unflattened object
                while ( index !== idx ) {
                    current = current[ parts[ idx ] ];
                    idx++;
                }

                // If the current part in loop is not created
                if ( !current[ part ] ) {
                    // If current index is last part
                    if ( index === partsLength - 1 ) {
                        // Set value on unflattened object
                        current[ part ] = value;
                    } else {
                        // If next part in flattened key is a number
                        if ( !isNaN( parseInt( parts[ index + 1 ] ) ) ) {
                            // Must be array so create empty array
                            current[ part ] = [];
                        } else {
                            // Otherwise its an object so create empty array
                            current[ part ] = {};
                        }
                    }
                }

                // Return current unflattened object
                return partResult;
            }, result );

            return result;
        }, {} ).each( function( value, key ) {
            // Clear up any array values that have been deleted but not changed array length
            if ( value instanceof Array ) {
                _.each( value, function( arrayValue, index ) {
                    if ( typeof arrayValue === "undefined" ) {
                        value = value.splice( index, 1 );
                    }
                } );
            }
        } ).value();
    }

    ExcludeFromJSONMixin = function() {
        // Cache current mixin methods to use later
        var oldToJSON = this.toJSON;

        // Wrap existing toJSON method
        this.toJSON = function() {
            // Run current toJSON function and cache response
            var json = oldToJSON.apply( this, arguments );

            // If excludeFromJSON exists on model
            if ( this.excludeFromJSON ) {
                // Flatten json object into single depth
                json = flatten( json );
                // Loop over excludeFromJSON array
                for ( var i = 0, len = this.excludeFromJSON.length; i < len; i++ ) {
                    // Delete property in excludeFromJSON from json response
                    delete json[ this.excludeFromJSON[ i ] ];
                    // Loop over json keys
                    for ( var key in json ) {
                        // Check if key includes part of exclude key i.e. parent object/array to be removed
                        if ( key.indexOf( this.excludeFromJSON[ i ] ) !== -1 ) {
                            // Delete key
                            delete json[ key ];
                        }
                    }
                }
                // Return flattened json into original structure minus deleted properties
                json = unflatten( json );
            }

            // Return json
            return json;
        };
    };

    return ExcludeFromJSONMixin;
} ));
<commit_msg>Fix AMD definition<commit_after>( function( root, factory ) {
    // Set up appropriately for the environment.
    // Start with AMD.
    if ( typeof define === 'function' && define.amd ) {
        define(
            [
                'underscore'
            ],
            function( _ ) {
                root.ExoSuit = root.ExoSuit || {};
                root.ExoSuit.Mixins = root.ExoSuit.Mixins || {};
                return ( root.ExoSuit.Mixins.ExcludeFromJSONMixin = factory( root, {}, _ ) );
            }
        );
    // Next for Node.js or CommonJS.
    } else if ( typeof exports !== 'undefined' ) {
        var _ = require( 'underscore' );

        module.exports = factory( root, exports, _ );
    // Finally, as a browser global.
    } else {
        root.ExoSuit = root.ExoSuit || {};
        root.ExoSuit.Mixins = root.ExoSuit.Mixins || {};
        root.ExoSuit.Mixins.ExcludeFromJSONMixin = factory( root, {}, root._ );
    }
}( this, function( root, ExcludeFromJSONMixin, _ ) {
    // Flatten a nested object to flat single depth object
    //
    // {
    //   "main" : {
    //      "childKey": "value",
    //      "myArray": [ "good", "bye" ],
    //      "arrayObjects": [ { "key": "value" } ]
    //   }
    // }
    //
    // to
    //
    // {
    //   "main.childKey" : "value",
    //   "main.myArray.0" : "good",
    //   "main.myArray.1" : "bye",
    //   "main.arrayObjects.0.key" : "value"
    // }
    function flatten( object, scope, prefix ) {
        prefix = prefix || '';
        scope = scope || {};

        // Reduce object into new object
        return _( object ).reduce( function( result, value, key ) {
            if ( _.isObject( value ) ) {
                // If value is an object/array, run it through flatten again with a set prefix
                flatten( value, result, prefix + key + '.' );
            } else {
                // If just a primitive value then set on result object
                result[ prefix + key ] = value;
            }

            return result;
        }, scope );
    }

    // Unflatten a single depth object with dot notation keys to a multi level object
    // Opposite of above flatten method
    function unflatten( object ) {
        return _.chain( object ).reduce( function( result, value, key ) {
            // Get parts information of flattened key
            var parts = key.split( "." ),
                partsLength = parts.length;

            // Reduce parts into unflattened object
            result = _.reduce( parts, function( partResult, part, index ) {
                var current = partResult,
                    idx = 0;

                // Get currently constructed unflattened object
                while ( index !== idx ) {
                    current = current[ parts[ idx ] ];
                    idx++;
                }

                // If the current part in loop is not created
                if ( !current[ part ] ) {
                    // If current index is last part
                    if ( index === partsLength - 1 ) {
                        // Set value on unflattened object
                        current[ part ] = value;
                    } else {
                        // If next part in flattened key is a number
                        if ( !isNaN( parseInt( parts[ index + 1 ] ) ) ) {
                            // Must be array so create empty array
                            current[ part ] = [];
                        } else {
                            // Otherwise its an object so create empty array
                            current[ part ] = {};
                        }
                    }
                }

                // Return current unflattened object
                return partResult;
            }, result );

            return result;
        }, {} ).each( function( value, key ) {
            // Clear up any array values that have been deleted but not changed array length
            if ( value instanceof Array ) {
                _.each( value, function( arrayValue, index ) {
                    if ( typeof arrayValue === "undefined" ) {
                        value = value.splice( index, 1 );
                    }
                } );
            }
        } ).value();
    }

    ExcludeFromJSONMixin = function() {
        // Cache current mixin methods to use later
        var oldToJSON = this.toJSON;

        // Wrap existing toJSON method
        this.toJSON = function() {
            // Run current toJSON function and cache response
            var json = oldToJSON.apply( this, arguments );

            // If excludeFromJSON exists on model
            if ( this.excludeFromJSON ) {
                // Flatten json object into single depth
                json = flatten( json );
                // Loop over excludeFromJSON array
                for ( var i = 0, len = this.excludeFromJSON.length; i < len; i++ ) {
                    // Delete property in excludeFromJSON from json response
                    delete json[ this.excludeFromJSON[ i ] ];
                    // Loop over json keys
                    for ( var key in json ) {
                        // Check if key includes part of exclude key i.e. parent object/array to be removed
                        if ( key.indexOf( this.excludeFromJSON[ i ] ) !== -1 ) {
                            // Delete key
                            delete json[ key ];
                        }
                    }
                }
                // Return flattened json into original structure minus deleted properties
                json = unflatten( json );
            }

            // Return json
            return json;
        };
    };

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


<commit_before>const path = require('path')
const fs = require('fs-extra')
const glob = require('../util/glob')
const exec = require('../util/exec')
const logger = require('../util/logger')
const getDirSize = require('./get-dir-size')
const collectStats = require('./collect-stats')
const collectDiffs = require('./collect-diffs')
const { statsAppDir, diffRepoDir, yarnEnvValues } = require('../constants')

async function runConfigs(
  configs = [],
  { statsConfig, relativeStatsAppDir, mainRepoPkgPaths, diffRepoPkgPaths },
  diffing = false
) {
  const results = []

  for (const config of configs) {
    logger(`Running config: ${config.title}${diffing ? ' (diff)' : ''}`)

    let mainRepoStats
    let diffRepoStats
    let diffs

    for (const pkgPaths of [mainRepoPkgPaths, diffRepoPkgPaths]) {
      let curStats = {
        General: {
          buildDuration: null,
          buildDurationCached: null,
          nodeModulesSize: null,
        },
      }

      // if stats-config is in root of project we're analyzing
      // the whole project so copy from each repo
      const curStatsAppPath = path.join(diffRepoDir, relativeStatsAppDir)

      // clean statsAppDir
      await fs.remove(statsAppDir)
      await fs.copy(curStatsAppPath, statsAppDir)

      logger(`Copying ${curStatsAppPath} ${statsAppDir}`)

      // apply config files
      for (const configFile of config.configFiles || []) {
        const filePath = path.join(statsAppDir, configFile.path)
        await fs.writeFile(filePath, configFile.content, 'utf8')
      }

      // links local builds of the packages and installs dependencies
      await linkPkgs(statsAppDir, pkgPaths)

      if (!diffing) {
        curStats.General.nodeModulesSize = await getDirSize(
          path.join(statsAppDir, 'node_modules')
        )
      }

      const buildStart = Date.now()
      await exec(`cd ${statsAppDir} && ${statsConfig.appBuildCommand}`, false, {
        env: yarnEnvValues,
      })
      curStats.General.buildDuration = Date.now() - buildStart

      // apply renames to get deterministic output names
      for (const rename of config.renames) {
        const results = await glob(rename.srcGlob, { cwd: statsAppDir })
        for (const result of results) {
          let dest = rename.removeHash
            ? result.replace(/(\.|-)[0-9a-f]{20}(\.|-)/g, '$1HASH$2')
            : rename.dest
          if (result === dest) continue
          await fs.move(
            path.join(statsAppDir, result),
            path.join(statsAppDir, dest)
          )
        }
      }

      const collectedStats = await collectStats(config, statsConfig)
      curStats = {
        ...curStats,
        ...collectedStats,
      }

      const applyRenames = (renames, stats) => {
        if (renames) {
          for (const rename of renames) {
            let { cur, prev } = rename
            cur = path.basename(cur)
            prev = path.basename(prev)

            Object.keys(stats).forEach((group) => {
              if (stats[group][cur]) {
                stats[group][prev] = stats[group][cur]
                stats[group][prev + ' gzip'] = stats[group][cur + ' gzip']
                delete stats[group][cur]
                delete stats[group][cur + ' gzip']
              }
            })
          }
        }
      }

      if (mainRepoStats) {
        diffRepoStats = curStats

        if (!diffing && config.diff !== false) {
          for (const groupKey of Object.keys(curStats)) {
            if (groupKey === 'General') continue
            let changeDetected = config.diff === 'always'

            const curDiffs = await collectDiffs(config.filesToTrack)
            changeDetected = changeDetected || Object.keys(curDiffs).length > 0

            applyRenames(curDiffs._renames, diffRepoStats)
            delete curDiffs._renames

            if (changeDetected) {
              logger('Detected change, running diff')
              diffs = await runConfigs(
                [
                  {
                    ...config,
                    configFiles: config.diffConfigFiles,
                  },
                ],
                {
                  statsConfig,
                  mainRepoPkgPaths,
                  diffRepoPkgPaths,
                  relativeStatsAppDir,
                },
                true
              )
              delete diffs._renames
              break
            }
          }
        }

        if (diffing) {
          // copy new files and get diff results
          return collectDiffs(config.filesToTrack)
        }
      } else {
        // set up diffing folder and copy initial files
        await collectDiffs(config.filesToTrack, true)

        /* eslint-disable-next-line */
        mainRepoStats = curStats
      }

      const secondBuildStart = Date.now()
      await exec(`cd ${statsAppDir} && ${statsConfig.appBuildCommand}`, false, {
        env: yarnEnvValues,
      })
      curStats.General.buildDurationCached = Date.now() - secondBuildStart
    }

    logger(`Finished running: ${config.title}`)

    results.push({
      title: config.title,
      mainRepoStats,
      diffRepoStats,
      diffs,
    })
  }

  return results
}

async function linkPkgs(pkgDir = '', pkgPaths) {
  await fs.remove(path.join(pkgDir, 'node_modules'))

  const pkgJsonPath = path.join(pkgDir, 'package.json')
  const pkgData = require(pkgJsonPath)

  if (!pkgData.dependencies && !pkgData.devDependencies) return

  for (const pkg of pkgPaths.keys()) {
    const pkgPath = pkgPaths.get(pkg)

    if (pkgData.dependencies && pkgData.dependencies[pkg]) {
      pkgData.dependencies[pkg] = pkgPath
    } else if (pkgData.devDependencies && pkgData.devDependencies[pkg]) {
      pkgData.devDependencies[pkg] = pkgPath
    }
  }
  await fs.writeFile(pkgJsonPath, JSON.stringify(pkgData, null, 2), 'utf8')

  await fs.remove(yarnEnvValues.YARN_CACHE_FOLDER)
  await exec(`cd ${pkgDir} && yarn install`, false, {
    env: yarnEnvValues,
  })
}

module.exports = runConfigs
<commit_msg>Update removeHash handling for stats-app (#30235)<commit_after>const path = require('path')
const fs = require('fs-extra')
const glob = require('../util/glob')
const exec = require('../util/exec')
const logger = require('../util/logger')
const getDirSize = require('./get-dir-size')
const collectStats = require('./collect-stats')
const collectDiffs = require('./collect-diffs')
const { statsAppDir, diffRepoDir, yarnEnvValues } = require('../constants')

async function runConfigs(
  configs = [],
  { statsConfig, relativeStatsAppDir, mainRepoPkgPaths, diffRepoPkgPaths },
  diffing = false
) {
  const results = []

  for (const config of configs) {
    logger(`Running config: ${config.title}${diffing ? ' (diff)' : ''}`)

    let mainRepoStats
    let diffRepoStats
    let diffs

    for (const pkgPaths of [mainRepoPkgPaths, diffRepoPkgPaths]) {
      let curStats = {
        General: {
          buildDuration: null,
          buildDurationCached: null,
          nodeModulesSize: null,
        },
      }

      // if stats-config is in root of project we're analyzing
      // the whole project so copy from each repo
      const curStatsAppPath = path.join(diffRepoDir, relativeStatsAppDir)

      // clean statsAppDir
      await fs.remove(statsAppDir)
      await fs.copy(curStatsAppPath, statsAppDir)

      logger(`Copying ${curStatsAppPath} ${statsAppDir}`)

      // apply config files
      for (const configFile of config.configFiles || []) {
        const filePath = path.join(statsAppDir, configFile.path)
        await fs.writeFile(filePath, configFile.content, 'utf8')
      }

      // links local builds of the packages and installs dependencies
      await linkPkgs(statsAppDir, pkgPaths)

      if (!diffing) {
        curStats.General.nodeModulesSize = await getDirSize(
          path.join(statsAppDir, 'node_modules')
        )
      }

      const buildStart = Date.now()
      await exec(`cd ${statsAppDir} && ${statsConfig.appBuildCommand}`, false, {
        env: yarnEnvValues,
      })
      curStats.General.buildDuration = Date.now() - buildStart

      // apply renames to get deterministic output names
      for (const rename of config.renames) {
        const results = await glob(rename.srcGlob, { cwd: statsAppDir })
        for (const result of results) {
          let dest = rename.removeHash
            ? result.replace(/(\.|-)[0-9a-f]{16}(\.|-)/g, '$1HASH$2')
            : rename.dest
          if (result === dest) continue
          await fs.move(
            path.join(statsAppDir, result),
            path.join(statsAppDir, dest)
          )
        }
      }

      const collectedStats = await collectStats(config, statsConfig)
      curStats = {
        ...curStats,
        ...collectedStats,
      }

      const applyRenames = (renames, stats) => {
        if (renames) {
          for (const rename of renames) {
            let { cur, prev } = rename
            cur = path.basename(cur)
            prev = path.basename(prev)

            Object.keys(stats).forEach((group) => {
              if (stats[group][cur]) {
                stats[group][prev] = stats[group][cur]
                stats[group][prev + ' gzip'] = stats[group][cur + ' gzip']
                delete stats[group][cur]
                delete stats[group][cur + ' gzip']
              }
            })
          }
        }
      }

      if (mainRepoStats) {
        diffRepoStats = curStats

        if (!diffing && config.diff !== false) {
          for (const groupKey of Object.keys(curStats)) {
            if (groupKey === 'General') continue
            let changeDetected = config.diff === 'always'

            const curDiffs = await collectDiffs(config.filesToTrack)
            changeDetected = changeDetected || Object.keys(curDiffs).length > 0

            applyRenames(curDiffs._renames, diffRepoStats)
            delete curDiffs._renames

            if (changeDetected) {
              logger('Detected change, running diff')
              diffs = await runConfigs(
                [
                  {
                    ...config,
                    configFiles: config.diffConfigFiles,
                  },
                ],
                {
                  statsConfig,
                  mainRepoPkgPaths,
                  diffRepoPkgPaths,
                  relativeStatsAppDir,
                },
                true
              )
              delete diffs._renames
              break
            }
          }
        }

        if (diffing) {
          // copy new files and get diff results
          return collectDiffs(config.filesToTrack)
        }
      } else {
        // set up diffing folder and copy initial files
        await collectDiffs(config.filesToTrack, true)

        /* eslint-disable-next-line */
        mainRepoStats = curStats
      }

      const secondBuildStart = Date.now()
      await exec(`cd ${statsAppDir} && ${statsConfig.appBuildCommand}`, false, {
        env: yarnEnvValues,
      })
      curStats.General.buildDurationCached = Date.now() - secondBuildStart
    }

    logger(`Finished running: ${config.title}`)

    results.push({
      title: config.title,
      mainRepoStats,
      diffRepoStats,
      diffs,
    })
  }

  return results
}

async function linkPkgs(pkgDir = '', pkgPaths) {
  await fs.remove(path.join(pkgDir, 'node_modules'))

  const pkgJsonPath = path.join(pkgDir, 'package.json')
  const pkgData = require(pkgJsonPath)

  if (!pkgData.dependencies && !pkgData.devDependencies) return

  for (const pkg of pkgPaths.keys()) {
    const pkgPath = pkgPaths.get(pkg)

    if (pkgData.dependencies && pkgData.dependencies[pkg]) {
      pkgData.dependencies[pkg] = pkgPath
    } else if (pkgData.devDependencies && pkgData.devDependencies[pkg]) {
      pkgData.devDependencies[pkg] = pkgPath
    }
  }
  await fs.writeFile(pkgJsonPath, JSON.stringify(pkgData, null, 2), 'utf8')

  await fs.remove(yarnEnvValues.YARN_CACHE_FOLDER)
  await exec(`cd ${pkgDir} && yarn install`, false, {
    env: yarnEnvValues,
  })
}

module.exports = runConfigs
<|endoftext|>


<commit_before>/*!
---
name: XmlToJsObject
description: Smart XML-Document to Javascript-Object converter

license: MIT-style X11 License
version: 1.0

authors:
  - Andi Dittrich

download: https://github.com/AndiDittrich/Javascript.XmlToJsObject
website: http://www.a3non.org/go/XmlToJsObject
demo: http://static.andidittrich.de/XmlToJsObject/Example.MooTools.html
demo2: http://static.andidittrich.de/XmlToJsObject/Example.html
demo3: http://static.andidittrich.de/XmlToJsObject/Example.Minimal.html

provides:
  - XmlToJsObject
  - Object.fromXML (MooTools)

...
 */
/**
 * Converts a XML-String/XMLDocument/XMLNode into a Javascript-Object
 */
var XmlToJsObject = (function(inputData, smartMode){
	// Smart-ModeFLag set ? set default value
	if (typeof(smartMode) == "undefined"){
		smartMode = true;
	}

	// private parser function
	var _convertNode = (function(xmlNode){

		// return object buffer
		var objData = {};

		// no element node ?
		if (xmlNode.nodeType != 1){
			return null;
		}

		// process attributes
		if (xmlNode.attributes.length > 0){
			// create attribute storage object
			if (!smartMode){
				objData['_attributes'] = {};
			}
			for (var i=0; i<xmlNode.attributes.length; i++){
				// get attribute
				var attribute = xmlNode.attributes.item(i);

				// assign attribute
				if (!smartMode){
					// store key => value pair into seperate @attribute storage
					objData['_attributes'][attribute.nodeName] = attribute.nodeValue;
				}else{
					// direct key => value assignment within same object
					objData[attribute.nodeName] = attribute.nodeValue;
				}
			}
		}

		// process child nodes
		if (xmlNode.hasChildNodes()){

			// get first child node
			var childNode = xmlNode.firstChild;

			// iterate over all direct child nodes; call XmlToJsObject recursively on Element-Nodes
			do{
				// text node ?
				if (childNode.nodeType == 3){
					// just whitespace ? skip processing!
					if (childNode.nodeValue.replace(/\s*/, '').length == 0){
						continue;
					}

					// key already assigned ?
					if (typeof(objData['_value']) == "undefined"){
						// directly assign child node
						objData['_value'] = childNode.nodeValue;
					}else{
						// array storage available ?
						if (typeof(objData['_value'].push) == "undefined") {
							objData['_value'] = [objData['_value']];
						}

						// push new node to array
						objData['_value'].push(childNode.nodeValue);
					}
				}

				// process element nodes
				if (childNode.nodeType == 1){
					// key already assigned ?
					if (typeof(objData[childNode.nodeName]) == "undefined" || objData[childNode.nodeName] == null){
						// directly assign child node
						objData[childNode.nodeName] = _convertNode(childNode);
					}else{
						// array storage available ?
						if (typeof(objData[childNode.nodeName].push) == "undefined") {
							objData[childNode.nodeName] = [objData[childNode.nodeName]];
						}

						// push new node to array
						objData[childNode.nodeName].push(_convertNode(childNode));
					}
				}

			// next child node
			}while ((childNode=childNode.nextSibling) != null)
		}
		return objData;
	});

	// xml string input ? parse xml => DocumentNode
	if (typeof(inputData)=='string'){
		// create new parser and extract first child
		var parser = new DOMParser();
		inputData = parser.parseFromString(inputData, 'text/xml');
	}

	// xml node input ?
	if (inputData instanceof Node){
		// store root node
		var rootNode = inputData;

		// document node ?
		if (rootNode.nodeType == 9){
			// get root node (first element node)
			rootNode = rootNode.firstChild;
			while (rootNode.nodeType != 1 && rootNode.nodeType != null){
				rootNode = rootNode.nextSibling;
			}
		}

		// convert xml node tree
		return _convertNode(rootNode);

	// unsupported input-type!
	}else{
		return null;
	}
});
/**
 * MooTools native Object.fromXML extension/wrapper
 */
if (typeof(MooTools) == 'object'){
	Object.extend('fromXML', XmlToJsObject);
}<commit_msg>mootools forge fix<commit_after>/*!
---
name: XmlToJsObject
description: Smart XML-Document to Javascript-Object converter

license: MIT-style X11 License
version: 1.2

authors:
  - Andi Dittrich

download: https://github.com/AndiDittrich/Javascript.XmlToJsObject
website: http://www.a3non.org/go/XmlToJsObject
demo: http://static.andidittrich.de/XmlToJsObject/Example.MooTools.html
demo2: http://static.andidittrich.de/XmlToJsObject/Example.html
demo3: http://static.andidittrich.de/XmlToJsObject/Example.Minimal.html

provides:
  - XmlToJsObject
  - Object.fromXML (MooTools)
...
*/
/**
 * Converts a XML-String/XMLDocument/XMLNode into a Javascript-Object
 */
var XmlToJsObject = (function(inputData, smartMode){
	// Smart-ModeFLag set ? set default value
	if (typeof(smartMode) == "undefined"){
		smartMode = true;
	}

	// private parser function
	var _convertNode = (function(xmlNode){

		// return object buffer
		var objData = {};

		// no element node ?
		if (xmlNode.nodeType != 1){
			return null;
		}

		// process attributes
		if (xmlNode.attributes.length > 0){
			// create attribute storage object
			if (!smartMode){
				objData['_attributes'] = {};
			}
			for (var i=0; i<xmlNode.attributes.length; i++){
				// get attribute
				var attribute = xmlNode.attributes.item(i);

				// assign attribute
				if (!smartMode){
					// store key => value pair into seperate @attribute storage
					objData['_attributes'][attribute.nodeName] = attribute.nodeValue;
				}else{
					// direct key => value assignment within same object
					objData[attribute.nodeName] = attribute.nodeValue;
				}
			}
		}

		// process child nodes
		if (xmlNode.hasChildNodes()){

			// get first child node
			var childNode = xmlNode.firstChild;

			// iterate over all direct child nodes; call XmlToJsObject recursively on Element-Nodes
			do{
				// text node ?
				if (childNode.nodeType == 3){
					// just whitespace ? skip processing!
					if (childNode.nodeValue.replace(/\s*/, '').length == 0){
						continue;
					}

					// key already assigned ?
					if (typeof(objData['_value']) == "undefined"){
						// directly assign child node
						objData['_value'] = childNode.nodeValue;
					}else{
						// array storage available ?
						if (typeof(objData['_value'].push) == "undefined") {
							objData['_value'] = [objData['_value']];
						}

						// push new node to array
						objData['_value'].push(childNode.nodeValue);
					}
				}

				// process element nodes
				if (childNode.nodeType == 1){
					// key already assigned ?
					if (typeof(objData[childNode.nodeName]) == "undefined" || objData[childNode.nodeName] == null){
						// directly assign child node
						objData[childNode.nodeName] = _convertNode(childNode);
					}else{
						// array storage available ?
						if (typeof(objData[childNode.nodeName].push) == "undefined") {
							objData[childNode.nodeName] = [objData[childNode.nodeName]];
						}

						// push new node to array
						objData[childNode.nodeName].push(_convertNode(childNode));
					}
				}

			// next child node
			}while ((childNode=childNode.nextSibling) != null)
		}
		return objData;
	});

	// xml string input ? parse xml => DocumentNode
	if (typeof(inputData)=='string'){
		// create new parser and extract first child
		var parser = new DOMParser();
		inputData = parser.parseFromString(inputData, 'text/xml');
	}

	// xml node input ?
	if (inputData instanceof Node){
		// store root node
		var rootNode = inputData;

		// document node ?
		if (rootNode.nodeType == 9){
			// get root node (first element node)
			rootNode = rootNode.firstChild;
			while (rootNode.nodeType != 1 && rootNode.nodeType != null){
				rootNode = rootNode.nextSibling;
			}
		}

		// convert xml node tree
		return _convertNode(rootNode);

	// unsupported input-type!
	}else{
		return null;
	}
});
/**
 * MooTools native Object.fromXML extension/wrapper
 */
if (typeof(MooTools) == 'object'){
	Object.extend('fromXML', XmlToJsObject);
}<|endoftext|>


<commit_before>import { assert } from '@ember/debug';
import { copy } from '@ember/object/internals';
import { typeOf } from '@ember/utils';
import { isArray } from '@ember/array';
import { get, setProperties, computed } from '@ember/object';
import StatefulArray from './array/stateful';
import FragmentArray from './array/fragment';
import {
  fragmentDidDirty,
  fragmentDidReset
} from './states';
import {
  internalModelFor,
  setFragmentOwner,
  setFragmentData,
  createFragment,
  isFragment
} from './fragment';
import isInstanceOfType from './util/instance-of-type';

/**
  @module ember-data-model-fragments
*/

// Create a unique type string for the combination of fragment property type,
// transform type (or fragment model), and polymorphic type key
function metaTypeFor(name, type, options) {
  let metaType = `-mf-${name}`;

  if (type) {
    metaType += `$${type}`;
  }

  if (options && options.polymorphic) {
    let typeKey = options.typeKey || 'type';
    metaType += `$${typeKey}`;
  }

  return metaType;
}

/**
  `MF.fragment` defines an attribute on a `DS.Model` or `MF.Fragment`. Much
  like `DS.belongsTo`, it creates a property that returns a single fragment of
  the given type.

  It takes an optional hash as a second parameter, currently supported options
  are:

  - `defaultValue`: An object literal or a function to be called to set the
    attribute to a default value if none is supplied. Values are deep copied
    before being used. Note that default values will be passed through the
    fragment's serializer when creating the fragment. Defaults to `null`.
  - `polymorphic`: Whether or not the fragments in the array can be child
    classes of the given type.
  - `typeKey`: If `polymorphic` is true, the property to use as the fragment
    type in the normalized data. Defaults to `type`.

  Example

  ```javascript
  App.Person = DS.Model.extend({
    name: MF.fragment('name', { defaultValue: {} })
  });

  App.Name = MF.Fragment.extend({
    first: DS.attr('string'),
    last: DS.attr('string')
  });
  ```

  @namespace MF
  @method fragment
  @param {String} type the fragment type
  @param {Object} options a hash of options
  @return {Attribute}
*/
function fragment(declaredModelName, options) {
  options = options || {};

  let metaType = metaTypeFor('fragment', declaredModelName, options);

  function setupFragment(store, record, key) {
    let internalModel = internalModelFor(record);
    let data = getWithDefault(internalModel, key, options, 'object');
    let fragment = internalModel._fragments[key];

    // Regardless of whether being called as a setter or getter, the fragment
    // may not be initialized yet, in which case the data will contain a
    // raw response or a stashed away fragment

    // If we already have a processed fragment in _data and our current fragment is
    // null simply reuse the one from data. We can be in this state after a rollback
    // for example
    if (!fragment && isFragment(data)) {
      fragment = data;
    // Else initialize the fragment
    } else if (data && data !== fragment) {
      if (fragment) {
        setFragmentData(fragment, data);
      } else {
        fragment = createFragment(store, declaredModelName, record, key, options, data);
      }

      internalModel._data[key] = fragment;
    } else {
      // Handle the adapter setting the fragment to null
      fragment = data;
    }

    return fragment;
  }

  function setFragmentValue(record, key, fragment, value) {
    let store = record.store;
    let internalModel = internalModelFor(record);

    assert(`You can only assign \`null\`, an object literal or a '${declaredModelName}' fragment instance to this property`, value === null || typeOf(value) === 'object' || isInstanceOfType(store.modelFor(declaredModelName), value));

    if (!value) {
      fragment = null;
    } else if (isFragment(value)) {
      // A fragment instance was given, so just replace the existing value
      fragment = setFragmentOwner(value, record, key);
    } else if (!fragment) {
      // A property hash was given but the property was null, so create a new
      // fragment with the data
      fragment = createFragment(store, declaredModelName, record, key, options, value);
    } else {
      // The fragment already exists and a property hash is given, so just set
      // its values and let the state machine take care of the dirtiness
      setProperties(fragment, value);

      return fragment;
    }

    if (internalModel._data[key] !== fragment) {
      fragmentDidDirty(record, key, fragment);
    } else {
      fragmentDidReset(record, key);
    }

    return fragment;
  }

  return fragmentProperty(metaType, options, setupFragment, setFragmentValue);
}

/**
  `MF.fragmentArray` defines an attribute on a `DS.Model` or `MF.Fragment`.
  Much like `DS.hasMany`, it creates a property that returns an array of
  fragments of the given type. The array is aware of its original state and so
  has a `hasDirtyAttributes` property and a `rollback` method.

  It takes an optional hash as a second parameter, currently supported options
  are:

  - `defaultValue`: An array literal or a function to be called to set the
    attribute to a default value if none is supplied. Values are deep copied
    before being used. Note that default values will be passed through the
    fragment's serializer when creating the fragment. Defaults to an empty
    array.
  - `polymorphic`: Whether or not the fragments in the array can be child
    classes of the given type.
  - `typeKey`: If `polymorphic` is true, the property to use as the fragment
    type in the normalized data. Defaults to `type`.

  Example

  ```javascript
  App.Person = DS.Model.extend({
    addresses: MF.fragmentArray('address')
  });

  App.Address = MF.Fragment.extend({
    street: DS.attr('string'),
    city: DS.attr('string'),
    region: DS.attr('string'),
    country: DS.attr('string')
  });
  ```

  @namespace MF
  @method fragmentArray
  @param {String} type the fragment type (optional)
  @param {Object} options a hash of options
  @return {Attribute}
*/
function fragmentArray(modelName, options) {
  options || (options = {});

  let metaType = metaTypeFor('fragment-array', modelName, options);

  return fragmentArrayProperty(metaType, options, function createFragmentArray(record, key) {
    return FragmentArray.create({
      type: modelName,
      options: options,
      name: key,
      owner: record
    });
  });
}

/**
  `MF.array` defines an attribute on a `DS.Model` or `MF.Fragment`. It creates a
  property that returns an array of values of the given primitive type. The
  array is aware of its original state and so has a `hasDirtyAttributes`
  property and a `rollback` method.

  It takes an optional hash as a second parameter, currently supported options
  are:

  - `defaultValue`: An array literal or a function to be called to set the
    attribute to a default value if none is supplied. Values are deep copied
    before being used. Note that default values will be passed through the
    fragment's serializer when creating the fragment.

  Example

  ```javascript
  App.Person = DS.Model.extend({
    aliases: MF.array('string')
  });
  ```

  @namespace MF
  @method array
  @param {String} type the type of value contained in the array
  @param {Object} options a hash of options
  @return {Attribute}
*/
function array(type, options) {
  if (typeof type === 'object') {
    options = type;
    type = undefined;
  } else {
    options || (options = {});
  }

  let metaType = metaTypeFor('array', type);

  return fragmentArrayProperty(metaType, options, function createStatefulArray(record, key) {
    return StatefulArray.create({
      options: options,
      name: key,
      owner: record
    });
  });
}

function fragmentProperty(type, options, setupFragment, setFragmentValue) {
  options = options || {};

  let meta = {
    type: type,
    isAttribute: true,
    isFragment: true,
    options: options
  };

  return computed({
    get(key) {
      let internalModel = internalModelFor(this);
      let fragment = setupFragment(this.store, this, key);

      return internalModel._fragments[key] = fragment;
    },
    set(key, value) {
      let internalModel = internalModelFor(this);
      let fragment = setupFragment(this.store, this, key);

      fragment = setFragmentValue(this, key, fragment, value);

      return internalModel._fragments[key] = fragment;
    }
  }).meta(meta);
}

function fragmentArrayProperty(metaType, options, createArray) {
  function setupFragmentArray(store, record, key) {
    let internalModel = internalModelFor(record);
    let data = getWithDefault(internalModel, key, options, 'array');
    let fragments = internalModel._fragments[key] || null;

    // If we already have a processed fragment in _data and our current fragment is
    // null simply reuse the one from data. We can be in this state after a rollback
    // for example
    if (data instanceof StatefulArray && !fragments) {
      fragments = data;
    // Create a fragment array and initialize with data
    } else if (data && data !== fragments) {
      fragments || (fragments = createArray(record, key));
      internalModel._data[key] = fragments;
      fragments.setupData(data);
    } else {
      // Handle the adapter setting the fragment array to null
      fragments = data;
    }

    return fragments;
  }

  function setFragmentValue(record, key, fragments, value) {
    let internalModel = internalModelFor(record);

    if (isArray(value)) {
      fragments || (fragments = createArray(record, key));
      fragments.setObjects(value);
    } else if (value === null) {
      fragments = null;
    } else {
      assert('A fragment array property can only be assigned an array or null');
    }

    if (internalModel._data[key] !== fragments || get(fragments, 'hasDirtyAttributes')) {
      fragmentDidDirty(record, key, fragments);
    } else {
      fragmentDidReset(record, key);
    }

    return fragments;
  }

  return fragmentProperty(metaType, options, setupFragmentArray, setFragmentValue);
}

/**
  `MF.fragmentOwner` defines a read-only attribute on a `MF.Fragment`
  instance. The attribute returns a reference to the fragment's owner
  record.

  Example

  ```javascript
  App.Person = DS.Model.extend({
    name: MF.fragment('name')
  });

  App.Name = MF.Fragment.extend({
    first: DS.attr('string'),
    last: DS.attr('string'),
    person: MF.fragmentOwner()
  });
  ```

  @namespace MF
  @method fragmentOwner
  @return {Attribute}
*/
function fragmentOwner() {
  return computed(function() {
    assert('Fragment owner properties can only be used on fragments.', isFragment(this));

    return internalModelFor(this)._owner;
  }).meta({
    isFragmentOwner: true
  }).readOnly();
}

// The default value of a fragment is either an array or an object,
// which should automatically get deep copied
function getDefaultValue(record, options, type) {
  let value;

  if (typeof options.defaultValue === 'function') {
    value = options.defaultValue();
  } else if ('defaultValue' in options) {
    value = options.defaultValue;
  } else if (type === 'array') {
    value = [];
  } else {
    return null;
  }

  assert(`The fragment's default value must be an ${type}`, (typeOf(value) == type) || (value === null));

  // No need to copy value if it was a function
  if (typeof options.defaultValue === 'function') {
    return value;
  }

  // Create a deep copy of the resulting value to avoid shared reference errors
  return copy(value, true);
}

// Returns the value of the property or the default propery
function getWithDefault(internalModel, key, options, type) {
  if (key in internalModel._data) {
    return internalModel._data[key];
  } else {
    return getDefaultValue(internalModel, options, type);
  }
}

export {
  fragment,
  fragmentArray,
  array,
  fragmentOwner
};
<commit_msg>Fixed trailing spaces<commit_after>import { assert } from '@ember/debug';
import { copy } from '@ember/object/internals';
import { typeOf } from '@ember/utils';
import { isArray } from '@ember/array';
import { get, setProperties, computed } from '@ember/object';
import StatefulArray from './array/stateful';
import FragmentArray from './array/fragment';
import {
  fragmentDidDirty,
  fragmentDidReset
} from './states';
import {
  internalModelFor,
  setFragmentOwner,
  setFragmentData,
  createFragment,
  isFragment
} from './fragment';
import isInstanceOfType from './util/instance-of-type';

/**
  @module ember-data-model-fragments
*/

// Create a unique type string for the combination of fragment property type,
// transform type (or fragment model), and polymorphic type key
function metaTypeFor(name, type, options) {
  let metaType = `-mf-${name}`;

  if (type) {
    metaType += `$${type}`;
  }

  if (options && options.polymorphic) {
    let typeKey = options.typeKey || 'type';
    metaType += `$${typeKey}`;
  }

  return metaType;
}

/**
  `MF.fragment` defines an attribute on a `DS.Model` or `MF.Fragment`. Much
  like `DS.belongsTo`, it creates a property that returns a single fragment of
  the given type.

  It takes an optional hash as a second parameter, currently supported options
  are:

  - `defaultValue`: An object literal or a function to be called to set the
    attribute to a default value if none is supplied. Values are deep copied
    before being used. Note that default values will be passed through the
    fragment's serializer when creating the fragment. Defaults to `null`.
  - `polymorphic`: Whether or not the fragments in the array can be child
    classes of the given type.
  - `typeKey`: If `polymorphic` is true, the property to use as the fragment
    type in the normalized data. Defaults to `type`.

  Example

  ```javascript
  App.Person = DS.Model.extend({
    name: MF.fragment('name', { defaultValue: {} })
  });

  App.Name = MF.Fragment.extend({
    first: DS.attr('string'),
    last: DS.attr('string')
  });
  ```

  @namespace MF
  @method fragment
  @param {String} type the fragment type
  @param {Object} options a hash of options
  @return {Attribute}
*/
function fragment(declaredModelName, options) {
  options = options || {};

  let metaType = metaTypeFor('fragment', declaredModelName, options);

  function setupFragment(store, record, key) {
    let internalModel = internalModelFor(record);
    let data = getWithDefault(internalModel, key, options, 'object');
    let fragment = internalModel._fragments[key];

    // Regardless of whether being called as a setter or getter, the fragment
    // may not be initialized yet, in which case the data will contain a
    // raw response or a stashed away fragment

    // If we already have a processed fragment in _data and our current fragment is
    // null simply reuse the one from data. We can be in this state after a rollback
    // for example
    if (!fragment && isFragment(data)) {
      fragment = data;
    // Else initialize the fragment
    } else if (data && data !== fragment) {
      if (fragment) {
        setFragmentData(fragment, data);
      } else {
        fragment = createFragment(store, declaredModelName, record, key, options, data);
      }

      internalModel._data[key] = fragment;
    } else {
      // Handle the adapter setting the fragment to null
      fragment = data;
    }

    return fragment;
  }

  function setFragmentValue(record, key, fragment, value) {
    let store = record.store;
    let internalModel = internalModelFor(record);

    assert(`You can only assign \`null\`, an object literal or a '${declaredModelName}' fragment instance to this property`, value === null || typeOf(value) === 'object' || isInstanceOfType(store.modelFor(declaredModelName), value));

    if (!value) {
      fragment = null;
    } else if (isFragment(value)) {
      // A fragment instance was given, so just replace the existing value
      fragment = setFragmentOwner(value, record, key);
    } else if (!fragment) {
      // A property hash was given but the property was null, so create a new
      // fragment with the data
      fragment = createFragment(store, declaredModelName, record, key, options, value);
    } else {
      // The fragment already exists and a property hash is given, so just set
      // its values and let the state machine take care of the dirtiness
      setProperties(fragment, value);

      return fragment;
    }

    if (internalModel._data[key] !== fragment) {
      fragmentDidDirty(record, key, fragment);
    } else {
      fragmentDidReset(record, key);
    }

    return fragment;
  }

  return fragmentProperty(metaType, options, setupFragment, setFragmentValue);
}

/**
  `MF.fragmentArray` defines an attribute on a `DS.Model` or `MF.Fragment`.
  Much like `DS.hasMany`, it creates a property that returns an array of
  fragments of the given type. The array is aware of its original state and so
  has a `hasDirtyAttributes` property and a `rollback` method.

  It takes an optional hash as a second parameter, currently supported options
  are:

  - `defaultValue`: An array literal or a function to be called to set the
    attribute to a default value if none is supplied. Values are deep copied
    before being used. Note that default values will be passed through the
    fragment's serializer when creating the fragment. Defaults to an empty
    array.
  - `polymorphic`: Whether or not the fragments in the array can be child
    classes of the given type.
  - `typeKey`: If `polymorphic` is true, the property to use as the fragment
    type in the normalized data. Defaults to `type`.

  Example

  ```javascript
  App.Person = DS.Model.extend({
    addresses: MF.fragmentArray('address')
  });

  App.Address = MF.Fragment.extend({
    street: DS.attr('string'),
    city: DS.attr('string'),
    region: DS.attr('string'),
    country: DS.attr('string')
  });
  ```

  @namespace MF
  @method fragmentArray
  @param {String} type the fragment type (optional)
  @param {Object} options a hash of options
  @return {Attribute}
*/
function fragmentArray(modelName, options) {
  options || (options = {});

  let metaType = metaTypeFor('fragment-array', modelName, options);

  return fragmentArrayProperty(metaType, options, function createFragmentArray(record, key) {
    return FragmentArray.create({
      type: modelName,
      options: options,
      name: key,
      owner: record
    });
  });
}

/**
  `MF.array` defines an attribute on a `DS.Model` or `MF.Fragment`. It creates a
  property that returns an array of values of the given primitive type. The
  array is aware of its original state and so has a `hasDirtyAttributes`
  property and a `rollback` method.

  It takes an optional hash as a second parameter, currently supported options
  are:

  - `defaultValue`: An array literal or a function to be called to set the
    attribute to a default value if none is supplied. Values are deep copied
    before being used. Note that default values will be passed through the
    fragment's serializer when creating the fragment.

  Example

  ```javascript
  App.Person = DS.Model.extend({
    aliases: MF.array('string')
  });
  ```

  @namespace MF
  @method array
  @param {String} type the type of value contained in the array
  @param {Object} options a hash of options
  @return {Attribute}
*/
function array(type, options) {
  if (typeof type === 'object') {
    options = type;
    type = undefined;
  } else {
    options || (options = {});
  }

  let metaType = metaTypeFor('array', type);

  return fragmentArrayProperty(metaType, options, function createStatefulArray(record, key) {
    return StatefulArray.create({
      options: options,
      name: key,
      owner: record
    });
  });
}

function fragmentProperty(type, options, setupFragment, setFragmentValue) {
  options = options || {};

  let meta = {
    type: type,
    isAttribute: true,
    isFragment: true,
    options: options
  };

  return computed({
    get(key) {
      let internalModel = internalModelFor(this);
      let fragment = setupFragment(this.store, this, key);

      return internalModel._fragments[key] = fragment;
    },
    set(key, value) {
      let internalModel = internalModelFor(this);
      let fragment = setupFragment(this.store, this, key);

      fragment = setFragmentValue(this, key, fragment, value);

      return internalModel._fragments[key] = fragment;
    }
  }).meta(meta);
}

function fragmentArrayProperty(metaType, options, createArray) {
  function setupFragmentArray(store, record, key) {
    let internalModel = internalModelFor(record);
    let data = getWithDefault(internalModel, key, options, 'array');
    let fragments = internalModel._fragments[key] || null;

    // If we already have a processed fragment in _data and our current fragment is
    // null simply reuse the one from data. We can be in this state after a rollback
    // for example
    if (data instanceof StatefulArray && !fragments) {
      fragments = data;
    // Create a fragment array and initialize with data
    } else if (data && data !== fragments) {
      fragments || (fragments = createArray(record, key));
      internalModel._data[key] = fragments;
      fragments.setupData(data);
    } else {
      // Handle the adapter setting the fragment array to null
      fragments = data;
    }

    return fragments;
  }

  function setFragmentValue(record, key, fragments, value) {
    let internalModel = internalModelFor(record);

    if (isArray(value)) {
      fragments || (fragments = createArray(record, key));
      fragments.setObjects(value);
    } else if (value === null) {
      fragments = null;
    } else {
      assert('A fragment array property can only be assigned an array or null');
    }

    if (internalModel._data[key] !== fragments || get(fragments, 'hasDirtyAttributes')) {
      fragmentDidDirty(record, key, fragments);
    } else {
      fragmentDidReset(record, key);
    }

    return fragments;
  }

  return fragmentProperty(metaType, options, setupFragmentArray, setFragmentValue);
}

/**
  `MF.fragmentOwner` defines a read-only attribute on a `MF.Fragment`
  instance. The attribute returns a reference to the fragment's owner
  record.

  Example

  ```javascript
  App.Person = DS.Model.extend({
    name: MF.fragment('name')
  });

  App.Name = MF.Fragment.extend({
    first: DS.attr('string'),
    last: DS.attr('string'),
    person: MF.fragmentOwner()
  });
  ```

  @namespace MF
  @method fragmentOwner
  @return {Attribute}
*/
function fragmentOwner() {
  return computed(function() {
    assert('Fragment owner properties can only be used on fragments.', isFragment(this));

    return internalModelFor(this)._owner;
  }).meta({
    isFragmentOwner: true
  }).readOnly();
}

// The default value of a fragment is either an array or an object,
// which should automatically get deep copied
function getDefaultValue(record, options, type) {
  let value;

  if (typeof options.defaultValue === 'function') {
    value = options.defaultValue();
  } else if ('defaultValue' in options) {
    value = options.defaultValue;
  } else if (type === 'array') {
    value = [];
  } else {
    return null;
  }

  assert(`The fragment's default value must be an ${type}`, (typeOf(value) == type) || (value === null));

  // No need to copy value if it was a function
  if (typeof options.defaultValue === 'function') {
    return value;
  }

  // Create a deep copy of the resulting value to avoid shared reference errors
  return copy(value, true);
}

// Returns the value of the property or the default propery
function getWithDefault(internalModel, key, options, type) {
  if (key in internalModel._data) {
    return internalModel._data[key];
  } else {
    return getDefaultValue(internalModel, options, type);
  }
}

export {
  fragment,
  fragmentArray,
  array,
  fragmentOwner
};
<|endoftext|>


<commit_before>import Ember from 'ember';

const {
  computed,
  defineProperty,
  get,
  Mixin,
  set,
} = Ember;

export function elem(blockName, elemName) {
  return `${blockName}__${elemName}`;
}

export default Mixin.create({

  classNameBindings: [
    'blockClassName',
    'modsClassNames',
  ],
  concatenatedProperties: ['mods'],

  blockName: null,
  elemName: null,
  mods: null,

  init() {
    this._super(...arguments);

    if (!get(this, 'mods')) {
      set(this, 'mods', []);
    }

    const mods = get(this, 'mods');
    const modsDependencies = mods.map((mod) => this._getModValueKey(mod));

    defineProperty(
      this,
      'modsClassNames',
      computed('blockClassName', ...modsDependencies, this._getModsClassNames)
    );
  },

  blockClassName: computed('blockName', 'elemName', function() {
    const blockName = get(this, 'blockName');
    const elemName = get(this, 'elemName');

    if (blockName && elemName) {
      return elem(blockName, elemName);
    } else if (blockName) {
      return `${blockName}`;
    }
  }),

  _getModName(modDefinition) {
    const [modName, modValueProperty] = modDefinition.split(':');
    return modValueProperty || modName;
  },

  _getModValueKey(modDefinition) {
    const [modName] = modDefinition.split(':');
    return modName;
  },

  _getNegativeModName(modDefinition) {
    const [,, negativeModValueProperty] = modDefinition.split(':');
    return negativeModValueProperty;
  },

  _getModsClassNames() {
    const blockClassName = get(this, 'blockClassName');
    const mods = get(this, 'mods');

    const modsClassNames = mods.map((mod) => {
      const modName = this._getModName(mod);
      const negativeModName = this._getNegativeModName(mod);
      const modValueProperty = this._getModValueKey(mod);
      const value = get(this, modValueProperty);

      const hasNegativeModName = typeof negativeModName !== 'undefined';

      if (hasNegativeModName || typeof value === 'boolean') {
        if (value) {
          return `${blockClassName}_${modName}`;
        } else if (hasNegativeModName) {
          return `${blockClassName}_${negativeModName}`;
        }
      } else if (value) {
        return `${blockClassName}_${modName}_${value}`;
      }
    });

    return modsClassNames.join(' ');
  },

});
<commit_msg>Added mod utility function.<commit_after>import Ember from 'ember';

const {
  computed,
  defineProperty,
  get,
  Mixin,
  set,
} = Ember;

export function elem(blockName, elemName) {
  return `${blockName}__${elemName}`;
}

export function mod(blockName, modDefinition) {
  const { modName, negativeModName, modValue } = modDefinition;
  const hasNegativeModName = typeof negativeModName !== 'undefined';

  if (typeof modValue === 'boolean') {
    if (hasNegativeModName && !modValue) {
      return `${blockName}_${negativeModName}`;
    } else if (modValue) {
      return `${blockName}_${modName}`;
    }
  } else if (modValue) {
    return `${blockName}_${modName}_${modValue}`;
  }
}

export default Mixin.create({

  classNameBindings: [
    'blockClassName',
    'modsClassNames',
  ],
  concatenatedProperties: ['mods'],

  blockName: null,
  elemName: null,
  mods: null,

  init() {
    this._super(...arguments);

    if (!get(this, 'mods')) {
      set(this, 'mods', []);
    }

    const mods = get(this, 'mods');
    const modsDependencies = mods.map((mod) => this._getModValueKey(mod));

    defineProperty(
      this,
      'modsClassNames',
      computed('blockClassName', ...modsDependencies, this._getModsClassNames)
    );
  },

  blockClassName: computed('blockName', 'elemName', function() {
    const blockName = get(this, 'blockName');
    const elemName = get(this, 'elemName');

    if (blockName && elemName) {
      return elem(blockName, elemName);
    } else if (blockName) {
      return `${blockName}`;
    }
  }),

  _getModName(modDefinition) {
    const [modName, modValueProperty] = modDefinition.split(':');
    return modValueProperty || modName;
  },

  _getModValueKey(modDefinition) {
    const [modName] = modDefinition.split(':');
    return modName;
  },

  _getNegativeModName(modDefinition) {
    const [,, negativeModValueProperty] = modDefinition.split(':');
    return negativeModValueProperty;
  },

  _getModsClassNames() {
    const blockClassName = get(this, 'blockClassName');
    const mods = get(this, 'mods');

    const modsClassNames = mods.map((modDefinition) => {
      const modName = this._getModName(modDefinition);
      const negativeModName = this._getNegativeModName(modDefinition);
      const modValueProperty = this._getModValueKey(modDefinition);
      const modValue = get(this, modValueProperty);

      return mod(blockClassName, {
        modName,
        negativeModName,
        modValue
      });
    });

    return modsClassNames.join(' ');
  },

});
<|endoftext|>


<commit_before>/**
  @module ember-svg-shapes
*/
import Ember from 'ember';

/**
  @class SvgMixin
  @namespace SvgShapes.Mixins
*/
export default Ember.Mixin.create({

    /**
      @property tagName
      @type {String}
      @private
      @default 'svg'
    */
    tagName: 'svg',

    /**
      @property attributeBindings
      @type {Array}
      @default ['style']
      @private
    */
    attributeBindings: ['style'],

    /**
      This is a computed property.  It sets the height and width of the svg element.
      @property style
      @type {String}
      @private
    */
    style: Ember.computed('size', function() {
        var size = this.get('size');
        return Ember.String.htmlSafe('width:' + size + 'px; height:' + size + 'px;');
    }),

    /**
      The stroke color.  Use this with `strokeWidth` to set a border around the shape.

        {{svg-triangle stroke="blue" strokeWidth="2"}}

      @property stroke
      @type {String}
    */
    stroke: '',

    /**
      The stroke width.    Use this with `stroke` to set a border around the shape.

        {{svg-triangle strokeWidth="2" stroke="blue"}}

      @property strokeWidth
      @type {Number}
      @default 0
    */
    strokeWidth: 0,

    /**
      The fill color.

            {{svg-triangle fill="blue"}}

      @property fill
      @type {String}
    */
    fill: ''
});
<commit_msg>update svg mixin<commit_after>/**
  @module ember-svg-shapes
*/
import Ember from 'ember';

/**
  @class SvgMixin
  @namespace SvgShapes.Mixins
*/
export default Ember.Mixin.create({

    /**
      @property tagName
      @type {String}
      @private
      @default 'svg'
    */
    tagName: 'svg',

    /**
      @property attributeBindings
      @type {Array}
      @default ['style']
      @private
    */
    attributeBindings: ['style'],

    /**
      This is a computed property.  It sets the height and width of the svg element.
      @property style
      @type {String}
      @private
    */
    style: Ember.computed('size', function() {
        var size = this.get('size');
        return Ember.String.htmlSafe('width:' + size + 'px; height:' + size + 'px;');
    }),

    /**
      The stroke color.  Use this with `strokeWidth` to set a border around the shape.

        {{svg-triangle stroke="blue" strokeWidth="2"}}

      @property stroke
      @type {String}
      @default 'black'
    */
    stroke: 'black',

    /**
      The stroke width.    Use this with `stroke` to set a border around the shape.

        {{svg-triangle strokeWidth="2" stroke="blue"}}

      @property strokeWidth
      @type {Number}
      @default 0
    */
    strokeWidth: 0,

    /**
      The fill color.

            {{svg-triangle fill="blue"}}

      @property fill
      @type {String}
    */
    fill: ''
});
<|endoftext|>