<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var App = require('app');
App.AddServiceController = App.WizardController.extend({

  name: 'addServiceController',

  totalSteps: 7,

  /**
   * Used for hiding back button in wizard
   */
  hideBackButton: true,

  /**
   * All wizards data will be stored in this variable
   *
   * cluster - cluster name
   * installOptions - ssh key, repo info, etc.
   * services - services list
   * hosts - list of selected hosts
   * slaveComponentHosts, - info about slave hosts
   * masterComponentHosts - info about master hosts
   * config??? - to be described later
   */
  content: Em.Object.create({
    cluster: null,
    hosts: null,
    installOptions: null,
    services: null,
    slaveComponentHosts: null,
    masterComponentHosts: null,
    serviceConfigProperties: null,
    advancedServiceConfig: null,
    controllerName: 'addServiceController',
    configGroups: [],
    clients: [],
    additionalClients: []
  }),

  setCurrentStep: function (currentStep, completed) {
    this._super(currentStep, completed);
    App.clusterStatus.setClusterStatus({
      wizardControllerName: this.get('name'),
      localdb: App.db.data
    });
  },

  /**
   * Load services data. Will be used at Select services(step4) step
   */
  loadServices: function () {
    var services = this.getDBProperty('services');
    if (!services) {
      services = {
        selectedServices: [],
        installedServices: []
      };
      App.StackService.find().forEach(function (item) {
        var isInstalled = App.Service.find().someProperty('id', item.get('serviceName'));
        item.set('isSelected', isInstalled);
        item.set('isInstalled', isInstalled);
        if (isInstalled) {
          services.selectedServices.push(item.get('serviceName'));
          services.installedServices.push(item.get('serviceName'));
        }
      }, this);
      this.setDBProperty('services', services);
    } else {
      App.StackService.find().forEach(function (item) {
        var isSelected = services.selectedServices.contains(item.get('serviceName'));
        var isInstalled = services.installedServices.contains(item.get('serviceName'));
        item.set('isSelected', isSelected);
        item.set('isInstalled', isInstalled);
      }, this);
      var isServiceWithSlave = App.StackService.find().filterProperty('isSelected').filterProperty('hasSlave').filterProperty('isInstalled', false).mapProperty('serviceName').length;
      var isServiceWithClient = App.StackService.find().filterProperty('isSelected').filterProperty('hasClient').filterProperty('isInstalled', false).mapProperty('serviceName').length;
      this.set('content.skipSlavesStep', !isServiceWithSlave && !isServiceWithClient);
      if (this.get('content.skipSlavesStep')) {
        this.get('isStepDisabled').findProperty('step', 3).set('value', this.get('content.skipSlavesStep'));
      }
    }
    this.set('content.services', App.StackService.find());
  },

  /**
   * Save data to model
   * @param stepController App.WizardStep4Controller
   */
  saveServices: function (stepController) {
    var services = {
      selectedServices: [],
      installedServices: []
    };
    var selectedServices = stepController.get('content').filterProperty('isSelected', true).filterProperty('isInstalled', false).mapProperty('serviceName');
    services.selectedServices.pushObjects(selectedServices);
    services.installedServices.pushObjects(stepController.get('content').filterProperty('isInstalled', true).mapProperty('serviceName'));
    this.setDBProperty('services', services);
    console.log('AddServiceController.saveServices: saved data', stepController.get('content'));

    this.set('content.selectedServiceNames', selectedServices);
    this.setDBProperty('selectedServiceNames', selectedServices);
    var isServiceWithSlave = stepController.get('content').filterProperty('isSelected').filterProperty('hasSlave').filterProperty('isInstalled', false).mapProperty('serviceName').length;
    var isServiceWithClient = App.StackService.find().filterProperty('isSelected').filterProperty('hasClient').filterProperty('isInstalled', false).mapProperty('serviceName').length;
    this.set('content.skipSlavesStep', !isServiceWithSlave && !isServiceWithClient);
    if (this.get('content.skipSlavesStep')) {
      this.get('isStepDisabled').findProperty('step', 3).set('value', this.get('content.skipSlavesStep'));
    }
  },

  /**
   * Save Master Component Hosts data to Main Controller
   * @param stepController App.WizardStep5Controller
   */
  saveMasterComponentHosts: function (stepController) {
    var obj = stepController.get('selectedServicesMasters');
    var masterComponentHosts = [];
    var installedComponents = App.HostComponent.find();

    obj.forEach(function (_component) {
      masterComponentHosts.push({
        display_name: _component.display_name,
        component: _component.component_name,
        hostName: _component.selectedHost,
        serviceId: _component.serviceId,
        isInstalled: installedComponents.someProperty('componentName', _component.component_name)
      });
    });

    console.log("AddServiceController.saveMasterComponentHosts: saved hosts ", masterComponentHosts);
    this.setDBProperty('masterComponentHosts', masterComponentHosts);
    this.set('content.masterComponentHosts', masterComponentHosts);

    this.set('content.skipMasterStep', this.get('content.masterComponentHosts').everyProperty('isInstalled', true));
    this.get('isStepDisabled').findProperty('step', 2).set('value', this.get('content.skipMasterStep'));
  },

  /**
   * Load master component hosts data for using in required step controllers
   */
  loadMasterComponentHosts: function () {
    this._super();
    this.set('content.skipMasterStep', this.get('content.masterComponentHosts').everyProperty('isInstalled', true));
    this.get('isStepDisabled').findProperty('step', 2).set('value', this.get('content.skipMasterStep'));
  },

  /**
   * Does service have any configs
   * @param {string} serviceName
   * @returns {boolean}
   */
  isServiceNotConfigurable: function (serviceName) {
    return App.get('services.noConfigTypes').contains(serviceName);
  },

  /**
   * Should Config Step be skipped (based on selected services list)
   * @returns {boolean}
   */
  skipConfigStep: function () {
    var skipConfigStep = true;
    var selectedServices = this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false).mapProperty('serviceName');
    selectedServices.map(function (serviceName) {
      skipConfigStep = skipConfigStep && this.isServiceNotConfigurable(serviceName);
    }, this);
    return skipConfigStep;
  },

  loadServiceConfigProperties: function () {
    this._super();
    if (!this.get('content.services')) {
      this.loadServices();
    }
    if (this.get('currentStep') > 1 && this.get('currentStep') < 6) {
      this.set('content.skipConfigStep', this.skipConfigStep());
      this.get('isStepDisabled').findProperty('step', 4).set('value', this.get('content.skipConfigStep'));
    }
  },

  saveServiceConfigProperties: function (stepController) {
    this._super(stepController);
    if (this.get('currentStep') > 1 && this.get('currentStep') < 6) {
      this.set('content.skipConfigStep', this.skipConfigStep());
      this.get('isStepDisabled').findProperty('step', 4).set('value', this.get('content.skipConfigStep'));
    }
  },

  /**
   * Load master component hosts data for using in required step controllers
   */
  loadSlaveComponentHosts: function () {
    var slaveComponentHosts = this.getDBProperty('slaveComponentHosts'),
      hosts = this.getDBProperty('hosts'),
      host_names = Em.keys(hosts);
    if (!Em.isNone(slaveComponentHosts)) {
      slaveComponentHosts.forEach(function (component) {
        component.hosts.forEach(function (host) {
          //Em.set(host, 'hostName', hosts[host.host_id].name);
          for (var i = 0; i < host_names.length; i++) {
            if (hosts[host_names[i]].id === host.host_id) {
              host.hostName = host_names[i];
              break;
            }
          }
        });
      });
    }
    if (!slaveComponentHosts) {
      slaveComponentHosts = this.getSlaveComponentHosts();
    }
    this.set("content.slaveComponentHosts", slaveComponentHosts);
    console.log("AddServiceController.loadSlaveComponentHosts: loaded hosts ", slaveComponentHosts);
  },

  /**
   * return slaveComponents bound to hosts
   * @return {Array}
   */
  getSlaveComponentHosts: function () {
    var components = this.get('slaveComponents');
    var result = [];
    var installedServices = App.Service.find().mapProperty('serviceName');
    var selectedServices = this.get('content.services').filterProperty('isSelected', true).mapProperty('serviceName');
    var installedComponentsMap = {};
    var uninstalledComponents = [];
    var hosts = this.get('content.hosts');

    components.forEach(function (component) {
      if (installedServices.contains(component.get('serviceName'))) {
        installedComponentsMap[component.get('componentName')] = [];
      } else if (selectedServices.contains(component.get('serviceName'))) {
        uninstalledComponents.push(component);
      }
    }, this);

    for (var hostName in hosts) {
      if (hosts[hostName].isInstalled) {
        hosts[hostName].hostComponents.forEach(function (component) {
          if (installedComponentsMap[component.HostRoles.component_name]) {
            installedComponentsMap[component.HostRoles.component_name].push(hostName);
          }
        }, this);
      }
    }

    for (var componentName in installedComponentsMap) {
      var component = {
        componentName: componentName,
        displayName: App.format.role(componentName),
        hosts: [],
        isInstalled: true
      };
      installedComponentsMap[componentName].forEach(function (hostName) {
        component.hosts.push({
          group: "Default",
          hostName: hostName,
          isInstalled: true
        });
      }, this);
      result.push(component);
    }

    uninstalledComponents.forEach(function (component) {
      var hosts = jQuery.extend(true, [], result.findProperty('componentName', 'DATANODE').hosts);
      hosts.setEach('isInstalled', false);
      result.push({
        componentName: component.get('componentName'),
        displayName: App.format.role(component.get('componentName')),
        hosts: hosts,
        isInstalled: false
      })
    });

    return result;
  },

  /**
   * Generate clients list for selected services and save it to model
   * @param stepController step4WizardController
   */
  saveClients: function (stepController) {
    var clients = [];
    var serviceComponents = App.StackServiceComponent.find();
    this.get('content.services').filterProperty('isSelected').filterProperty('isInstalled',false).forEach(function (_service) {
      var serviceClients = serviceComponents.filterProperty('serviceName', _service.get('serviceName')).filterProperty('isClient');
      serviceClients.forEach(function (client) {
        clients.push({
          component_name: client.get('componentName'),
          display_name: client.get('displayName'),
          isInstalled: false
        });
      }, this);
    }, this);

    this.setDBProperty('clientInfo', clients);
    this.set('content.clients', clients);
    console.log("AddServiceController.saveClients: saved list ", clients);
  },

  /**
   * Load data for all steps until current step
   */
  loadAllPriorSteps: function () {
    var step = this.get('currentStep');
    switch (step) {
      case '7':
      case '6':
      case '5':
        this.load('cluster');
        this.set('content.additionalClients', []);
      case '4':
        this.loadServiceConfigGroups();
        this.loadServiceConfigProperties();
      case '3':
        this.loadServices();
        this.loadClients();
        this.loadSlaveComponentHosts();//depends on loadServices
      case '2':
        this.loadMasterComponentHosts();
        this.load('hosts');
      case '1':
        this.loadServices();
    }
  },

  /**
   * Remove all loaded data.
   * Created as copy for App.router.clearAllSteps
   */
  clearAllSteps: function () {
    this.clearInstallOptions();
    // clear temporary information stored during the install
    this.set('content.cluster', this.getCluster());
  },

  /**
   * Clear all temporary data
   */
  finish: function () {
    this.clearAllSteps();
    this.clearStorageData();
    this.resetDbNamespace();
    App.router.get('updateController').updateAll();
  },

  installServices: function (callback) {
    this.set('content.cluster.oldRequestsId', []);
    this.installAdditionalClients();
    var selectedServices = this.get('content.services').filterProperty('isInstalled', false).filterProperty('isSelected', true).mapProperty('serviceName');
    var name = 'common.services.update';
    var data = {
      "context": Em.I18n.t('requestInfo.installServices'),
      "ServiceInfo": {"state": "INSTALLED"},
      "urlParams": "ServiceInfo/service_name.in(" + selectedServices.join(',')  + ")"
    };
    this.installServicesRequest(name, data, callback);
  },

  installServicesRequest: function (name, data, callback) {
    callback = callback || Em.K;
    App.ajax.send({
      name: name,
      sender: this,
      data: data,
      success: 'installServicesSuccessCallback',
      error: 'installServicesErrorCallback'
    }).then(callback, callback);
  },

  /**
   * installs clients before install new services
   * on host where some components require this
   * @method installAdditionalClients
   */
  installAdditionalClients: function () {
    this.get('content.additionalClients').forEach(function (c) {
      if (c.hostNames.length > 0) {
        var queryStr = 'HostRoles/component_name='+ c.componentName + '&HostRoles/host_name.in(' + c.hostNames.join() + ')';
        App.ajax.send({
          name: 'common.host_component.update',
          sender: this,
          data: {
            query: queryStr,
            context: 'Install ' + App.format.role(c.componentName),
            HostRoles: {
              state: 'INSTALLED'
            }
          }
        });
      }
    }, this);
  }
});
<commit_msg>AMBARI-7182. HDFS should be successfully added on storm+zk cluster. (jaimin)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var App = require('app');
App.AddServiceController = App.WizardController.extend({

  name: 'addServiceController',

  totalSteps: 7,

  /**
   * Used for hiding back button in wizard
   */
  hideBackButton: true,

  /**
   * All wizards data will be stored in this variable
   *
   * cluster - cluster name
   * installOptions - ssh key, repo info, etc.
   * services - services list
   * hosts - list of selected hosts
   * slaveComponentHosts, - info about slave hosts
   * masterComponentHosts - info about master hosts
   * config??? - to be described later
   */
  content: Em.Object.create({
    cluster: null,
    hosts: null,
    installOptions: null,
    services: null,
    slaveComponentHosts: null,
    masterComponentHosts: null,
    serviceConfigProperties: null,
    advancedServiceConfig: null,
    controllerName: 'addServiceController',
    configGroups: [],
    clients: [],
    additionalClients: []
  }),

  setCurrentStep: function (currentStep, completed) {
    this._super(currentStep, completed);
    App.clusterStatus.setClusterStatus({
      wizardControllerName: this.get('name'),
      localdb: App.db.data
    });
  },

  /**
   * Load services data. Will be used at Select services(step4) step
   */
  loadServices: function () {
    var services = this.getDBProperty('services');
    if (!services) {
      services = {
        selectedServices: [],
        installedServices: []
      };
      App.StackService.find().forEach(function (item) {
        var isInstalled = App.Service.find().someProperty('id', item.get('serviceName'));
        item.set('isSelected', isInstalled);
        item.set('isInstalled', isInstalled);
        if (isInstalled) {
          services.selectedServices.push(item.get('serviceName'));
          services.installedServices.push(item.get('serviceName'));
        }
      }, this);
      this.setDBProperty('services', services);
    } else {
      App.StackService.find().forEach(function (item) {
        var isSelected = services.selectedServices.contains(item.get('serviceName'));
        var isInstalled = services.installedServices.contains(item.get('serviceName'));
        item.set('isSelected', isSelected);
        item.set('isInstalled', isInstalled);
      }, this);
      var isServiceWithSlave = App.StackService.find().filterProperty('isSelected').filterProperty('hasSlave').filterProperty('isInstalled', false).mapProperty('serviceName').length;
      var isServiceWithClient = App.StackService.find().filterProperty('isSelected').filterProperty('hasClient').filterProperty('isInstalled', false).mapProperty('serviceName').length;
      this.set('content.skipSlavesStep', !isServiceWithSlave && !isServiceWithClient);
      if (this.get('content.skipSlavesStep')) {
        this.get('isStepDisabled').findProperty('step', 3).set('value', this.get('content.skipSlavesStep'));
      }
    }
    this.set('content.services', App.StackService.find());
  },

  /**
   * Save data to model
   * @param stepController App.WizardStep4Controller
   */
  saveServices: function (stepController) {
    var services = {
      selectedServices: [],
      installedServices: []
    };
    var selectedServices = stepController.get('content').filterProperty('isSelected', true).filterProperty('isInstalled', false).mapProperty('serviceName');
    services.selectedServices.pushObjects(selectedServices);
    services.installedServices.pushObjects(stepController.get('content').filterProperty('isInstalled', true).mapProperty('serviceName'));
    this.setDBProperty('services', services);
    console.log('AddServiceController.saveServices: saved data', stepController.get('content'));

    this.set('content.selectedServiceNames', selectedServices);
    this.setDBProperty('selectedServiceNames', selectedServices);
    var isServiceWithSlave = stepController.get('content').filterProperty('isSelected').filterProperty('hasSlave').filterProperty('isInstalled', false).mapProperty('serviceName').length;
    var isServiceWithClient = App.StackService.find().filterProperty('isSelected').filterProperty('hasClient').filterProperty('isInstalled', false).mapProperty('serviceName').length;
    this.set('content.skipSlavesStep', !isServiceWithSlave && !isServiceWithClient);
    if (this.get('content.skipSlavesStep')) {
      this.get('isStepDisabled').findProperty('step', 3).set('value', this.get('content.skipSlavesStep'));
    }
  },

  /**
   * Save Master Component Hosts data to Main Controller
   * @param stepController App.WizardStep5Controller
   */
  saveMasterComponentHosts: function (stepController) {
    var obj = stepController.get('selectedServicesMasters');
    var masterComponentHosts = [];
    var installedComponents = App.HostComponent.find();

    obj.forEach(function (_component) {
      masterComponentHosts.push({
        display_name: _component.display_name,
        component: _component.component_name,
        hostName: _component.selectedHost,
        serviceId: _component.serviceId,
        isInstalled: installedComponents.someProperty('componentName', _component.component_name)
      });
    });

    console.log("AddServiceController.saveMasterComponentHosts: saved hosts ", masterComponentHosts);
    this.setDBProperty('masterComponentHosts', masterComponentHosts);
    this.set('content.masterComponentHosts', masterComponentHosts);

    this.set('content.skipMasterStep', this.get('content.masterComponentHosts').everyProperty('isInstalled', true));
    this.get('isStepDisabled').findProperty('step', 2).set('value', this.get('content.skipMasterStep'));
  },

  /**
   * Load master component hosts data for using in required step controllers
   */
  loadMasterComponentHosts: function () {
    this._super();
    this.set('content.skipMasterStep', this.get('content.masterComponentHosts').everyProperty('isInstalled', true));
    this.get('isStepDisabled').findProperty('step', 2).set('value', this.get('content.skipMasterStep'));
  },

  /**
   * Does service have any configs
   * @param {string} serviceName
   * @returns {boolean}
   */
  isServiceNotConfigurable: function (serviceName) {
    return App.get('services.noConfigTypes').contains(serviceName);
  },

  /**
   * Should Config Step be skipped (based on selected services list)
   * @returns {boolean}
   */
  skipConfigStep: function () {
    var skipConfigStep = true;
    var selectedServices = this.get('content.services').filterProperty('isSelected', true).filterProperty('isInstalled', false).mapProperty('serviceName');
    selectedServices.map(function (serviceName) {
      skipConfigStep = skipConfigStep && this.isServiceNotConfigurable(serviceName);
    }, this);
    return skipConfigStep;
  },

  loadServiceConfigProperties: function () {
    this._super();
    if (!this.get('content.services')) {
      this.loadServices();
    }
    if (this.get('currentStep') > 1 && this.get('currentStep') < 6) {
      this.set('content.skipConfigStep', this.skipConfigStep());
      this.get('isStepDisabled').findProperty('step', 4).set('value', this.get('content.skipConfigStep'));
    }
  },

  saveServiceConfigProperties: function (stepController) {
    this._super(stepController);
    if (this.get('currentStep') > 1 && this.get('currentStep') < 6) {
      this.set('content.skipConfigStep', this.skipConfigStep());
      this.get('isStepDisabled').findProperty('step', 4).set('value', this.get('content.skipConfigStep'));
    }
  },

  /**
   * Load master component hosts data for using in required step controllers
   */
  loadSlaveComponentHosts: function () {
    var slaveComponentHosts = this.getDBProperty('slaveComponentHosts'),
      hosts = this.getDBProperty('hosts'),
      host_names = Em.keys(hosts);
    if (!Em.isNone(slaveComponentHosts)) {
      slaveComponentHosts.forEach(function (component) {
        component.hosts.forEach(function (host) {
          //Em.set(host, 'hostName', hosts[host.host_id].name);
          for (var i = 0; i < host_names.length; i++) {
            if (hosts[host_names[i]].id === host.host_id) {
              host.hostName = host_names[i];
              break;
            }
          }
        });
      });
    }
    if (!slaveComponentHosts) {
      slaveComponentHosts = this.getSlaveComponentHosts();
    }
    this.set("content.slaveComponentHosts", slaveComponentHosts);
    console.log("AddServiceController.loadSlaveComponentHosts: loaded hosts ", slaveComponentHosts);
  },

  /**
   * return slaveComponents bound to hosts
   * @return {Array}
   */
  getSlaveComponentHosts: function () {
    var components = this.get('slaveComponents');
    var result = [];
    var installedServices = App.Service.find().mapProperty('serviceName');
    var selectedServices = this.get('content.services').filterProperty('isSelected', true).mapProperty('serviceName');
    var installedComponentsMap = {};
    var uninstalledComponents = [];
    var hosts = this.get('content.hosts');
    var masterComponents = App.get('components.masters');
    var nonMasterComponentHosts = [];

    components.forEach(function (component) {
      if (installedServices.contains(component.get('serviceName'))) {
        installedComponentsMap[component.get('componentName')] = [];
      } else if (selectedServices.contains(component.get('serviceName'))) {
        uninstalledComponents.push(component);
      }
    }, this);

    for (var hostName in hosts) {
      if (hosts[hostName].isInstalled) {
        var isMasterComponentHosted = false;
        hosts[hostName].hostComponents.forEach(function (component) {
          if (installedComponentsMap[component.HostRoles.component_name]) {
            installedComponentsMap[component.HostRoles.component_name].push(hostName);
          }
          if (masterComponents.contains(component.HostRoles.component_name)) {
            isMasterComponentHosted = true;
          }
        }, this);
        if (!isMasterComponentHosted) {
          nonMasterComponentHosts.push(hostName);
        }
      }
    }

    for (var componentName in installedComponentsMap) {
      var component = {
        componentName: componentName,
        displayName: App.format.role(componentName),
        hosts: [],
        isInstalled: true
      };
      installedComponentsMap[componentName].forEach(function (hostName) {
        component.hosts.push({
          group: "Default",
          hostName: hostName,
          isInstalled: true
        });
      }, this);
      result.push(component);
    }

    if (!nonMasterComponentHosts.length) {
      nonMasterComponentHosts.push(Object.keys(this.get('content.hosts'))[0]);
    }
    var uninstalledComponentHosts =  nonMasterComponentHosts.map(function(_hostName){
      return {
        group: "Default",
        hostName: _hostName,
        isInstalled: false
      }
    });
    uninstalledComponents.forEach(function (component) {
      result.push({
        componentName: component.get('componentName'),
        displayName: App.format.role(component.get('componentName')),
        hosts: uninstalledComponentHosts,
        isInstalled: false
      })
    });

    return result;
  },

  /**
   * Generate clients list for selected services and save it to model
   * @param stepController step4WizardController
   */
  saveClients: function (stepController) {
    var clients = [];
    var serviceComponents = App.StackServiceComponent.find();
    this.get('content.services').filterProperty('isSelected').filterProperty('isInstalled',false).forEach(function (_service) {
      var serviceClients = serviceComponents.filterProperty('serviceName', _service.get('serviceName')).filterProperty('isClient');
      serviceClients.forEach(function (client) {
        clients.push({
          component_name: client.get('componentName'),
          display_name: client.get('displayName'),
          isInstalled: false
        });
      }, this);
    }, this);

    this.setDBProperty('clientInfo', clients);
    this.set('content.clients', clients);
    console.log("AddServiceController.saveClients: saved list ", clients);
  },

  /**
   * Load data for all steps until current step
   */
  loadAllPriorSteps: function () {
    var step = this.get('currentStep');
    switch (step) {
      case '7':
      case '6':
      case '5':
        this.load('cluster');
        this.set('content.additionalClients', []);
      case '4':
        this.loadServiceConfigGroups();
        this.loadServiceConfigProperties();
      case '3':
        this.loadServices();
        this.loadClients();
        this.loadSlaveComponentHosts();//depends on loadServices
      case '2':
        this.loadMasterComponentHosts();
        this.load('hosts');
      case '1':
        this.loadServices();
    }
  },

  /**
   * Remove all loaded data.
   * Created as copy for App.router.clearAllSteps
   */
  clearAllSteps: function () {
    this.clearInstallOptions();
    // clear temporary information stored during the install
    this.set('content.cluster', this.getCluster());
  },

  /**
   * Clear all temporary data
   */
  finish: function () {
    this.clearAllSteps();
    this.clearStorageData();
    this.resetDbNamespace();
    App.router.get('updateController').updateAll();
  },

  installServices: function (callback) {
    this.set('content.cluster.oldRequestsId', []);
    this.installAdditionalClients();
    var selectedServices = this.get('content.services').filterProperty('isInstalled', false).filterProperty('isSelected', true).mapProperty('serviceName');
    var name = 'common.services.update';
    var data = {
      "context": Em.I18n.t('requestInfo.installServices'),
      "ServiceInfo": {"state": "INSTALLED"},
      "urlParams": "ServiceInfo/service_name.in(" + selectedServices.join(',')  + ")"
    };
    this.installServicesRequest(name, data, callback);
  },

  installServicesRequest: function (name, data, callback) {
    callback = callback || Em.K;
    App.ajax.send({
      name: name,
      sender: this,
      data: data,
      success: 'installServicesSuccessCallback',
      error: 'installServicesErrorCallback'
    }).then(callback, callback);
  },

  /**
   * installs clients before install new services
   * on host where some components require this
   * @method installAdditionalClients
   */
  installAdditionalClients: function () {
    this.get('content.additionalClients').forEach(function (c) {
      if (c.hostNames.length > 0) {
        var queryStr = 'HostRoles/component_name='+ c.componentName + '&HostRoles/host_name.in(' + c.hostNames.join() + ')';
        App.ajax.send({
          name: 'common.host_component.update',
          sender: this,
          data: {
            query: queryStr,
            context: 'Install ' + App.format.role(c.componentName),
            HostRoles: {
              state: 'INSTALLED'
            }
          }
        });
      }
    }, this);
  }
});
<|endoftext|>


<commit_before>// Get Programming with JavaScript
// Listings 13.03 and 13.04
// Picking a question at random
// Uses the number generator module

var getQuiz = function () {
  var qIndex = 0;

  var questions = [
    { question: "7 x 8", answer: "56" },
    { question: "12 x 12", answer: "144" },
    { question: "5 x 6", answer: "30" },
    { question: "9 x 3", answer: "27" }
  ];

  var getQuestion = function () {
    qIndex = between(0, questions.length - 1);
    return questions[qIndex].question;
  };

  var checkAnswer = function (userAnswer) {
    if (userAnswer === questions[qIndex].answer) {
      return "Correct!";
    } else {
      return "No, the answer is " + questions[qIndex].answer;
    }
  };

  return {
    quizMe: getQuestion,
    submit: checkAnswer
  };
};

var quiz = getQuiz();

/* Further Adventures
 *
 * 1) Run the program.
 *
 * 2) Take the quiz, using the quiz.quizMe and
 *    quiz.submit methods.
 *
 *    > quiz.quizMe()
 *      What is the highest mountain in the world?
 *    > quiz.submit("K2")
 *
 * 3) Add some more questions and answers, run the
 *    program and take the quiz again.
 *
 * 4) Update the program so that it keeps
 *    a score of correct answers.
 *
 * 5) Define a showScore function that displays
 *    the current score.
 *
 */<commit_msg>Update quizMe and submit example<commit_after>// Get Programming with JavaScript
// Listings 13.03 and 13.04
// Picking a question at random
// Uses the number generator module

var getQuiz = function () {
  var qIndex = 0;

  var questions = [
    { question: "7 x 8", answer: "56" },
    { question: "12 x 12", answer: "144" },
    { question: "5 x 6", answer: "30" },
    { question: "9 x 3", answer: "27" }
  ];

  var getQuestion = function () {
    qIndex = between(0, questions.length - 1);
    return questions[qIndex].question;
  };

  var checkAnswer = function (userAnswer) {
    if (userAnswer === questions[qIndex].answer) {
      return "Correct!";
    } else {
      return "No, the answer is " + questions[qIndex].answer;
    }
  };

  return {
    quizMe: getQuestion,
    submit: checkAnswer
  };
};

var quiz = getQuiz();

/* Further Adventures
 *
 * 1) Run the program.
 *
 * 2) Take the quiz, using the quiz.quizMe and
 *    quiz.submit methods.
 *
 *    > quiz.quizMe()
 *      12 x 12
 *    > quiz.submit("144")
 *
 * 3) Add some more questions and answers, run the
 *    program and take the quiz again.
 *
 * 4) Update the program so that it keeps
 *    a score of correct answers.
 *
 * 5) Define a showScore function that displays
 *    the current score.
 *
 */
<|endoftext|>


<commit_before>

/**
 * Float a number of things up on a page (hearts, flowers, 👌 ...)
 * @param {object}  options  all of the options are in an object
 * ---
 * @param {string}  content  the character or string to float
 * @param {int}     number   the number of items
 * @param {int}     duration the amount of seconds it takes to float up (default 10s)
 * @param {int}     repeat   the number of times you want the animation to repeat (default: 'infinite')
 * @author Haroen Viaene <hello@haroen.me>
 */
(function(root, factory) {
  'use strict';

  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], function() {
      return (root.pagesearch = factory());
    });
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory();
  } else {
    // Browser globals
    root.pagesearch = factory();
  }
})(this, function() {
  // UMD Definition above, do not remove this line

  // To get to know more about the Universal Module Definition
  // visit: https://github.com/umdjs/umd

  'use strict';

  /**
   * search for dom elements on your page
   * @param  {object} options
   * options: {
   *  input: 'input[type=search]',
   *  find: '.results article',
   *  parents: 0
   *}
   */
  var pagesearch = function(options) {
    window.addEventListener('DOMContentLoaded',function(){
      options.parents = options.parents || 0;
      options.input = options.input || 'input[type=search]';
      var search = document.querySelector(options.input);
      var elements = document.querySelectorAll(options.find);

      search.addEventListener('input',function(){
        for (var i = 0; i < elements.length; i++) {
          var searchString = search.value.toLowerCase();
          if (elements[i].textContent.toLowerCase().indexOf(searchString) === -1) {
            elements[i].classList.add('hidden');
          } else {
            elements[i].classList.remove('hidden');
          }
        };
      });
    });
  };

  return pagesearch;

});
<commit_msg>remove wrongly copied things<commit_after>(function(root, factory) {
  'use strict';

  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], function() {
      return (root.pagesearch = factory());
    });
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory();
  } else {
    // Browser globals
    root.pagesearch = factory();
  }
})(this, function() {
  // UMD Definition above, do not remove this line

  // To get to know more about the Universal Module Definition
  // visit: https://github.com/umdjs/umd

  'use strict';

  /**
   * search for dom elements on your page
   * @param  {object} options
   * options: {
   *  input: 'input[type=search]',
   *  find: '.results article',
   *  parents: 0
   *}
   */
  var pagesearch = function(options) {
    window.addEventListener('DOMContentLoaded',function(){
      options.parents = options.parents || 0;
      options.input = options.input || 'input[type=search]';
      var search = document.querySelector(options.input);
      var elements = document.querySelectorAll(options.find);

      search.addEventListener('input',function(){
        for (var i = 0; i < elements.length; i++) {
          var searchString = search.value.toLowerCase();
          if (elements[i].textContent.toLowerCase().indexOf(searchString) === -1) {
            elements[i].classList.add('hidden');
          } else {
            elements[i].classList.remove('hidden');
          }
        };
      });
    });
  };

  return pagesearch;

});
<|endoftext|>


<commit_before>"use strict";

class Pagination{

	constructor(el, options = {}){
		this.el     = el;
		this.pages  = [];

		this.length = options.length || 20;
		this.active = options.active || 0;
	}

	createLink(index){
		let result = New("a", {
			textContent: index + 1,
			href: "#"
		});

		result.addEventListener()

		return result;
	}

	get length(){ return this._length || 0 }
	set length(input){
		input = +input;
		if(input < 1) input = 1;
		if(input !== this._length){

			/** We need more link elements */
			let numPages = this.pages.length;
			if(input > numPages){
				for(let i = numPages; i < input; ++i){
					let link = this.createLink(i);
					this.pages.push(this.el.appendChild(link));
				}
			}

			this._length = input;
		}
	}

	get active(){ return this._active || 0 }
	set active(input){
		input = +input;

		/** Ensure input falls within valid range */
		let l = this.length;
		if(input < 0)       input = 0;
		else if(input >= l) input = l - 1;

		if(input !== this._active){
			let link = this.pages[this._active];
			link && link.classList.remove("active");

			this._active = input;

			(link = this.pages[input]) && link.classList.add("active")
		}
	}
}
<commit_msg>Add logic for updating length of links list<commit_after>"use strict";

class Pagination{

	constructor(el, options = {}){
		this._length = 0;
		this.pages   = [];

		this.el      = el;
		this.length  = options.length || 20;
		this.active  = options.active || 10;
	}

	createLink(index){
		let result = New("a", {
			textContent: index,
			href: "#"
		});

		result.addEventListener(pressEvent, e => {
			this.active = index;
			e.preventDefault();
			return false;
		});

		return result;
	}

	get length(){ return this._length || 0 }
	set length(input){
		input = +input;
		if(input < 1) input = 1;
		if(input !== this._length){

			/** We're extending the current page range */
			if(input > this._length)
				for(let i = this._length; i < input; ++i){
					let link = this.pages[i];
					link || this.pages.push(link = this.createLink(i));
					this.el.appendChild(link);
				}

			/** Shrinking the page range */
			else{

				/** The currently active index exceeds the new bounds. Cap it. */
				if(input <= this._active)
					this.active = input - 1;

				for(let i = this._length - 1; i >= input; --i){
					let link = this.pages[i];
					if(link.parentNode)
						link.parentNode.removeChild(link);
				}
			}

			this._length = input;
		}
	}

	get active(){ return this._active || 0 }
	set active(input){
		input = +input;

		/** Ensure input falls within valid range */
		let l = this.length;
		if(input < 0)       input = 0;
		else if(input >= l) input = l - 1;

		if(input !== this._active){
			let link = this.pages[this._active];
			link && link.classList.remove("active");

			this._active = input;

			(link = this.pages[input]) && link.classList.add("active")
		}
	}
}
<|endoftext|>


<commit_before>var fs = require('fs')
var path = require('path')
var Feed = require('feed')
var Remarkable = require('remarkable')
var highlighter = require('highlight.js')

var marked = new Remarkable({
	html: true,
	linkify: true,
	highlight: function (code) {
		return highlighter.highlightAuto(code).value
	}
})

var sluglify = function (str) {
	str = str.replace(/^\s+|\s+$/g, '') // trim
	str = str.toLowerCase()

	// remove accents, swap ñ for n, and other invalid chars
	var invChar = 'àáäâèéëêìíïîòóöôùúüûñç·/_,:;'
	var invCharTo = 'aaaaeeeeiiiioooouuuunc------'

	for (var i = 0, l = invChar.length; i < l; i++) {
		str = str.replace(new RegExp(invChar.charAt(i), 'g'), invCharTo.charAt(i))
	}

	str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
		.replace(/\s+/g, '-') // collapse whitespace and replace by -
		.replace(/-+/g, '-') // collapse dashes

	return str
}

var Paperpress = function (config) {
	var self = this
	if (config === undefined) {
		config = {}
	}
	this.baseDirectory = config.baseDirectory || 'static'
	this.uriPrefix = config.uriPrefix
	this.pathBuilder = config.pathBuilder || function (item, collectionName) {
		var path = '/' + collectionName + '/' + item.slug
		if (self.uriPrefix) {
			path = this.uriPrefix + path
		}

		return path
	}

	this.items = []
	this.paths = []
	this._hooks = config.hooks || []
}

/**
**************************************
********** Private Functions *********
**************************************
**/
Paperpress.prototype._getCollections = function () {
	try {
		var collections = fs.readdirSync(this.baseDirectory).filter((collection) => {
			var path = this.baseDirectory + '/' + collection
			var stats = fs.statSync(path)

			return stats.isDirectory()
		})
		return collections
	} catch (e) {
		console.error('[Paperpress] ERROR - Can\'t read directory:', this.baseDirectory)
		return null
	}
}

Paperpress.prototype._titleToSlug = function (title) {
	return sluglify(title)
}

Paperpress.prototype._directoryToItem = function (directory) {
	var item = JSON.parse(fs.readFileSync(directory.path + '/info.json').toString())

	if (!item.title) {
		console.warn('[Paperpress] item ' + directory.path + ' without title')
		return
	}

	if (!item.date) {
		console.warn('[Paperpress] item ' + directory.path + ' without date')
		return
	}

	item.slug = this._titleToSlug((item.slug === undefined) ? item.title : item.slug)

	item.path = item.path || this.pathBuilder(item, directory.collectionName)
	item.date = new Date(item.date)
	this.paths.push(item.path)

	if (item.contentType === 'html') {
		item.content = fs.readFileSync(directory.path + '/content.html').toString()
	} else {
		var content = fs.readFileSync(directory.path + '/content.md').toString()
		item.content = marked.render(content)
	}

	return item
}

Paperpress.prototype._fileToItem = function (file) {
	var fileContent = fs.readFileSync(file.path).toString()
	var fileType = (path.extname(file.path) === '.md') ? '.md' : '.html'
	var name = file.name.replace(fileType, '')
	var slug = this._titleToSlug(name)

	var item = {
		title: name,
		slug: slug
	}

	item.path = this.pathBuilder(item, file.collectionName)
	item.content = (fileType === '.md') ? marked.render(fileContent) : fileContent
	this.paths.push(item.path)

	return item
}

Paperpress.prototype._getDuplicatePaths = function () {
	var paths = this.paths.slice()
	var duplicatePaths = []

	paths.sort().forEach(function (item, i) {
		if (paths[i + 1] === item) {
			duplicatePaths.push(item)
		}
	})

	return duplicatePaths
}

Paperpress.prototype._loadCollection = function (collectionName) {
	var self = this

	self.items = self.items.filter(function (item) {
		return item.type !== collectionName
	})

	fs.readdirSync(this.baseDirectory + '/' + collectionName).forEach(function (itemName) {
		var path = self.baseDirectory + '/' + collectionName + '/' + itemName
		var stats = fs.statSync(path)

		if (itemName.indexOf('.') === 0) { return }

		var item
		if (stats.isDirectory()) {
			item = self._directoryToItem({
				path: path,
				stats: stats,
				collectionName: collectionName
			})
		} else {
			item = self._fileToItem({
				name: itemName,
				path: path,
				collectionName: collectionName
			})
		}

		if (item) {
			item.type = collectionName
			self._hooks.forEach(function (fn) {
				fn(item)
			})

			self.items.push(item)
		}
	})
}

Paperpress.prototype._sortByDate = function (items) {
	return items.sort(function (a, b) {
		return new Date(a.date).getTime() - new Date(b.date).getTime() <= 0 ? 1 : -1
	})
}

/**
**************************************
********** Public Functions **********
**************************************
**/
Paperpress.prototype.getCollection = function (collectionName) {
	var collection = this.items.filter((item) => {
		return item.type === collectionName
	})

	return this._sortByDate(collection)
}

Paperpress.prototype.getCollections = function (collectionsName) {
	var collection = this.items.filter((item) => {
		return collectionsName.indexOf(item.type) >= 0
	})

	return this._sortByDate(collection)
}

Paperpress.prototype.load = function () {
	var collections = this._getCollections()
	try {
		collections.forEach((collection) => {
			this._loadCollection(collection)
		})
	} catch (e) {
		console.error('[Paperpress] ERROR on load', e.message)
		return null
	}

	var duplicatePaths = this._getDuplicatePaths()
	if (duplicatePaths.length > 0) {
		console.warn('[Paperpress] Duplicated paths:', duplicatePaths)
	}

	return true
}

Paperpress.prototype.addHook = function (hook) {
	this._hooks.push(hook)
}

/**
**************************************
********** Helpers Functions *********
**************************************
**/
Paperpress.helpers = {}
Paperpress.helpers.createFeed = function (description, items) {
	// Create the Feed instance
	try {
		var feed = new Feed(description)
	} catch (e) {
		console.error('[Paperpress] ERROR - Feed. Can\'t create the feed check the description object')
		return null
	}

	// Load the items on the feed
	try {
		items.forEach(function (item) {
			item.link = description.link + item.path
			item.date = new Date(item.date)

			feed.addItem(item)
		})
	} catch (e) {
		console.error('[Paperpress] ERROR - Feed. Undefined array for items')
		return null
	}

	// Test if there is no error with the feed render function
	try {
		feed.render()
	} catch (e) {
		console.error('[Paperpress] ERROR - Feed', e)
		return null
	}

	return feed
}

exports.Paperpress = Paperpress
<commit_msg>Remove arrow functions to pass Travis w/ Nodev0.12<commit_after>var fs = require('fs')
var path = require('path')
var Feed = require('feed')
var Remarkable = require('remarkable')
var highlighter = require('highlight.js')

var marked = new Remarkable({
	html: true,
	linkify: true,
	highlight: function (code) {
		return highlighter.highlightAuto(code).value
	}
})

var sluglify = function (str) {
	str = str.replace(/^\s+|\s+$/g, '') // trim
	str = str.toLowerCase()

	// remove accents, swap ñ for n, and other invalid chars
	var invChar = 'àáäâèéëêìíïîòóöôùúüûñç·/_,:;'
	var invCharTo = 'aaaaeeeeiiiioooouuuunc------'

	for (var i = 0, l = invChar.length; i < l; i++) {
		str = str.replace(new RegExp(invChar.charAt(i), 'g'), invCharTo.charAt(i))
	}

	str = str.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
		.replace(/\s+/g, '-') // collapse whitespace and replace by -
		.replace(/-+/g, '-') // collapse dashes

	return str
}

var Paperpress = function (config) {
	var self = this
	if (config === undefined) {
		config = {}
	}
	this.baseDirectory = config.baseDirectory || 'static'
	this.uriPrefix = config.uriPrefix
	this.pathBuilder = config.pathBuilder || function (item, collectionName) {
		var path = '/' + collectionName + '/' + item.slug
		if (self.uriPrefix) {
			path = this.uriPrefix + path
		}

		return path
	}

	this.items = []
	this.paths = []
	this._hooks = config.hooks || []
}

/**
**************************************
********** Private Functions *********
**************************************
**/
Paperpress.prototype._getCollections = function () {
	var that = this
	try {
		var collections = fs.readdirSync(this.baseDirectory).filter(function (collection) {
			var path = that.baseDirectory + '/' + collection
			var stats = fs.statSync(path)

			return stats.isDirectory()
		})
		return collections
	} catch (e) {
		console.error('[Paperpress] ERROR - Can\'t read directory:', this.baseDirectory)
		return null
	}
}

Paperpress.prototype._titleToSlug = function (title) {
	return sluglify(title)
}

Paperpress.prototype._directoryToItem = function (directory) {
	var item = JSON.parse(fs.readFileSync(directory.path + '/info.json').toString())

	if (!item.title) {
		console.warn('[Paperpress] item ' + directory.path + ' without title')
		return
	}

	if (!item.date) {
		console.warn('[Paperpress] item ' + directory.path + ' without date')
		return
	}

	item.slug = this._titleToSlug((item.slug === undefined) ? item.title : item.slug)

	item.path = item.path || this.pathBuilder(item, directory.collectionName)
	item.date = new Date(item.date)
	this.paths.push(item.path)

	if (item.contentType === 'html') {
		item.content = fs.readFileSync(directory.path + '/content.html').toString()
	} else {
		var content = fs.readFileSync(directory.path + '/content.md').toString()
		item.content = marked.render(content)
	}

	return item
}

Paperpress.prototype._fileToItem = function (file) {
	var fileContent = fs.readFileSync(file.path).toString()
	var fileType = (path.extname(file.path) === '.md') ? '.md' : '.html'
	var name = file.name.replace(fileType, '')
	var slug = this._titleToSlug(name)

	var item = {
		title: name,
		slug: slug
	}

	item.path = this.pathBuilder(item, file.collectionName)
	item.content = (fileType === '.md') ? marked.render(fileContent) : fileContent
	this.paths.push(item.path)

	return item
}

Paperpress.prototype._getDuplicatePaths = function () {
	var paths = this.paths.slice()
	var duplicatePaths = []

	paths.sort().forEach(function (item, i) {
		if (paths[i + 1] === item) {
			duplicatePaths.push(item)
		}
	})

	return duplicatePaths
}

Paperpress.prototype._loadCollection = function (collectionName) {
	var self = this

	self.items = self.items.filter(function (item) {
		return item.type !== collectionName
	})

	fs.readdirSync(this.baseDirectory + '/' + collectionName).forEach(function (itemName) {
		var path = self.baseDirectory + '/' + collectionName + '/' + itemName
		var stats = fs.statSync(path)

		if (itemName.indexOf('.') === 0) { return }

		var item
		if (stats.isDirectory()) {
			item = self._directoryToItem({
				path: path,
				stats: stats,
				collectionName: collectionName
			})
		} else {
			item = self._fileToItem({
				name: itemName,
				path: path,
				collectionName: collectionName
			})
		}

		if (item) {
			item.type = collectionName
			self._hooks.forEach(function (fn) {
				fn(item)
			})

			self.items.push(item)
		}
	})
}

Paperpress.prototype._sortByDate = function (items) {
	return items.sort(function (a, b) {
		return new Date(a.date).getTime() - new Date(b.date).getTime() <= 0 ? 1 : -1
	})
}

/**
**************************************
********** Public Functions **********
**************************************
**/
Paperpress.prototype.getCollection = function (collectionName) {
	var collection = this.items.filter(function (item) {
		return item.type === collectionName
	})

	return this._sortByDate(collection)
}

Paperpress.prototype.getCollections = function (collectionsName) {
	var collection = this.items.filter(function (item) {
		return collectionsName.indexOf(item.type) >= 0
	})

	return this._sortByDate(collection)
}

Paperpress.prototype.load = function () {
	var that = this
	var collections = this._getCollections()
	try {
		collections.forEach(function (collection) {
			that._loadCollection(collection)
		})
	} catch (e) {
		console.error('[Paperpress] ERROR on load', e.message)
		return null
	}

	var duplicatePaths = this._getDuplicatePaths()
	if (duplicatePaths.length > 0) {
		console.warn('[Paperpress] Duplicated paths:', duplicatePaths)
	}

	return true
}

Paperpress.prototype.addHook = function (hook) {
	this._hooks.push(hook)
}

/**
**************************************
********** Helpers Functions *********
**************************************
**/
Paperpress.helpers = {}
Paperpress.helpers.createFeed = function (description, items) {
	// Create the Feed instance
	try {
		var feed = new Feed(description)
	} catch (e) {
		console.error('[Paperpress] ERROR - Feed. Can\'t create the feed check the description object')
		return null
	}

	// Load the items on the feed
	try {
		items.forEach(function (item) {
			item.link = description.link + item.path
			item.date = new Date(item.date)

			feed.addItem(item)
		})
	} catch (e) {
		console.error('[Paperpress] ERROR - Feed. Undefined array for items')
		return null
	}

	// Test if there is no error with the feed render function
	try {
		feed.render()
	} catch (e) {
		console.error('[Paperpress] ERROR - Feed', e)
		return null
	}

	return feed
}

exports.Paperpress = Paperpress
<|endoftext|>


<commit_before>'use strict';
var dashboard = {
    "_id": '55128442e603d7e01ab1688c',
    "code": "DASHBOARD",
    "domain": "%domain%",
    "sitePrefix": "%site%",
    "apiPrefix": "%api%",
    "locked": true,
    "port": 80,
	"protocol": "http",
    "profile": "%wrkDir%/soajs/FILES/profiles/profile.js",
    "deployer": {
	    "type": "%deployType%",
	    "selected": "%deployDriver%",
	    "manual": {
	    	"nodes": "%containerNode%",
	    },
	    "container": {
		    "docker": {
			    "local": {
				    "nodes": "%deployDockerNodes%",
				    "socketPath": "/var/run/docker.sock",
			    },
			    "remote": {
				    "apiPort": "%dockerRemotePort%",
				    "nodes": "%deployDockerNodes%",
				    "protocol": "https",
				    "auth": {
					    "token": "%dockertoken%"
				    }
			    }
		    },
		    "kubernetes":{
			    "local":{
				    "nodes": "%containerNode%",
				    "apiPort": "%kubernetesRemotePort%",
				    "namespace": "%namespace%",
                    "auth": {
				        "token": "%kubetoken%"
                    }
			    },
			    "remote":{
				    "nodes": "%containerNode%",
				    "apiPort": "%kubernetesRemotePort%",
				    "namespace": "%namespace%",
                    "auth": {
                        "token": "%kubetoken%"
                    }
			    }
		    }
	    }
    },
    "description": "this is the Dashboard environment",
    "dbs": {
        "config": {
            "prefix": "%clusterPrefix%"
        },
	    "session": {
		    "cluster": "dash_cluster",
		    "tenantSpecific": false,
		    "name": "core_session",
		    'store': {},
		    "collection": "sessions",
		    'stringify': false,
		    'expireAfter': 1000 * 60 * 60 * 24 * 14 // 2 weeks
	    },
        "databases": {
            "urac": {
                "cluster": "dash_cluster",
                "tenantSpecific": true
            }
        }
    },
    "services": {
        "controller": {
            "maxPoolSize": 100,
            "authorization": true,
            "requestTimeout": 30,
            "requestTimeoutRenewal": 0
        },
        "config": {
            "awareness": {
                "cacheTTL": 1000 * 60 * 60, // 1 hr
                "healthCheckInterval": 1000 * 5, // 5 seconds
                "autoRelaodRegistry": 1000 * 60 * 60, // 1 hr
                "maxLogCount": 5,
                "autoRegisterService": true
            },
            "agent": {
                "topologyDir": "%wrkDir%/soajs/"
            },
            "key": {
                "algorithm": 'aes256',
                "password": '%keySecret%'
            },
            "logger": {
                "src": true,
                "level": "debug",
                "formatter": {
	                //"outputMode": "bunyan",
	                "levelInString": true,
	                "outputMode": 'long'
                }
            },
            "cors": {
                "enabled": true,
                "origin": '*',
                "credentials": 'true',
                "methods": 'GET,HEAD,PUT,PATCH,POST,DELETE',
                "headers": 'key,soajsauth,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization',
                "maxage": 1728000
            },
            "oauth": {
                "grants": ['password', 'refresh_token'],
                "debug": false,
	            "accessTokenLifetime": 7200,
	            "refreshTokenLifetime": 1209600
            },
            "ports": {
	            "controller": 4000,
	            "maintenanceInc": 1000,
	            "randomInc": 100
            },
            "cookie": {
	            "secret": "%cookieSecret%"
            },
            "session": {
                "name": "soajsID",
                "secret": "%sessionSecret%",
                "cookie": {
                    "path": '/',
                    "httpOnly": true,
                    "secure": false,
                    "maxAge": null
                },
                "resave": false,
                "saveUninitialized": false,
                "rolling": false,
                "unset": "keep"
            }
        }
    }
};

module.exports = dashboard;
<commit_msg>bug fix<commit_after>'use strict';
var dashboard = {
    "_id": '55128442e603d7e01ab1688c',
    "code": "DASHBOARD",
    "domain": "%domain%",
    "sitePrefix": "%site%",
    "apiPrefix": "%api%",
    "locked": true,
    "port": 80,
	"protocol": "http",
    "profile": "%wrkDir%/soajs/FILES/profiles/profile.js",
    "deployer": {
	    "type": "%deployType%",
	    "selected": "%deployDriver%",
	    "manual": {
	    	"nodes": "%containerNode%",
	    },
	    "container": {
		    "docker": {
			    "local": {
				    "nodes": "%deployDockerNodes%",
				    "socketPath": "/var/run/docker.sock",
			    },
			    "remote": {
				    "apiPort": "%dockerRemotePort%",
				    "nodes": "%deployDockerNodes%",
				    "apiProtocol": "https",
				    "auth": {
					    "token": "%dockertoken%"
				    }
			    }
		    },
		    "kubernetes":{
			    "local":{
				    "nodes": "%containerNode%",
				    "apiPort": "%kubernetesRemotePort%",
				    "namespace": "%namespace%",
                    "auth": {
				        "token": "%kubetoken%"
                    }
			    },
			    "remote":{
				    "nodes": "%containerNode%",
				    "apiPort": "%kubernetesRemotePort%",
				    "namespace": "%namespace%",
                    "auth": {
                        "token": "%kubetoken%"
                    }
			    }
		    }
	    }
    },
    "description": "this is the Dashboard environment",
    "dbs": {
        "config": {
            "prefix": "%clusterPrefix%"
        },
	    "session": {
		    "cluster": "dash_cluster",
		    "tenantSpecific": false,
		    "name": "core_session",
		    'store': {},
		    "collection": "sessions",
		    'stringify': false,
		    'expireAfter': 1000 * 60 * 60 * 24 * 14 // 2 weeks
	    },
        "databases": {
            "urac": {
                "cluster": "dash_cluster",
                "tenantSpecific": true
            }
        }
    },
    "services": {
        "controller": {
            "maxPoolSize": 100,
            "authorization": true,
            "requestTimeout": 30,
            "requestTimeoutRenewal": 0
        },
        "config": {
            "awareness": {
                "cacheTTL": 1000 * 60 * 60, // 1 hr
                "healthCheckInterval": 1000 * 5, // 5 seconds
                "autoRelaodRegistry": 1000 * 60 * 60, // 1 hr
                "maxLogCount": 5,
                "autoRegisterService": true
            },
            "agent": {
                "topologyDir": "%wrkDir%/soajs/"
            },
            "key": {
                "algorithm": 'aes256',
                "password": '%keySecret%'
            },
            "logger": {
                "src": true,
                "level": "debug",
                "formatter": {
	                //"outputMode": "bunyan",
	                "levelInString": true,
	                "outputMode": 'long'
                }
            },
            "cors": {
                "enabled": true,
                "origin": '*',
                "credentials": 'true',
                "methods": 'GET,HEAD,PUT,PATCH,POST,DELETE',
                "headers": 'key,soajsauth,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization',
                "maxage": 1728000
            },
            "oauth": {
                "grants": ['password', 'refresh_token'],
                "debug": false,
	            "accessTokenLifetime": 7200,
	            "refreshTokenLifetime": 1209600
            },
            "ports": {
	            "controller": 4000,
	            "maintenanceInc": 1000,
	            "randomInc": 100
            },
            "cookie": {
	            "secret": "%cookieSecret%"
            },
            "session": {
                "name": "soajsID",
                "secret": "%sessionSecret%",
                "cookie": {
                    "path": '/',
                    "httpOnly": true,
                    "secure": false,
                    "maxAge": null
                },
                "resave": false,
                "saveUninitialized": false,
                "rolling": false,
                "unset": "keep"
            }
        }
    }
};

module.exports = dashboard;
<|endoftext|>


<commit_before>/**
	The MIT License (MIT)

	Copyright (c) 2014 MyChannel-Apps.de

	Permission is hereby granted, free of charge, to any person obtaining a copy
	of this software and associated documentation files (the "Software"), to deal
	in the Software without restriction, including without limitation the rights
	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the Software is
	furnished to do so, subject to the following conditions:

	The above copyright notice and this permission notice shall be included in
	all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
	THE SOFTWARE.

	@author		Christoph Kühl <djchrisnet>, Adrian Preuß <Bizarrus>
*/

if(!Array.prototype.each) {
	Object.defineProperty(Array.prototype, 'each', {
		enumerable:		false,
		configurable:	false,
		writable:		false,
		value:			function(callback) {
			for(var index = 0; index < this.length; index++) {
				if(callback.apply(this[index], index) === false) {
					break;
				}
			}
		}
	});
}

if(!Array.prototype.random) {
	Object.defineProperty(Array.prototype, 'random', {
		enumerable:		false,
		configurable:	false,
		writable:		false,
		value:			function() {
			return this[Math.floor((Math.random() * this.length))];
		}
	});
}<commit_msg>better Random<commit_after>/**
	The MIT License (MIT)

	Copyright (c) 2014 MyChannel-Apps.de

	Permission is hereby granted, free of charge, to any person obtaining a copy
	of this software and associated documentation files (the "Software"), to deal
	in the Software without restriction, including without limitation the rights
	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the Software is
	furnished to do so, subject to the following conditions:

	The above copyright notice and this permission notice shall be included in
	all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
	THE SOFTWARE.

	@author		Christoph Kühl <djchrisnet>, Adrian Preuß <Bizarrus>
*/

if(!Array.prototype.each) {
	Object.defineProperty(Array.prototype, 'each', {
		enumerable:		false,
		configurable:	false,
		writable:		false,
		value:			function(callback) {
			for(var index = 0; index < this.length; index++) {
				if(callback.apply(this[index], index) === false) {
					break;
				}
			}
		}
	});
}

if(!Array.prototype.random) {
	Object.defineProperty(Array.prototype, 'random', {
		enumerable:		false,
		configurable:	false,
		writable:		false,
		value:			function() {
			return this[RandomOperations.nextInt(this.length)];
		}
	});
}<|endoftext|>


<commit_before>'use strict';

var app = {
    owl:null,
    preloader:null,
    form:"#search-form",
    searchContainer:"#search-container",
    selected:[],
    user:{},
    init:function(){
        this.initCarousel();
        this.initPreloader();
        $(this.form).on("submit", this.searchForm);
    },
    initCarousel:function(){
        $("#owl-demo").owlCarousel({
            autoPlay: 4000,
            items : 1,
            singleItem: true,
            autoHeight: true,
            itemsScaleUp:true
        });
        this.owl = $(".owl-carousel").data('owlCarousel');
    },
    initPreloader:function(){
        var opts = {
            lines: 11, // The number of lines to draw
            length: 9, // The length of each line
            width: 2, // The line thickness
            radius: 6, // The radius of the inner circle
            corners: 1, // Corner roundness (0..1)
            rotate: 0, // The rotation offset
            direction: 1, // 1: clockwise, -1: counterclockwise
            color: '#000', // #rgb or #rrggbb or array of colors
            speed: 1, // Rounds per second
            trail: 22, // Afterglow percentage
            shadow: false, // Whether to render a shadow
            hwaccel: false, // Whether to use hardware acceleration
            className: 'spinner loading', // The CSS class to assign to the spinner
            zIndex: 2e9, // The z-index (defaults to 2000000000)
            top: '50%', // Top position relative to parent
            left: '90%' // Left position relative to parent
        };
        this.preloader = new Spinner(opts).spin();
    },
    searchForm:function(event){
        event.preventDefault? event.preventDefault(): event.returnValue = false;
        $.ajax({
            url:$("#send-form").val().trim(),
            type:'post',
            data:$(event.target).serialize(),
            dataType:'json',
            beforeSend:function(){
                $(this.form).off();
                app.showLoading();
            },
            success:function(response){
                if(response.state === 'ok'){
                    $(".content-container").fadeOut(500,function(){
                        $(this).hide()
                            .html(response.template)
                            .fadeIn(500);
                        if(app.owl){
                            app.owl.destroy();
                        }
                        app.owl = null;
                        app.user.id = response.userId;
                        app.user.type = response.userType;
                        app.initVoting(response.userType);
                    });
                }else {
                    app.showModal(
                        "Mensaje",
                        response.message,
                        "Aceptar"
                    );
                }
            },
            error:function(){
                app.showModal(
                    "Mensaje",
                    "Ops! parece que se ha presentado un error en el sistema, por favor intentalo más tarde :(",
                    "Aceptar"
                );
            },
            complete:function(){
                $(this.form).on("submit", this.searchForm);
                app.hideLoading();
            }
        });
    },
    showLoading:function(target){
        if(!target){
            target = $(this.searchContainer)[0];
        }
        target.appendChild(this.preloader.el);
    },
    hideLoading:function(target){
        if(!target){
            target = $(this.searchContainer)[0];
        }
        $(target).find(".spinner.loading").remove();
    },
    showModal:function(title, message, acceptButton, agreeCallback){
        var $modal = $('#modal');
        var html = $modal.html()
            .replace("{$title}", title)
            .replace("{$message}", message)
            .replace("{$acceptButton}", acceptButton);
        $modal.html(html).modal('show');
        $modal.off("hidden.bs.modal").on("hidden.bs.modal", function(){
            if(agreeCallback !== undefined){
                agreeCallback();
            }
        });
        $modal = html = undefined;
    },
    showConfirmModal:function(title, message, acceptButton, agreeCallback){
        var $modal = $('#modal-confirm');
        var html = $modal.html()
            .replace("{$title}", title)
            .replace("{$message}", message)
            .replace("{$acceptButton}", acceptButton);
        $modal.html(html).modal('show');
        $(".agree-option").off("click").on("click", function(){
            if(agreeCallback !== undefined){
                agreeCallback();
            }
        });
        $modal = html = undefined;
    },
    initVoting:function(target){
        $(".owl-candidates").owlCarousel({
            autoPlay: 6000,
            items : 5,
            autoHeight: true,
            itemsScaleUp:true
        });

        $(".candidate.item").on("click", function(event){
            app.selectCandidate(event, target);
        });

        $("#send-vote").on("click", function(){
            app.showConfirmModal(
                "Confirmación",
                "¿Confirma que desea registrar su voto?",
                "Aceptar",
                function(){
                    app.sendVote();
                }
            );
        });
    },
    sendVote:function(){
        if(app.selected.length === 0){
            app.showModal(
                "Mensaje",
                "Para poder realizar la votación debe escoger al menos un candidato.",
                "Aceptar"
            );
            return;
        }
        $.ajax({
            url:$("#send-vote-url").val().trim(),
            type:"POST",
            dataType:'json',
            data:{
                data:JSON.stringify({
                    userId:app.user.id,
                    userType:app.user.type,
                    selected:app.selected
                })
            },
            beforeSend:function(){
                $("#send-vote").off("click");
                app.showLoading($("#modal-confirm").find(".modal-body")[0]);
            },
            success:function(response){
                app.showModal(
                    "Mensaje",
                    response.message,
                    "Aceptar",
                    function(){
                        location.reload();
                    }
                );
            },
            error:function(){
                app.showModal(
                    "Mensaje",
                    "Ops! parece que hay un problema en el servidor, por favor intentalo nuevamente.",
                    "Aceptar"
                );
            },
            complete:function(){
                app.hideLoading($("#modal-confirm").find(".modal-body")[0]);
                app.user = {};
                app.selected = [];
            }
        });
    },
    selectCandidate:function(event, target){
        var item = app.findObjectUp(event.target, ".item");
        var $item = $(item);
        var attr = $item.attr("target");
        var i = 0;
        var found = false;
        while(i < app.selected.length && !found){
            if(app.selected[i].tag === attr){
                $(".candidate.item[selected][target='" + attr + "']")
                    .removeAttr("selected")
                    .find(".item-mark")
                    .removeClass("slidein")
                    .addClass("slideout");
                found = true;
            }
            i += 1;
        }
        if(found){
            app.selected.splice(i-1, 1);
        }
        app.selected.push({
            tag:attr,
            id:$item.attr("target-id"),
            type:attr.split("-")[1]
        });

        $item.find(".item-mark")
            .removeClass("slideout")
            .addClass("slidein");
        $item.attr("selected", true);
        item = undefined;
    },
    jQueryContains:function($jq,elem){
        for(var i=0; i<$jq.length;i++){
            if($jq[i]===elem)
                return true;
        }
        return false;
    },
    findObjectUp:function(target, selector){
        var $jq = $(selector);
        var obj = target;
        while(app.jQueryContains($jq,obj) === false){
            if(obj.parentNode){
                obj = obj.parentNode;
            }else{
                return null;
            }
        }
        return obj;
    }
};
app.init();<commit_msg>efecto fade para cambio de imágenes del home<commit_after>'use strict';

var app = {
    owl:null,
    preloader:null,
    form:"#search-form",
    searchContainer:"#search-container",
    selected:[],
    user:{},
    init:function(){
        this.initCarousel();
        this.initPreloader();
        $(this.form).on("submit", this.searchForm);
    },
    initCarousel:function(){
        $("#owl-demo").owlCarousel({
            autoPlay: 4000,
            items : 1,
            singleItem: true,
            autoHeight: true,
            itemsScaleUp:true,
            transitionStyle:"fade"
        });
        this.owl = $(".owl-carousel").data('owlCarousel');
    },
    initPreloader:function(){
        var opts = {
            lines: 11, // The number of lines to draw
            length: 9, // The length of each line
            width: 2, // The line thickness
            radius: 6, // The radius of the inner circle
            corners: 1, // Corner roundness (0..1)
            rotate: 0, // The rotation offset
            direction: 1, // 1: clockwise, -1: counterclockwise
            color: '#000', // #rgb or #rrggbb or array of colors
            speed: 1, // Rounds per second
            trail: 22, // Afterglow percentage
            shadow: false, // Whether to render a shadow
            hwaccel: false, // Whether to use hardware acceleration
            className: 'spinner loading', // The CSS class to assign to the spinner
            zIndex: 2e9, // The z-index (defaults to 2000000000)
            top: '50%', // Top position relative to parent
            left: '90%' // Left position relative to parent
        };
        this.preloader = new Spinner(opts).spin();
    },
    searchForm:function(event){
        event.preventDefault? event.preventDefault(): event.returnValue = false;
        $.ajax({
            url:$("#send-form").val().trim(),
            type:'post',
            data:$(event.target).serialize(),
            dataType:'json',
            beforeSend:function(){
                $(this.form).off();
                app.showLoading();
            },
            success:function(response){
                if(response.state === 'ok'){
                    $(".content-container").fadeOut(500,function(){
                        $(this).hide()
                            .html(response.template)
                            .fadeIn(500);
                        if(app.owl){
                            app.owl.destroy();
                        }
                        app.owl = null;
                        app.user.id = response.userId;
                        app.user.type = response.userType;
                        app.initVoting(response.userType);
                    });
                }else {
                    app.showModal(
                        "Mensaje",
                        response.message,
                        "Aceptar"
                    );
                }
            },
            error:function(){
                app.showModal(
                    "Mensaje",
                    "Ops! parece que se ha presentado un error en el sistema, por favor intentalo más tarde :(",
                    "Aceptar"
                );
            },
            complete:function(){
                $(this.form).on("submit", this.searchForm);
                app.hideLoading();
            }
        });
    },
    showLoading:function(target){
        if(!target){
            target = $(this.searchContainer)[0];
        }
        target.appendChild(this.preloader.el);
    },
    hideLoading:function(target){
        if(!target){
            target = $(this.searchContainer)[0];
        }
        $(target).find(".spinner.loading").remove();
    },
    showModal:function(title, message, acceptButton, agreeCallback){
        var $modal = $('#modal');
        var html = $modal.html()
            .replace("{$title}", title)
            .replace("{$message}", message)
            .replace("{$acceptButton}", acceptButton);
        $modal.html(html).modal('show');
        $modal.off("hidden.bs.modal").on("hidden.bs.modal", function(){
            if(agreeCallback !== undefined){
                agreeCallback();
            }
        });
        $modal = html = undefined;
    },
    showConfirmModal:function(title, message, acceptButton, agreeCallback){
        var $modal = $('#modal-confirm');
        var html = $modal.html()
            .replace("{$title}", title)
            .replace("{$message}", message)
            .replace("{$acceptButton}", acceptButton);
        $modal.html(html).modal('show');
        $(".agree-option").off("click").on("click", function(){
            if(agreeCallback !== undefined){
                agreeCallback();
            }
        });
        $modal = html = undefined;
    },
    initVoting:function(target){
        $(".owl-candidates").owlCarousel({
            autoPlay: 6000,
            items : 5,
            autoHeight: true,
            itemsScaleUp:true
        });

        $(".candidate.item").on("click", function(event){
            app.selectCandidate(event, target);
        });

        $("#send-vote").on("click", function(){
            app.showConfirmModal(
                "Confirmación",
                "¿Confirma que desea registrar su voto?",
                "Aceptar",
                function(){
                    app.sendVote();
                }
            );
        });
    },
    sendVote:function(){
        if(app.selected.length === 0){
            app.showModal(
                "Mensaje",
                "Para poder realizar la votación debe escoger al menos un candidato.",
                "Aceptar"
            );
            return;
        }
        $.ajax({
            url:$("#send-vote-url").val().trim(),
            type:"POST",
            dataType:'json',
            data:{
                data:JSON.stringify({
                    userId:app.user.id,
                    userType:app.user.type,
                    selected:app.selected
                })
            },
            beforeSend:function(){
                $("#send-vote").off("click");
                app.showLoading($("#modal-confirm").find(".modal-body")[0]);
            },
            success:function(response){
                app.showModal(
                    "Mensaje",
                    response.message,
                    "Aceptar",
                    function(){
                        location.reload();
                    }
                );
            },
            error:function(){
                app.showModal(
                    "Mensaje",
                    "Ops! parece que hay un problema en el servidor, por favor intentalo nuevamente.",
                    "Aceptar"
                );
            },
            complete:function(){
                app.hideLoading($("#modal-confirm").find(".modal-body")[0]);
                app.user = {};
                app.selected = [];
            }
        });
    },
    selectCandidate:function(event, target){
        var item = app.findObjectUp(event.target, ".item");
        var $item = $(item);
        var attr = $item.attr("target");
        var i = 0;
        var found = false;
        while(i < app.selected.length && !found){
            if(app.selected[i].tag === attr){
                $(".candidate.item[selected][target='" + attr + "']")
                    .removeAttr("selected")
                    .find(".item-mark")
                    .removeClass("slidein")
                    .addClass("slideout");
                found = true;
            }
            i += 1;
        }
        if(found){
            app.selected.splice(i-1, 1);
        }
        app.selected.push({
            tag:attr,
            id:$item.attr("target-id"),
            type:attr.split("-")[1]
        });

        $item.find(".item-mark")
            .removeClass("slideout")
            .addClass("slidein");
        $item.attr("selected", true);
        item = undefined;
    },
    jQueryContains:function($jq,elem){
        for(var i=0; i<$jq.length;i++){
            if($jq[i]===elem)
                return true;
        }
        return false;
    },
    findObjectUp:function(target, selector){
        var $jq = $(selector);
        var obj = target;
        while(app.jQueryContains($jq,obj) === false){
            if(obj.parentNode){
                obj = obj.parentNode;
            }else{
                return null;
            }
        }
        return obj;
    }
};
app.init();<|endoftext|>


<commit_before>var exports = module.exports  = {};

var read_str = function(str) {
    var tokens = tokenizer(str);
    console.log(tokens);
    var reader = new Reader(tokens);
    var result = read_form(reader);
    return result;
};

var tokenizer = function(str) {
    var re_tokenizer = /[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"`,;)]*)/g;
    var match;
    var results = [];
    while (match = re_tokenizer.exec(str)[1]) {
        results.push(match[0]);
    }
    return results;
};

var read_form = function(reader) {
    //    console.log('read_form:', reader);
    var result;
    var form = reader.peek();

    // console.log('read_form, token: ', form);
    switch(form) {
    case '(': // list
        console.log('list start');
        return read_list(reader);
    case ')': // list
        console.error('list end in read_form not read_list');
        return null;
    default: // atom
        return read_atom(reader);
    }
};

var read_list = function(reader) {
    var result = [];
    // console.log(reader);
    var token = reader.next();
    // Clear the list start
    if (token !== '(') {
        console.warn('Expected: list start "("');
    }
    while ((token = reader.peek()) !== ')') {
        console.log('parsed:', token);
        result.push(read_form(reader));
    }
    // Clear the list end
    console.log('list end');
    reader.next();
    return result;
};

var read_atom = function(reader) {
    var number;
    var atom = reader.next();
    console.log('read_atom', atom);
    if (number = parseInt(atom, 10)) {
        return number;
    } else {
        return new Symbol(atom);
    }
};

var Symbol = function(value) {
    this.name = value;
    this.type = 'Symbol';
    return this.name;
};

var Reader = function(tokens) {
    this.tokens = tokens;
    this.position = 0;
    //    console.log('Tokens: ', this.tokens);
    this.next = function() {
        var token = this.peek();
        this.position++;
        return token;

    };
    this.peek =function() {
        return this.tokens[this.position];
    };

};

var pr_str = function(ast) {
    console.log(ast);
    // ast.map(function(e, i, c) {
    //     switch(typeof e) {
    //     case 'array': return a.join(' ');
    //     default: return e;
    //     };
    // });
};

exports.read_str = read_str;

var tests = ['1', '(+ 1 2)', '(+ 2 (+ 2 (- 4 1)))'];
tests.map(function(e, i, c) {
    console.log('-------------------------------');
    console.log(e, ':\n',
                JSON.stringify(read_str(e)),
                pr_str(read_str(e)));
});
<commit_msg>Symbols support<commit_after>var exports = module.exports  = {};

var read_str = function(str) {
    var tokens = tokenizer(str);
    console.log(tokens);
    var reader = new Reader(tokens);
    var result = read_form(reader);
    return result;
};

var tokenizer = function(str) {
    var re_tokenizer = /[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"`,;)]*)/g;
    var match;
    var results = [];
    while (match = re_tokenizer.exec(str)[1]) {
        results.push(match[0]);
    }
    return results;
};

var read_form = function(reader) {
    //    console.log('read_form:', reader);
    var result;
    var form = reader.peek();

    // console.log('read_form, token: ', form);
    switch(form) {
    case '(': // list
        console.log('list start');
        return read_list(reader);
    case ')': // list
        console.error('list end in read_form not read_list');
        return null;
    default: // atom
        return read_atom(reader);
    }
};

var read_list = function(reader) {
    var result = [];
    // console.log(reader);
    var token = reader.next();
    // Clear the list start
    if (token !== '(') {
        console.warn('Expected: list start "("');
    }
    while ((token = reader.peek()) !== ')') {
        console.log('parsed:', token);
        result.push(read_form(reader));
    }
    // Clear the list end
    console.log('list end');
    reader.next();
    return result;
};

var read_atom = function(reader) {
    var number;
    var atom = reader.next();
    console.log('read_atom', typeof atom, atom);
    if (/^\d+$/.test(atom)) {
        return parseInt(atom, 10);
    } else if (atom === "true") {
        return true;
    } else if (atom === "false") {
        return false;
    } else {
        return new Symbol(atom);
    }
};

var Symbol = function(value) {
    this.name = value;
    this.type = 'Symbol';
    return this.name;
};

var Reader = function(tokens) {
    this.tokens = tokens;
    this.position = 0;
    //    console.log('Tokens: ', this.tokens);
    this.next = function() {
        var token = this.peek();
        this.position++;
        return token;

    };
    this.peek =function() {
        return this.tokens[this.position];
    };

};

var pr_str = function(ast) {
    console.log(ast);
    // ast.map(function(e, i, c) {
    //     switch(typeof e) {
    //     case 'array': return a.join(' ');
    //     default: return e;
    //     };
    // });
};

exports.read_str = read_str;

var tests = ['1', '(+ 1 2)', '(+ 2 (+ 2 (- 4 1)))', '(if (true) 1 0)'];
tests.map(function(e, i, c) {
    console.log('-------------------------------');
    console.log(e, ':\n',
                JSON.stringify(read_str(e)),
                pr_str(read_str(e)));
});
<|endoftext|>