<commit_before>import React from "react";
import ReactDom from "react-dom";

class Layout extends React.Component {
  render() {
    return (

Hello

    );
  }
}

ReactDom.render(<Layout/>, document.getElementById('app'));
<commit_msg><Timer/> Created<commit_after>import React from "react";
import ReactDom from "react-dom";

// <Timer />
// ----------------------------------
const Timer = React.createClass({

 getInitialState () {
    return {times: 500};
  },

  componentDidMount() {
    setInterval(this.run, 1000);
  },

  run() {
    let oldstate = this.state.times;
    let newstate = oldstate - 1;
    this.setState({times: newstate});
  },

  render() {
    return (

        {this.state.times}

    )
  }

});

ReactDom.render(<Timer/>, document.getElementById('app'));
<|endoftext|>


<commit_before>(function angularFor(window, document, undefined) {
  'use strict';

  angular.module('angularOauth', [])

  .provider('Token', function () {

    /**
		 * Given an flat object, returns a query string for use in URLs.  Note
		 * that for a given object, the return value may be.
		 *
		 * @example
		 *

			 // returns 'color=red&size=large'
			 objectToQueryString({color: 'red', size: 'large'})
		 *

		 *
		 * @param {Object} obj A flat object containing keys for such a string.
		 * @returns {string} A string suitable as a query string.
		 */
    var objectToQueryString = function (obj) {
      var str = [];
      angular.forEach(obj, function (value, key) {
        str.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
      });
      return str.join("&");
    };

    // This response_type MUST be passed to the authorization endpoint using
    // the implicit grant flow (4.2.1 of RFC 6749).
    var RESPONSE_TYPE = 'token';

    // Create a special object for config fields that are required and missing.
    // If any config items still contain it when Token is used, raise an error.
    var REQUIRED_AND_MISSING = {};

    var config = {
      clientId: REQUIRED_AND_MISSING,
      redirectUri: REQUIRED_AND_MISSING,
      authorizationEndpoint: REQUIRED_AND_MISSING,
      localStorageName: 'accessToken',
      verifyFunc: REQUIRED_AND_MISSING,
      scopes: []
    };

    this.extendConfig = function (configExtension) {
      config = angular.extend(config, configExtension);
    };

    this.$get = function ($q, $http, $window, $rootScope) {
      var requiredAndMissing = [];
      angular.forEach(config, function (value, key) {
        if (value === REQUIRED_AND_MISSING) {
          requiredAndMissing.push(key);
        }
      });

      if (requiredAndMissing.length) {
        throw new Error("TokenProvider is insufficiently configured.  Please " +
          "configure the following options using " +
          "TokenProvider.extendConfig: " + requiredAndMissing.join(", "));
      }

      if (!config.clientId) {
        throw new Error("clientId needs to be configured using TokenProvider.");
      }

      var getParams = function () {
        // TODO: Facebook uses comma-delimited scopes. This is not compliant with section 3.3 but perhaps support later.

        return {
          response_type: config.responseType || RESPONSE_TYPE,
          client_id: config.clientId,
          redirect_uri: config.redirectUri,
          scope: config.scopes.join(" ")
        };
      };

      var buildAuthorizationUrl = function (extraParams) {
        var params = angular.extend(getParams(), extraParams);
        return config.authorizationEndpoint + '?' + objectToQueryString(params);
      };

      return {
        // TODO: get/set might want to support expiration to reauthenticate
        // TODO: check for localStorage support and otherwise perhaps use other methods of storing data (e.g. cookie)

        /**
         * Returns the stored access token.
         *
         * @returns {string} The access token.
         */
        get: function () {
          return localStorage[config.localStorageName];
        },

        /**
         * Persist the access token so that it can be retrieved later by.
         *
         * @param accessToken
         */
        set: function (accessToken) {
          localStorage[config.localStorageName] = accessToken;
        },

        /**
         * Forgets the access token.
         */
        clear: function () {
          localStorage.removeItem(config.localStorageName);
        },

        /**
         * Verifies that the access token is was issued for the use of the current client.
         *
         * @param accessToken An access token received from the authorization server.
         * @returns {Promise} Promise that will be resolved when the authorization server has verified that the
         *  token is valid, and we've verified that the token is passed back has audience that matches our client
         *  ID (to prevent the Confused Deputy Problem).
         *
         *  If there's an error verifying the token, the promise is rejected with an object identifying the `name` error
         *  in the name member.  The `name` can be either:
         *
         *    - `invalid_audience`: The audience didn't match our client ID.
         *    - `error_response`: The server responded with an error, typically because the token was invalid.  In this
         *      case, the callback parameters to `error` callback on `$http` are available in the object (`data`,
         *      `status`, `headers`, `config`).
         */
        verifyAsync: function (accessToken) {
          return config.verifyFunc(config, accessToken);
        },

        /**
         * Verifies an access token asynchronously.
         *
         * @param extraParams Additional params to be appended to the query string of the request.
         * @param popupOptions Settings for the display of the popup.
         * @returns {Promise} Promise that will be resolved when the authorization server has verified that the
         *  token is valid, and we've verified that the token is passed back has audience that matches our client
         *  ID (to prevent the Confused Deputy Problem).
         *
         *  If there's an error verifying the token, the promise is rejected with an object identifying the `name` error
         *  in the name member.  The `name` can be either:
         *
         *    - `invalid_audience`: The audience didn't match our client ID.
         *    - `error_response`: The server responded with an error, typically because the token was invalid.  In this
         *      case, the callback parameters to `error` callback on `$http` are available in the object (`data`,
         *      `status`, `headers`, `config`).
         */
        getTokenByPopup: function (extraParams, popupOptions) {
          popupOptions = angular.extend({
            name: 'AuthPopup',
            openParams: {
              width: 650,
              height: 300,
              resizable: true,
              scrollbars: true,
              status: true
            }
          }, popupOptions);

          var deferred = $q.defer();
          var url = buildAuthorizationUrl(extraParams);
          //var resolved = false; // Unused?

          var formatPopupOptions = function (options) {
            var pairs = [];
            angular.forEach(options, function (value, key) {
              if (value || value === 0) {
                value = value === true ? 'yes' : value;
                pairs.push(key + '=' + value);
              }
            });
            return pairs.join(',');
          };

          var popup = window.open(url, popupOptions.name, formatPopupOptions(popupOptions.openParams));

          // TODO: binding occurs for each reauthentication, leading to leaks for long-running apps.

          angular.element($window).bind('message', function (event) {
            // Use JQuery originalEvent if present
            event = event.originalEvent || event;
            if (event.source === popup && event.origin === window.location.origin) {
              $rootScope.$apply(function () {
                if (event.data.access_token) {
                  deferred.resolve(event.data);
                } else {
                  deferred.reject(event.data);
                }
              });
            }
          });

          // TODO: reject deferred if the popup was closed without a message being delivered + maybe offer a timeout

          return deferred.promise;
        },

        getTokenInSameWindow: function (extraParams) {
          var url = buildAuthorizationUrl(extraParams);
          $window.location.href = url;
        }
      };
    };
  })

  /**
   * A controller for the redirect endpoint that inspects the URL redirected to by the authorization server and sends
   * it back to other windows using.
   */
  .controller('CallbackCtrl', function ($scope, $location) {

    /**
     * Parses an escaped url query string into key-value pairs.
     *
     * (Copied from Angular.js in the AngularJS project.)
     *
     * @returns Object.<(string|boolean)>
     */
    function parseKeyValue( /**string*/ keyValue) {
      var obj = {};
      var key_value, key;

      angular.forEach((keyValue || "").split('&'), function (keyValue) {
        if (keyValue) {
          key_value = keyValue.split('=');
          key = decodeURIComponent(key_value[0]);
          obj[key] = angular.isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true;
        }
      });

      return obj;
    }

    var queryString = $location.path().substring(1); // preceding slash omitted

    var params = parseKeyValue(queryString);

    // TODO: The target origin should be set to an explicit origin.  Otherwise, a malicious site that can receive
    //       the token if it manages to change the location of the parent. (See:
    //       https://developer.mozilla.org/en/docs/DOM/window.postMessage#Security_concerns)

    window.opener.postMessage(params, "*");
    window.close();
  });

})(window, document);<commit_msg>added expiration.<commit_after>(function angularFor(window, document, undefined) {
  'use strict';

  angular.module('angularOauth', [])

  .provider('Token', function () {

    /**
		 * Given an flat object, returns a query string for use in URLs.  Note
		 * that for a given object, the return value may be.
		 *
		 * @example
		 *

			 // returns 'color=red&size=large'
			 objectToQueryString({color: 'red', size: 'large'})
		 *

		 *
		 * @param {Object} obj A flat object containing keys for such a string.
		 * @returns {string} A string suitable as a query string.
		 */
    var objectToQueryString = function (obj) {
      var str = [];
      angular.forEach(obj, function (value, key) {
        str.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
      });
      return str.join("&");
    };

    // This response_type MUST be passed to the authorization endpoint using
    // the implicit grant flow (4.2.1 of RFC 6749).
    var RESPONSE_TYPE = 'token';

    // Create a special object for config fields that are required and missing.
    // If any config items still contain it when Token is used, raise an error.
    var REQUIRED_AND_MISSING = {};

    var config = {
      clientId: REQUIRED_AND_MISSING,
      redirectUri: REQUIRED_AND_MISSING,
      authorizationEndpoint: REQUIRED_AND_MISSING,
      localStorageName: 'accessToken',
      verifyFunc: REQUIRED_AND_MISSING,
      scopes: []
    };

    this.extendConfig = function (configExtension) {
      config = angular.extend(config, configExtension);
    };

    this.$get = function ($q, $http, $window, $rootScope) {
      var requiredAndMissing = [];
      angular.forEach(config, function (value, key) {
        if (value === REQUIRED_AND_MISSING) {
          requiredAndMissing.push(key);
        }
      });

      if (requiredAndMissing.length) {
        throw new Error("TokenProvider is insufficiently configured.  Please " +
          "configure the following options using " +
          "TokenProvider.extendConfig: " + requiredAndMissing.join(", "));
      }

      if (!config.clientId) {
        throw new Error("clientId needs to be configured using TokenProvider.");
      }

      var getParams = function () {
        // TODO: Facebook uses comma-delimited scopes. This is not compliant with section 3.3 but perhaps support later.

        return {
          response_type: config.responseType || RESPONSE_TYPE,
          client_id: config.clientId,
          redirect_uri: config.redirectUri,
          scope: config.scopes.join(" ")
        };
      };

      var buildAuthorizationUrl = function (extraParams) {
        var params = angular.extend(getParams(), extraParams);
        return config.authorizationEndpoint + '?' + objectToQueryString(params);
      };

      return {
        // TODO: get/set might want to support expiration to reauthenticate
        // TODO: check for localStorage support and otherwise perhaps use other methods of storing data (e.g. cookie)

        /**
         * Returns the stored access token.
         *
         * @returns {string} The access token.
         */
        get: function() {
          if (localStorage[config.localStorageName + '_expires']) {
            return (new Date(localStorage['token-expires']) > new Date()) && localStorage[config.localStorageName];
          } else {
            return localStorage[config.localStorageName];
          }
        },

        /**
         * Persist the access token so that it can be retrieved later by.
         *
         * @param accessToken
         */
        set: function(params) {
          if (typeof params === 'object') {
            localStorage[config.localStorageName] = params.access_token
            if (params.expires_in) {
              var t = new Date();
              t.setSeconds(t.getSeconds() + parseInt(params.expires_in));
              localStorage.setItem(config.localStorageName + '_expires', t.toISOString());
            }
          } else if (typeof params === 'string') {
            localStorage[config.localStorageName] = params;
          }
        },

        /**
         * Forgets the access token.
         */
        clear: function () {
          localStorage.removeItem(config.localStorageName);
        },

        /**
         * Verifies that the access token is was issued for the use of the current client.
         *
         * @param accessToken An access token received from the authorization server.
         * @returns {Promise} Promise that will be resolved when the authorization server has verified that the
         *  token is valid, and we've verified that the token is passed back has audience that matches our client
         *  ID (to prevent the Confused Deputy Problem).
         *
         *  If there's an error verifying the token, the promise is rejected with an object identifying the `name` error
         *  in the name member.  The `name` can be either:
         *
         *    - `invalid_audience`: The audience didn't match our client ID.
         *    - `error_response`: The server responded with an error, typically because the token was invalid.  In this
         *      case, the callback parameters to `error` callback on `$http` are available in the object (`data`,
         *      `status`, `headers`, `config`).
         */
        verifyAsync: function (accessToken) {
          return config.verifyFunc(config, accessToken);
        },

        /**
         * Verifies an access token asynchronously.
         *
         * @param extraParams Additional params to be appended to the query string of the request.
         * @param popupOptions Settings for the display of the popup.
         * @returns {Promise} Promise that will be resolved when the authorization server has verified that the
         *  token is valid, and we've verified that the token is passed back has audience that matches our client
         *  ID (to prevent the Confused Deputy Problem).
         *
         *  If there's an error verifying the token, the promise is rejected with an object identifying the `name` error
         *  in the name member.  The `name` can be either:
         *
         *    - `invalid_audience`: The audience didn't match our client ID.
         *    - `error_response`: The server responded with an error, typically because the token was invalid.  In this
         *      case, the callback parameters to `error` callback on `$http` are available in the object (`data`,
         *      `status`, `headers`, `config`).
         */
        getTokenByPopup: function (extraParams, popupOptions) {
          popupOptions = angular.extend({
            name: 'AuthPopup',
            openParams: {
              width: 650,
              height: 300,
              resizable: true,
              scrollbars: true,
              status: true
            }
          }, popupOptions);

          var deferred = $q.defer();
          var url = buildAuthorizationUrl(extraParams);
          //var resolved = false; // Unused?

          var formatPopupOptions = function (options) {
            var pairs = [];
            angular.forEach(options, function (value, key) {
              if (value || value === 0) {
                value = value === true ? 'yes' : value;
                pairs.push(key + '=' + value);
              }
            });
            return pairs.join(',');
          };

          var popup = window.open(url, popupOptions.name, formatPopupOptions(popupOptions.openParams));

          // TODO: binding occurs for each reauthentication, leading to leaks for long-running apps.

          angular.element($window).bind('message', function (event) {
            // Use JQuery originalEvent if present
            event = event.originalEvent || event;
            if (event.source === popup && event.origin === window.location.origin) {
              $rootScope.$apply(function () {
                if (event.data.access_token) {
                  deferred.resolve(event.data);
                } else {
                  deferred.reject(event.data);
                }
              });
            }
          });

          // TODO: reject deferred if the popup was closed without a message being delivered + maybe offer a timeout

          return deferred.promise;
        },

        getTokenInSameWindow: function (extraParams) {
          var url = buildAuthorizationUrl(extraParams);
          $window.location.href = url;
        }
      };
    };
  })

  /**
   * A controller for the redirect endpoint that inspects the URL redirected to by the authorization server and sends
   * it back to other windows using.
   */
  .controller('CallbackCtrl', function ($scope, $location) {

    /**
     * Parses an escaped url query string into key-value pairs.
     *
     * (Copied from Angular.js in the AngularJS project.)
     *
     * @returns Object.<(string|boolean)>
     */
    function parseKeyValue( /**string*/ keyValue) {
      var obj = {};
      var key_value, key;

      angular.forEach((keyValue || "").split('&'), function (keyValue) {
        if (keyValue) {
          key_value = keyValue.split('=');
          key = decodeURIComponent(key_value[0]);
          obj[key] = angular.isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true;
        }
      });

      return obj;
    }

    var queryString = $location.path().substring(1); // preceding slash omitted

    var params = parseKeyValue(queryString);

    // TODO: The target origin should be set to an explicit origin.  Otherwise, a malicious site that can receive
    //       the token if it manages to change the location of the parent. (See:
    //       https://developer.mozilla.org/en/docs/DOM/window.postMessage#Security_concerns)

    window.opener.postMessage(params, "*");
    window.close();
  });

})(window, document);<|endoftext|>


<commit_before>/**
 * Created by Awesome on 1/30/2016.
 */

// use strict
'use strict';

// require dependencies
var mongorito = require('mongorito');

/**
 * build model
 */
class model extends mongorito.Model {
    /**
     * construct model entity
     *
     * @param props
     */
    constructor(props) {
        // run super
        super(props);

        // bind set/get methods
        this.getAttributes = this.getAttributes.bind(this);
        this.setAttributes = this.setAttributes.bind(this);

        // bind model methods
        this.isModel = this.isModel.bind(this);

        // set model location
        this._modelLocation = module.parent.filename.replace(global.appRoot, '');
        this._loads         = {};

        // run attributes method
        this.getAttributes();

        // set attributes before save
        this.before ('save', 'setAttributes');
        // this.after  ('save', 'getAttributes');
    }

    /**
     * gets models from attributes
     *
     * @param next
     */
    * getAttributes(next) {
        // loop attributes
        for (var key in this.attributes) {
            // set let attribute
            let attr = this.attributes[key];

            // check if is object
            if (attr === Object(attr) && attr.model) {
                // load model
                if (!this._loads[attr.model]) {
                    this._loads[attr.model] = require(global.appRoot + attr.model);
                }

                // yield model
                let load = yield this._loads[attr.model].findById(attr.id);

                // set model
                this.set(key, load);
            } else if (Array.isArray(attr)) {
                // set array variable
                var arr = [];
                // loop object array
                for (var i = 0; i < attr.length; i++) {
                    // check if is object
                    if (attr[i] === Object(attr[i]) && attr[i].model) {
                        // load model
                        if (!this._loads[attr[i].model]) {
                            this._loads[attr[i].model] = require(global.appRoot + attr[i].model);
                        }

                        // yield model
                        let load = yield this._loads[attr[i].model].findById(attr[i].id);

                        // set model
                        arr.push(load);
                    } else {
                        arr.push(attr[i]);
                    }
                }

                // set array
                this.set(key, arr);
            }
        }

        // run next
        yield next;
    }

    /**
     * sets attributes
     *
     * @param next
     */
    * setAttributes(next) {
        // loop attributes
        for (var key in this.attributes) {
            // set let attribute
            let attr = this.attributes[key];

            // check if entity
            if (this.isModel(attr)) {
                // set array for save
                this.set(key, {
                    'id'    : attr.get('_id').toString(),
                    'model' : attr._modelLocation
                });
            } else if (Array.isArray(attr)) {
                // set arr variable
                var arr = [];
                // loop object array
                for (var i = 0; i < attr.length; i++) {
                    // check if is object
                    if (this.isModel(attr[i])) {
                        arr.push({
                            'id'    : attr[i].get('_id').toString(),
                            'model' : attr[i]._modelLocation
                        });
                    } else {
                        arr.push(attr[i]);
                    }
                }

                // set array
                this.set(key, arr);
            }
        }

        // run next
        yield next;
    }

    /**
     * check if model
     *
     * @param obj
     * @returns {boolean}
     * @private
     */
    isModel(obj) {
        // check if model
        if (obj === Object(obj) && obj._modelLocation) {
            return true;
        }
    }
}

/**
 * export default model class
 *
 * @type {model}
 */
module.exports = model;<commit_msg>log for trace in model<commit_after>/**
 * Created by Awesome on 1/30/2016.
 */

// use strict
'use strict';

// require dependencies
var mongorito = require('mongorito');

/**
 * build model
 */
class model extends mongorito.Model {
    /**
     * construct model entity
     *
     * @param props
     */
    constructor(attrs, options) {
        // run super
        super(attrs, options);

        // bind set/get methods
        this.getAttributes = this.getAttributes.bind(this);
        this.setAttributes = this.setAttributes.bind(this);

        // bind model methods
        this.isModel = this.isModel.bind(this);

        // set model location
        this._modelLocation = module.parent.filename.replace(global.appRoot, '');
        this._loads         = {};

        // run attributes method
        this.getAttributes();

        // set attributes before save
        this.before ('save', 'setAttributes');
        this.after  ('save', 'getAttributes');
    }

    /**
     * gets models from attributes
     *
     * @param next
     */
    * getAttributes(next) {
        // loop attributes
        for (var key in this.attributes) {
            // set let attribute
            let attr = this.attributes[key];

            // check if is object
            if (attr === Object(attr) && attr.model) {
                // load model
                if (!this._loads[attr.model]) {
                    this._loads[attr.model] = require(global.appRoot + attr.model);
                }

                // yield model
                let load = yield this._loads[attr.model].findById(attr.id);

                // set model
                this.attributes[key] = load;
            } else if (Array.isArray(attr)) {
                // set array variable
                var arr = [];
                // loop object array
                for (var i = 0; i < attr.length; i++) {
                    // check if is object
                    if (attr[i] === Object(attr[i]) && attr[i].model) {
                        // load model
                        if (!this._loads[attr[i].model]) {
                            this._loads[attr[i].model] = require(global.appRoot + attr[i].model);
                        }

                        // yield model
                        let load = yield this._loads[attr[i].model].findById(attr[i].id);

                        // set model
                        arr.push(load);
                    } else {
                        arr.push(attr[i]);
                    }
                }

                // set array
                this.attributes[key] = arr;
            }
        }

        // run next
        console.log('next!');
        yield next;
    }

    /**
     * sets attributes
     *
     * @param next
     */
    * setAttributes(next) {
        // loop attributes
        for (var key in this.attributes) {
            // set let attribute
            let attr = this.attributes[key];

            // check if entity
            if (this.isModel(attr)) {
                // set array for save
                this.set(key, {
                    'id'    : attr.get('_id').toString(),
                    'model' : attr._modelLocation
                });
            } else if (Array.isArray(attr)) {
                // set arr variable
                var arr = [];
                // loop object array
                for (var i = 0; i < attr.length; i++) {
                    // check if is object
                    if (this.isModel(attr[i])) {
                        arr.push({
                            'id'    : attr[i].get('_id').toString(),
                            'model' : attr[i]._modelLocation
                        });
                    } else {
                        arr.push(attr[i]);
                    }
                }

                // set array
                this.set(key, arr);
            }
        }

        // run next
        yield next;
    }

    /**
     * check if model
     *
     * @param obj
     * @returns {boolean}
     * @private
     */
    isModel(obj) {
        // check if model
        if (obj === Object(obj) && obj._modelLocation) {
            return true;
        }
    }
}

/**
 * export default model class
 *
 * @type {model}
 */
module.exports = model;<|endoftext|>


<commit_before>/*
 Mixin that controllers with editable models can use. E.g. App.UserProfileController

 @see App.UserProfileRoute and App.UserProfileController to see it in action.
 */
App.SaveOnExitMixin = Ember.Mixin.create({
    actions : {
        goToStep: function(step){
            $("body").animate({ scrollTop: 0 }, 600);
            var model = this.get('model');
            var controller = this;

            if (!model.get('isDirty')) {
                if (step) controller.transitionToRoute(step);
            }

            if (model.get('isNew')) {
                model.one('didCreate', function(){
                    if (step) controller.transitionToRoute(step);
                });
            } else {
                model.one('didUpdate', function(){
                    if (step) controller.transitionToRoute(step);
                });
            }

            // If there is a flash property on the controller then
            // reset as we are changing steps now
            if (this.get('flash') && step)
                this.set('flash', null);

            // The class using this mixin must have an implementation of _save()
            // or use a mixin which includes one, eg App.ControllerObjectSaveMixin
            if (typeof this._save === 'function')
              this._save();
        },

        goToPreviousStep: function(){
            var step = this.get('previousStep');
            this.send('goToStep', step);
        },

        goToNextStep: function(){
            var step = this.get('nextStep');
            this.send('goToStep', step);
        },

        goToNextNoSave: function(){
            if (this.get('nextStep')){
                this.transitionToRoute(this.get('nextStep'));
            }
        },

        goToPreviousNoSave: function(){
            if (this.get('previousStep')){
                this.transitionToRoute(this.get('previousStep'));
            }
        }

    }
});

App.ControllerObjectStatusMixin = Em.Mixin.create({

    modelStatus: function () {
        if (!this.get('model.isSaving') && !this.get('model.isDirty')) {
            return 'ready';
        } else if (this.get('model.isSaving')) {
            return 'busy';
        } else if (this.get('model.isDirty')) {
            return 'dirty';
        }
    }.property('model.isSaving', 'model.isDirty'),

});

App.ControllerObjectSaveMixin = Em.Mixin.create({
    flash: null,
    scrollTopBeforeSave: true,
    redirectRouteName: 'home',

    // If there is a modelStatus property on the controller
    // then use to re-set the flash message on change
    // This shouldn't happen after the didUpdate call
    // below has set a flash message but will happen when
    // editing the record => isDirty or the record is
    // reloaded, eg changing tabs
    resetFlash: function () {
        this.set('flash', null);
    }.observes('modelStatus'),

    _save: function () {
        var self = this,
            model = this.get('model');

        if (this.get('flash'))
            this.set('flash', null);

        model.one('didUpdate', function () {
            self.set('flash', {
                type: 'success',
                text: gettext('Successfully saved')
            });
        });

        model.one('becameInvalid', function(record) {
            // Ember-data currently has no clear way of dealing with the state
            // loaded.created.invalid on server side validation, so we transition
            // to the uncommitted state to allow resubmission
            if (record.get('isNew')) {
                record.transitionTo('loaded.created.uncommitted');
            } else {
                record.transitionTo('loaded.updated.uncommitted');
            }
        });

        if (model) {
          model.set('errors', {});
          model.save();
        }
    },

    actions: {
        saveAndRedirect: function () {
            debugger;
            var self = this,
                model = this.get('model'),
                redirected = false,
                saveEvent = model.get('isNew') ? 'didCreate' : 'didUpdate';

            var t = model.one(saveEvent, function () {
                if (!redirected) {
                    redirected = true;
                    self.transitionToRoute(self.redirectRouteName);
                }
            });

            // If the save was invalid then we should cancel the redirect
            // otherwise the model.one above will trigger later when/if the
            // model is successfully updated/created => causing a redirect
            // unless the redirected variable is true.
            // TODO: It would be better to get a 'handle' for the one off
            //       trigger above and then cancel it if the save was invalid
            model.one('becameInvalid', function () {
                redirected = true;
            });

            this._save();
        },

        save: function() {
            if (this.scrollTopBeforeSave)
                $('body').animate({ scrollTop: 0 }, 600);

            this._save();
        },

        rollback: function() {
            if (this.scrollTopBeforeSave)
                $("body").animate({ scrollTop: 0 }, 600);

            var model = this.get('model');
            if (model) model.rollback();
        }
    }

});<commit_msg>remove debugger<commit_after>/*
 Mixin that controllers with editable models can use. E.g. App.UserProfileController

 @see App.UserProfileRoute and App.UserProfileController to see it in action.
 */
App.SaveOnExitMixin = Ember.Mixin.create({
    actions : {
        goToStep: function(step){
            $("body").animate({ scrollTop: 0 }, 600);
            var model = this.get('model');
            var controller = this;

            if (!model.get('isDirty')) {
                if (step) controller.transitionToRoute(step);
            }

            if (model.get('isNew')) {
                model.one('didCreate', function(){
                    if (step) controller.transitionToRoute(step);
                });
            } else {
                model.one('didUpdate', function(){
                    if (step) controller.transitionToRoute(step);
                });
            }

            // If there is a flash property on the controller then
            // reset as we are changing steps now
            if (this.get('flash') && step)
                this.set('flash', null);

            // The class using this mixin must have an implementation of _save()
            // or use a mixin which includes one, eg App.ControllerObjectSaveMixin
            if (typeof this._save === 'function')
              this._save();
        },

        goToPreviousStep: function(){
            var step = this.get('previousStep');
            this.send('goToStep', step);
        },

        goToNextStep: function(){
            var step = this.get('nextStep');
            this.send('goToStep', step);
        },

        goToNextNoSave: function(){
            if (this.get('nextStep')){
                this.transitionToRoute(this.get('nextStep'));
            }
        },

        goToPreviousNoSave: function(){
            if (this.get('previousStep')){
                this.transitionToRoute(this.get('previousStep'));
            }
        }

    }
});

App.ControllerObjectStatusMixin = Em.Mixin.create({

    modelStatus: function () {
        if (!this.get('model.isSaving') && !this.get('model.isDirty')) {
            return 'ready';
        } else if (this.get('model.isSaving')) {
            return 'busy';
        } else if (this.get('model.isDirty')) {
            return 'dirty';
        }
    }.property('model.isSaving', 'model.isDirty'),

});

App.ControllerObjectSaveMixin = Em.Mixin.create({
    flash: null,
    scrollTopBeforeSave: true,
    redirectRouteName: 'home',

    // If there is a modelStatus property on the controller
    // then use to re-set the flash message on change
    // This shouldn't happen after the didUpdate call
    // below has set a flash message but will happen when
    // editing the record => isDirty or the record is
    // reloaded, eg changing tabs
    resetFlash: function () {
        this.set('flash', null);
    }.observes('modelStatus'),

    _save: function () {
        var self = this,
            model = this.get('model');

        if (this.get('flash'))
            this.set('flash', null);

        model.one('didUpdate', function () {
            self.set('flash', {
                type: 'success',
                text: gettext('Successfully saved')
            });
        });

        model.one('becameInvalid', function(record) {
            // Ember-data currently has no clear way of dealing with the state
            // loaded.created.invalid on server side validation, so we transition
            // to the uncommitted state to allow resubmission
            if (record.get('isNew')) {
                record.transitionTo('loaded.created.uncommitted');
            } else {
                record.transitionTo('loaded.updated.uncommitted');
            }
        });

        if (model) {
          model.set('errors', {});
          model.save();
        }
    },

    actions: {
        saveAndRedirect: function () {
            var self = this,
                model = this.get('model'),
                redirected = false,
                saveEvent = model.get('isNew') ? 'didCreate' : 'didUpdate';

            var t = model.one(saveEvent, function () {
                if (!redirected) {
                    redirected = true;
                    self.transitionToRoute(self.redirectRouteName);
                }
            });

            // If the save was invalid then we should cancel the redirect
            // otherwise the model.one above will trigger later when/if the
            // model is successfully updated/created => causing a redirect
            // unless the redirected variable is true.
            // TODO: It would be better to get a 'handle' for the one off
            //       trigger above and then cancel it if the save was invalid
            model.one('becameInvalid', function () {
                redirected = true;
            });

            this._save();
        },

        save: function() {
            if (this.scrollTopBeforeSave)
                $('body').animate({ scrollTop: 0 }, 600);

            this._save();
        },

        rollback: function() {
            if (this.scrollTopBeforeSave)
                $("body").animate({ scrollTop: 0 }, 600);

            var model = this.get('model');
            if (model) model.rollback();
        }
    }

});<|endoftext|>


<commit_before>const path = require('path');
const favicon = require('serve-favicon');
const compress = require('compression');
const cors = require('cors');
const helmet = require('helmet');
const bodyParser = require('body-parser');
const promise = require('bluebird');

const feathers = require('feathers');
const configuration = require('feathers-configuration');
const hooks = require('feathers-hooks');
const rest = require('feathers-rest');
const socketio = require('feathers-socketio');

const handler = require('feathers-errors/handler');
const multer = require('multer');
const multipartMiddleware = multer();
const dauria = require('dauria');
const notFound = require('feathers-errors/not-found');

const middleware = require('./middleware');
const services = require('./services');
const appHooks = require('./app.hooks');

const sequelize = require('./sequelize');

const authentication = require('./authentication');

const app = feathers();

// Load app configuration
app.configure(configuration());
// Enable CORS, security, compression, favicon and body parsing
app.use(cors());
app.use(helmet());
app.use(compress());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(favicon(path.join(app.get('public'), 'favicon.ico')));
// Host the public folder
app.use('/', feathers.static(app.get('public')));

// Set up Plugins and providers
app.configure(hooks());
app.configure(sequelize);
app.configure(rest());
app.configure(socketio());

// Configure other middleware (see `middleware/index.js`)
app.configure(middleware);
app.configure(authentication);
// Set up our services (see `services/index.js`)
app.configure(services);

// const AWS = require('aws-sdk');
const AWS = require('aws-sdk');
const BlobService = require('feathers-blob');
const S3BlobStore = require('s3-blob-store');

// TODO: Move into the services directory
// S3 Image Service
var s3 = promise.promisifyAll(new AWS.S3({
  accessKeyId: process.env.S3_ID,
  secretAccessKey: process.env.S3_KEY
}));
// s3 =

const blobStore = S3BlobStore({
  client: s3,
  bucket: 'stanky-clams'
});

const blobService = BlobService({
  Model: blobStore
});

app.use('/s3/images/new',
  // multer parses the file named 'uri'.
  // Without extra params the data is
  // temporarely kept in memory
  multipartMiddleware.single('uri'),
  // another middleware, this time to
  // transfer the received file to feathers
  function(req,res,next){
    req.feathers.file = req.file;
    next();
  },
  blobService
);

app.get('/s3/images', (req, res, next) => {
  const params = {Bucket: 'stanky-clams'};
  s3.listObjects(params, (err, data) => {
    if (err) {
      console.log(err);
    } else {
      const mappedURLs = data.Contents.map((object) => `https://s3.amazonaws.com/stanky-clams/${object.Key}`);
      res.json(mappedURLs);
    }
  });
});

app.get('/s3/images/test', (req, res, next) => {
  var galleryId;
  var position;
  if (req.query.hasOwnProperty('galleryId')) {
    galleryId = req.query.galleryid;
  }
  const params = {Bucket: 'stanky-clams'};
  // const s3.listObjectsAsync = promise.promisify(s3.listObjects);

  s3.listObjectsAsync(params)
    .then((data) => data.Contents.map((object) => s3.headObjectAsync({Bucket: 'stanky-clams', Key: object.Key})))
    .then((allObjectHeadPromises) => Promise.all(allObjectHeadPromises))
    .then((allObjectHeads) => {
      console.log('objectHeadsLengths', allObjectHeads.length);
      res.json(allObjectHeads);
    })
    .catch((err) => {
      console.log(err);
    });
  // s3.listObjects(params, (err, data) => {
  //   if (err) {
  //     console.log(err);
  //   } else {
  //     // make a http request for the head of each object
  //     // promise.all the requests
  //     // filter the results by the gallery id
  //     // map over each remaining object and construct the url
  //     // res.json the arr of urls
  //
  //     // const oneObject = data.Contents[0];
  //     // s3.headObject({Bucket: 'stanky-clams', Key: oneObject.Key}, (err, objectData) => {
  //     //   res.json(objectData);
  //     // });
  //
  //     // const objectsMetaData = data.Contents.map((object) => {
  //     //   const objectParams = {Bucket: 'stanky-clams', Key: object.Key}
  //     //   return s3.headObject(objectParams, (err, objectData) => {
  //     //     if (err) {
  //     //       console.log(err);
  //     //     } else {
  //     //       return objectData.Metadata;
  //     //     }
  //     //   });
  //     // });
  //     // console.log(objectsMetaData);
  //     // res.json(objectsMetaData);
  //     // s3.headObject()
  //     // res.json(data);
  //   }
  // });
});

// before-create Hook to get the file (if there is any)
// and turn it into a datauri,
// transparently getting feathers-blob
// to work with multipart file uploads

// TODO: Add galleryId & position as key-values pairs
app.service('/s3/images/new').before({
  create: [
    function(hook) {
      if (!hook.data.uri && hook.params.file){
        const file = hook.params.file;
        const uri = dauria.getBase64DataURI(file.buffer, file.mimetype);
        hook.data = {uri: uri};
      }
      hook.params.s3 = {
        ACL: 'public-read',
        Key: hook.data.name,
        Metadata: {
          'galleryid': hook.data.galleryId.toString(),
          'position': hook.data.position.toString()
        }
      };
      // hook.params.name = hook.data.name;
      // hook.params.position = hook.data.position;
      // hook.params.galleryId = hook.data.galleryId;
    }
  ]
});

// TODO: programatically get all image urls from a specific gallery (using key value pairs)

// TODO: programatically get a specific image url

// app.get('/s3/images/:name', (req, res, next) => {
//   blobService.get(req.params.name)
//     .then(function (result) {
//       console.log(result);
//       res.json(result);
//     }).catch(function(err) {
//       console.log(err);
//     });
// });

// Configure a middleware for 404s and the error handler
app.use(notFound());
app.use(handler());

app.hooks(appHooks);

module.exports = app;
<commit_msg>added a filter by galleryid functionality to the s3/images service<commit_after>const path = require('path');
const favicon = require('serve-favicon');
const compress = require('compression');
const cors = require('cors');
const helmet = require('helmet');
const bodyParser = require('body-parser');
const promise = require('bluebird');

const feathers = require('feathers');
const configuration = require('feathers-configuration');
const hooks = require('feathers-hooks');
const rest = require('feathers-rest');
const socketio = require('feathers-socketio');

const handler = require('feathers-errors/handler');
const multer = require('multer');
const multipartMiddleware = multer();
const dauria = require('dauria');
const notFound = require('feathers-errors/not-found');

const middleware = require('./middleware');
const services = require('./services');
const appHooks = require('./app.hooks');

const sequelize = require('./sequelize');

const authentication = require('./authentication');

const app = feathers();

// Load app configuration
app.configure(configuration());
// Enable CORS, security, compression, favicon and body parsing
app.use(cors());
app.use(helmet());
app.use(compress());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(favicon(path.join(app.get('public'), 'favicon.ico')));
// Host the public folder
app.use('/', feathers.static(app.get('public')));

// Set up Plugins and providers
app.configure(hooks());
app.configure(sequelize);
app.configure(rest());
app.configure(socketio());

// Configure other middleware (see `middleware/index.js`)
app.configure(middleware);
app.configure(authentication);
// Set up our services (see `services/index.js`)
app.configure(services);

// const AWS = require('aws-sdk');
const AWS = require('aws-sdk');
const BlobService = require('feathers-blob');
const S3BlobStore = require('s3-blob-store');

// TODO: Move into the services directory
// S3 Image Service
var s3 = promise.promisifyAll(new AWS.S3({
  accessKeyId: process.env.S3_ID,
  secretAccessKey: process.env.S3_KEY
}));
// s3 =

const blobStore = S3BlobStore({
  client: s3,
  bucket: 'stanky-clams'
});

const blobService = BlobService({
  Model: blobStore
});

app.use('/s3/images/new',
  // multer parses the file named 'uri'.
  // Without extra params the data is
  // temporarely kept in memory
  multipartMiddleware.single('uri'),
  // another middleware, this time to
  // transfer the received file to feathers
  function(req,res,next){
    req.feathers.file = req.file;
    next();
  },
  blobService
);

// app.get('/s3/images', (req, res, next) => {
//   const params = {Bucket: 'stanky-clams'};
//   s3.listObjects(params, (err, data) => {
//     if (err) {
//       console.log(err);
//     } else {
//       res.json(data);
//       const mappedURLs = data.Contents.map((object) => `https://s3.amazonaws.com/stanky-clams/${object.Key}`);
//       // res.json(mappedURLs);
//     }
//   });
// });

app.get('/s3/images', (req, res, next) => {
  const params = {Bucket: 'stanky-clams'};

  var resultantArr = [];
  var objectKeys = [];
  // Fetch list of objects in bucket
  // Make a http request for the head/metadata of each object
  // Filter the objects for the galleryId specified in the query params
  //

  s3.listObjectsAsync(params)
    .then((data) => {
      objectKeys = data.Contents;
      return data.Contents.map((object) => s3.headObjectAsync({Bucket: 'stanky-clams', Key: object.Key}));
    })
    .then((allObjectHeadPromises) => Promise.all(allObjectHeadPromises))
    .then((allObjectHeads) => allObjectHeads.filter((objectHead) => {
      if (req.query.hasOwnProperty('galleryid')) {
        if (objectHead.Metadata.hasOwnProperty('galleryid')) {
          return objectHead.Metadata.galleryid === req.query.galleryid;
        }
      } else {
        return objectHead;
      }
    }))
    .then((filteredObjects) => {
      filteredObjects.forEach((filteredObject) => {
        objectKeys.forEach((objectKey) => {
          if (filteredObject.ETag === objectKey.ETag) {
            resultantArr.push(`https://s3.amazonaws.com/stanky-clams/${objectKey.Key}`);
          }
        });
      });
      res.json(resultantArr);
    })
    .catch(console.error);
});

// before-create Hook to get the file (if there is any)
// and turn it into a datauri,
// transparently getting feathers-blob
// to work with multipart file uploads

// TODO: Add galleryId & position as key-values pairs
app.service('/s3/images/new').before({
  create: [
    function(hook) {
      if (!hook.data.uri && hook.params.file){
        const file = hook.params.file;
        const uri = dauria.getBase64DataURI(file.buffer, file.mimetype);
        hook.data = {uri: uri};
      }
      hook.params.s3 = {
        ACL: 'public-read',
        Key: hook.data.name,
        Metadata: {
          'galleryid': hook.data.galleryId.toString(),
          'position': hook.data.position.toString()
        }
      };
      // hook.params.name = hook.data.name;
      // hook.params.position = hook.data.position;
      // hook.params.galleryId = hook.data.galleryId;
    }
  ]
});

// TODO: programatically get all image urls from a specific gallery (using key value pairs)

// TODO: programatically get a specific image url

// app.get('/s3/images/:name', (req, res, next) => {
//   blobService.get(req.params.name)
//     .then(function (result) {
//       console.log(result);
//       res.json(result);
//     }).catch(function(err) {
//       console.log(err);
//     });
// });

// Configure a middleware for 404s and the error handler
app.use(notFound());
app.use(handler());

app.hooks(appHooks);

module.exports = app;
<|endoftext|>


<commit_before>/**
 * Controller for Components
 *
 * @module
 */

'use strict';

var _ = require('lodash'),
  control = require('../control'),
  db = require('./db'),
  uid = require('../uid'),
  files = require('../files'),
  schema = require('../schema'),
  siteService = require('./sites'),
  references = require('./references'),
  bluebird = require('bluebird'),
  path = require('path'),
  glob = require('glob'),
  referenceProperty = '_ref',
  mediaDir = path.join(process.cwd(), 'public');

/**
 * Takes a ref, and returns the component name within it.
 * @param {string} uri
 * @returns {string}
 * @example /components/base  returns base
 * @example /components/text/instances/0  returns text
 * @example /components/image.html  returns image
 */
function getName(uri) {
  var result = /components\/(.+?)[\/\.@]/.exec(uri) || /components\/(.+)/.exec(uri);

  return result && result[1];
}

/**
 * @param {string} uri
 * @param {object} [locals]
 */
function get(uri, locals) {
  var promise,
    name = getName(uri),
    componentModule = name && files.getComponentModule(name);

  if (_.isFunction(componentModule)) {
    promise = componentModule(uri, locals);
  } else {
    promise = db.get(uri).then(JSON.parse);
  }

  return promise;
}

/**
 * return a list of all components
 * @returns {array}
 */
function list() {
  return files.getComponents();
}

/**
 * PUT to just :id or @latest writes to both locations and creates a new version.
 * @param {string} uri   Assumes no @version
 * @param {object} data
 * @returns {Promise}
 */
function putLatest(uri, data) {
  data = JSON.stringify(data);
  return [
    { type: 'put', key: references.replaceVersion(uri), value: data }
  ];
}

/**
 *
 * @param {string} uri   Assumes no @version
 * @param {object} data
 * @returns {Promise}
 */
function putPublished(uri, data) {
  data = JSON.stringify(data);
  return [
    { type: 'put', key: references.replaceVersion(uri, 'published'), value: data }
  ];
}

/**
 *
 * @param {string} uri  Assumes no @version
 * @param {object} data
 * @param {string} tag  unique tag
 * @returns {Promise}
 */
function putTag(uri, data, tag) {
  data = JSON.stringify(data);
  return [
    { type: 'put', key: references.replaceVersion(uri, tag), value: data }
  ];
}

/**
 *
 * @param {string} uri
 * @param {object} data
 * @returns {Promise}
 */
function putDefaultBehavior(uri, data) {
  const split = uri.split('@'),
    path = split[0],
    version = split[1];

  if (version) {
    switch (version) {
      case 'published':
        return putPublished(path, data);
      case 'latest':
        return putLatest(path, data);
      default:
        return putTag(path, data, version);
    }
  } else {
    return putLatest(path, data);
  }
}

/**
 * @param {string} uri
 * @param {string} data
 * @param {object} [locals]
 * @returns {Promise}
 */
function put(uri, data, locals) {
  var result,
    componentModule = files.getComponentModule(getName(uri));

  if (componentModule && _.isFunction(componentModule.put)) {
    result = componentModule.put(uri, data, locals);
  } else {
    result = putDefaultBehavior(uri, data);
  }
  return result;
}

/**
 * Clear all of an object properties (in place), not a new object.
 *
 * @param {object} obj
 * @returns {object}
 */
function clearOwnProperties(obj) {
  _.forOwn(obj, function (value, key) {
    delete obj[key];
  });

  return obj;
}

/**
 * True if this is a reference object that also has real data in it.
 *
 * Used to determine if that data should be preserved or not.
 *
 * @param {object} obj
 * @returns {boolean}
 */
function isReferencedAndReal(obj) {
  return _.isString(obj[referenceProperty]) && _.size(obj) > 1;
}

/**
 * If the ref has a version that is "propagating" like @published or @latest, replace all versions in the data
 *  with the new version (in-place).
 * @param {string} uri
 * @param {object} data
 * @returns {object}
 */
function replacePropagatingVersions(uri, data) {
  if (references.isPropagatingVersion(uri)) {
    references.replaceAllVersions(uri.split('@')[1])(data);
  }

  return data;
}

/**
 * Split cascading component data into individual components
 * @param {string} uri  Root reference in uri form
 * @param {object} data  Cascading component data
 * @returns {[{key: string, value: object}]}
 */
function splitCascadingData(uri, data) {
  var ops, list;

  // search for _ref with _size greater than 1
  list = _.listDeepObjects(data, isReferencedAndReal);
  ops = _.map(list.reverse(), function (obj) {
    var ref = obj[referenceProperty],
      // since children are before parents, no one will see data below them
      op = {key: ref, value: _.omit(obj, referenceProperty)};

    // omit cloned 1 level deep and we clear what omit cloned from obj
    //  so the op gets the first level of data, but it's removed from the main obj
    clearOwnProperties(obj);
    obj[referenceProperty] = ref;

    return op;
  });

  // add the cleaned root object at the end
  ops.push({key: uri, value: data});

  return ops;
}

/**
 * Get a list of all the put operations needed to complete a cascading PUT
 *
 * NOTE: this function changes the data object _in-place_ for speed and memory reasons. We are not okay with doing
 * a deep clone here, because that will significantly slow down this operation.  If someone wants to deep clone the data
 * before this operation, they can.
 *
 * @param {string} uri
 * @param {object} data
 * @param {object} [locals]
 * @returns {Promise}
 */
function getPutOperations(uri, data, locals) {
  // potentially propagate version throughout object
  const components = splitCascadingData(uri, replacePropagatingVersions(uri, data));

  // if locals exist and there are more than one component being put,
  // then we should pass a read-only version to each component so they can't affect each other
  // this operation isn't needed in the common case of putting a single object
  if (!!locals && components.length > 0) {
    locals = control.setReadOnly(_.cloneDeep(locals));
  }

  return bluebird.map(components, function (op) {
    // run each through the normal put, which may or may not hit custom component logic
    return put(op.key, op.value, locals);
  }).then(function (ops) {
    // flatten to list of final batch ops
    return _.filter(_.flattenDeep(ops), _.identity);
  });
}

/**
 * @param {string} uri
 * @param {object} data
 * @param {object} [locals]
 * @returns {Promise}
 */
function cascadingPut(uri, data, locals) {
  // split data into pieces
  return getPutOperations(uri, data, locals)
    .then(function (ops) {
      // return ops if successful
      return db.batch(ops).return(ops);
    })
    .then(function (ops) {
      // return the value of the last batch operation (the root object) if successful
      const rootOp = _.last(ops);

      return rootOp && JSON.parse(rootOp.value);
    });
}

/**
 *
 * @param uri
 * @param data
 * @param locals
 * @returns {*}
 */
function publish(uri, data, locals) {
  if (data && _.size(data) > 0) {
    return cascadingPut(uri, data, locals);
  } else {
    return get(references.replaceVersion(uri), locals).then(function (data) {
      return cascadingPut(uri, data, locals);
    });
  }
}

/**
 * Delete component data.
 *
 * Gets old values, so we can return them when the thing is deleted
 * @param {string} uri
 * @param {object} [locals]
 * @returns {Promise}
 */
function del(uri, locals) {
  return get(uri).then(function (oldData) {
    var promise,
      componentModule = files.getComponentModule(getName(uri));

    if (componentModule && _.isFunction(componentModule.del)) {
      promise = componentModule.del(uri, locals);
    } else {
      promise = db.del(uri).return(uri);
    }

    return promise.return(oldData);
  });
}

/**
 * @param {string} uri
 * @param {object} data
 * @param {object} [locals]
 * @returns {Promise}
 */
function post(uri, data, locals) {
  uri += '/' + uid.get();
  return cascadingPut(uri, data, locals).then(function (result) {
    result._ref = uri;
    return result;
  });
}

/**
 * @param {string} uri
 */
function getSchema(uri) {
  return bluebird.try(function () {
    return schema.getSchema(files.getComponentPath(getName(uri)));
  });
}

/**
 * Check root of their project, or the 1st level of their node_modules
 *
 * @param {string} name
 * @param {string} [templateName]  'template', 'sitemap', 'apple', 'facebook'
 * @returns {[string]}  List of all templates available.
 */
function getPossibleTemplates(name, templateName) {
  const filePath = files.getComponentPath(name);

  if (_.isString(filePath)) {
    return glob.sync(path.join(filePath, templateName + '.*'));
  }

  return [];
}

/**
 * Get the first template found for a particular component
 * @param {string} name  i.e., 'article', 'paragraph', 'content', 'my-layout'
 * @param {string} templateName  i.e., 'template', 'sitemap', 'apple', 'facebook'
 * @returns {string|undefined}
 */
function getTemplate(name, templateName) {

  if (!templateName) {
    throw new TypeError('Missing template name.');
  }

  // if there are slashes in this name, they've given us a reference like /components/name/instances/id
  if (name.indexOf('/') !== -1) {
    name = getName(name);
  }

  // return the first template found
  return module.exports.getPossibleTemplates(name, templateName)[0];
}

/**
 * @param {string} [ref]
 * @param {object} data
 * @returns {{refs: object, components: Array}}
 */
function getIndices(ref, data) {
  var components,
    refs = {};

  refs[ref] = data;
  _.assign(refs, _.indexBy(_.listDeepObjects(data, '_ref'), '_ref'));
  components = _.uniq(_.filter(_.map(Object.keys(refs), function (ref) { return getName(ref); }), _.identity));

  return {
    refs: refs,
    components: components
  };
}

/**
 * @param {string} name
 * @param {string} slug
 */
function getStyles(name, slug) {
  var site = siteService.sites()[slug],
    assetDir = site && site.assetDir || mediaDir,
    assetDirLen = assetDir.length,
    assetPath = site && site.assetPath || '';

  return _.map(_.filter([
    path.join(assetDir, 'css', name + '.css'),
    path.join(assetDir, 'css', name + '.' + slug + '.css')
  ], files.fileExists), function (filePath) {
    return path.join(assetPath, filePath.substr(assetDirLen));
  });
}

/**
 * @param {string} name
 * @param {string} slug
 */
function getScripts(name, slug) {
  var site = siteService.sites()[slug],
    assetDir = site && site.assetDir || mediaDir,
    assetDirLen = assetDir.length,
    assetPath = site && site.assetPath || '';

  return _.map(_.filter([
    path.join(assetDir, 'js', name + '.js'),
    path.join(assetDir, 'js', name + '.' + slug + '.js')
  ], files.fileExists), function (filePath) {
    return path.join(assetPath, filePath.substr(assetDirLen));
  });
}

/**
 * Join all the arguments into a large string seperated by '.'
 *
 * @returns {string}
 */
function joinArguments() {
  return _.slice(arguments).join('.');
}

// outsiders can act on components too
module.exports.get = get;
module.exports.list = list;
module.exports.put = cascadingPut; // special: could lead to multiple put operations
module.exports.publish = publish;
module.exports.del = del;
module.exports.post = post;

// maybe server.js people want to reach in and reuse these?
module.exports.putLatest = putLatest;
module.exports.putPublished = putPublished;
module.exports.putTag = putTag;
module.exports.putDefaultBehavior = putDefaultBehavior;

// repeatable look-ups
module.exports.getName = getName; //too large to memoize
module.exports.getTemplate = getTemplate; //too large to memoize
module.exports.getPossibleTemplates = control.memoize(getPossibleTemplates, joinArguments);
module.exports.getSchema = control.memoize(getSchema);
module.exports.getScripts = control.memoize(getScripts, joinArguments);
module.exports.getStyles = control.memoize(getStyles, joinArguments);

// data rearrangement
module.exports.getIndices = getIndices;
module.exports.getPutOperations = getPutOperations;
<commit_msg>add JSDocs as per Morgans comment<commit_after>/**
 * Controller for Components
 *
 * @module
 */

'use strict';

var _ = require('lodash'),
  control = require('../control'),
  db = require('./db'),
  uid = require('../uid'),
  files = require('../files'),
  schema = require('../schema'),
  siteService = require('./sites'),
  references = require('./references'),
  bluebird = require('bluebird'),
  path = require('path'),
  glob = require('glob'),
  referenceProperty = '_ref',
  mediaDir = path.join(process.cwd(), 'public');

/**
 * Takes a ref, and returns the component name within it.
 * @param {string} uri
 * @returns {string}
 * @example /components/base  returns base
 * @example /components/text/instances/0  returns text
 * @example /components/image.html  returns image
 */
function getName(uri) {
  var result = /components\/(.+?)[\/\.@]/.exec(uri) || /components\/(.+)/.exec(uri);

  return result && result[1];
}

/**
 * @param {string} uri
 * @param {object} [locals]
 */
function get(uri, locals) {
  var promise,
    name = getName(uri),
    componentModule = name && files.getComponentModule(name);

  if (_.isFunction(componentModule)) {
    promise = componentModule(uri, locals);
  } else {
    promise = db.get(uri).then(JSON.parse);
  }

  return promise;
}

/**
 * return a list of all components
 * @returns {array}
 */
function list() {
  return files.getComponents();
}

/**
 * PUT to just :id or @latest writes to both locations and creates a new version.
 * @param {string} uri   Assumes no @version
 * @param {object} data
 * @returns {Promise}
 */
function putLatest(uri, data) {
  data = JSON.stringify(data);
  return [
    { type: 'put', key: references.replaceVersion(uri), value: data }
  ];
}

/**
 *
 * @param {string} uri   Assumes no @version
 * @param {object} data
 * @returns {Promise}
 */
function putPublished(uri, data) {
  data = JSON.stringify(data);
  return [
    { type: 'put', key: references.replaceVersion(uri, 'published'), value: data }
  ];
}

/**
 *
 * @param {string} uri  Assumes no @version
 * @param {object} data
 * @param {string} tag  unique tag
 * @returns {Promise}
 */
function putTag(uri, data, tag) {
  data = JSON.stringify(data);
  return [
    { type: 'put', key: references.replaceVersion(uri, tag), value: data }
  ];
}

/**
 *
 * @param {string} uri
 * @param {object} data
 * @returns {Promise}
 */
function putDefaultBehavior(uri, data) {
  const split = uri.split('@'),
    path = split[0],
    version = split[1];

  if (version) {
    switch (version) {
      case 'published':
        return putPublished(path, data);
      case 'latest':
        return putLatest(path, data);
      default:
        return putTag(path, data, version);
    }
  } else {
    return putLatest(path, data);
  }
}

/**
 * @param {string} uri
 * @param {string} data
 * @param {object} [locals]
 * @returns {Promise}
 */
function put(uri, data, locals) {
  var result,
    componentModule = files.getComponentModule(getName(uri));

  if (componentModule && _.isFunction(componentModule.put)) {
    result = componentModule.put(uri, data, locals);
  } else {
    result = putDefaultBehavior(uri, data);
  }
  return result;
}

/**
 * Clear all of an object properties (in place), not a new object.
 *
 * @param {object} obj
 * @returns {object}
 */
function clearOwnProperties(obj) {
  _.forOwn(obj, function (value, key) {
    delete obj[key];
  });

  return obj;
}

/**
 * True if this is a reference object that also has real data in it.
 *
 * Used to determine if that data should be preserved or not.
 *
 * @param {object} obj
 * @returns {boolean}
 */
function isReferencedAndReal(obj) {
  return _.isString(obj[referenceProperty]) && _.size(obj) > 1;
}

/**
 * If the ref has a version that is "propagating" like @published or @latest, replace all versions in the data
 *  with the new version (in-place).
 * @param {string} uri
 * @param {object} data
 * @returns {object}
 */
function replacePropagatingVersions(uri, data) {
  if (references.isPropagatingVersion(uri)) {
    references.replaceAllVersions(uri.split('@')[1])(data);
  }

  return data;
}

/**
 * Split cascading component data into individual components
 * @param {string} uri  Root reference in uri form
 * @param {object} data  Cascading component data
 * @returns {[{key: string, value: object}]}
 */
function splitCascadingData(uri, data) {
  var ops, list;

  // search for _ref with _size greater than 1
  list = _.listDeepObjects(data, isReferencedAndReal);
  ops = _.map(list.reverse(), function (obj) {
    var ref = obj[referenceProperty],
      // since children are before parents, no one will see data below them
      op = {key: ref, value: _.omit(obj, referenceProperty)};

    // omit cloned 1 level deep and we clear what omit cloned from obj
    //  so the op gets the first level of data, but it's removed from the main obj
    clearOwnProperties(obj);
    obj[referenceProperty] = ref;

    return op;
  });

  // add the cleaned root object at the end
  ops.push({key: uri, value: data});

  return ops;
}

/**
 * Get a list of all the put operations needed to complete a cascading PUT
 *
 * NOTE: this function changes the data object _in-place_ for speed and memory reasons. We are not okay with doing
 * a deep clone here, because that will significantly slow down this operation.  If someone wants to deep clone the data
 * before this operation, they can.
 *
 * @param {string} uri
 * @param {object} data
 * @param {object} [locals]
 * @returns {Promise}
 */
function getPutOperations(uri, data, locals) {
  // potentially propagate version throughout object
  const components = splitCascadingData(uri, replacePropagatingVersions(uri, data));

  // if locals exist and there are more than one component being put,
  // then we should pass a read-only version to each component so they can't affect each other
  // this operation isn't needed in the common case of putting a single object
  if (!!locals && components.length > 0) {
    locals = control.setReadOnly(_.cloneDeep(locals));
  }

  return bluebird.map(components, function (op) {
    // run each through the normal put, which may or may not hit custom component logic
    return put(op.key, op.value, locals);
  }).then(function (ops) {
    // flatten to list of final batch ops
    return _.filter(_.flattenDeep(ops), _.identity);
  });
}

/**
 * @param {string} uri
 * @param {object} data
 * @param {object} [locals]
 * @returns {Promise}
 */
function cascadingPut(uri, data, locals) {
  // split data into pieces
  return getPutOperations(uri, data, locals)
    .then(function (ops) {
      // return ops if successful
      return db.batch(ops).return(ops);
    })
    .then(function (ops) {
      // return the value of the last batch operation (the root object) if successful
      const rootOp = _.last(ops);

      return rootOp && JSON.parse(rootOp.value);
    });
}

/**
 *
 * @param {string} uri
 * @param {object} data
 * @param {object} [locals]
 * @returns {Promise}
 */
function publish(uri, data, locals) {
  if (data && _.size(data) > 0) {
    return cascadingPut(uri, data, locals);
  } else {
    return get(references.replaceVersion(uri), locals).then(function (data) {
      return cascadingPut(uri, data, locals);
    });
  }
}

/**
 * Delete component data.
 *
 * Gets old values, so we can return them when the thing is deleted
 * @param {string} uri
 * @param {object} [locals]
 * @returns {Promise}
 */
function del(uri, locals) {
  return get(uri).then(function (oldData) {
    var promise,
      componentModule = files.getComponentModule(getName(uri));

    if (componentModule && _.isFunction(componentModule.del)) {
      promise = componentModule.del(uri, locals);
    } else {
      promise = db.del(uri).return(uri);
    }

    return promise.return(oldData);
  });
}

/**
 * @param {string} uri
 * @param {object} data
 * @param {object} [locals]
 * @returns {Promise}
 */
function post(uri, data, locals) {
  uri += '/' + uid.get();
  return cascadingPut(uri, data, locals).then(function (result) {
    result._ref = uri;
    return result;
  });
}

/**
 * @param {string} uri
 */
function getSchema(uri) {
  return bluebird.try(function () {
    return schema.getSchema(files.getComponentPath(getName(uri)));
  });
}

/**
 * Check root of their project, or the 1st level of their node_modules
 *
 * @param {string} name
 * @param {string} [templateName]  'template', 'sitemap', 'apple', 'facebook'
 * @returns {[string]}  List of all templates available.
 */
function getPossibleTemplates(name, templateName) {
  const filePath = files.getComponentPath(name);

  if (_.isString(filePath)) {
    return glob.sync(path.join(filePath, templateName + '.*'));
  }

  return [];
}

/**
 * Get the first template found for a particular component
 * @param {string} name  i.e., 'article', 'paragraph', 'content', 'my-layout'
 * @param {string} templateName  i.e., 'template', 'sitemap', 'apple', 'facebook'
 * @returns {string|undefined}
 */
function getTemplate(name, templateName) {

  if (!templateName) {
    throw new TypeError('Missing template name.');
  }

  // if there are slashes in this name, they've given us a reference like /components/name/instances/id
  if (name.indexOf('/') !== -1) {
    name = getName(name);
  }

  // return the first template found
  return module.exports.getPossibleTemplates(name, templateName)[0];
}

/**
 * @param {string} [ref]
 * @param {object} data
 * @returns {{refs: object, components: Array}}
 */
function getIndices(ref, data) {
  var components,
    refs = {};

  refs[ref] = data;
  _.assign(refs, _.indexBy(_.listDeepObjects(data, '_ref'), '_ref'));
  components = _.uniq(_.filter(_.map(Object.keys(refs), function (ref) { return getName(ref); }), _.identity));

  return {
    refs: refs,
    components: components
  };
}

/**
 * @param {string} name
 * @param {string} slug
 */
function getStyles(name, slug) {
  var site = siteService.sites()[slug],
    assetDir = site && site.assetDir || mediaDir,
    assetDirLen = assetDir.length,
    assetPath = site && site.assetPath || '';

  return _.map(_.filter([
    path.join(assetDir, 'css', name + '.css'),
    path.join(assetDir, 'css', name + '.' + slug + '.css')
  ], files.fileExists), function (filePath) {
    return path.join(assetPath, filePath.substr(assetDirLen));
  });
}

/**
 * @param {string} name
 * @param {string} slug
 */
function getScripts(name, slug) {
  var site = siteService.sites()[slug],
    assetDir = site && site.assetDir || mediaDir,
    assetDirLen = assetDir.length,
    assetPath = site && site.assetPath || '';

  return _.map(_.filter([
    path.join(assetDir, 'js', name + '.js'),
    path.join(assetDir, 'js', name + '.' + slug + '.js')
  ], files.fileExists), function (filePath) {
    return path.join(assetPath, filePath.substr(assetDirLen));
  });
}

/**
 * Join all the arguments into a large string seperated by '.'
 *
 * @returns {string}
 */
function joinArguments() {
  return _.slice(arguments).join('.');
}

// outsiders can act on components too
module.exports.get = get;
module.exports.list = list;
module.exports.put = cascadingPut; // special: could lead to multiple put operations
module.exports.publish = publish;
module.exports.del = del;
module.exports.post = post;

// maybe server.js people want to reach in and reuse these?
module.exports.putLatest = putLatest;
module.exports.putPublished = putPublished;
module.exports.putTag = putTag;
module.exports.putDefaultBehavior = putDefaultBehavior;

// repeatable look-ups
module.exports.getName = getName; //too large to memoize
module.exports.getTemplate = getTemplate; //too large to memoize
module.exports.getPossibleTemplates = control.memoize(getPossibleTemplates, joinArguments);
module.exports.getSchema = control.memoize(getSchema);
module.exports.getScripts = control.memoize(getScripts, joinArguments);
module.exports.getStyles = control.memoize(getStyles, joinArguments);

// data rearrangement
module.exports.getIndices = getIndices;
module.exports.getPutOperations = getPutOperations;
<|endoftext|>


<commit_before>/*

  Navigation store

*/

import modalActions from "../modal";
import likedActions from "../liked";
import shareActions from "../share";
import Sections from "../../blocks/sections";
import Discover from "../../blocks/discover";

import { routeActions } from "../routing";

let sectionsVisible = false;
let discoverVisible = false;

const back = () => routeActions.goBack();
const profileLink = process.env.NATIVE ? "/profile" : "/profile/settings";

const sectionsAction = (props) => {
  const { modal, dispatch } = props;

  if (process.env.NATIVE) return routeActions.push("/sections");

  discoverVisible = false;
  sectionsVisible = true;
  return modalActions.render(Sections, { keepNav: true });
};

const discoverAction = (props) => {
  const { modal, dispatch } = props;

  if (process.env.NATIVE) return routeActions.push("/discover");

  sectionsVisible = false;
  discoverVisible = true;
  return modalActions.render(Discover, {
    keepNav: true, layoutOverride: ["background--light-secondary"],
  });
};

const sectionsActive = ({ path, modal }) => {
  if (process.env.NATIVE) return path === "/sections";
  return sectionsVisible && modal.visible;
};

const discoverActive = ({ path, modal }) => {
  if (process.env.NATIVE) return path === "/discover";
  return discoverVisible && modal.visible;
};

let homeLink = "/";
if (process.env.WEB) homeLink = "/give/now";
let links = {
  TOP: [
    {
      id: 1,
      label: "Home",
      link: homeLink,
      icon: "icon-logo",
      isActive: ({ path, modal }) => (path === homeLink && !modal.visible),
    },
    {
      id: 2,
      label: "Sections",
      action: sectionsAction,
      icon: "icon-sections",
      isActive: sectionsActive,
    },
    {
      id: 3,
      label: "Groups",
      link: "/groups/finder",
      icon: "icon-groups",
      isActive: ({ path, modal }) => (path === "/groups/finder" && !modal.visible),
    },
    {
      id: 4,
      label: "Discover",
      action: discoverAction,
      icon: "icon-search",
      isActive: discoverActive,
    },
    {
      id: 5,
      label: "Profile",
      link: profileLink,
      icon: "icon-profile",
      isActive: ({ path, modal }) => (path === profileLink && !modal.visible),
    },
  ],
  CONTENT: [
    { id: 1, action: back, icon: "icon-arrow-back" },
    // { id: 2, action: showSections, icon:"icon-sections" },
    { id: 2, action: false, icon: "icon-like", activeIcon: "icon-like-solid", isActive: props => props.liked },
    { id: 3, action: shareActions.share, icon: "icon-share" },
  ],
  BASIC_CONTENT: [
    { id: 1, action: back, icon: "icon-arrow-back" },
  ],
  MODAL: [
    { id: 1, action: modalActions.hide, icon: "icon-close" },
  ],
  DOWN: [
    { id: 1, action: modalActions.hide, icon: "icon-arrow-down" },
  ],
};

// use basic nav for web right now
if (process.env.WEB) {
  links = {
    TOP: links.TOP,
    CONTENT: links.TOP,
    BASIC_CONTENT: links.TOP,
    MODAL: links.MODAL,
    DOWN: links.DOWN,
  };
}

const initial = {
  level: "TOP",
  visible: true,
  links: links.TOP,
  bgColor: "#202020",
  fgColor: "dark",
  // bgColor: "#e7e7e7",
  // fgColor: "light",
};

export default function nav(state = initial, action) {
  switch (action.type) {
    case "NAV.SET_LEVEL":
      return { ...state, ...{
        level: action.level,
        links: links[action.level],
        bgColor: action.bgColor || initial.bgColor,
        fgColor: action.fgColor || initial.fgColor,
      } };
    case "NAV.SET_LINKS":
      return { ...state, ...{
        links: [...state.links, ...action.links],
      } };
    case "NAV.SET_COLOR":
      return { ...state, ...{
        bgColor: action.bgColor,
        fgColor: action.fgColor,
      } };
    case "NAV.RESET_COLOR":
      return { ...state, ...{
        bgColor: initial.bgColor,
        fgColor: initial.fgColor,
      } };
    case "NAV.SET_ACTION":

      const newLinks = [
        ...state.links.slice(0, action.props.id - 1),
        {
          ...state.links[action.props.id - 1],
          action: action.props.action,
        },
        ...state.links.slice(action.props.id),
      ];

      if (links[action.level]) {
        links[action.level] = newLinks;
      }

      return { ...state, ...{
        links: newLinks,
      } };
    case "NAV.SET_VISIBILITY":
      return { ...state, ...{
        visible: action.visible },
      };
    default:
      return state;
  }
}
<commit_msg>lint store nav reducer<commit_after>/*

  Navigation store

*/

import modalActions from "../modal";
import shareActions from "../share";
import Sections from "../../blocks/sections";
import Discover from "../../blocks/discover";

import { routeActions } from "../routing";

let sectionsVisible = false;
let discoverVisible = false;

const back = () => routeActions.goBack();
const profileLink = process.env.NATIVE ? "/profile" : "/profile/settings";

const sectionsAction = () => {
  if (process.env.NATIVE) return routeActions.push("/sections");

  discoverVisible = false;
  sectionsVisible = true;
  return modalActions.render(Sections, { keepNav: true });
};

const discoverAction = () => {
  if (process.env.NATIVE) return routeActions.push("/discover");

  sectionsVisible = false;
  discoverVisible = true;
  return modalActions.render(Discover, {
    keepNav: true, layoutOverride: ["background--light-secondary"],
  });
};

const sectionsActive = ({ path, modal }) => {
  if (process.env.NATIVE) return path === "/sections";
  return sectionsVisible && modal.visible;
};

const discoverActive = ({ path, modal }) => {
  if (process.env.NATIVE) return path === "/discover";
  return discoverVisible && modal.visible;
};

let homeLink = "/";
if (process.env.WEB) homeLink = "/give/now";
let links = {
  TOP: [
    {
      id: 1,
      label: "Home",
      link: homeLink,
      icon: "icon-logo",
      isActive: ({ path, modal }) => (path === homeLink && !modal.visible),
    },
    {
      id: 2,
      label: "Sections",
      action: sectionsAction,
      icon: "icon-sections",
      isActive: sectionsActive,
    },
    {
      id: 3,
      label: "Groups",
      link: "/groups/finder",
      icon: "icon-groups",
      isActive: ({ path, modal }) => (path === "/groups/finder" && !modal.visible),
    },
    {
      id: 4,
      label: "Discover",
      action: discoverAction,
      icon: "icon-search",
      isActive: discoverActive,
    },
    {
      id: 5,
      label: "Profile",
      link: profileLink,
      icon: "icon-profile",
      isActive: ({ path, modal }) => (path === profileLink && !modal.visible),
    },
  ],
  CONTENT: [
    { id: 1, action: back, icon: "icon-arrow-back" },
    // { id: 2, action: showSections, icon:"icon-sections" },
    {
      id: 2,
      action: false,
      icon: "icon-like",
      activeIcon: "icon-like-solid",
      isActive: props => props.liked,
    },
    { id: 3, action: shareActions.share, icon: "icon-share" },
  ],
  BASIC_CONTENT: [
    { id: 1, action: back, icon: "icon-arrow-back" },
  ],
  MODAL: [
    { id: 1, action: modalActions.hide, icon: "icon-close" },
  ],
  DOWN: [
    { id: 1, action: modalActions.hide, icon: "icon-arrow-down" },
  ],
};

// use basic nav for web right now
if (process.env.WEB) {
  links = {
    TOP: links.TOP,
    CONTENT: links.TOP,
    BASIC_CONTENT: links.TOP,
    MODAL: links.MODAL,
    DOWN: links.DOWN,
  };
}

const initial = {
  level: "TOP",
  visible: true,
  links: links.TOP,
  bgColor: "#202020",
  fgColor: "dark",
  // bgColor: "#e7e7e7",
  // fgColor: "light",
};

export default function nav(state = initial, action) {
  switch (action.type) {
    case "NAV.SET_LEVEL":
      return {
        ...state,
        ...{
          level: action.level,
          links: links[action.level],
          bgColor: action.bgColor || initial.bgColor,
          fgColor: action.fgColor || initial.fgColor,
        },
      };
    case "NAV.SET_LINKS":
      return {
        ...state,
        ...{
          links: [...state.links, ...action.links],
        },
      };
    case "NAV.SET_COLOR":
      return {
        ...state,
        ...{
          bgColor: action.bgColor,
          fgColor: action.fgColor,
        },
      };
    case "NAV.RESET_COLOR":
      return {
        ...state,
        ...{
          bgColor: initial.bgColor,
          fgColor: initial.fgColor,
        },
      };
    case "NAV.SET_ACTION": // eslint-disable-line no-case-declarations
      const newLinks = [
        ...state.links.slice(0, action.props.id - 1),
        {
          ...state.links[action.props.id - 1],
          action: action.props.action,
        },
        ...state.links.slice(action.props.id),
      ];

      if (links[action.level]) {
        links[action.level] = newLinks;
      }

      return {
        ...state,
        ...{
          links: newLinks,
        },
      };
    case "NAV.SET_VISIBILITY":
      return {
        ...state,
        ...{
          visible: action.visible,
        },
      };
    default:
      return state;
  }
}
<|endoftext|>


<commit_before>'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace ns
*/
var ns = {};

/**
* @name ArrayBuffer
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/buffer}
*/
setReadOnly( ns, 'ArrayBuffer', require( '@stdlib/array/buffer' ) );

/**
* @name arrayCtors
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/ctors}
*/
setReadOnly( ns, 'arrayCtors', require( '@stdlib/array/ctors' ) );

/**
* @name convertArray
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/convert}
*/
setReadOnly( ns, 'convertArray', require( '@stdlib/array/convert' ) );

/**
* @name arrayDataType
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/dtype}
*/
setReadOnly( ns, 'arrayDataType', require( '@stdlib/array/dtype' ) );

/**
* @name arrayDataTypes
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/dtypes}
*/
setReadOnly( ns, 'arrayDataTypes', require( '@stdlib/array/dtypes' ) );

/**
* @name Float32Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/float32}
*/
setReadOnly( ns, 'Float32Array', require( '@stdlib/array/float32' ) );

/**
* @name Float64Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/float64}
*/
setReadOnly( ns, 'Float64Array', require( '@stdlib/array/float64' ) );

/**
* @name Int16Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/int16}
*/
setReadOnly( ns, 'Int16Array', require( '@stdlib/array/int16' ) );

/**
* @name Int32Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/int32}
*/
setReadOnly( ns, 'Int32Array', require( '@stdlib/array/int32' ) );

/**
* @name Int8Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/int8}
*/
setReadOnly( ns, 'Int8Array', require( '@stdlib/array/int8' ) );

/**
* @name reviveTypedArray
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/reviver}
*/
setReadOnly( ns, 'reviveTypedArray', require( '@stdlib/array/reviver' ) );

/**
* @name SharedArrayBuffer
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/shared-buffer}
*/
setReadOnly( ns, 'SharedArrayBuffer', require( '@stdlib/array/shared-buffer' ) );

/**
* @name typedarray2json
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/to-json}
*/
setReadOnly( ns, 'typedarray2json', require( '@stdlib/array/to-json' ) );

/**
* @name typedarray
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/typed}
*/
setReadOnly( ns, 'typedarray', require( '@stdlib/array/typed' ) );

/**
* @name typedarrayCtors
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/typed-ctors}
*/
setReadOnly( ns, 'typedarrayCtors', require( '@stdlib/array/typed-ctors' ) );

/**
* @name typedarrayDataTypes
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/typed-dtypes}
*/
setReadOnly( ns, 'typedarrayDataTypes', require( '@stdlib/array/typed-dtypes' ) );

/**
* @name Uint16Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/uint16}
*/
setReadOnly( ns, 'Uint16Array', require( '@stdlib/array/uint16' ) );

/**
* @name Uint32Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/uint32}
*/
setReadOnly( ns, 'Uint32Array', require( '@stdlib/array/uint32' ) );

/**
* @name Uint8Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/uint8}
*/
setReadOnly( ns, 'Uint8Array', require( '@stdlib/array/uint8' ) );

/**
* @name Uint8ClampedArray
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/uint8c}
*/
setReadOnly( ns, 'Uint8ClampedArray', require( '@stdlib/array/uint8c' ) );

// EXPORTS //

module.exports = ns;
<commit_msg>Update namespace<commit_after>'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace ns
*/
var ns = {};

/**
* @name ArrayBuffer
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/buffer}
*/
setReadOnly( ns, 'ArrayBuffer', require( '@stdlib/array/buffer' ) );

/**
* @name arrayCtors
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/ctors}
*/
setReadOnly( ns, 'arrayCtors', require( '@stdlib/array/ctors' ) );

/**
* @name convertArray
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/convert}
*/
setReadOnly( ns, 'convertArray', require( '@stdlib/array/convert' ) );

/**
* @name convertArraySame
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/convert-same}
*/
setReadOnly( ns, 'convertArraySame', require( '@stdlib/array/convert-same' ) );

/**
* @name arrayDataType
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/dtype}
*/
setReadOnly( ns, 'arrayDataType', require( '@stdlib/array/dtype' ) );

/**
* @name arrayDataTypes
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/dtypes}
*/
setReadOnly( ns, 'arrayDataTypes', require( '@stdlib/array/dtypes' ) );

/**
* @name Float32Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/float32}
*/
setReadOnly( ns, 'Float32Array', require( '@stdlib/array/float32' ) );

/**
* @name Float64Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/float64}
*/
setReadOnly( ns, 'Float64Array', require( '@stdlib/array/float64' ) );

/**
* @name Int16Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/int16}
*/
setReadOnly( ns, 'Int16Array', require( '@stdlib/array/int16' ) );

/**
* @name Int32Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/int32}
*/
setReadOnly( ns, 'Int32Array', require( '@stdlib/array/int32' ) );

/**
* @name Int8Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/int8}
*/
setReadOnly( ns, 'Int8Array', require( '@stdlib/array/int8' ) );

/**
* @name reviveTypedArray
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/reviver}
*/
setReadOnly( ns, 'reviveTypedArray', require( '@stdlib/array/reviver' ) );

/**
* @name SharedArrayBuffer
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/shared-buffer}
*/
setReadOnly( ns, 'SharedArrayBuffer', require( '@stdlib/array/shared-buffer' ) );

/**
* @name typedarray2json
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/to-json}
*/
setReadOnly( ns, 'typedarray2json', require( '@stdlib/array/to-json' ) );

/**
* @name typedarray
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/typed}
*/
setReadOnly( ns, 'typedarray', require( '@stdlib/array/typed' ) );

/**
* @name typedarrayCtors
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/typed-ctors}
*/
setReadOnly( ns, 'typedarrayCtors', require( '@stdlib/array/typed-ctors' ) );

/**
* @name typedarrayDataTypes
* @memberof ns
* @readonly
* @type {Function}
* @see {@link module:@stdlib/array/typed-dtypes}
*/
setReadOnly( ns, 'typedarrayDataTypes', require( '@stdlib/array/typed-dtypes' ) );

/**
* @name Uint16Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/uint16}
*/
setReadOnly( ns, 'Uint16Array', require( '@stdlib/array/uint16' ) );

/**
* @name Uint32Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/uint32}
*/
setReadOnly( ns, 'Uint32Array', require( '@stdlib/array/uint32' ) );

/**
* @name Uint8Array
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/uint8}
*/
setReadOnly( ns, 'Uint8Array', require( '@stdlib/array/uint8' ) );

/**
* @name Uint8ClampedArray
* @memberof ns
* @readonly
* @constructor
* @see {@link module:@stdlib/array/uint8c}
*/
setReadOnly( ns, 'Uint8ClampedArray', require( '@stdlib/array/uint8c' ) );

// EXPORTS //

module.exports = ns;
<|endoftext|>