<commit_before>/*
 * Copyrights phwang
 * Written by Paul Hwang
 * File name: go_config_module.js
 */

module.exports = {
    malloc: function (container_val) {
        return new GoConfigObject(container_val);
    },
};

function GoConfigObject(container_val) {
    "use strict";
    this.theContainerObject = container_val;

    this.objectName = function () {
        return "GoConfigObject";
    };

    this.containerObject = function () {
        return this.theContainerObject;
    };

    this.sessionObject = function () {
        return this.containerObject().sessionObject();
    };

    this.rootObject = function () {
        return this.sessionObject().rootObject();
    };

    this.gameObject = function () {
        return this.containerObject().gameObject();
    };

    this.myName = function () {
        return this.rootObject().myName();
    };

    this.opponentName = function () {
        return this.sessionObject().hisName();
    };

    this.boardSize = function () {
        return this.theBoardSize;
    };

    this.setBoardSize = function (val) {
        this.theBoardSize = Number(val);
    };

    this.myColor = function () {
        return this.theMyColor;
    };

    this.hisColor = function () {
        if (this.theMyColor === GO.BLACK_STONE()) {
            return GO.WHITE_STONE();
        }
        else {
            return GO.BLACK_STONE();
        }
    };

    this.setMyColor = function (val) {
        if (val === "black") {
            this.theMyColor = GO.BLACK_STONE();
        } else if (val === "white") {
            this.theMyColor = GO.WHITE_STONE();
        } else {
            this.abend("setMyColor", val);
        }
    };

    this.setMyColor_ = function (val) {
        this.theMyColor = Number(val);
    };

    this.handicapPoint = function () {
        return this.theHandicapPoint;
    };

    this.setHandicapPoint = function (val) {
        this.theHandicapPoint = Number(val);
    };

    this.komiPoint = function () {
        return this.theKomiPoint;
    };

    this.setKomiPoint = function (val) {
        this.theKomiPoint = Number(val);
    };

    this.realKomiPoint = function () {
        if (!this.theKomiPoint) {
            return 0;
        }
        return this.theKomiPoint + 0.5;
    };

    this.playBothSides = function () {
        return (this.myName() === this.opponentName());
    };

    this.isValidCoordinate = function (data_val) {
        return (0 <= coordinate_val) && (coordinate_val < board_size_val);
        if (data_val < 0) {
            GO.goAbend("GoBoardObject.isValidCoordinate", data_val);
            return false;
        }
        if (data_val >= this.boardSize()) {
            GO.goAbend("GoBoardObject.isValidCoordinate", data_val);
            return false;
        }
        return true;
    };

    this.createConfig = function (json_data_val) {
        this.debug(true, "creataConfig", "data=" + json_data_val);
        var config_data = JSON.parse(json_data_val);
        this.setBoardSize(config_data.board_size);
        this.setMyColor_(config_data.color);
        this.setKomiPoint(config_data.komi);
        this.setHandicapPoint(config_data.handicap);
    };

    this.createTwoBoardOpponentConfig = function () {
        var config = new GoConfigObject(this.opponentName());
        config.theOpponentName = this.myName();
        config.theBoardSize = this.boardSize();
        config.theMyColor = this.hisColor();
        config.theHandicapPoint = this.handicapPoint();
        config.theKomiPoint = this.komiPoint();
        return config;
    };

    this.isValidCoordinates = function (x_val, y_val) {
        return this.isValidCoordinate(x_val) && this.isValidCoordinate(y_val) ;
    };

    this.isValidCoordinate = function (coordinate_val) {
        return (0 <= coordinate_val) && (coordinate_val < this.boardSize());
    };

    this.debug = function (debug_val, str1_val, str2_val) {
        if (debug_val) {
            this.logit(str1_val, "==" + str2_val);
        }
    };

    this.abend = function (str1_val, str2_val) {
        return this.containerObject().goAbend(this.objectName() + "." + str1_val, str2_val);
    };

    this.logit = function (str1_val, str2_val) {
        return this.containerObject().goLog(this.objectName() + "." + str1_val, str2_val);
    };

    this.theBoardSize = 19;
    this.theHandicapPoint = 0;
}
<commit_msg>config<commit_after>/*
 * Copyrights phwang
 * Written by Paul Hwang
 * File name: go_config_module.js
 */

module.exports = {
    malloc: function (container_val) {
        return new GoConfigObject(container_val);
    },
};

function GoConfigObject(container_val) {
    "use strict";
    this.theContainerObject = container_val;

    this.objectName = function () {
        return "GoConfigObject";
    };

    this.containerObject = function () {
        return this.theContainerObject;
    };

    this.sessionObject = function () {
        return this.containerObject().sessionObject();
    };

    this.rootObject = function () {
        return this.sessionObject().rootObject();
    };

    this.gameObject = function () {
        return this.containerObject().gameObject();
    };

    this.myName = function () {
        return this.rootObject().myName();
    };

    this.opponentName = function () {
        return this.sessionObject().hisName();
    };

    this.boardSize = function () {
        return this.theBoardSize;
    };

    this.setBoardSize = function (val) {
        this.theBoardSize = Number(val);
    };

    this.myColor = function () {
        return this.theMyColor;
    };

    this.hisColor = function () {
        if (this.theMyColor === GO.BLACK_STONE()) {
            return GO.WHITE_STONE();
        }
        else {
            return GO.BLACK_STONE();
        }
    };

    this.setMyColor = function (val) {
        if (val === "black") {
            this.theMyColor = GO.BLACK_STONE();
            return;
        }
        if (val === "white") {
            this.theMyColor = GO.WHITE_STONE();
            return;
        }
        this.abend("setMyColor", val);
    };

    this.setMyColor_ = function (val) {
        this.theMyColor = Number(val);
    };

    this.handicapPoint = function () {
        return this.theHandicapPoint;
    };

    this.setHandicapPoint = function (val) {
        this.theHandicapPoint = Number(val);
    };

    this.komiPoint = function () {
        return this.theKomiPoint;
    };

    this.setKomiPoint = function (val) {
        this.theKomiPoint = Number(val);
    };

    this.realKomiPoint = function () {
        if (!this.theKomiPoint) {
            return 0;
        }
        return this.theKomiPoint + 0.5;
    };

    this.playBothSides = function () {
        return (this.myName() === this.opponentName());
    };

    this.isValidCoordinate = function (data_val) {
        return (0 <= coordinate_val) && (coordinate_val < board_size_val);
        if (data_val < 0) {
            GO.goAbend("GoBoardObject.isValidCoordinate", data_val);
            return false;
        }
        if (data_val >= this.boardSize()) {
            GO.goAbend("GoBoardObject.isValidCoordinate", data_val);
            return false;
        }
        return true;
    };

    this.createConfig = function (json_data_val) {
        this.debug(true, "creataConfig", "data=" + json_data_val);
        var config_data = JSON.parse(json_data_val);
        this.setBoardSize(config_data.board_size);
        this.setMyColor_(config_data.color);
        this.setKomiPoint(config_data.komi);
        this.setHandicapPoint(config_data.handicap);
    };

    this.createTwoBoardOpponentConfig = function () {
        var config = new GoConfigObject(this.opponentName());
        config.theOpponentName = this.myName();
        config.theBoardSize = this.boardSize();
        config.theMyColor = this.hisColor();
        config.theHandicapPoint = this.handicapPoint();
        config.theKomiPoint = this.komiPoint();
        return config;
    };

    this.isValidCoordinates = function (x_val, y_val) {
        return this.isValidCoordinate(x_val) && this.isValidCoordinate(y_val) ;
    };

    this.isValidCoordinate = function (coordinate_val) {
        return (0 <= coordinate_val) && (coordinate_val < this.boardSize());
    };

    this.debug = function (debug_val, str1_val, str2_val) {
        if (debug_val) {
            this.logit(str1_val, "==" + str2_val);
        }
    };

    this.abend = function (str1_val, str2_val) {
        return this.containerObject().goAbend(this.objectName() + "." + str1_val, str2_val);
    };

    this.logit = function (str1_val, str2_val) {
        return this.containerObject().goLog(this.objectName() + "." + str1_val, str2_val);
    };

    this.theBoardSize = 19;
    this.theHandicapPoint = 0;
}
<|endoftext|>


<commit_before>class Job extends React.Component {
  constructor() {
    super();
  }

  render() {
    let data = this.props.jobData;

    let locations = data.location.map((location) => location.name).reverse();

    if (locations.length >= 2) {
      locations = `${locations.slice(0, -1).join(', ')} and ${locations[locations.length - 1]}`;
    }

    return (

            <picture>
              <source srcset={data.company.image.lg} media="(max-width: 992px)" />

            </picture>

            {data.company.name} - {data.title}

{data.ingress}

Type: {data.employment.name}

Sted: {locations}

Frist: {data.deadline || 'Ikke spesifisert'}

    );
  }
}

export default Job;
<commit_msg>Format deadline in Job.<commit_after>import moment from 'moment';

moment.locale('nb');

class Job extends React.Component {
  constructor() {
    super();
  }

  render() {
    let data = this.props.jobData;

    let locations = data.location.map((location) => location.name).reverse();

    if (locations.length >= 2) {
      locations = `${locations.slice(0, -1).join(', ')} and ${locations[locations.length - 1]}`;
    }

    let deadline = data.deadline ? moment(data.deadline).format('Do MMMM YYYY, HH:mm') : 'Ikke spesifisert';

    return (

            <picture>
              <source srcset={data.company.image.lg} media="(max-width: 992px)" />

            </picture>

            {data.company.name} - {data.title}

{data.ingress}

Type: {data.employment.name}

Sted: {locations}

Frist: {deadline}

    );
  }
}

export default Job;
<|endoftext|>


<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.
 */

import Ember from 'ember';
import UILoggerMixin from '../mixins/ui-logger';

export default Ember.Route.extend(UILoggerMixin, {

  savedQueries: Ember.inject.service(),

  model() {
    return this.store.findAll('savedQuery').then(savedQueries => savedQueries.toArray());
  },

  setupController(controller, model) {
    this._super(...arguments);

    controller.set('savedQuerylist', model);

    controller.set('showDeleteSaveQueryModal', false);
    controller.set('selectedSavedQueryId', null);
    controller.set('preview', {"noSort":true});
    controller.set('title', {"noSort":true});
    controller.set('dataBase', {"noSort":true});
    controller.set('owner', {"noSort":true});
  },

  actions: {
    sort(sortProp, sortField, key) {
      let perm = {};
      perm[key] = true;
      this.get('controller').set(sortField, perm);
      this.get('controller').set('sortProp', [sortProp]);
    },
    deleteSavedQuery(){
      let queryId = this.get('controller').get('selectedSavedQueryId');
      let self = this;

      console.log('deleteSavedQuery', queryId);

      this.get('store').queryRecord('saved-query', { filter: { id: queryId } }, {reload: true}).then(function(record) {
        record.destroyRecord().then(function(data) {
          self.send('deleteSavedQueryDeclined');
          self.send('refreshSavedQueryList');
        });
      }, (error) => {
        console.log('error', error);
      });
    },

    refreshSavedQueryList(){
      this.get('store').findAll('saved-query').then(data => {
        let savedQueryList = [];
        data.forEach(x => {
          let localSavedQuery = {
            'id': x.get('id'),
            'dataBase': x.get('dataBase'),
            'title': x.get('title'),
            'queryFile': x.get('queryFile'),
            'owner': x.get('owner'),
            'shortQuery': x.get('shortQuery')
          };
          savedQueryList.pushObject(localSavedQuery);
        });

        this.get('controller').set('savedQuerylist',savedQueryList);
      });
    },

    deleteSavedQueryDeclined(){
      this.get('controller').set('selectedSavedQueryId', null);
      this.get('controller').set('showDeleteSaveQueryModal', false );
    },

    openDeleteSavedQueryModal(id){
      this.get('controller').set('showDeleteSaveQueryModal', true );
      this.get('controller').set('selectedSavedQueryId', id );
    },

    openAsWorksheet(savedQuery){

      let hasWorksheetModel = this.modelFor('queries'), self = this;
      let worksheetId;

      if (Ember.isEmpty(hasWorksheetModel)){
        worksheetId = 1;
      }else {

        let isWorksheetExist = (this.controllerFor('queries').get('model').filterBy('title', savedQuery.title).get('length') > 0);
        if(isWorksheetExist) {
          this.transitionTo('queries.query', savedQuery.title);
          return;
        }

        let worksheets = this.controllerFor('queries').get('model');
        worksheets.forEach((worksheet) => {
          worksheet.set('selected', false);
        });
        worksheetId = `worksheet${worksheets.get('length') + 1}`;
      }
      var isTabExisting = this.store.peekRecord('worksheet', savedQuery.id);
      if(isTabExisting) {
        self.transitionTo('queries.query', isTabExisting.get("id"));
        return;
      }
      this.get("savedQueries").fetchSavedQuery(savedQuery.get('queryFile')).then(function(response) {
        let localWs = {
          id: savedQuery.get('id'),
          title: savedQuery.get('title'),
          queryFile: savedQuery.get('queryFile'),
          query: response.file.fileContent,
          selectedDb : savedQuery.get('dataBase'),
          owner: savedQuery.get('owner'),
          selected: true
        };

        self.store.createRecord('worksheet', localWs );
        self.controllerFor('queries').set('worksheets', self.store.peekAll('worksheet'));

        self.transitionTo('queries.query', savedQuery.get('id'));
      }, (error) => {
         self.get('logger').danger('Failed to load the query', self.extractError(error));
      });
    }
  }

});
<commit_msg>AMBARI-22759 [Hive Views 2.0] Deleting a Saved query is Buggy<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.
 */

import Ember from 'ember';
import UILoggerMixin from '../mixins/ui-logger';

export default Ember.Route.extend(UILoggerMixin, {

  savedQueries: Ember.inject.service(),

  model() {
    return this.store.findAll('savedQuery').then(savedQueries => savedQueries.toArray());
  },

  setupController(controller, model) {
    this._super(...arguments);

    controller.set('savedQuerylist', model);

    controller.set('showDeleteSaveQueryModal', false);
    controller.set('selectedSavedQueryId', null);
    controller.set('preview', {"noSort":true});
    controller.set('title', {"noSort":true});
    controller.set('dataBase', {"noSort":true});
    controller.set('owner', {"noSort":true});
  },

  actions: {
    sort(sortProp, sortField, key) {
      let perm = {};
      perm[key] = true;
      this.get('controller').set(sortField, perm);
      this.get('controller').set('sortProp', [sortProp]);
    },
    deleteSavedQuery(){
      let queryId = this.get('controller').get('selectedSavedQueryId');
      let self = this;

      console.log('deleteSavedQuery', queryId);
      let recordToDelete = this.get('store').peekRecord('saved-query', queryId);
      recordToDelete.destroyRecord().then(function (data) {
        self.send('deleteSavedQueryDeclined');
        self.send('refreshSavedQueryList');
      }, (error) => {
        console.log('error', error);
      });
    },

    refreshSavedQueryList(){
      this.get('store').findAll('saved-query').then(data => {
        let savedQueryList = [];
        data.forEach(x => {
          let localSavedQuery = {
            'id': x.get('id'),
            'dataBase': x.get('dataBase'),
            'title': x.get('title'),
            'queryFile': x.get('queryFile'),
            'owner': x.get('owner'),
            'shortQuery': x.get('shortQuery')
          };
          savedQueryList.pushObject(localSavedQuery);
        });

        this.get('controller').set('savedQuerylist',savedQueryList);
      });
    },

    deleteSavedQueryDeclined(){
      this.get('controller').set('selectedSavedQueryId', null);
      this.get('controller').set('showDeleteSaveQueryModal', false );
    },

    openDeleteSavedQueryModal(id){
      this.get('controller').set('showDeleteSaveQueryModal', true );
      this.get('controller').set('selectedSavedQueryId', id );
    },

    openAsWorksheet(savedQuery){

      let hasWorksheetModel = this.modelFor('queries'), self = this;
      let worksheetId;

      if (Ember.isEmpty(hasWorksheetModel)){
        worksheetId = 1;
      }else {

        let isWorksheetExist = (this.controllerFor('queries').get('model').filterBy('title', savedQuery.title).get('length') > 0);
        if(isWorksheetExist) {
          this.transitionTo('queries.query', savedQuery.title);
          return;
        }

        let worksheets = this.controllerFor('queries').get('model');
        worksheets.forEach((worksheet) => {
          worksheet.set('selected', false);
        });
        worksheetId = `worksheet${worksheets.get('length') + 1}`;
      }
      var isTabExisting = this.store.peekRecord('worksheet', savedQuery.id);
      if(isTabExisting) {
        self.transitionTo('queries.query', isTabExisting.get("id"));
        return;
      }
      this.get("savedQueries").fetchSavedQuery(savedQuery.get('queryFile')).then(function(response) {
        let localWs = {
          id: savedQuery.get('id'),
          title: savedQuery.get('title'),
          queryFile: savedQuery.get('queryFile'),
          query: response.file.fileContent,
          selectedDb : savedQuery.get('dataBase'),
          owner: savedQuery.get('owner'),
          selected: true
        };

        self.store.createRecord('worksheet', localWs );
        self.controllerFor('queries').set('worksheets', self.store.peekAll('worksheet'));

        self.transitionTo('queries.query', savedQuery.get('id'));
      }, (error) => {
         self.get('logger').danger('Failed to load the query', self.extractError(error));
      });
    }
  }

});
<|endoftext|>


<commit_before>class ExperimentsService {
    /*@ngInject*/
    constructor(projectsAPI) {
        this.projectsAPI = projectsAPI;
    }

    getAllForProject(projectID) {
        return this.projectsAPI(projectID).one('experiments').getList();
    }

    createForProject(projectID, experiment) {
        return this.projectsAPI(projectID).one('experiments').customPOST(experiment);
    }

    updateForProject(projectID, experimentID, what) {
        return this.projectsAPI(projectID).one('experiments', experimentID).customPUT(what);
    }

    getForProject(projectID, experimentID) {
        return this.projectsAPI(projectID).one('experiments', experimentID).customGET();
    }

    createTask(projectID, experimentID, experimentTask) {
        return this.projectsAPI(projectID).one('experiments', experimentID).one('tasks').customPOST(experimentTask);
    }

    updateTask(projectID, experimentID, taskID, task) {
        return this.projectsAPI(projectID).one('experiments', experimentID).one('tasks', taskID).customPUT(task);
    }

    addTemplateToTask(projectID, experimentID, taskID, templateID) {
        return this.projectsAPI(projectID).one('experiments', experimentID).one('tasks', taskID)
            .one('template', templateID).customPOST({});
    }

    updateTaskTemplateProperties(projectID, experimentID, taskID, updateArgs) {
        return this.projectsAPI(projectID).one('experiments', experimentID).one('tasks', taskID)
            .one('template').customPUT(updateArgs);
    }

    updateTaskTemplateFiles(projectId, experimentId, taskId, updateFilesArgs) {
        return this.projectsAPI(projectId).one('experiments', experimentId).one('tasks', taskId)
            .one('template').customPUT(updateFilesArgs);
    }

    updateTaskTemplateSamples(projectId, experimentId, taskId, updateSamplesArgs) {
        return this.projectsAPI(projectId).one('experiments', experimentId).one('tasks', taskId)
            .one('template').customPUT(updateSamplesArgs);
    }

    updateProcess(projectId, experimentId, processId, updateArgs) {
        return this.projectsAPI(projectId)
            .one('experiments', experimentId)
            .one('processes', processId).customPUT(updateArgs)
            .then((process) => this.convertDatePropertyAttributes(process));
    }

    deleteTask(projectID, experimentID, taskID) {
        return this.projectsAPI(projectID).one('experiments', experimentID).one('tasks', taskID).customDELETE();
    }

    getSamplesForExperiment(projectId, experimentId) {
        return this.projectsAPI(projectId).one('experiments', experimentId).one('samples').customGET();
    }

    getProcessesForExperiment(projectId, experimentId) {
        return this.projectsAPI(projectId).one('experiments', experimentId).one('processes').customGET();
    }

    getProcessForExperiment(projectId, experimentId, processId) {
        return this.projectsAPI(projectId)
            .one('experiments', experimentId)
            .one('processes', processId).customGET()
            .then((process) => this.convertDatePropertyAttributes(process));
    }

    getFilesForExperiment(projectId, experimentId) {
        return this.projectsAPI(projectId).one('experiments', experimentId).one('files').customGET();
    }

    createProcessFromTemplate(projectId, experimentId, templateId) {
        return this.projectsAPI(projectId).one('experiments', experimentId).one('processes').one('templates', templateId)
            .customPOST();
    }

    convertDatePropertyAttributes(process) {
        if (process.setup) {
            let setup = process.setup;
            for (var i = 0; i < setup.length; i++) {
                let s = setup[i];
                if (s.properties) {
                    let properties = s.properties;
                    for (var j = 0; j < properties.length; j++) {
                        let property = properties[j];
                        if (property.otype && (property.otype == 'date')){
                            if (property.value) {
                                property.value = this.convertDateValueFromTransport(property.value);
                            }
                        }
                    }
                }
            }
        }
        return process;
    }

    convertDateValueForTransport(dateObj) {
        return dateObj.getTime();
    }

    convertDateValueFromTransport(dateNumber) {
        return new Date(dateNumber);
    }

}

angular.module('materialscommons').service('experimentsService', ExperimentsService);
<commit_msg>Example of using foreach and filter to shorten method.<commit_after>class ExperimentsService {
    /*@ngInject*/
    constructor(projectsAPI) {
        this.projectsAPI = projectsAPI;
    }

    getAllForProject(projectID) {
        return this.projectsAPI(projectID).one('experiments').getList();
    }

    createForProject(projectID, experiment) {
        return this.projectsAPI(projectID).one('experiments').customPOST(experiment);
    }

    updateForProject(projectID, experimentID, what) {
        return this.projectsAPI(projectID).one('experiments', experimentID).customPUT(what);
    }

    getForProject(projectID, experimentID) {
        return this.projectsAPI(projectID).one('experiments', experimentID).customGET();
    }

    createTask(projectID, experimentID, experimentTask) {
        return this.projectsAPI(projectID).one('experiments', experimentID).one('tasks').customPOST(experimentTask);
    }

    updateTask(projectID, experimentID, taskID, task) {
        return this.projectsAPI(projectID).one('experiments', experimentID).one('tasks', taskID).customPUT(task);
    }

    addTemplateToTask(projectID, experimentID, taskID, templateID) {
        return this.projectsAPI(projectID).one('experiments', experimentID).one('tasks', taskID)
            .one('template', templateID).customPOST({});
    }

    updateTaskTemplateProperties(projectID, experimentID, taskID, updateArgs) {
        return this.projectsAPI(projectID).one('experiments', experimentID).one('tasks', taskID)
            .one('template').customPUT(updateArgs);
    }

    updateTaskTemplateFiles(projectId, experimentId, taskId, updateFilesArgs) {
        return this.projectsAPI(projectId).one('experiments', experimentId).one('tasks', taskId)
            .one('template').customPUT(updateFilesArgs);
    }

    updateTaskTemplateSamples(projectId, experimentId, taskId, updateSamplesArgs) {
        return this.projectsAPI(projectId).one('experiments', experimentId).one('tasks', taskId)
            .one('template').customPUT(updateSamplesArgs);
    }

    updateProcess(projectId, experimentId, processId, updateArgs) {
        return this.projectsAPI(projectId)
            .one('experiments', experimentId)
            .one('processes', processId).customPUT(updateArgs)
            .then((process) => this.convertDatePropertyAttributes(process));
    }

    deleteTask(projectID, experimentID, taskID) {
        return this.projectsAPI(projectID).one('experiments', experimentID).one('tasks', taskID).customDELETE();
    }

    getSamplesForExperiment(projectId, experimentId) {
        return this.projectsAPI(projectId).one('experiments', experimentId).one('samples').customGET();
    }

    getProcessesForExperiment(projectId, experimentId) {
        return this.projectsAPI(projectId).one('experiments', experimentId).one('processes').customGET();
    }

    getProcessForExperiment(projectId, experimentId, processId) {
        return this.projectsAPI(projectId)
            .one('experiments', experimentId)
            .one('processes', processId).customGET()
            .then((process) => this.convertDatePropertyAttributes(process));
    }

    getFilesForExperiment(projectId, experimentId) {
        return this.projectsAPI(projectId).one('experiments', experimentId).one('files').customGET();
    }

    createProcessFromTemplate(projectId, experimentId, templateId) {
        return this.projectsAPI(projectId).one('experiments', experimentId).one('processes').one('templates', templateId)
            .customPOST();
    }

    convertDatePropertyAttributes(process) {
        if (process.setup) {
            let setup = process.setup;
            for (var i = 0; i < setup.length; i++) {
                let s = setup[i];
                if (s.properties) {
                    let properties = s.properties;
                    for (var j = 0; j < properties.length; j++) {
                        let property = properties[j];
                        if (property.otype && (property.otype == 'date')){
                            if (property.value) {
                                property.value = this.convertDateValueFromTransport(property.value);
                            }
                        }
                    }
                }
            }
        }
        return process;
    }

    convertDatePropertyAttributes2(process) {
        angular.forEach(process.setup, (s) => s.properties.filter(p => p.otype === 'date')
            .forEach(p => {
                if (p.value) {
                    p.value = this.convertDateValueFromTransport(p.value)
                }
            }));
    }

    convertDateValueForTransport(dateObj) {
        return dateObj.getTime();
    }

    convertDateValueFromTransport(dateNumber) {
        return new Date(dateNumber);
    }

}

angular.module('materialscommons').service('experimentsService', ExperimentsService);
<|endoftext|>


<commit_before>import React from 'react';
import sortBy from 'lodash/sortBy';

// Components
import Spinner from 'components/ui/Spinner';
import CustomTable from 'components/ui/customtable/CustomTable';

// Table components
import EditAction from './actions/EditAction';
import DeleteAction from './actions/DeleteAction';

// TDs
import StatusTD from './td/StatusTD';
import RelatedContentTD from './td/RelatedContentTD';

class DatasetTable extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      datasets: [],
      loading: true
    };
  }

  componentDidMount() {
    this.getDatasets();
  }

  /**
   * HELPERS
   * - getDatasets
  */
  getDatasets() {
    const { application } = this.props;
    const url = `${process.env.WRI_API_URL}/dataset?application=${application.join(',')}&includes=widget,layer,metadata,vocabulary&page[size]=${Date.now() / 100000}`;
    console.log(url);
    fetch(new Request(url))
      .then((response) => {
        if (response.ok) {
          return response.json();
        }
        throw new Error(response.statusText);
      })
      .then((response) => {
        const datasets = sortBy(response.data.map(dataset =>
          Object.assign({}, dataset.attributes, {
            id: dataset.id
          })
        ), 'name');
        this.setState({ datasets, loading: false });
      })
      .catch(() => {
        this.setState({ message: 'Error loading datasets', loading: false });
      });
  }

  render() {
    return (

        <Spinner className="-light" isLoading={this.state.loading} />

        <CustomTable
          columns={[
            { label: 'Name', value: 'name' },
            { label: 'Status', value: 'status', td: StatusTD },
            { label: 'Provider', value: 'provider' },
            { label: 'Related content', value: 'status', td: RelatedContentTD }
          ]}
          actions={{
            show: true,
            list: [
              { name: 'Edit', route: 'admin_data_detail', params: { tab: 'datasets', subtab: 'edit', id: '{{id}}' }, show: true, component: EditAction },
              { name: 'Remove', route: 'admin_data_detail', params: { tab: 'datasets', subtab: 'remove', id: '{{id}}' }, component: DeleteAction, componentProps: { authorization: this.props.authorization } }
              // { name: 'Metadata', route: 'admin_data_detail', params: { tab: 'datasets', subtab: 'metadata', id: '{{id}}' }, path: '/admin/data/datasets/:id/metadata', component: MetadataAction },
              // { name: 'Vocabularies', route: 'admin_data_detail', params: { tab: 'datasets', subtab: 'vocabularies', id: '{{id}}' }, path: '/admin/data/datasets/:id/vocabularies', component: VocabularyAction },
              // { name: 'Widgets', route: 'admin_data_detail', params: { tab: 'datasets', subtab: 'widgets', id: '{{id}}' }, path: '/admin/data/datasets/:id/widgets', component: WidgetAction }
              // { name: 'Layers', route: 'admin_data', params: { tab: 'datasets', subtab: 'layers', id: ':id' }, path: '/admin/data/datasets/:id/layers', component: LayerAction }
            ]
          }}
          filters={false}
          data={this.state.datasets}
          pageSize={20}
          pagination={{
            enabled: true,
            pageSize: 20,
            page: 0
          }}
          onToggleSelectedRow={(ids) => { console.info(ids); }}
          onRowDelete={(id) => { console.info(id); }}
        />

    );
  }
}

DatasetTable.defaultProps = {
  application: ['rw'],
  columns: [],
  actions: {}
};

DatasetTable.propTypes = {
  application: React.PropTypes.array.isRequired,
  authorization: React.PropTypes.string
};

export default DatasetTable;
<commit_msg>Datasets: style implemented<commit_after>import React from 'react';
import sortBy from 'lodash/sortBy';

// Components
import Spinner from 'components/ui/Spinner';
import CustomTable from 'components/ui/customtable/CustomTable';

// Table components
import EditAction from './actions/EditAction';
import DeleteAction from './actions/DeleteAction';

// TDs
import StatusTD from './td/StatusTD';
import RelatedContentTD from './td/RelatedContentTD';

class DatasetTable extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      datasets: [],
      loading: true
    };
  }

  componentDidMount() {
    this.getDatasets();
  }

  /**
   * HELPERS
   * - getDatasets
  */
  getDatasets() {
    const { application } = this.props;
    const url = `${process.env.WRI_API_URL}/dataset?application=${application.join(',')}&includes=widget,layer,metadata,vocabulary&page[size]=${Date.now() / 100000}`;

    fetch(new Request(url))
      .then((response) => {
        if (response.ok) {
          return response.json();
        }
        throw new Error(response.statusText);
      })
      .then((response) => {
        const datasets = sortBy(response.data.map(dataset =>
          Object.assign({}, dataset.attributes, {
            id: dataset.id
          })
        ), 'name');
        this.setState({ datasets, loading: false });
      })
      .catch(() => {
        this.setState({ message: 'Error loading datasets', loading: false });
      });
  }

  render() {
    return (

        <Spinner className="-light" isLoading={this.state.loading} />

        <CustomTable
          columns={[
            { label: 'Name', value: 'name' },
            { label: 'Status', value: 'status', td: StatusTD },
            { label: 'Provider', value: 'provider' },
            { label: 'Related content', value: 'status', td: RelatedContentTD }
          ]}
          actions={{
            show: true,
            list: [
              { name: 'Edit', route: 'admin_data_detail', params: { tab: 'datasets', subtab: 'edit', id: '{{id}}' }, show: true, component: EditAction },
              { name: 'Remove', route: 'admin_data_detail', params: { tab: 'datasets', subtab: 'remove', id: '{{id}}' }, component: DeleteAction, componentProps: { authorization: this.props.authorization } }
              // { name: 'Metadata', route: 'admin_data_detail', params: { tab: 'datasets', subtab: 'metadata', id: '{{id}}' }, path: '/admin/data/datasets/:id/metadata', component: MetadataAction },
              // { name: 'Vocabularies', route: 'admin_data_detail', params: { tab: 'datasets', subtab: 'vocabularies', id: '{{id}}' }, path: '/admin/data/datasets/:id/vocabularies', component: VocabularyAction },
              // { name: 'Widgets', route: 'admin_data_detail', params: { tab: 'datasets', subtab: 'widgets', id: '{{id}}' }, path: '/admin/data/datasets/:id/widgets', component: WidgetAction }
              // { name: 'Layers', route: 'admin_data', params: { tab: 'datasets', subtab: 'layers', id: ':id' }, path: '/admin/data/datasets/:id/layers', component: LayerAction }
            ]
          }}
          filters={false}
          data={this.state.datasets}
          pageSize={20}
          pagination={{
            enabled: true,
            pageSize: 20,
            page: 0
          }}
          onToggleSelectedRow={(ids) => { console.info(ids); }}
          onRowDelete={(id) => { console.info(id); }}
        />

    );
  }
}

DatasetTable.defaultProps = {
  application: ['rw'],
  columns: [],
  actions: {}
};

DatasetTable.propTypes = {
  application: React.PropTypes.array.isRequired,
  authorization: React.PropTypes.string
};

export default DatasetTable;
<|endoftext|>


<commit_before>
  /**
   *  WMS layers pane for basemap chooser
   */

  cdb.admin.WMSBasemapLayersPaneItem = cdb.core.Model.extend({
  });

  cdb.admin.WMSBasemapLayersPaneItems = Backbone.Collection.extend({
    model: cdb.admin.WMSBasemapLayersPaneItem
  });

  cdb.admin.WMSBasemapLayersPaneItemView = cdb.core.View.extend({

    tagName: "li",

    template_base: '
<%= name %>
 Add this',

    events: {
      'click a.button'   : "_onClickLayer"
    },

    initialize: function() {
      this.template = _.template(this.template_base);
    },

    _onClickLayer: function(e) {
      this.killEvent(e);

      var self = this;

      if ($(e.target).hasClass("disabled")) return;

      var name = this.model.get("name") || this.model.get("title");
      if (name && parseInt(name) && _.isNumber(parseInt(name))) name = "w" + name;

      var className = name.replace(/default/g, '').replace(/\s+/g, '').replace(/[^a-zA-Z_0-9 ]/g, "").toLowerCase();

      var w = new cdb.admin.WMSService({
        wms_url:        this.options.url,
        layer:          this.model.get("name"),
        srs:            this.model.get("srs"),
        title:          this.model.get("title"),
        name:           this.model.get("name"),
        bounding_boxes: this.model.get("bounding_boxes")
      });

      cdb.god.trigger('mixpanel', "WMS layer selected", w.toJSON());
      this.trigger('layer_selected');

      w.save({},{
        success: function(m) {

          if (m.get('mapproxy_id')) {

            var urlTemplate = m.getProxyTiles();
            var layer = new cdb.admin.TileLayer({
              urlTemplate:    urlTemplate,
              attribution:    m.get('attribution') || null,
              maxZoom:        21,
              minZoom:        0,
              name:           m.get("title") || m.get("name"),
              proxy:          true,
              bounding_boxes: m.get('bounding_boxes')
            });

            var name = layer._generateClassName(urlTemplate);
            self.trigger('layer_choosen', layer, name);
          }
        }
      });

    },

    render: function() {
      var options = this.model.toJSON();
      this.$el.html(this.template(options));
      return this;
    }

  });

  cdb.admin.WMSBasemapLayersPane = cdb.core.View.extend({

    className: "basemap-pane",

    initialize: function() {

      var self = this;

      _.bindAll(this, '_showLoader');

      this.template = this.options.template || cdb.templates.getTemplate('table/views/basemap/basemap_chooser_wms_pane');

      this._loadLayers(this.options.layers);

      this.render();

      setTimeout(function() {
        self.trigger("enableBack", this);
      }, 200);
    },

    checkTileJson: function() {},

    _loadLayers: function(layers) {
      var items = _.map(layers, function(item) {
        return new cdb.admin.WMSBasemapLayersPaneItem({
          name:           item.name,
          title:          item.title,
          srs:            item.srs,
          crs:            item.crs,
          bounding_boxes: item.llbbox
        });

      });

      this.items = new cdb.admin.WMSBasemapLayersPaneItems(items);
    },

    _hideLoader: function() {},
    _hideError: function() {},

    _showLoader: function() {
      this.$el.append(cdb.templates.getTemplate('table/views/basemap/basemap_chooser_wms_proxy_loader')());
      this.$('.basemap_chooser_wms_items').hide();
    },

    render: function() {

      this.clearSubViews();

      this.$el.html(this.template({ layers: this.options.layers }));

      var self = this;
      this.items.each(function(layer) {

        var view = new cdb.admin.WMSBasemapLayersPaneItemView({
          model: layer,
          url: self.options.url
        });

        self.$("ul").append(view.render().$el);
        self.addView(view);

        view.bind('layer_selected', self._showLoader, this);
        view.bind("layer_choosen", function(layer) {
          self.trigger('successChooser', layer, "wms_name");
        });

      });

      return this;
    }
  });
<commit_msg>CDB-2723 - changed mixpanel parameters<commit_after>
  /**
   *  WMS layers pane for basemap chooser
   */

  cdb.admin.WMSBasemapLayersPaneItem = cdb.core.Model.extend({
  });

  cdb.admin.WMSBasemapLayersPaneItems = Backbone.Collection.extend({
    model: cdb.admin.WMSBasemapLayersPaneItem
  });

  cdb.admin.WMSBasemapLayersPaneItemView = cdb.core.View.extend({

    tagName: "li",

    template_base: '
<%= name %>
 Add this',

    events: {
      'click a.button'   : "_onClickLayer"
    },

    initialize: function() {
      this.template = _.template(this.template_base);
    },

    _onClickLayer: function(e) {
      this.killEvent(e);

      var self = this;

      if ($(e.target).hasClass("disabled")) return;

      var name = this.model.get("name") || this.model.get("title");
      if (name && parseInt(name) && _.isNumber(parseInt(name))) name = "w" + name;

      var className = name.replace(/default/g, '').replace(/\s+/g, '').replace(/[^a-zA-Z_0-9 ]/g, "").toLowerCase();

      var d = {
        wms_url:        this.options.url,
        layer:          this.model.get("name"),
        srs:            this.model.get("srs"),
        title:          this.model.get("title"),
        name:           this.model.get("name"),
        bounding_boxes: this.model.get("bounding_boxes")
      }

      var w = new cdb.admin.WMSService(d);

      cdb.god.trigger('mixpanel', "WMS layer selected", d);
      this.trigger('layer_selected');

      w.save({},{
        success: function(m) {

          if (m.get('mapproxy_id')) {

            var urlTemplate = m.getProxyTiles();
            var layer = new cdb.admin.TileLayer({
              urlTemplate:    urlTemplate,
              attribution:    m.get('attribution') || null,
              maxZoom:        21,
              minZoom:        0,
              name:           m.get("title") || m.get("name"),
              proxy:          true,
              bounding_boxes: m.get('bounding_boxes')
            });

            var name = layer._generateClassName(urlTemplate);
            self.trigger('layer_choosen', layer, name);
          }
        }
      });

    },

    render: function() {
      var options = this.model.toJSON();
      this.$el.html(this.template(options));
      return this;
    }

  });

  cdb.admin.WMSBasemapLayersPane = cdb.core.View.extend({

    className: "basemap-pane",

    initialize: function() {

      var self = this;

      _.bindAll(this, '_showLoader');

      this.template = this.options.template || cdb.templates.getTemplate('table/views/basemap/basemap_chooser_wms_pane');

      this._loadLayers(this.options.layers);

      this.render();

      setTimeout(function() {
        self.trigger("enableBack", this);
      }, 200);
    },

    checkTileJson: function() {},

    _loadLayers: function(layers) {
      var items = _.map(layers, function(item) {
        return new cdb.admin.WMSBasemapLayersPaneItem({
          name:           item.name,
          title:          item.title,
          srs:            item.srs,
          crs:            item.crs,
          bounding_boxes: item.llbbox
        });

      });

      this.items = new cdb.admin.WMSBasemapLayersPaneItems(items);
    },

    _hideLoader: function() {},
    _hideError: function() {},

    _showLoader: function() {
      this.$el.append(cdb.templates.getTemplate('table/views/basemap/basemap_chooser_wms_proxy_loader')());
      this.$('.basemap_chooser_wms_items').hide();
    },

    render: function() {

      this.clearSubViews();

      this.$el.html(this.template({ layers: this.options.layers }));

      var self = this;
      this.items.each(function(layer) {

        var view = new cdb.admin.WMSBasemapLayersPaneItemView({
          model: layer,
          url: self.options.url
        });

        self.$("ul").append(view.render().$el);
        self.addView(view);

        view.bind('layer_selected', self._showLoader, this);
        view.bind("layer_choosen", function(layer) {
          self.trigger('successChooser', layer, "wms_name");
        });

      });

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


<commit_before>import { buildSelector } from '../helpers';

/**
 * Creates an action to click an element
 *
 * @example
 *
 *   var page = PageObject.create({
 *     submit: clickable('button[type=submit]')
 *   });
 *
 *   page.submit();
 *
 * @param {string} selector - CSS selector of the element to click
 * @param {Object} options - Additional options
 * @param {string} options.scope - Overrides parent scope
 * @param {number} options.at - Reduce the set of matched elements to the one at the specified index
 * @param {boolean} options.resetScope - Ignore parent scope
 * @return {Descriptor}
 */
export function clickable(selector, options = {}) {
  return {
    isDescriptor: true,

    value() {
      /* global click */
      click(buildSelector(this, selector, options));

      return this;
    }
  };
}
<commit_msg>Use jsdoc for clickable property<commit_after>import { buildSelector } from '../helpers';

/**
 * Clicks element matched by selector
 *
 * @example
 *
 * // <button class="continue">Continue<button>
 * // <button>Cancel</button>
 *
 * var page = PageObject.create({
 *   continue: clickable('button.continue')
 * });
 *
 * // clicks on element with selector 'button.continue'
 * page.continue();
 *
 * @example
 *
 * //

 * //   <button>Continue<button>
 * //

 * // <button>Cancel</button>
 *
 * var page = PageObject.create({
 *   continue: clickable('button.continue', { scope: '.scope' })
 * });
 *
 * // clicks on element with selector '.scope button.continue'
 * page.continue();
 *
 * @example
 *
 * //

 * //   <button>Continue<button>
 * //

 * // <button>Cancel</button>
 *
 * var page = PageObject.create({
 *   scope: '.scope',
 *   continue: clickable('button.continue')
 * });
 *
 * // clicks on element with selector '.scope button.continue'
 * page.continue();
 *
 * @public
 *
 * @param {string} selector - CSS selector of the element to click
 * @param {Object} options - Additional options
 * @param {string} options.scope - Overrides parent scope
 * @param {number} options.at - Reduce the set of matched elements to the one at the specified index
 * @param {boolean} options.resetScope - Ignore parent scope
 * @return {Descriptor}
 */

export function clickable(selector, options = {}) {
  return {
    isDescriptor: true,

    value() {
      /* global click */
      click(buildSelector(this, selector, options));

      return this;
    }
  };
}
<|endoftext|>


<commit_before>function every1(array, test) {
    for (let elem of array) {
        if (!test(elem)) return false;
    }
    return true;
}

function every2(array, test) {
    return !array.some(elem => !test(elem));
}

console.log(every1([1, 3, 5], n => n < 10));
// → true
console.log(every1([2, 4, 16], n => n < 10));
// → false
console.log(every1([], n => n < 10));
// → true

console.log(every2([1, 3, 5], n => n < 10));
// → true
console.log(every2([2, 4, 16], n => n < 10));
// → false
console.log(every2([], n => n < 10));
// → true
<commit_msg>Add chapter 5, exercise 3<commit_after>function every(array, test) {
	for (let el of array) {
		if (!test(el)) {
			return false;
		}
	}

	return true;
}

function everySome(array, test) {
	return !array.some(n => !test(n));
}
<|endoftext|>


<commit_before>(function (Q, $, window, undefined) {
/**
 * Assets/service/preview tool.
 * Renders a tool to preview services
 * @class Assets/service/preview
 * @constructor
 * @param {Object} [options] options to pass besides the ones to Streams/preview tool
 */
Q.Tool.define("Assets/service/preview", ["Streams/preview"], function(options, preview) {
	var tool = this;
	tool.preview = preview;

	// to set uploaded images sizes
	tool.preview.state.imagepicker.save = "Assets/service";

	Q.addStylesheet('{{Assets}}/css/tools/ServicePreview.css', { slotName: 'Assets' });

	preview.state.creatable.preprocess = function (_proceed) {
		tool.openDialog(function (dialog) {
			var requiredParticipants = [];
			$(".Assets_service_requiredParticipants div[data-streamName].Q_selected").each(function () {
				requiredParticipants.push($(this).attr("data-streamName"));
			});

			Q.handle(_proceed, preview, [{
				title: $("input[name=title]", dialog).val(),
				content: $("textarea[name=description]", dialog).val(),
				attributes: {
					price: $("input[name=price]", dialog).val(),
					link: $("input[name=link]", dialog).val(),
					payment: $("select[name=payment]", dialog).val(),
					requiredParticipants: requiredParticipants
				}
			}]);
		}, function () {
			Q.handle(_proceed, preview, [false]);
		});
	};

	// check for related services before delete
	preview.state.beforeClose = function (_delete) {
		tool.element.classList.add("Q_working");

		Q.req("Assets/services", "data", function (err, responce) {
			if (Q.firstErrorMessage(err, responce && responce.errors)) {
				return;
			}

			tool.element.classList.remove("Q_working");

			var relatedServices = Q.getObject("slots.data.relatedServices", responce) || [];

			if (relatedServices.length) {
				var message = tool.text.services.AreYouSureDelete;
				message += "
" + tool.text.services.AmountServicesRelated.interpolate({amount: relatedServices.length});

				Q.confirm(message, function (result) {
					if (!result){
						return;
					}

					_delete();
				});

				return;
			}

			_delete();
		}, {
			fields: {
				publisherId: preview.state.publisherId,
				streamName: preview.state.streamName
			}
		});
	};

	$(tool.element).on(Q.Pointer.fastclick, function () {
		Q.handle(tool.state.onInvoke, tool);
	});

	Q.Text.get('Assets/content', function (err, text) {
		var msg = Q.firstErrorMessage(err);
		if (msg) {
			return console.warn(msg);
		}

		tool.text = text;

		preview.state.onRefresh.add(tool.refresh.bind(tool));
	});
},

{
	editable: true,
	onInvoke: new Q.Event(function () {
		var tool = this;
		var state = this.state;
		var previewState = tool.preview.state;

		if (!previewState.publisherId || !previewState.streamName || !state.editable) {
			return;
		}

		Q.Streams.get(previewState.publisherId, previewState.streamName, function () {
			if (!this.testWriteLevel('edit')) {
				return;
			}

			tool.edit();
		});
	})
},

{
	refresh: function (stream, callback) {
		var tool = this;
		tool.stream = stream;
		var ps = tool.preview.state;
		var $toolElement = $(tool.element);
		var price = stream.getAttribute('price');

		Q.Template.render('Assets/service/preview', {
			title: stream.fields.title,
			price: price ? '($' + parseFloat(price).toFixed(2) + ')' : '',
		}, function (err, html) {
			if (err) return;
			tool.element.innerHTML = html;

			tool.preview.icon($("img.Streams_preview_icon", tool.element)[0]);
		});

		Q.Streams.Stream.onFieldChanged(ps.publisherId, ps.streamName)
		.set(function (fields, changed) {
			if (changed.title) {
				tool.$('.Streams_preview_title').html(changed.title);
			}
		}, tool);

		Q.Streams.Stream.onAttribute(ps.publisherId, ps.streamName, "price")
		.set(function (attributes, k) {
			var price = parseFloat(attributes[k]);
			price = price ? "($" + price.toFixed(2) + ")" : '';
			$("span.Assets_service_preview_price", tool.element).html(price);
		}, tool);
	},
	edit: function () {
		var tool = this;
		var previewState = this.preview.state;

		Q.Streams.get(previewState.publisherId, previewState.streamName, function () {
			var stream = this;
			if (!stream.testWriteLevel('edit')) {
				return;
			}

			tool.openDialog(function (dialog) {
				stream.pendingFields.title = $("input[name=title]", dialog).val();
				stream.pendingFields.content = $("textarea[name=description]", dialog).val();
				var requiredParticipants = [];
				$(".Assets_service_requiredParticipants div[data-streamName].Q_selected").each(function () {
					requiredParticipants.push($(this).attr("data-streamName"));
				});
				stream.setAttribute('requiredParticipants', requiredParticipants);
				stream.setAttribute('payment', $("select[name=payment]", dialog).val());
				stream.setAttribute('price', $("input[name=price]", dialog).val());
				stream.setAttribute('link', $("input[name=link]", dialog).val());
				stream.save({
					onSave: function () {
						stream.refresh();
					}
				});
			}, null, {
				title: stream.fields.title,
				payment: stream.getAttribute('payment'),
				price: stream.getAttribute('price'),
				selectedParticipants: stream.getAttribute('requiredParticipants'),
				link: stream.getAttribute('link'),
				description: stream.fields.content
			});
		});
	},
	openDialog: function (saveCallback, closeCallback, fields) {
		var tool = this;
		var relatedParticipants = Q.extend({}, Q.getObject("Assets.service.relatedParticipants", Q));
		var selectedParticipants = Q.getObject("selectedParticipants", fields);
		if (selectedParticipants) {
			Q.each(relatedParticipants, function (index) {
				relatedParticipants[index].selected = selectedParticipants.includes(index);
			});
		}

		Q.Dialogs.push({
			title: Q.getObject("services.NewServiceTemplate.Title", tool.text) || "New Service Template",
			template: {
				name: "Assets/service/composer",
				fields: Q.extend({
					relatedParticipants: relatedParticipants,
					text: tool.text
				}, fields)
			},
			className: "Assets_service_composer",
			onActivate: function (dialog) {
				$("input,textarea", dialog).plugin('Q/placeholders');

				var $price = $("label[for=price]", dialog);
				var payment = Q.getObject("payment", fields) || 'free';
				if (payment === 'free') {
					$price.hide();
				}

				var $payment = $("select[name=payment]", dialog).on('change', function () {
					if ($payment.val() === 'free') {
						$("input[name=price]", $price).val('');
						$price.hide();
					} else {
						$price.show();
					}
				});
				$payment.val(payment).trigger("change");

				$(".Assets_service_requiredParticipants div[data-streamName]", dialog).on(Q.Pointer.fastclick, function () {
					$(this).toggleClass("Q_selected");
				});

				$("button[name=save]", dialog).on(Q.Pointer.fastclick, function () {
					var $form = $(this).closest("form");
					var valid = true;

					Q.each(['title', 'price', 'description'], function (i, value) {
						var $item = $("input[name=" + value + "]", $form);

						if ($item.is(":visible") && $item.attr('required') && !$item.val()) {
							$item.addClass('Q_error');
							valid = false;
						} else {
							$item.removeClass('Q_error');
						}
					});

					if (!valid) {
						return false;
					}

					Q.handle(saveCallback, dialog, [dialog]);
					Q.Dialogs.pop();
					return false;
				});
			},
			onClose: function (dialog) {
				Q.handle(closeCallback, dialog, [dialog]);
			}
		});
	}
});

Q.Template.set('Assets/service/preview',
	'
'
	+ ''
	+ '
'
	+ '
{{title}}
'
	+ '{{price}}'
	+ '

'
);

Q.Template.set("Assets/service/composer",
	'<form>' +
	'	<input type="text" name="title" required placeholder="{{text.services.NewServiceTemplate.TitlePlaceholder}}" value="{{title}}">' +
	'	<select name="payment"><option value="free">{{text.services.Free}}</option><option value="optional">{{text.services.OptionalContribution}}</option><option value="required">{{text.services.RequiredPayment}}</option></select>' +
	'	<input type="text" name="price" required placeholder="{{text.services.NewServiceTemplate.PricePlaceholder}}" value="{{price}}">' +
	'	{{#if relatedParticipants}}' +
	'		{{text.services.NewServiceTemplate.SelectRequiredParticipants}}' +
	'
' +
	'			{{#each relatedParticipants}}' +
	'
{{this.streamName}}
' +
	'			{{/each}}' +
	'
' +
	'	{{/if}}' +
	'	<input type="text" name="link" placeholder="{{text.services.NewServiceTemplate.LinkPlaceholder}}" value="{{link}}">' +
	'	<textarea name="description" placeholder="{{text.services.NewServiceTemplate.DescriptionPlaceholder}}">{{description}}</textarea>' +
	'	<button name="save" class="Q_button">{{text.services.NewServiceTemplate.SaveService}}</button>' +
	'</form>'
);

})(Q, Q.$, window);<commit_msg>Updated Assets/service/preview tool. Use stream.observe() to listen messages without participating.<commit_after>(function (Q, $, window, undefined) {
/**
 * Assets/service/preview tool.
 * Renders a tool to preview services
 * @class Assets/service/preview
 * @constructor
 * @param {Object} [options] options to pass besides the ones to Streams/preview tool
 */
Q.Tool.define("Assets/service/preview", ["Streams/preview"], function(options, preview) {
	var tool = this;
	tool.preview = preview;

	// to set uploaded images sizes
	tool.preview.state.imagepicker.save = "Assets/service";

	Q.addStylesheet('{{Assets}}/css/tools/ServicePreview.css', { slotName: 'Assets' });

	preview.state.creatable.preprocess = function (_proceed) {
		tool.openDialog(function (dialog) {
			var requiredParticipants = [];
			$(".Assets_service_requiredParticipants div[data-streamName].Q_selected").each(function () {
				requiredParticipants.push($(this).attr("data-streamName"));
			});

			Q.handle(_proceed, preview, [{
				title: $("input[name=title]", dialog).val(),
				content: $("textarea[name=description]", dialog).val(),
				attributes: {
					price: $("input[name=price]", dialog).val(),
					link: $("input[name=link]", dialog).val(),
					payment: $("select[name=payment]", dialog).val(),
					requiredParticipants: requiredParticipants
				}
			}]);
		}, function () {
			Q.handle(_proceed, preview, [false]);
		});
	};

	// check for related services before delete
	preview.state.beforeClose = function (_delete) {
		tool.element.classList.add("Q_working");

		Q.req("Assets/services", "data", function (err, responce) {
			if (Q.firstErrorMessage(err, responce && responce.errors)) {
				return;
			}

			tool.element.classList.remove("Q_working");

			var relatedServices = Q.getObject("slots.data.relatedServices", responce) || [];

			if (relatedServices.length) {
				var message = tool.text.services.AreYouSureDelete;
				message += "
" + tool.text.services.AmountServicesRelated.interpolate({amount: relatedServices.length});

				Q.confirm(message, function (result) {
					if (!result){
						return;
					}

					_delete();
				});

				return;
			}

			_delete();
		}, {
			fields: {
				publisherId: preview.state.publisherId,
				streamName: preview.state.streamName
			}
		});
	};

	$(tool.element).on(Q.Pointer.fastclick, function () {
		Q.handle(tool.state.onInvoke, tool);
	});

	Q.Text.get('Assets/content', function (err, text) {
		var msg = Q.firstErrorMessage(err);
		if (msg) {
			return console.warn(msg);
		}

		tool.text = text;

		preview.state.onRefresh.add(tool.refresh.bind(tool));
	});
},

{
	editable: true,
	onInvoke: new Q.Event(function () {
		var tool = this;
		var state = this.state;
		var previewState = tool.preview.state;

		if (!previewState.publisherId || !previewState.streamName || !state.editable) {
			return;
		}

		Q.Streams.get(previewState.publisherId, previewState.streamName, function () {
			if (!this.testWriteLevel('edit')) {
				return;
			}

			tool.edit();
		});
	})
},

{
	refresh: function (stream, callback) {
		// track stream changes online
		stream.observe();

		var tool = this;
		tool.stream = stream;
		var ps = tool.preview.state;
		var price = stream.getAttribute('price');

		Q.Template.render('Assets/service/preview', {
			title: stream.fields.title,
			price: price ? '($' + parseFloat(price).toFixed(2) + ')' : '',
		}, function (err, html) {
			if (err) return;
			tool.element.innerHTML = html;

			tool.preview.icon($("img.Streams_preview_icon", tool.element)[0]);
		});

		Q.Streams.Stream.onFieldChanged(ps.publisherId, ps.streamName)
		.set(function (fields, changed) {
			if (changed.title) {
				tool.$('.Streams_preview_title').html(changed.title);
			}
		}, tool);

		Q.Streams.Stream.onAttribute(ps.publisherId, ps.streamName, "price")
		.set(function (attributes, k) {
			var price = parseFloat(attributes[k]);
			price = price ? "($" + price.toFixed(2) + ")" : '';
			$("span.Assets_service_preview_price", tool.element).html(price);
		}, tool);
	},
	edit: function () {
		var tool = this;
		var previewState = this.preview.state;

		Q.Streams.get(previewState.publisherId, previewState.streamName, function () {
			var stream = this;
			if (!stream.testWriteLevel('edit')) {
				return;
			}

			tool.openDialog(function (dialog) {
				stream.pendingFields.title = $("input[name=title]", dialog).val();
				stream.pendingFields.content = $("textarea[name=description]", dialog).val();
				var requiredParticipants = [];
				$(".Assets_service_requiredParticipants div[data-streamName].Q_selected").each(function () {
					requiredParticipants.push($(this).attr("data-streamName"));
				});
				stream.setAttribute('requiredParticipants', requiredParticipants);
				stream.setAttribute('payment', $("select[name=payment]", dialog).val());
				stream.setAttribute('price', $("input[name=price]", dialog).val());
				stream.setAttribute('link', $("input[name=link]", dialog).val());
				stream.save({
					onSave: function () {
						stream.refresh();
					}
				});
			}, null, {
				title: stream.fields.title,
				payment: stream.getAttribute('payment'),
				price: stream.getAttribute('price'),
				selectedParticipants: stream.getAttribute('requiredParticipants'),
				link: stream.getAttribute('link'),
				description: stream.fields.content
			});
		});
	},
	openDialog: function (saveCallback, closeCallback, fields) {
		var tool = this;
		var relatedParticipants = Q.extend({}, Q.getObject("Assets.service.relatedParticipants", Q));
		var selectedParticipants = Q.getObject("selectedParticipants", fields);
		if (selectedParticipants) {
			Q.each(relatedParticipants, function (index) {
				relatedParticipants[index].selected = selectedParticipants.includes(index);
			});
		}

		Q.Dialogs.push({
			title: Q.getObject("services.NewServiceTemplate.Title", tool.text) || "New Service Template",
			template: {
				name: "Assets/service/composer",
				fields: Q.extend({
					relatedParticipants: relatedParticipants,
					text: tool.text
				}, fields)
			},
			className: "Assets_service_composer",
			onActivate: function (dialog) {
				$("input,textarea", dialog).plugin('Q/placeholders');

				var $price = $("label[for=price]", dialog);
				var payment = Q.getObject("payment", fields) || 'free';
				if (payment === 'free') {
					$price.hide();
				}

				var $payment = $("select[name=payment]", dialog).on('change', function () {
					if ($payment.val() === 'free') {
						$("input[name=price]", $price).val('');
						$price.hide();
					} else {
						$price.show();
					}
				});
				$payment.val(payment).trigger("change");

				$(".Assets_service_requiredParticipants div[data-streamName]", dialog).on(Q.Pointer.fastclick, function () {
					$(this).toggleClass("Q_selected");
				});

				$("button[name=save]", dialog).on(Q.Pointer.fastclick, function () {
					var $form = $(this).closest("form");
					var valid = true;

					Q.each(['title', 'price', 'description'], function (i, value) {
						var $item = $("input[name=" + value + "]", $form);

						if ($item.is(":visible") && $item.attr('required') && !$item.val()) {
							$item.addClass('Q_error');
							valid = false;
						} else {
							$item.removeClass('Q_error');
						}
					});

					if (!valid) {
						return false;
					}

					Q.handle(saveCallback, dialog, [dialog]);
					Q.Dialogs.pop();
					return false;
				});
			},
			onClose: function (dialog) {
				Q.handle(closeCallback, dialog, [dialog]);
			}
		});
	},
	Q: {
		beforeRemove: function () {
			if (this.stream) {
				this.stream.neglect();
			}
		}
	}
});

Q.Template.set('Assets/service/preview',
	'
'
	+ ''
	+ '
'
	+ '
{{title}}
'
	+ '{{price}}'
	+ '

'
);

Q.Template.set("Assets/service/composer",
	'<form>' +
	'	<input type="text" name="title" required placeholder="{{text.services.NewServiceTemplate.TitlePlaceholder}}" value="{{title}}">' +
	'	<select name="payment"><option value="free">{{text.services.Free}}</option><option value="optional">{{text.services.OptionalContribution}}</option><option value="required">{{text.services.RequiredPayment}}</option></select>' +
	'	<input type="text" name="price" required placeholder="{{text.services.NewServiceTemplate.PricePlaceholder}}" value="{{price}}">' +
	'	{{#if relatedParticipants}}' +
	'		{{text.services.NewServiceTemplate.SelectRequiredParticipants}}' +
	'
' +
	'			{{#each relatedParticipants}}' +
	'
{{this.streamName}}
' +
	'			{{/each}}' +
	'
' +
	'	{{/if}}' +
	'	<input type="text" name="link" placeholder="{{text.services.NewServiceTemplate.LinkPlaceholder}}" value="{{link}}">' +
	'	<textarea name="description" placeholder="{{text.services.NewServiceTemplate.DescriptionPlaceholder}}">{{description}}</textarea>' +
	'	<button name="save" class="Q_button">{{text.services.NewServiceTemplate.SaveService}}</button>' +
	'</form>'
);

})(Q, Q.$, window);<|endoftext|>


<commit_before>define([ 'jquery' ], function(jquery) {
	var hi5 = {
		version : "0.7.0"
	};
	var grammar = {};

	grammar["Application"] = function($e) {
		handleUIElements($e);
	};

	grammar["TrimmedWindow"] = function($e) {
		handleUIElements($e);
		handleUIElements($e, ".Menu");
		handleUIElements($e, ".TrimBar");
	};

	grammar["Menu"] = function($e) {
		var $menuTrigger = $("☰");
		$menuTrigger.click(function() {
			// show the menu panel configured below
			$e.show();
		});
		// add to container of the menu
		$e.parent().prepend($menuTrigger);

		// the menu panel which will be shown if the menu trigger is pressed
		$e.addClass("w3-sidenav w3-white w3-card-2 w3-animate-right");
		$e.hide();
		$e.css("right", "0");

		var $closeItem = $(""
				+ "Close×");
		$e.prepend($closeItem);
		$closeItem.click(function() {
			$e.hide();
		});

		handleUIElements($e, ".MenuItem");
	};

	grammar["MenuItem"] = function($e) {
		// TODO handle sub menus
		handleUIElements($e, ".MenuItem");
	};

	grammar["DirectMenuItem"] = function($e) {
		processDirectItem($e, true, true);
	};
	grammar["DirectToolItem"] = function($e) {
		processDirectItem($e, false, false);
	}

	grammar["GenericStack"] = function($e, stackElementsType) {
		if (stackElementsType == null) {
			stackElementsType = $e.children().eq(0).attr("etype");
		}

		var $ul = $("

");
		$e.children("." + stackElementsType).hide().each(function() {
			var $p = $(this);
			var $a = $("" + $p.attr("label") + "");

			var iconSpanHtml = getIconSpanHtml($p, $p.attr("iconURI"));
			if (iconSpanHtml) {
				$a.prepend(iconSpanHtml);
			}

			var $li = $("

");
			var clickHandler = function() {
				var $pers = $e.children("." + stackElementsType);
				$pers.hide();
				$pers.eq($li.index()).show();
				$ul.children().attr("active", "false");
				$li.attr("active", "true");
			};
			$a.click(clickHandler);
			// install click handler also for stack element
			// to allow to programmatically show it
			$p.click(clickHandler);
			$li.append($a);
			$ul.append($li);
		});
		$e.prepend($ul);
		handleUIElements($e);
		// select first stack element
		$ul.find("a").eq(0).trigger('click');
	};

	grammar["PerspectiveStack"] = function($e) {
		grammar["GenericStack"]($e, "Perspective");
	};

	grammar["Perspective"] = function($e) {
		handleUIElements($e);
	};

	grammar["PartStack"] = function($e) {
		grammar["GenericStack"]($e, "Part");
	};

	grammar["Part"] = function($e) {
		$("[tags~='ViewMenu']", $e).each(function() {
			handleUIElements($e, ".Menu");
		});
		handleUIElements($e, ".ToolBar");

		$e.addClass("w3-panel");
		$e.addClass("w3-border");
		var contribution = $e.attr("contributionuri");

		if (!contribution) {
			contribution = $e.attr("state_index");
		}

		var url = toUrl($e, contribution);
		var $contents = $("

");
		$e.append($contents);
		$contents.load(url);
	};

	grammar["TrimBar"] = function($e) {
		var dir = $e.attr("direction");
		handleUIElements($e);
	};

	grammar["ToolBar"] = function($e) {
		$e.addClass("w3-right");
		handleUIElements($e);
	};

	grammar["HandledToolItem"] = function($e) {
		$e.html("<button class='w3-btn w3-white'>
"
				+ $e.attr("label") + "</button>");
		$e.css("float", "left");
	};

	function applyRule($e) {
		var etype = $e.attr("etype");
		var rule = grammar[etype];

		if (rule == null) {
			console.error("No rule found for: " + etype);
		} else {
			rule($e);
		}
	}

	function processDirectItem($e, hideParentOnClick, showLabel) {
		var $a = $("");

		var label = $e.attr("label");
		if (showLabel) {
			if (label !== "") {
				$a.text(label);
			}
		} else {
			$a.attr("title", label);
		}

		var iconSpanHtml = getIconSpanHtml($e, $e.attr("iconURI"));
		if (iconSpanHtml) {
			if (!showLabel) {
				iconSpanHtml.removeClass("w3-margin-right");
			}
			$a.prepend(iconSpanHtml);
		}

		$e.prepend($a);
		var requireModule = toUrl($e, $e.attr("contributionuri"));
		$a.click(function() {
			// hide the menu panel
			if (hideParentOnClick) {
				$e.parent().hide();
			}
			require([ requireModule ], function(handler) {
				if (typeof handler.execute === 'function') {
					if (typeof handler.canExecute === 'function' && !handler.canExecute()) {
						return;
					}
					handler.execute();
				}
			});
		})
	}

	function getIconSpanHtml($e, iconURI) {
		if (iconURI) {
			if (iconURI.startsWith('fa-')) {
				return $("");
			} else {
				return toUrl($e, iconURI);
			}
		}
		return false;
	}

	function handleUIElements($e, filter) {
		$e.children(".UIElement " + (filter == null ? "" : filter)).each(function() {
			applyRule($(this));
		});
	}

	function toUrl($e, relativePath) {
		return $e.attr("contributoruri") + "/" + relativePath;
	}

	function getParamNames(fn) {
		var fstr = fn.toString();
		return fstr.match(/\(.*?\)/)[0].replace(/[()]/gi, '').replace(/\s/gi, '').split(',');
	}

	var PartService = function($context) {
		this.$context = $context;
	};
	PartService.prototype.loadUIElement = function(id, fn) {
		this.$context.load("hi5/ws/model/element/" + id, function() {
			$uiElement = $("[elementid='" + id + "']", this);
			applyRule($uiElement);
			if (typeof fn === 'function') {
				fn();
			}
		});
	};
	PartService.prototype.showPerspective = function(id, callback) {
		$(document).find(".Perspective[elementid='" + id + "']").each(function() {
			var $this = $(this);
			// each stack element knows how to show itself when clicked on,
			// see GenericStack rule
			$this.trigger('click');
			callback.apply($this);
		});
	};
	PartService.prototype.select = function(selector) {
		// first find the enclosing Part div, then start searching from that
		// context downwards
		return this.$context.closest(".Part").find(selector);
	};

	$.fn.hi5 = function(fn) {
		var names = getParamNames(fn);
		this.each(function() {
			var $this = $(this);
			var context = {
				partService : new PartService($this)
			};

			var args = new Array();

			for (var i = 0; i < names.length; i++) {
				var name = names[i];
				var arg = context[name];
				args.push(arg);
			}

			fn.apply(this, args);
		})
	};

	return hi5;
});<commit_msg>switched direct item rendering from  to <commit_after>define([ 'jquery' ], function(jquery) {
	var hi5 = {
		version : "0.7.0"
	};
	var grammar = {};

	grammar["Application"] = function($e) {
		handleUIElements($e);
	};

	grammar["TrimmedWindow"] = function($e) {
		handleUIElements($e);
		handleUIElements($e, ".Menu");
		handleUIElements($e, ".TrimBar");
	};

	grammar["Menu"] = function($e) {
		var $menuTrigger = $("☰");
		$menuTrigger.click(function() {
			// show the menu panel configured below
			$e.show();
		});
		// add to container of the menu
		$e.parent().prepend($menuTrigger);

		// the menu panel which will be shown if the menu trigger is pressed
		$e.addClass("w3-sidenav w3-white w3-card-2 w3-animate-right");
		$e.hide();
		$e.css("right", "0");

		var $closeItem = $(""
				+ "Close×");
		$e.prepend($closeItem);
		$closeItem.click(function() {
			$e.hide();
		});

		handleUIElements($e, ".MenuItem");
	};

	grammar["MenuItem"] = function($e) {
		// TODO handle sub menus
		handleUIElements($e, ".MenuItem");
	};

	grammar["DirectMenuItem"] = function($e) {
		processDirectItem($e, true, true);
	};
	grammar["DirectToolItem"] = function($e) {
		processDirectItem($e, false, false);
	}

	grammar["GenericStack"] = function($e, stackElementsType) {
		if (stackElementsType == null) {
			stackElementsType = $e.children().eq(0).attr("etype");
		}

		var $ul = $("

");
		$e.children("." + stackElementsType).hide().each(function() {
			var $p = $(this);
			var $a = $("" + $p.attr("label") + "");

			var iconSpanHtml = getIconSpanHtml($p, $p.attr("iconURI"));
			if (iconSpanHtml) {
				$a.prepend(iconSpanHtml);
			}

			var $li = $("

");
			var clickHandler = function() {
				var $pers = $e.children("." + stackElementsType);
				$pers.hide();
				$pers.eq($li.index()).show();
				$ul.children().attr("active", "false");
				$li.attr("active", "true");
			};
			$a.click(clickHandler);
			// install click handler also for stack element
			// to allow to programmatically show it
			$p.click(clickHandler);
			$li.append($a);
			$ul.append($li);
		});
		$e.prepend($ul);
		handleUIElements($e);
		// select first stack element
		$ul.find("a").eq(0).trigger('click');
	};

	grammar["PerspectiveStack"] = function($e) {
		grammar["GenericStack"]($e, "Perspective");
	};

	grammar["Perspective"] = function($e) {
		handleUIElements($e);
	};

	grammar["PartStack"] = function($e) {
		grammar["GenericStack"]($e, "Part");
	};

	grammar["Part"] = function($e) {
		$("[tags~='ViewMenu']", $e).each(function() {
			handleUIElements($e, ".Menu");
		});
		handleUIElements($e, ".ToolBar");

		$e.addClass("w3-panel");
		$e.addClass("w3-border");
		var contribution = $e.attr("contributionuri");

		if (!contribution) {
			contribution = $e.attr("state_index");
		}

		var url = toUrl($e, contribution);
		var $contents = $("

");
		$e.append($contents);
		$contents.load(url);
	};

	grammar["TrimBar"] = function($e) {
		var dir = $e.attr("direction");
		handleUIElements($e);
	};

	grammar["ToolBar"] = function($e) {
		$e.addClass("w3-right");
		handleUIElements($e);
	};

	grammar["HandledToolItem"] = function($e) {
		$e.html("<button class='w3-btn w3-white'>
"
				+ $e.attr("label") + "</button>");
		$e.css("float", "left");
	};

	function applyRule($e) {
		var etype = $e.attr("etype");
		var rule = grammar[etype];

		if (rule == null) {
			console.error("No rule found for: " + etype);
		} else {
			rule($e);
		}
	}

	function processDirectItem($e, hideParentOnClick, showLabel) {
		var $a = $("");

		var label = $e.attr("label");
		if (showLabel) {
			if (label !== "") {
				$a.text(label);
			}
		} else {
			$a.attr("title", label);
		}

		var iconSpanHtml = getIconSpanHtml($e, $e.attr("iconURI"));
		if (iconSpanHtml) {
			if (!showLabel) {
				iconSpanHtml.removeClass("w3-margin-right");
			}
			$a.prepend(iconSpanHtml);
		}

		$e.prepend($a);
		var requireModule = toUrl($e, $e.attr("contributionuri"));
		$a.click(function() {
			// hide the menu panel
			if (hideParentOnClick) {
				$e.parent().hide();
			}
			require([ requireModule ], function(handler) {
				if (typeof handler.execute === 'function') {
					if (typeof handler.canExecute === 'function' && !handler.canExecute()) {
						return;
					}
					handler.execute();
				}
			});
		})
	}

	function getIconSpanHtml($e, iconURI) {
		if (iconURI) {
			if (iconURI.startsWith('fa-')) {
				return $("");
			} else {
				return toUrl($e, iconURI);
			}
		}
		return false;
	}

	function handleUIElements($e, filter) {
		$e.children(".UIElement " + (filter == null ? "" : filter)).each(function() {
			applyRule($(this));
		});
	}

	function toUrl($e, relativePath) {
		return $e.attr("contributoruri") + "/" + relativePath;
	}

	function getParamNames(fn) {
		var fstr = fn.toString();
		return fstr.match(/\(.*?\)/)[0].replace(/[()]/gi, '').replace(/\s/gi, '').split(',');
	}

	var PartService = function($context) {
		this.$context = $context;
	};
	PartService.prototype.loadUIElement = function(id, fn) {
		this.$context.load("hi5/ws/model/element/" + id, function() {
			$uiElement = $("[elementid='" + id + "']", this);
			applyRule($uiElement);
			if (typeof fn === 'function') {
				fn();
			}
		});
	};
	PartService.prototype.showPerspective = function(id, callback) {
		$(document).find(".Perspective[elementid='" + id + "']").each(function() {
			var $this = $(this);
			// each stack element knows how to show itself when clicked on,
			// see GenericStack rule
			$this.trigger('click');
			callback.apply($this);
		});
	};
	PartService.prototype.select = function(selector) {
		// first find the enclosing Part div, then start searching from that
		// context downwards
		return this.$context.closest(".Part").find(selector);
	};

	$.fn.hi5 = function(fn) {
		var names = getParamNames(fn);
		this.each(function() {
			var $this = $(this);
			var context = {
				partService : new PartService($this)
			};

			var args = new Array();

			for (var i = 0; i < names.length; i++) {
				var name = names[i];
				var arg = context[name];
				args.push(arg);
			}

			fn.apply(this, args);
		})
	};

	return hi5;
});<|endoftext|>


<commit_before>/**
 *
 * weatherunderground adapter
 *
 * Adapter loading the json forecast of weatherunderground
 *
 * note: you need an account and an api key to get the forecast. This is free for non excess usage: 500 requests/d
 * see: http://www.wunderground.com/weather/api/d/pricing
 *
 * register for a key:
 * http://www.wunderground.com/weather/api/d/questionnaire.html?plan=a&level=0&history=undefined
 *
 * see http://www.wunderground.com/weather/api/d/docs?d=data/hourly
 * for reference of the possible values from hourly WU forecast
 *
 */

"use strict";

var utils = require(__dirname + '/lib/utils'); // Get common adapter utils

var request = require('request');

var adapter = utils.adapter({
    name: 'weatherunderground',

    unload: function (callback) {
        adapter.log.info("adapter weatherunderground is unloading");
    },
    discover: function (callback) {
    },
    install: function (callback) {
        adapter.log.info("adapter weatherunderground installed");
    },
    uninstall: function (callback) {
        adapter.log.info("adapter weatherunderground UN-installed");
    },
    objectChange: function (id, obj) {
        adapter.log.info('objectChange ' + id + ' ' + JSON.stringify(obj));
    },
    stateChange: function (id, state) {
        adapter.log.info('stateChange ' + id + ' ' + JSON.stringify(state));
    },
    ready: function () {
        adapter.log.info("Adapter weatherunderground got 'Ready' Signal - starting scheduler to look for forecasts");
        getWuForecastData();
    },
    message: function (obj) {
    }
});

function getWuForecastData() {

    //debug

    var url = "http://api.wunderground.com/api/" + adapter.config.apikey + "/hourly/q/" + adapter.config.location + ".json";

    request({url: url, json: true}, function(error, response, body) {
        if (!error && response.statusCode === 200) {
            var qpf_sum = 0;
            var pop_max = 0;
            var uvi_sum = 0;

            for (var i = 0; i < 24; i++) {
                try {
                    //adapter.log.info("WU-Response Body: " + JSON.stringify(body.hourly_forecast[0].FCTTIME)); // Print the json response
                    //var forecast = JSON.parse(body.jsonData);
                    //adapter.log.info("version: " + body.response.version);
                    // see http://www.wunderground.com/weather/api/d/docs?d=resources/phrase-glossary for infos about properties and codes
                    adapter.setState("forecast." + i + "h.time", {ack: true, val: body.hourly_forecast[i].FCTTIME.pretty});
                    adapter.setState("forecast." + i + "h.temp", {ack: true, val: body.hourly_forecast[i].temp.metric});
                    adapter.setState("forecast." + i + "h.fctcode", {ack: true, val: body.hourly_forecast[i].fctcode}); //forecast description number -> see link above
                    adapter.setState("forecast." + i + "h.sky", {ack: true, val: body.hourly_forecast[i].sky}); //?
                    adapter.setState("forecast." + i + "h.wspd", {ack: true, val: body.hourly_forecast[i].wspd.metric}); // windspeed in kmh
                    adapter.setState("forecast." + i + "h.wdir", {ack: true, val: body.hourly_forecast[i].wdir.degrees}); //wind dir in degrees
                    adapter.setState("forecast." + i + "h.uvi", {ack: true, val: body.hourly_forecast[i].uvi}); //UV Index -> wikipedia
                    adapter.setState("forecast." + i + "h.humidity", {ack: true, val: body.hourly_forecast[i].humidity});
                    adapter.setState("forecast." + i + "h.heatindex", {ack: true, val: body.hourly_forecast[i].heatindex.metric}); // -> wikipedia
                    adapter.setState("forecast." + i + "h.feelslike", {ack: true, val: body.hourly_forecast[i].feelslike.metric}); // -> wikipedia
                    adapter.setState("forecast." + i + "h.qpf", {ack: true, val: body.hourly_forecast[i].qpf.metric}); // Quantitative precipitation forecast
                    adapter.setState("forecast." + i + "h.snow", {ack: true, val: body.hourly_forecast[i].snow.metric});
                    adapter.setState("forecast." + i + "h.pop", {ack: true, val: body.hourly_forecast[i].pop}); // probability of Precipitation
                    adapter.setState("forecast." + i + "h.mslp", {ack: true, val: body.hourly_forecast[i].mslp.metric}); // mean sea level pressure

                    qpf_sum += Number(body.hourly_forecast[i].qpf.metric);
                    uvi_sum += Number(body.hourly_forecast[i].uvi);
                    if (Number(body.hourly_forecast[i].uvi) > pop_max) {
                        pop_max = Number(body.hourly_forecast[i].uvi);
                    }

                    // 6h
                    if (i == 5) {
                        adapter.setState("forecast.6h.sum.qpf", {ack: true, val: qpf_sum});
                        adapter.setState("forecast.6h.sum.pop", {ack: true, val: pop_max});
                        adapter.setState("forecast.6h.sum.uvi", {ack: true, val: uvi_sum/6});
                    }
                    // 12h
                    if (i == 11) {
                        adapter.setState("forecast.12h.sum.qpf", {ack: true, val: qpf_sum});
                        adapter.setState("forecast.12h.sum.pop", {ack: true, val: pop_max});
                        adapter.setState("forecast.12h.sum.uvi", {ack: true, val: uvi_sum/12});
                    }
                    // 24h
                    if (i == 23) {
                        adapter.setState("forecast.24h.sum.qpf", {ack: true, val: qpf_sum});
                        adapter.setState("forecast.24h.sum.pop", {ack: true, val: pop_max});
                        adapter.setState("forecast.24h.sum.uvi", {ack: true, val: uvi_sum/24});
                    }
                } catch (error) {
                    adapter.log.error("Could not parse Forecast-Data: " + error);
                }
            }
        } else
        {
            // ERROR
            adapter.log.error("Wunderground reported an error: " + error);
        }
    });
}

<commit_msg>initial version<commit_after>/**
 *
 * weatherunderground adapter
 *
 * Adapter loading the json forecast of weatherunderground
 *
 * note: you need an account and an api key to get the forecast. This is free for non excess usage: 500 requests/d
 * see: http://www.wunderground.com/weather/api/d/pricing
 *
 * register for a key:
 * http://www.wunderground.com/weather/api/d/questionnaire.html?plan=a&level=0&history=undefined
 *
 * see http://www.wunderground.com/weather/api/d/docs?d=data/hourly
 * for reference of the possible values from hourly WU forecast
 *
 */

"use strict";

var utils = require(__dirname + '/lib/utils'); // Get common adapter utils

var request = require('request');

var adapter = utils.adapter({
    name: 'weatherunderground',

    unload: function (callback) {
        adapter.log.info("adapter weatherunderground is unloading");
    },
    discover: function (callback) {
    },
    install: function (callback) {
        adapter.log.info("adapter weatherunderground installed");
    },
    uninstall: function (callback) {
        adapter.log.info("adapter weatherunderground UN-installed");
    },
    objectChange: function (id, obj) {
        adapter.log.info('objectChange ' + id + ' ' + JSON.stringify(obj));
    },
    stateChange: function (id, state) {
        adapter.log.info('stateChange ' + id + ' ' + JSON.stringify(state));
    },
    ready: function () {
        adapter.log.info("Adapter weatherunderground got 'Ready' Signal - starting scheduler to look for forecasts");
        getWuForecastData();
    },
    message: function (obj) {
    }
});

function getWuForecastData() {

    //debug

    var url = "http://api.wunderground.com/api/" + adapter.config.apikey + "/hourly/q/" + adapter.config.location + ".json";

    request({url: url, json: true}, function(error, response, body) {
        if (!error && response.statusCode === 200) {
            var qpf_sum = 0;
            var pop_max = 0;
            var uvi_sum = 0;

            for (var i = 0; i < 24; i++) {
                try {
                    //adapter.log.info("WU-Response Body: " + JSON.stringify(body.hourly_forecast[0].FCTTIME)); // Print the json response
                    //var forecast = JSON.parse(body.jsonData);
                    //adapter.log.info("version: " + body.response.version);
                    // see http://www.wunderground.com/weather/api/d/docs?d=resources/phrase-glossary for infos about properties and codes
                    adapter.setState("forecast." + i + "h.time", {ack: true, val: body.hourly_forecast[i].FCTTIME.pretty});
                    adapter.setState("forecast." + i + "h.temp", {ack: true, val: body.hourly_forecast[i].temp.metric});
                    adapter.setState("forecast." + i + "h.fctcode", {ack: true, val: body.hourly_forecast[i].fctcode}); //forecast description number -> see link above
                    adapter.setState("forecast." + i + "h.sky", {ack: true, val: body.hourly_forecast[i].sky}); //?
                    adapter.setState("forecast." + i + "h.wspd", {ack: true, val: body.hourly_forecast[i].wspd.metric}); // windspeed in kmh
                    adapter.setState("forecast." + i + "h.wdir", {ack: true, val: body.hourly_forecast[i].wdir.degrees}); //wind dir in degrees
                    adapter.setState("forecast." + i + "h.uvi", {ack: true, val: body.hourly_forecast[i].uvi}); //UV Index -> wikipedia
                    adapter.setState("forecast." + i + "h.humidity", {ack: true, val: body.hourly_forecast[i].humidity});
                    adapter.setState("forecast." + i + "h.heatindex", {ack: true, val: body.hourly_forecast[i].heatindex.metric}); // -> wikipedia
                    adapter.setState("forecast." + i + "h.feelslike", {ack: true, val: body.hourly_forecast[i].feelslike.metric}); // -> wikipedia
                    adapter.setState("forecast." + i + "h.qpf", {ack: true, val: body.hourly_forecast[i].qpf.metric}); // Quantitative precipitation forecast
                    adapter.setState("forecast." + i + "h.snow", {ack: true, val: body.hourly_forecast[i].snow.metric});
                    adapter.setState("forecast." + i + "h.pop", {ack: true, val: body.hourly_forecast[i].pop}); // probability of Precipitation
                    adapter.setState("forecast." + i + "h.mslp", {ack: true, val: body.hourly_forecast[i].mslp.metric}); // mean sea level pressure

                    qpf_sum += Number(body.hourly_forecast[i].qpf.metric);
                    uvi_sum += Number(body.hourly_forecast[i].uvi);
                    if (Number(body.hourly_forecast[i].uvi) > pop_max) {
                        pop_max = Number(body.hourly_forecast[i].uvi);
                    }

                    // 6h
                    if (i == 5) {
                        adapter.setState("forecast.6h.sum.qpf", {ack: true, val: qpf_sum});
                        adapter.setState("forecast.6h.sum.pop", {ack: true, val: pop_max});
                        adapter.setState("forecast.6h.sum.uvi", {ack: true, val: uvi_sum/6});
                    }
                    // 12h
                    if (i == 11) {
                        adapter.setState("forecast.12h.sum.qpf", {ack: true, val: qpf_sum});
                        adapter.setState("forecast.12h.sum.pop", {ack: true, val: pop_max});
                        adapter.setState("forecast.12h.sum.uvi", {ack: true, val: uvi_sum/12});
                    }
                    // 24h
                    if (i == 23) {
                        adapter.setState("forecast.24h.sum.qpf", {ack: true, val: qpf_sum});
                        adapter.setState("forecast.24h.sum.pop", {ack: true, val: pop_max});
                        adapter.setState("forecast.24h.sum.uvi", {ack: true, val: uvi_sum/24});
                    }
                    adapter.log.info("all forecasts values set");
                } catch (error) {
                    adapter.log.error("Could not parse Forecast-Data: " + error);
                }
            }
        } else
        {
            // ERROR
            adapter.log.error("Wunderground reported an error: " + error);
        }
    });
}

<|endoftext|>


<commit_before>'use strict'; // eslint-disable-line

const webpack = require('webpack');
const merge = require('webpack-merge');
const CleanPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const CopyGlobsPlugin = require('copy-globs-webpack-plugin');
const config = require('./config');

const assetsFilenames = (config.enabled.cacheBusting) ? config.cacheBusting : '[name]';
const sourceMapQueryStr = (config.enabled.sourceMaps) ? '+sourceMap' : '-sourceMap';

let webpackConfig = {
  context: config.paths.assets,
  entry: config.entry,
  devtool: (config.enabled.sourceMaps ? '#source-map' : undefined),
  output: {
    path: config.paths.dist,
    publicPath: config.publicPath,
    filename: `scripts/${assetsFilenames}.js`,
  },
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.js?$/,
        include: config.paths.assets,
        loader: 'babel',
      },
      {
        test: /\.js$/,
        exclude: [/(node_modules|bower_components)(?![/|\\](bootstrap|foundation-sites))/],
        loader: 'buble',
        options: { objectAssign: 'Object.assign' },
      },
      {
        test: /\.css$/,
        include: config.paths.assets,
        use: ExtractTextPlugin.extract({
          fallback: 'style',
          use: [
            `css?${sourceMapQueryStr}`,
            {
              loader: 'postcss-loader',
              options: {
                sourceMap: sourceMapQueryStr,
                config: {
                  ctx: {},
                  path: './assets/build/postcss.config.js',
                },
              },
            },
          ],
        }),
      },
      {
        test: /\.scss$/,
        include: config.paths.assets,
        loader: ExtractTextPlugin.extract({
          fallback: 'style',
          use: [
            `css?${sourceMapQueryStr}`,
            {
              loader: 'postcss-loader',
              options: {
                sourceMap: sourceMapQueryStr,
                config: {
                  ctx: {},
                  path: './assets/build/postcss.config.js',
                },
              },
            },
            `resolve-url?${sourceMapQueryStr}`,
            `sass?${sourceMapQueryStr}`,
          ],
        }),
      },
      {
        test: /\.(png|jpe?g|gif|svg|ico)$/,
        include: config.paths.assets,
        loader: 'file',
        options: {
          name: `[path]${assetsFilenames}.[ext]`,
        },
      },
      {
        test: /\.(ttf|eot|woff2?|png|jpe?g|gif|svg)$/,
        include: /node_modules/,
        loader: 'file',
        options: {
          name: `vendor/${assetsFilenames}.[ext]`,
        },
      },
    ],
  },
  resolve: {
    alias: {
      vue: 'vue/dist/vue.js',
    },
    modules: [
      config.paths.assets,
      'node_modules',
    ],
    enforceExtension: false,
  },
  resolveLoader: {
    moduleExtensions: ['-loader'],
  },
  plugins: [
    new CleanPlugin([config.paths.dist], {
      root: config.paths.root,
      verbose: false,
    }),
    new CopyGlobsPlugin({
      pattern: config.copy,
      output: `[path]${assetsFilenames}.[ext]`,
      manifest: config.manifest,
    }),
    new ExtractTextPlugin({
      filename: `styles/${assetsFilenames}.css`,
      allChunks: true,
    }),
    new webpack.DefinePlugin({
      WEBPACK_PUBLIC_PATH: false,
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: config.enabled.optimize,
      stats: { colors: true },
    }),
    new webpack.LoaderOptionsPlugin({
      test: /\.js$/,
      options: {
        eslint: { failOnWarning: false, failOnError: true },
      },
    }),
    new webpack.optimize.ModuleConcatenationPlugin(),
  ],
};

/* eslint-disable global-require */ /** Let's only load dependencies as needed */

if (config.enabled.optimize) {
  webpackConfig = merge(webpackConfig, require('./webpack.config.optimize'));
}

if (config.env.production) {
  webpackConfig.plugins.push(new webpack.NoEmitOnErrorsPlugin());
}

if (config.enabled.cacheBusting) {
  const WebpackAssetsManifest = require('webpack-assets-manifest');

  webpackConfig.plugins.push(
    new WebpackAssetsManifest({
      output: 'assets.json',
      space: 2,
      writeToDisk: false,
      assets: config.manifest,
      replacer: require('./util/assetManifestsFormatter'),
    })
  );
}

module.exports = webpackConfig;
<commit_msg>add: optimize plugins<commit_after>'use strict'; // eslint-disable-line

const webpack = require('webpack');
const merge = require('webpack-merge');
const CleanPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const CopyGlobsPlugin = require('copy-globs-webpack-plugin');
const config = require('./config');

const assetsFilenames = (config.enabled.cacheBusting) ? config.cacheBusting : '[name]';
const sourceMapQueryStr = (config.enabled.sourceMaps) ? '+sourceMap' : '-sourceMap';

let webpackConfig = {
  context: config.paths.assets,
  entry: config.entry,
  devtool: (config.enabled.sourceMaps ? '#source-map' : undefined),
  output: {
    path: config.paths.dist,
    publicPath: config.publicPath,
    filename: `scripts/${assetsFilenames}.js`,
  },
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.js?$/,
        include: config.paths.assets,
        loader: 'babel',
      },
      {
        test: /\.js$/,
        exclude: [/(node_modules|bower_components)(?![/|\\](bootstrap|foundation-sites))/],
        loader: 'buble',
        options: { objectAssign: 'Object.assign' },
      },
      {
        test: /\.css$/,
        include: config.paths.assets,
        use: ExtractTextPlugin.extract({
          fallback: 'style',
          use: [
            `css?${sourceMapQueryStr}`,
            {
              loader: 'postcss-loader',
              options: {
                sourceMap: sourceMapQueryStr,
                config: {
                  ctx: {},
                  path: './assets/build/postcss.config.js',
                },
              },
            },
          ],
        }),
      },
      {
        test: /\.scss$/,
        include: config.paths.assets,
        loader: ExtractTextPlugin.extract({
          fallback: 'style',
          use: [
            `css?${sourceMapQueryStr}`,
            {
              loader: 'postcss-loader',
              options: {
                sourceMap: sourceMapQueryStr,
                config: {
                  ctx: {},
                  path: './assets/build/postcss.config.js',
                },
              },
            },
            `resolve-url?${sourceMapQueryStr}`,
            `sass?${sourceMapQueryStr}`,
          ],
        }),
      },
      {
        test: /\.(png|jpe?g|gif|svg|ico)$/,
        include: config.paths.assets,
        loader: 'file',
        options: {
          name: `[path]${assetsFilenames}.[ext]`,
        },
      },
      {
        test: /\.(ttf|eot|woff2?|png|jpe?g|gif|svg)$/,
        include: /node_modules/,
        loader: 'file',
        options: {
          name: `vendor/${assetsFilenames}.[ext]`,
        },
      },
    ],
  },
  resolve: {
    alias: {
      vue: 'vue/dist/vue.js',
    },
    modules: [
      config.paths.assets,
      'node_modules',
    ],
    enforceExtension: false,
  },
  resolveLoader: {
    moduleExtensions: ['-loader'],
  },
  plugins: [
    new CleanPlugin([config.paths.dist], {
      root: config.paths.root,
      verbose: false,
    }),
    new CopyGlobsPlugin({
      pattern: config.copy,
      output: `[path]${assetsFilenames}.[ext]`,
      manifest: config.manifest,
    }),
    new ExtractTextPlugin({
      filename: `styles/${assetsFilenames}.css`,
      allChunks: true,
    }),
    new webpack.DefinePlugin({
      WEBPACK_PUBLIC_PATH: false,
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: config.enabled.optimize,
      stats: { colors: true },
    }),
    new webpack.LoaderOptionsPlugin({
      test: /\.js$/,
      options: {
        eslint: { failOnWarning: false, failOnError: true },
      },
    }),
  ],
};

/* eslint-disable global-require */ /** Let's only load dependencies as needed */

if (config.enabled.optimize) {
  webpackConfig = merge(webpackConfig, require('./webpack.config.optimize'));
}

if (config.env.production) {
  webpackConfig.plugins.push(new webpack.NoEmitOnErrorsPlugin());
  webpackConfig.plugins.push(new webpack.optimize.ModuleConcatenationPlugin());
  webpackConfig.plugins.push(new webpack.optimize.DedupePlugin());
  webpackConfig.plugins.push(new webpack.optimize.AggressiveMergingPlugin());
}

if (config.enabled.cacheBusting) {
  const WebpackAssetsManifest = require('webpack-assets-manifest');

  webpackConfig.plugins.push(
    new WebpackAssetsManifest({
      output: 'assets.json',
      space: 2,
      writeToDisk: false,
      assets: config.manifest,
      replacer: require('./util/assetManifestsFormatter'),
    })
  );
}

module.exports = webpackConfig;
<|endoftext|>