<commit_before>// Call Congress
(function() {
  function validatePhoneNumber(phone) {
    // Remove spaces, parentheses, dashes
    phone = phone.replace(/\s/g, '')
      .replace(/\(/g, '')
      .replace(/\)/g, '')
      .replace(/\-/g, '');

    // Remove country code
    // TODO: Add support for non-US country codes on backend?
    phone = phone.replace('+', '')
    if (phone.charAt(0) == '1') phone = phone.substr(1);

    // Return formatted phone number if valid
    return phone.length == 10 ? phone : false;
  }

  var callCongress = document.getElementById('fftf-call-congress');

  callCongress.addEventListener('submit', function(e) {
    e.preventDefault();

    var phone = validatePhoneNumber(e.currentTarget.querySelector('input[type=text]').value);

    if (!phone) return alert('Please enter a valid US phone number!');

    var xhr = new XMLHttpRequest();

    function logStatus(e) {
      if (e.type == 'error') {
        alert('If you are using Privacy Badger or another ad blocker, please allow requests to https://call-congress.fightforthefuture.org and try again.')
      }

      if (xhr.status) console.log(xhr.status, xhr.statusText);
    }

    xhr.addEventListener('load', logStatus);
    xhr.addEventListener('error', logStatus);

    xhr.open('post', 'https://call-congress.fightforthefuture.org/create', true);
    xhr.send("campaignId=battleforthenet-2017&userPhone=" + phone);

    document.getElementById("call-congress-form").style.display = "none";
    document.getElementById("phone-script").style.display = "block";

    // new CallActionModal();
  });
})();
<commit_msg>Revert "Don’t use FormData because its no supported everywhere"<commit_after>// Call Congress
(function() {
  function validatePhoneNumber(phone) {
    // Remove spaces, parentheses, dashes
    phone = phone.replace(/\s/g, '')
      .replace(/\(/g, '')
      .replace(/\)/g, '')
      .replace(/\-/g, '');

    // Remove country code
    // TODO: Add support for non-US country codes on backend?
    phone = phone.replace('+', '')
    if (phone.charAt(0) == '1') phone = phone.substr(1);

    // Return formatted phone number if valid
    return phone.length == 10 ? phone : false;
  }

  var callCongress = document.getElementById('fftf-call-congress');

  callCongress.addEventListener('submit', function(e) {
    e.preventDefault();

    var phone = validatePhoneNumber(e.currentTarget.querySelector('input[type=text]').value);

    if (!phone) return alert('Please enter a valid US phone number!');

    var data = new FormData();
    data.append('campaignId', 'battleforthenet-2017');
    data.append('userPhone', phone);

    var xhr = new XMLHttpRequest();

    function logStatus(e) {
      if (e.type == 'error') {
        alert('If you are using Privacy Badger or another ad blocker, please allow requests to https://call-congress.fightforthefuture.org and try again.')
      }

      if (xhr.status) console.log(xhr.status, xhr.statusText);
    }

    xhr.addEventListener('load', logStatus);
    xhr.addEventListener('error', logStatus);

    xhr.open('post', 'https://call-congress.fightforthefuture.org/create', true);
    xhr.send(data);

    document.getElementById("call-congress-form").style.display = "none";
    document.getElementById("phone-script").style.display = "block";

    // new CallActionModal();
  });
})();
<|endoftext|>


<commit_before>'use strict';

var Q = require('q');
var AbstractClientResource = require('./../abstract-client-resource');

/**
 * No-Op callback
 */
function noop() {}

/**
 * Process Definition Resource
 * @class
 * @memberof CamSDK.client.resource
 * @augments CamSDK.client.AbstractClientResource
 */
var ProcessDefinition = AbstractClientResource.extend(
/** @lends  CamSDK.client.resource.ProcessDefinition.prototype */
  {
  /**
   * Suspends the process definition instance
   *
   * @param  {Object.<String, *>} [params]
   * @param  {requestCallback}    [done]
   */
    suspend: function(params, done) {
    // allows to pass only a callback
      if (typeof params === 'function') {
        done = params;
        params = {};
      }
      params = params || {};
      done = done || noop;

      return this.http.post(this.path, {
        done: done
      });
    },

  /**
   * Retrieves the statistics of a process definition.
   *
   * @param  {Function} [done]
   */
    stats: function(done) {
      return this.http.post(this.path, {
        done: done || noop
      });
    },

  /**
   * Retrieves the BPMN 2.0 XML document of a process definition.
   *
   * @param  {Function} [done]
   */
  // xml: function(id, done) {
  //   return this.http.post(this.path + +'/xml', {
  //     done: done || noop
  //   });
  // },

  /**
   * Starts a process instance from a process definition.
   *
   * @param  {Object} [varname]
   * @param  {Function} [done]
   */
    start: function(done) {
      return this.http.post(this.path, {
        data: {},
        done: done
      });
    }
  },
/** @lends  CamSDK.client.resource.ProcessDefinition */
  {
  /**
   * API path for the process instance resource
   */
    path: 'process-definition',

  /**
   * Retrieve a single process definition
   *
   * @param  {uuid}     id    of the process definition to be requested
   * @param  {Function} done
   */
    get: function(id, done) {

    // var pointer = '';
    // if (data.key) {
    //   pointer = 'key/'+ data.key;
    // }
    // else if (data.id) {
    //   pointer = data.id;
    // }

      return this.http.get(this.path +'/'+ id, {
        done: done
      });
    },

  /**
   * Retrieve a single process definition
   *
   * @param  {String}   key    of the process definition to be requested
   * @param  {Function} done
   */
    getByKey: function(key, done) {
      return this.http.get(this.path +'/key/'+ key, {
        done: done
      });
    },

  /**
   * Get a list of process definitions
   * @param  {Object} params                        Query parameters as follow
   * @param  {String} [params.name]                 Filter by name.
   * @param  {String} [params.nameLike]             Filter by names that the parameter is a substring of.
   * @param  {String} [params.deploymentId]         Filter by the deployment the id belongs to.
   * @param  {String} [params.key]                  Filter by key, i.e. the id in the BPMN 2.0 XML. Exact match.
   * @param  {String} [params.keyLike]              Filter by keys that the parameter is a substring of.
   * @param  {String} [params.category]             Filter by category. Exact match.
   * @param  {String} [params.categoryLike]         Filter by categories that the parameter is a substring of.
   * @param  {String} [params.ver]                  Filter by version.
   * @param  {String} [params.latest]               Only include those process definitions that are latest versions.
   *                                                Values may be "true" or "false".
   * @param  {String} [params.resourceName]         Filter by the name of the process definition resource. Exact match.
   * @param  {String} [params.resourceNameLike]     Filter by names of those process definition resources that the parameter is a substring of.
   * @param  {String} [params.startableBy]          Filter by a user name who is allowed to start the process.
   * @param  {String} [params.active]               Only include active process definitions.
   *                                                Values may be "true" or "false".
   * @param  {String} [params.suspended]            Only include suspended process definitions.
   *                                                Values may be "true" or "false".
   * @param  {String} [params.incidentId]           Filter by the incident id.
   * @param  {String} [params.incidentType]         Filter by the incident type.
   * @param  {String} [params.incidentMessage]      Filter by the incident message. Exact match.
   * @param  {String} [params.incidentMessageLike]  Filter by the incident message that the parameter is a substring of.
   *
   * @param  {String} [params.sortBy]               Sort the results lexicographically by a given criterion.
   *                                                Valid values are category, "key", "id", "name", "version" and "deploymentId".
   *                                                Must be used in conjunction with the "sortOrder" parameter.
   *
   * @param  {String} [params.sortOrder]            Sort the results in a given order.
   *                                                Values may be asc for ascending "order" or "desc" for descending order.
   *                                                Must be used in conjunction with the sortBy parameter.
   *
   * @param  {Integer} [params.firstResult]         Pagination of results. Specifies the index of the first result to return.
   * @param  {Integer} [params.maxResults]          Pagination of results. Specifies the maximum number of results to return.
   *                                                Will return less results, if there are no more results left.

   * @param  {requestCallback} [done]
   *
   * @example
   * CamSDK.resource('process-definition').list({
   *   nameLike: 'Process'
   * }, function(err, results) {
   *   //
   * });
   */
    list: function() {
      return AbstractClientResource.list.apply(this, arguments);
    },

  /**
   * Fetch the variables of a process definition
   * @param  {Object.<String, *>} data
   * @param  {String}             [data.id]     of the process
   * @param  {String}             [data.key]    of the process
   * @param  {Array}              [data.names]  of variables to be fetched
   * @param  {Function}           [done]
   */
    formVariables: function(data, done) {
      var pointer = '';
      done = done || noop;
      if (data.key) {
        pointer = 'key/'+ data.key;
      }
      else if (data.id) {
        pointer = data.id;
      }
      else {
        var err = new Error('Process definition task variables needs either a key or an id.');
        done(err);
        return Q.reject(err);
      }

      var queryData = {
        deserializeValues: data.deserializeValues
      };

      if(data.names) {
        queryData.variableNames = (data.names || []).join(',');
      }

      return this.http.get(this.path +'/'+ pointer +'/form-variables', {
        data: queryData,
        done: done
      });
    },

  /**
   * Submit a form to start a process definition
   *
   * @param  {Object.<String, *>} data
   * @param  {String}             [data.key]            start the process-definition with this key
   * @param  {String}             [data.id]             or: start the process-definition with this id
   * @param  {String}             [data.businessKey]    of the process to be set
   * @param  {Array}              [data.variables]      variables to be set
   * @param  {Function}           [done]
   */
    submitForm: function(data, done) {
      var pointer = '';
      done = done || noop;
      if (data.key) {
        pointer = 'key/'+ data.key;
      }
      else if (data.id) {
        pointer = data.id;
      }
      else {
        return done(new Error('Process definition task variables needs either a key or an id.'));
      }

      return this.http.post(this.path +'/'+ pointer +'/submit-form', {
        data: {
          businessKey : data.businessKey,
          variables: data.variables
        },
        done: done
      });
    },

  /**
   * Retrieves the form of a process definition.
   * @param  {Function} [done]
   */
    startForm: function(data, done) {
      var path = this.path +'/'+ (data.key ? 'key/'+ data.key : data.id) +'/startForm';
      return this.http.get(path, {
        done: done || noop
      });
    },

  /**
   * Retrieves the form of a process definition.
   * @param  {Function} [done]
   */
    xml: function(data, done) {
      var path = this.path +'/'+ (data.id ? data.id : 'key/'+ data.key) +'/xml';
      return this.http.get(path, {
        done: done || noop
      });
    },

  /**
   * Retrieves runtime statistics of a given process definition grouped by activities
   * @param  {Function} [done]
   */
    statistics: function(data, done) {
      var path = this.path +'/'+ (data.id ? data.id : 'key/'+ data.key) +'/statistics';
      return this.http.get(path, {
        data: data,
        done: done || noop
      });
    },

  /**
   * Submits the form of a process definition.
   *
   * @param  {Object} [data]
   * @param  {Function} [done]
   */
    submit: function(data, done) {
      var path = this.path;
      if (data.key) {
        path += '/key/'+ data.key;
      }
      else {
        path += '/'+ data.id;
      }
      path += '/submit-form';

      return this.http.post(path, {
        data: data,
        done: done
      });
    },

  /**
   * Suspends one or more process definitions
   *
   * @param  {String|String[]}    ids
   * @param  {Object.<String, *>} [params]
   * @param  {requestCallback}    [done]
   */
    suspend: function(ids, params, done) {
    // allows to pass only a callback
      if (typeof params === 'function') {
        done = params;
        params = {};
      }
      params = params || {};
      done = done || noop;
    // allows to pass a single ID
      ids = Array.isArray(ids) ? ids : [ids];

      return this.http.post(this.path, {
        done: done
      });
    },

  /**
   * Instantiates a given process definition.
   *
   * @param {Object} [params]
   * @param {String} [params.id]              The id of the process definition to be instantiated. Must be omitted if key is provided.
   * @param {String} [params.key]             The key of the process definition (the latest version thereof) to be instantiated. Must be omitted if id is provided.
   * @param {String} [params.tenantId]				The id of the tenant the process definition belongs to. Must be omitted if id is provided.
   * @param {String} [params.variables]       A JSON object containing the variables the process is to be initialized with. Each key corresponds to a variable name and each value to a variable value.
   * @param {String} [params.businessKey]     The business key the process instance is to be initialized with. The business key uniquely identifies the process instance in the context of the given process definition.
   * @param {String} [params.caseInstanceId]  The case instance id the process instance is to be initialized with.
   */
    start: function(params, done) {
      var url = this.path + '/';

      if (params.id) {
        url = url + params.id;
      } else {
        url = url + 'key/' + params.key;

        if (params.tenantId) {
          url = url + '/tenant-id/' + params.tenantId;
        }
      }

      return this.http.post(url + '/start', {
        data: params,
        done: done
      });
    }
  });

module.exports = ProcessDefinition;

<commit_msg>feat(api-client): add tenantId support for submitForm method<commit_after>'use strict';

var Q = require('q');
var AbstractClientResource = require('./../abstract-client-resource');

/**
 * No-Op callback
 */
function noop() {}

/**
 * Process Definition Resource
 * @class
 * @memberof CamSDK.client.resource
 * @augments CamSDK.client.AbstractClientResource
 */
var ProcessDefinition = AbstractClientResource.extend(
/** @lends  CamSDK.client.resource.ProcessDefinition.prototype */
  {
  /**
   * Suspends the process definition instance
   *
   * @param  {Object.<String, *>} [params]
   * @param  {requestCallback}    [done]
   */
    suspend: function(params, done) {
    // allows to pass only a callback
      if (typeof params === 'function') {
        done = params;
        params = {};
      }
      params = params || {};
      done = done || noop;

      return this.http.post(this.path, {
        done: done
      });
    },

  /**
   * Retrieves the statistics of a process definition.
   *
   * @param  {Function} [done]
   */
    stats: function(done) {
      return this.http.post(this.path, {
        done: done || noop
      });
    },

  /**
   * Retrieves the BPMN 2.0 XML document of a process definition.
   *
   * @param  {Function} [done]
   */
  // xml: function(id, done) {
  //   return this.http.post(this.path + +'/xml', {
  //     done: done || noop
  //   });
  // },

  /**
   * Starts a process instance from a process definition.
   *
   * @param  {Object} [varname]
   * @param  {Function} [done]
   */
    start: function(done) {
      return this.http.post(this.path, {
        data: {},
        done: done
      });
    }
  },
/** @lends  CamSDK.client.resource.ProcessDefinition */
  {
  /**
   * API path for the process instance resource
   */
    path: 'process-definition',

  /**
   * Retrieve a single process definition
   *
   * @param  {uuid}     id    of the process definition to be requested
   * @param  {Function} done
   */
    get: function(id, done) {

    // var pointer = '';
    // if (data.key) {
    //   pointer = 'key/'+ data.key;
    // }
    // else if (data.id) {
    //   pointer = data.id;
    // }

      return this.http.get(this.path +'/'+ id, {
        done: done
      });
    },

  /**
   * Retrieve a single process definition
   *
   * @param  {String}   key    of the process definition to be requested
   * @param  {Function} done
   */
    getByKey: function(key, done) {
      return this.http.get(this.path +'/key/'+ key, {
        done: done
      });
    },

  /**
   * Get a list of process definitions
   * @param  {Object} params                        Query parameters as follow
   * @param  {String} [params.name]                 Filter by name.
   * @param  {String} [params.nameLike]             Filter by names that the parameter is a substring of.
   * @param  {String} [params.deploymentId]         Filter by the deployment the id belongs to.
   * @param  {String} [params.key]                  Filter by key, i.e. the id in the BPMN 2.0 XML. Exact match.
   * @param  {String} [params.keyLike]              Filter by keys that the parameter is a substring of.
   * @param  {String} [params.category]             Filter by category. Exact match.
   * @param  {String} [params.categoryLike]         Filter by categories that the parameter is a substring of.
   * @param  {String} [params.ver]                  Filter by version.
   * @param  {String} [params.latest]               Only include those process definitions that are latest versions.
   *                                                Values may be "true" or "false".
   * @param  {String} [params.resourceName]         Filter by the name of the process definition resource. Exact match.
   * @param  {String} [params.resourceNameLike]     Filter by names of those process definition resources that the parameter is a substring of.
   * @param  {String} [params.startableBy]          Filter by a user name who is allowed to start the process.
   * @param  {String} [params.active]               Only include active process definitions.
   *                                                Values may be "true" or "false".
   * @param  {String} [params.suspended]            Only include suspended process definitions.
   *                                                Values may be "true" or "false".
   * @param  {String} [params.incidentId]           Filter by the incident id.
   * @param  {String} [params.incidentType]         Filter by the incident type.
   * @param  {String} [params.incidentMessage]      Filter by the incident message. Exact match.
   * @param  {String} [params.incidentMessageLike]  Filter by the incident message that the parameter is a substring of.
   *
   * @param  {String} [params.sortBy]               Sort the results lexicographically by a given criterion.
   *                                                Valid values are category, "key", "id", "name", "version" and "deploymentId".
   *                                                Must be used in conjunction with the "sortOrder" parameter.
   *
   * @param  {String} [params.sortOrder]            Sort the results in a given order.
   *                                                Values may be asc for ascending "order" or "desc" for descending order.
   *                                                Must be used in conjunction with the sortBy parameter.
   *
   * @param  {Integer} [params.firstResult]         Pagination of results. Specifies the index of the first result to return.
   * @param  {Integer} [params.maxResults]          Pagination of results. Specifies the maximum number of results to return.
   *                                                Will return less results, if there are no more results left.

   * @param  {requestCallback} [done]
   *
   * @example
   * CamSDK.resource('process-definition').list({
   *   nameLike: 'Process'
   * }, function(err, results) {
   *   //
   * });
   */
    list: function() {
      return AbstractClientResource.list.apply(this, arguments);
    },

  /**
   * Fetch the variables of a process definition
   * @param  {Object.<String, *>} data
   * @param  {String}             [data.id]     of the process
   * @param  {String}             [data.key]    of the process
   * @param  {Array}              [data.names]  of variables to be fetched
   * @param  {Function}           [done]
   */
    formVariables: function(data, done) {
      var pointer = '';
      done = done || noop;
      if (data.key) {
        pointer = 'key/'+ data.key;
      }
      else if (data.id) {
        pointer = data.id;
      }
      else {
        var err = new Error('Process definition task variables needs either a key or an id.');
        done(err);
        return Q.reject(err);
      }

      var queryData = {
        deserializeValues: data.deserializeValues
      };

      if(data.names) {
        queryData.variableNames = (data.names || []).join(',');
      }

      return this.http.get(this.path +'/'+ pointer +'/form-variables', {
        data: queryData,
        done: done
      });
    },

  /**
   * Submit a form to start a process definition
   *
   * @param  {Object.<String, *>} data
   * @param  {String}             [data.key]            start the process-definition with this key
   * @param  {String}             [data.tenantId]       and the this tenant-id
   * @param  {String}             [data.id]             or: start the process-definition with this id
   * @param  {String}             [data.businessKey]    of the process to be set
   * @param  {Array}              [data.variables]      variables to be set
   * @param  {Function}           [done]
   */
    submitForm: function(data, done) {
      var pointer = '';
      done = done || noop;
      if (data.key) {
        pointer = 'key/'+ data.key;
        if (data.tenantId) {
          pointer += '/tenant-id/' + data.tenantId;
        }
      }
      else if (data.id) {
        pointer = data.id;
      }
      else {
        return done(new Error('Process definition task variables needs either a key or an id.'));
      }

      return this.http.post(this.path +'/'+ pointer +'/submit-form', {
        data: {
          businessKey : data.businessKey,
          variables: data.variables
        },
        done: done
      });
    },

  /**
   * Retrieves the form of a process definition.
   * @param  {Function} [done]
   */
    startForm: function(data, done) {
      var path = this.path +'/'+ (data.key ? 'key/'+ data.key : data.id) +'/startForm';
      return this.http.get(path, {
        done: done || noop
      });
    },

  /**
   * Retrieves the form of a process definition.
   * @param  {Function} [done]
   */
    xml: function(data, done) {
      var path = this.path +'/'+ (data.id ? data.id : 'key/'+ data.key) +'/xml';
      return this.http.get(path, {
        done: done || noop
      });
    },

  /**
   * Retrieves runtime statistics of a given process definition grouped by activities
   * @param  {Function} [done]
   */
    statistics: function(data, done) {
      var path = this.path +'/'+ (data.id ? data.id : 'key/'+ data.key) +'/statistics';
      return this.http.get(path, {
        data: data,
        done: done || noop
      });
    },

  /**
   * Submits the form of a process definition.
   *
   * @param  {Object} [data]
   * @param  {Function} [done]
   */
    submit: function(data, done) {
      var path = this.path;
      if (data.key) {
        path += '/key/'+ data.key;
      }
      else {
        path += '/'+ data.id;
      }
      path += '/submit-form';

      return this.http.post(path, {
        data: data,
        done: done
      });
    },

  /**
   * Suspends one or more process definitions
   *
   * @param  {String|String[]}    ids
   * @param  {Object.<String, *>} [params]
   * @param  {requestCallback}    [done]
   */
    suspend: function(ids, params, done) {
    // allows to pass only a callback
      if (typeof params === 'function') {
        done = params;
        params = {};
      }
      params = params || {};
      done = done || noop;
    // allows to pass a single ID
      ids = Array.isArray(ids) ? ids : [ids];

      return this.http.post(this.path, {
        done: done
      });
    },

  /**
   * Instantiates a given process definition.
   *
   * @param {Object} [params]
   * @param {String} [params.id]              The id of the process definition to be instantiated. Must be omitted if key is provided.
   * @param {String} [params.key]             The key of the process definition (the latest version thereof) to be instantiated. Must be omitted if id is provided.
   * @param {String} [params.tenantId]				The id of the tenant the process definition belongs to. Must be omitted if id is provided.
   * @param {String} [params.variables]       A JSON object containing the variables the process is to be initialized with. Each key corresponds to a variable name and each value to a variable value.
   * @param {String} [params.businessKey]     The business key the process instance is to be initialized with. The business key uniquely identifies the process instance in the context of the given process definition.
   * @param {String} [params.caseInstanceId]  The case instance id the process instance is to be initialized with.
   */
    start: function(params, done) {
      var url = this.path + '/';

      if (params.id) {
        url = url + params.id;
      } else {
        url = url + 'key/' + params.key;

        if (params.tenantId) {
          url = url + '/tenant-id/' + params.tenantId;
        }
      }

      return this.http.post(url + '/start', {
        data: params,
        done: done
      });
    }
  });

module.exports = ProcessDefinition;

<|endoftext|>


<commit_before>/* Licensed 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.
 */
'use strict';

angular.module('flowableModeler')
  .controller('ProcessesCtrl', ['$rootScope', '$scope', '$translate', '$http', '$timeout','$location', '$modal', function ($rootScope, $scope, $translate, $http, $timeout, $location, $modal) {

      // Main page (needed for visual indicator of current page)
      $rootScope.setMainPageById('processes');
      $rootScope.formItems = undefined;

      // get latest thumbnails
      $scope.imageVersion = Date.now();

	  $scope.model = {
        filters: [
            {id: 'processes', labelKey: 'PROCESSES'}
		],

		sorts: [
		        {id: 'modifiedDesc', labelKey: 'MODIFIED-DESC'},
		        {id: 'modifiedAsc', labelKey: 'MODIFIED-ASC'},
		        {id: 'nameAsc', labelKey: 'NAME-ASC'},
		        {id: 'nameDesc', labelKey: 'NAME-DESC'}
		]
	  };

	  if ($rootScope.modelFilter) {
		  $scope.model.activeFilter = $rootScope.modelFilter.filter;
		  $scope.model.activeSort = $rootScope.modelFilter.sort;
		  $scope.model.filterText = $rootScope.modelFilter.filterText;

	  } else {
		  // By default, show first filter and use first sort
	      $scope.model.activeFilter = $scope.model.filters[0];
	      $scope.model.activeSort = $scope.model.sorts[0];
	      $rootScope.modelFilter = {
	        filter: $scope.model.activeFilter,
	        sort: $scope.model.activeSort,
	        filterText: ''
	      };
	  }

	  $scope.activateFilter = function(filter) {
		  $scope.model.activeFilter = filter;
		  $rootScope.modelFilter.filter = filter;
		  $scope.loadProcesses();
	  };

	  $scope.activateSort = function(sort) {
		  $scope.model.activeSort = sort;
		  $rootScope.modelFilter.sort = sort;
		  $scope.loadProcesses();
	  };

	  $scope.loadProcesses = function() {
		  $scope.model.loading = true;

		  var params = {
		      filter: $scope.model.activeFilter.id,
		      sort: $scope.model.activeSort.id,
		      modelType: 0
		  };

		  if ($scope.model.filterText && $scope.model.filterText != '') {
		    params.filterText = $scope.model.filterText;
		  }

		  $http({method: 'GET', url: FLOWABLE.APP_URL.getModelsUrl(), params: params}).
		  	success(function(data, status, headers, config) {
	    		$scope.model.processes = data;
	    		$scope.model.loading = false;
	        }).
	        error(function(data, status, headers, config) {
	           console.log('Something went wrong: ' + data);
	           $scope.model.loading = false;
	        });
	  };

	  var timeoutFilter = function() {
	      $scope.model.isFilterDelayed = true;
	      $timeout(function() {
	          $scope.model.isFilterDelayed = false;
	          if ($scope.model.isFilterUpdated) {
	              $scope.model.isFilterUpdated = false;
	              timeoutFilter();
	          } else {
	              $scope.model.filterText = $scope.model.pendingFilterText;
	              $rootScope.modelFilter.filterText = $scope.model.filterText;
	              $scope.loadProcesses();
	          }
	      }, 500);
	  };

	  $scope.filterDelayed = function() {
	      if ($scope.model.isFilterDelayed) {
	          $scope.model.isFilterUpdated = true;
	      } else {
	          timeoutFilter();
	      }
	  };

	  $scope.createProcess = function(mode) {
	    var modalInstance = _internalCreateModal({
	        template: 'views/popup/process-create.html?version=' + Date.now()
	    }, $modal, $scope);
	  };

	  $scope.importProcess = function () {
          _internalCreateModal({
              template: 'views/popup/process-import.html?version=' + Date.now()
          }, $modal, $scope);
	  };

	  $scope.showProcessDetails = function(process) {
	      if (process) {
	          $rootScope.editorHistory = [];
	          $location.path("/processes/" + process.id);
	      }
	  };

	  $scope.editProcessDetails = function(process) {
		  if (process) {
		      $rootScope.editorHistory = [];
              $location.path("/editor/" + process.id);
		  }
	  };

	  // Finally, load initial processes
	  $scope.loadProcesses();
  }]);

angular.module('flowableModeler')
.controller('CreateNewProcessModelCtrl', ['$rootScope', '$scope', '$modal', '$http', '$location',
                                          function ($rootScope, $scope, $modal, $http, $location) {

    $scope.model = {
       loading: false,
       process: {
            name: '',
            key: '',
            description: '',
           	modelType: 0
       }
    };

    if ($scope.initialModelType !== undefined) {
        $scope.model.process.modelType = $scope.initialModelType;
    }

    $scope.ok = function () {

        if (!$scope.model.process.name || $scope.model.process.name.length == 0 ||
        	!$scope.model.process.key || $scope.model.process.key.length == 0) {

            return;
        }

        $scope.model.loading = true;

        $http({method: 'POST', url: FLOWABLE.APP_URL.getModelsUrl(), data: $scope.model.process}).
            success(function(data) {
                $scope.$hide();

                $scope.model.loading = false;
                $rootScope.editorHistory = [];
                $location.path("/editor/" + data.id);
            }).
            error(function(data, status, headers, config) {
                $scope.model.loading = false;
                $scope.model.errorMessage = data.message;
            });
    };

    $scope.cancel = function () {
        if(!$scope.model.loading) {
            $scope.$hide();
        }
    };
}]);

angular.module('flowableModeler')
.controller('DuplicateProcessModelCtrl', ['$rootScope', '$scope', '$modal', '$http', '$location',
                                          function ($rootScope, $scope, $modal, $http, $location) {

    $scope.model = {
       loading: false,
       process: {
            name: '',
            key: '',
            description: ''
       }
    };

    if ($scope.originalModel) {
        //clone the model
        $scope.model.process.name = $scope.originalModel.process.name;
        $scope.model.process.key = $scope.originalModel.process.key;
        $scope.model.process.description = $scope.originalModel.process.description;
        $scope.model.process.id = $scope.originalModel.process.id;
        $scope.model.process.modelType = $scope.originalModel.process.modelType;
    }

    $scope.ok = function () {

        if (!$scope.model.process.name || $scope.model.process.name.length == 0 ||
        	!$scope.model.process.key || $scope.model.process.key.length == 0) {

            return;
        }

        $scope.model.loading = true;

        $http({method: 'POST', url: FLOWABLE.APP_URL.getCloneModelsUrl(), data: $scope.model.process}).
            success(function(data) {
                $scope.$hide();

                $scope.model.loading = false;
                $rootScope.editorHistory = [];
                $location.path("/editor/" + data.id);
            }).
            error(function(data, status, headers, config) {
                $scope.model.loading = false;
                $scope.model.errorMessage = data.message;
            });
    };

    $scope.cancel = function () {
        if(!$scope.model.loading) {
            $scope.$hide();
        }
    };
}]);

angular.module('flowableModeler')
.controller('ImportProcessModelCtrl', ['$rootScope', '$scope', '$http', 'Upload', '$location', function ($rootScope, $scope, $http, Upload, $location) {

  $scope.model = {
       loading: false
  };

  $scope.onFileSelect = function($files, isIE) {

      $scope.model.loading = true;

      for (var i = 0; i < $files.length; i++) {
          var file = $files[i];

          var url;
          if (isIE) {
              url = FLOWABLE.APP_URL.getImportProcessModelTextUrl();
          } else {
              url = FLOWABLE.APP_URL.getImportProcessModelUrl();
          }

          Upload.upload({
              url: url,
              method: 'POST',
              file: file
          }).progress(function(evt) {
              $scope.model.uploadProgress = parseInt(100.0 * evt.loaded / evt.total);

          }).success(function(data) {
              $scope.model.loading = false;

              $location.path("/editor/" + data.id);
              $scope.$hide();

          }).error(function(data) {

              if (data && data.message) {
                  $scope.model.errorMessage = data.message;
              }

              $scope.model.error = true;
              $scope.model.loading = false;
          });
      }
  };

  $scope.cancel = function () {
	  if(!$scope.model.loading) {
		  $scope.$hide();
	  }
  };
}]);
<commit_msg>Issue #711: Duplicate process does not work (#743)<commit_after>/* Licensed 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.
 */
'use strict';

angular.module('flowableModeler')
  .controller('ProcessesCtrl', ['$rootScope', '$scope', '$translate', '$http', '$timeout','$location', '$modal', function ($rootScope, $scope, $translate, $http, $timeout, $location, $modal) {

      // Main page (needed for visual indicator of current page)
      $rootScope.setMainPageById('processes');
      $rootScope.formItems = undefined;

      // get latest thumbnails
      $scope.imageVersion = Date.now();

	  $scope.model = {
        filters: [
            {id: 'processes', labelKey: 'PROCESSES'}
		],

		sorts: [
		        {id: 'modifiedDesc', labelKey: 'MODIFIED-DESC'},
		        {id: 'modifiedAsc', labelKey: 'MODIFIED-ASC'},
		        {id: 'nameAsc', labelKey: 'NAME-ASC'},
		        {id: 'nameDesc', labelKey: 'NAME-DESC'}
		]
	  };

	  if ($rootScope.modelFilter) {
		  $scope.model.activeFilter = $rootScope.modelFilter.filter;
		  $scope.model.activeSort = $rootScope.modelFilter.sort;
		  $scope.model.filterText = $rootScope.modelFilter.filterText;

	  } else {
		  // By default, show first filter and use first sort
	      $scope.model.activeFilter = $scope.model.filters[0];
	      $scope.model.activeSort = $scope.model.sorts[0];
	      $rootScope.modelFilter = {
	        filter: $scope.model.activeFilter,
	        sort: $scope.model.activeSort,
	        filterText: ''
	      };
	  }

	  $scope.activateFilter = function(filter) {
		  $scope.model.activeFilter = filter;
		  $rootScope.modelFilter.filter = filter;
		  $scope.loadProcesses();
	  };

	  $scope.activateSort = function(sort) {
		  $scope.model.activeSort = sort;
		  $rootScope.modelFilter.sort = sort;
		  $scope.loadProcesses();
	  };

	  $scope.loadProcesses = function() {
		  $scope.model.loading = true;

		  var params = {
		      filter: $scope.model.activeFilter.id,
		      sort: $scope.model.activeSort.id,
		      modelType: 0
		  };

		  if ($scope.model.filterText && $scope.model.filterText != '') {
		    params.filterText = $scope.model.filterText;
		  }

		  $http({method: 'GET', url: FLOWABLE.APP_URL.getModelsUrl(), params: params}).
		  	success(function(data, status, headers, config) {
	    		$scope.model.processes = data;
	    		$scope.model.loading = false;
	        }).
	        error(function(data, status, headers, config) {
	           console.log('Something went wrong: ' + data);
	           $scope.model.loading = false;
	        });
	  };

	  var timeoutFilter = function() {
	      $scope.model.isFilterDelayed = true;
	      $timeout(function() {
	          $scope.model.isFilterDelayed = false;
	          if ($scope.model.isFilterUpdated) {
	              $scope.model.isFilterUpdated = false;
	              timeoutFilter();
	          } else {
	              $scope.model.filterText = $scope.model.pendingFilterText;
	              $rootScope.modelFilter.filterText = $scope.model.filterText;
	              $scope.loadProcesses();
	          }
	      }, 500);
	  };

	  $scope.filterDelayed = function() {
	      if ($scope.model.isFilterDelayed) {
	          $scope.model.isFilterUpdated = true;
	      } else {
	          timeoutFilter();
	      }
	  };

	  $scope.createProcess = function(mode) {
	    var modalInstance = _internalCreateModal({
	        template: 'views/popup/process-create.html?version=' + Date.now()
	    }, $modal, $scope);
	  };

	  $scope.importProcess = function () {
          _internalCreateModal({
              template: 'views/popup/process-import.html?version=' + Date.now()
          }, $modal, $scope);
	  };

	  $scope.showProcessDetails = function(process) {
	      if (process) {
	          $rootScope.editorHistory = [];
	          $location.path("/processes/" + process.id);
	      }
	  };

	  $scope.editProcessDetails = function(process) {
		  if (process) {
		      $rootScope.editorHistory = [];
              $location.path("/editor/" + process.id);
		  }
	  };

	  // Finally, load initial processes
	  $scope.loadProcesses();
  }]);

angular.module('flowableModeler')
.controller('CreateNewProcessModelCtrl', ['$rootScope', '$scope', '$modal', '$http', '$location',
                                          function ($rootScope, $scope, $modal, $http, $location) {

    $scope.model = {
       loading: false,
       process: {
            name: '',
            key: '',
            description: '',
           	modelType: 0
       }
    };

    if ($scope.initialModelType !== undefined) {
        $scope.model.process.modelType = $scope.initialModelType;
    }

    $scope.ok = function () {

        if (!$scope.model.process.name || $scope.model.process.name.length == 0 ||
        	!$scope.model.process.key || $scope.model.process.key.length == 0) {

            return;
        }

        $scope.model.loading = true;

        $http({method: 'POST', url: FLOWABLE.APP_URL.getModelsUrl(), data: $scope.model.process}).
            success(function(data) {
                $scope.$hide();

                $scope.model.loading = false;
                $rootScope.editorHistory = [];
                $location.path("/editor/" + data.id);
            }).
            error(function(data, status, headers, config) {
                $scope.model.loading = false;
                $scope.model.errorMessage = data.message;
            });
    };

    $scope.cancel = function () {
        if(!$scope.model.loading) {
            $scope.$hide();
        }
    };
}]);

angular.module('flowableModeler')
.controller('DuplicateProcessModelCtrl', ['$rootScope', '$scope', '$modal', '$http', '$location',
                                          function ($rootScope, $scope, $modal, $http, $location) {

    $scope.model = {
       loading: false,
       process: {
            name: '',
            key: '',
            description: ''
       }
    };

    if ($scope.originalModel) {
        //clone the model
        $scope.model.process.name = $scope.originalModel.process.name;
        $scope.model.process.key = $scope.originalModel.process.key;
        $scope.model.process.description = $scope.originalModel.process.description;
        $scope.model.process.id = $scope.originalModel.process.id;
        $scope.model.process.modelType = $scope.originalModel.process.modelType;
    }

    $scope.ok = function () {

        if (!$scope.model.process.name || $scope.model.process.name.length == 0 ||
        	!$scope.model.process.key || $scope.model.process.key.length == 0) {

            return;
        }

        $scope.model.loading = true;

        $http({method: 'POST', url: FLOWABLE.APP_URL.getCloneModelsUrl($scope.model.process.id), data: $scope.model.process}).
            success(function(data) {
                $scope.$hide();

                $scope.model.loading = false;
                $rootScope.editorHistory = [];
                $location.path("/editor/" + data.id);
            }).
            error(function(data, status, headers, config) {
                $scope.model.loading = false;
                $scope.model.errorMessage = data.message;
            });
    };

    $scope.cancel = function () {
        if(!$scope.model.loading) {
            $scope.$hide();
        }
    };
}]);

angular.module('flowableModeler')
.controller('ImportProcessModelCtrl', ['$rootScope', '$scope', '$http', 'Upload', '$location', function ($rootScope, $scope, $http, Upload, $location) {

  $scope.model = {
       loading: false
  };

  $scope.onFileSelect = function($files, isIE) {

      $scope.model.loading = true;

      for (var i = 0; i < $files.length; i++) {
          var file = $files[i];

          var url;
          if (isIE) {
              url = FLOWABLE.APP_URL.getImportProcessModelTextUrl();
          } else {
              url = FLOWABLE.APP_URL.getImportProcessModelUrl();
          }

          Upload.upload({
              url: url,
              method: 'POST',
              file: file
          }).progress(function(evt) {
              $scope.model.uploadProgress = parseInt(100.0 * evt.loaded / evt.total);

          }).success(function(data) {
              $scope.model.loading = false;

              $location.path("/editor/" + data.id);
              $scope.$hide();

          }).error(function(data) {

              if (data && data.message) {
                  $scope.model.errorMessage = data.message;
              }

              $scope.model.error = true;
              $scope.model.loading = false;
          });
      }
  };

  $scope.cancel = function () {
	  if(!$scope.model.loading) {
		  $scope.$hide();
	  }
  };
}]);
<|endoftext|>


<commit_before>/*
 * created @ 2012 09 10
 *
 * created by fvi@
 *
 *
 */

exports.openCivilView = function() {
	height = Ti.Platform.displayCaps.platformHeight, width = Ti.Platform.displayCaps.platformWidth;
	var food_arr = [];

	var background_path = require('/util/getbackPathWithTime').getPath();
	var view = Titanium.UI.createView({
		backgroundImage : background_path
	});
	var house_image = Titanium.UI.createImageView({
		image : '/images/civ/ancient/house/house1.png',
		width : 'auto',
		height : 'auto',
		center : {
			x : width * 0.3,
			y : height * 0.4
		}
	});

	view.add(house_image);

	var man_image = Titanium.UI.createImageView({
		images : ['/images/civ/ancient/man/man0.png', '/images/civ/ancient/man/man10.png', '/images/civ/ancient/man/man11.png', '/images/civ/ancient/man/man12.png'],
		duration : 1500,
		repeatCount : 0,
		width : 'auto',
		height : 'auto',
		top : height * 0.5
	});
	man_image.start();

	man_image.addEventListener('click', function(e) {

		require('/ui/common/serifView/Serif').openView(view);
		Titanium.App.Properties.setString('first_contact', 'need_apple')

	});

	view.add(man_image);

	var cupcell_image = Titanium.UI.createImageView({
		image : '/images/civ/cupcell/cupcell.png',
		width : 'auto',
		height : 'auto',
		center : {
			x : width * 0.5,
			y : -1 * height
		}
	});

	view.add(cupcell_image);

	var item_button = Titanium.UI.createButton({
		backgroundImage : '/images/button/give/give.png',
		height : height * 0.1,
		width : width * 0.3,
		center : {
			x : width * 0.7,
			y : height * 0.9
		}
	});

	view.add(item_button);

	item_button.addEventListener('click', function(e) {
		var item_view = require('/ui/common/SelectBoard/selectItems').openView(view);
		item_button.setTouchEnabled(false);
		//StartAnimation(); このメソッドでアニメーションを開始する

	});

	//変更　アイテムに関するアニメーションを関数に変更
	function StartAnimation() {
		cupcell_image.animate({
			center : {
				x : width * 0.5,
				y : height * 0.65
			},
			duration : 1500
		}, function(e) {
			//second animation
			cupcell_image.animate({
				center : {
					x : width * 0.5,
					y : height * 0.6
				},
				duration : 500
			}, function(e) {
				//third animation
				cupcell_image.setImage('/images/civ/cupcell/cupcell_open.png');
				food_arr.push(Ti.UI.createImageView({
					image : '/images/civ/food/apple.png',
					width : 'auto',
					height : 'auto',
					center : {
						x : width * 0.5,
						y : height * 0.4
					}
				}));
				view.add(food_arr[0]);

				var disappear_time = setTimeout(function(e) {
					//cupcell_image.setCenter({x:width * 0.5,y:-1 * height});
					cupcell_image.setImage('/images/civ/cupcell/cupcell.png');
					cupcell_image.animate({
						center : {
							x : width * 0.5,
							y : -1 * height
						},
						duration : 500
					})
					item_button.setTouchEnabled(true);

					clearTimeout(disappear_time);

				}, 2000);

				var item_disappear_time = setTimeout(function(e) {
					//STUB的処理
					view.remove(food_arr[0]);
					clearTimeout(item_disappear_time);
				}, 2500);
			})
		})
	}

	var invest_button = Titanium.UI.createButton({
		backgroundImage : '/images/button/invest/investment.png',
		height : height * 0.1,
		width : width * 0.3,

		center : {
			x : width * 0.3,
			y : height * 0.9
		}

	});

	invest_button.addEventListener('click', function(e) {
		//背景黒のビューを設定
		var invest_view = require('/ui/common/SelectBoard/SelectBoard').openView(view);
		var invest_label = Titanium.UI.createLabel({
			text : 'これはてすとです',
			textAlign : 'center',
			color : 'black',
			width : invest_view.width * 0.9,
			height : invest_view.height * 0.7
		});
		invest_view.add(invest_label);

	});

	view.add(invest_button);

	//ボードに関する設定
	var board = require('/ui/common/CivBoard/Board').createBoard();

	view.add(board);

	return view;
}
<commit_msg>plus comment<commit_after>/*
 * created @ 2012 09 10
 *
 * created by fvi@
 *
 *
 */

exports.openCivilView = function() {
	height = Ti.Platform.displayCaps.platformHeight, width = Ti.Platform.displayCaps.platformWidth;
	var food_arr = [];

	var background_path = require('/util/getbackPathWithTime').getPath();
	var view = Titanium.UI.createView({
		backgroundImage : background_path
	});
	var house_image = Titanium.UI.createImageView({
		image : '/images/civ/ancient/house/house1.png',
		width : 'auto',
		height : 'auto',
		center : {
			x : width * 0.3,
			y : height * 0.4
		}
	});

	view.add(house_image);

	var man_image = Titanium.UI.createImageView({
		images : ['/images/civ/ancient/man/man0.png', '/images/civ/ancient/man/man10.png', '/images/civ/ancient/man/man11.png', '/images/civ/ancient/man/man12.png'],
		duration : 1500,
		repeatCount : 0,
		width : 'auto',
		height : 'auto',
		top : height * 0.5
	});
	man_image.start();

	man_image.addEventListener('click', function(e) {

		require('/ui/common/serifView/Serif').openView(view);
		Titanium.App.Properties.setString('first_contact', 'need_apple')

	});

	view.add(man_image);

	var cupcell_image = Titanium.UI.createImageView({
		image : '/images/civ/cupcell/cupcell.png',
		width : 'auto',
		height : 'auto',
		center : {
			x : width * 0.5,
			y : -1 * height
		}
	});

	view.add(cupcell_image);

	var item_button = Titanium.UI.createButton({
		backgroundImage : '/images/button/give/give.png',
		height : height * 0.1,
		width : width * 0.3,
		center : {
			x : width * 0.7,
			y : height * 0.9
		}
	});

	view.add(item_button);

	item_button.addEventListener('click', function(e) {
		var item_view = require('/ui/common/SelectBoard/selectItems').openView(view);
		item_button.setTouchEnabled(false);
		//StartAnimation(); このメソッドでアニメーションを開始するよ

	});

	//変更　アイテムに関するアニメーションを関数に変更
	function StartAnimation() {
		cupcell_image.animate({
			center : {
				x : width * 0.5,
				y : height * 0.65
			},
			duration : 1500
		}, function(e) {
			//second animation
			cupcell_image.animate({
				center : {
					x : width * 0.5,
					y : height * 0.6
				},
				duration : 500
			}, function(e) {
				//third animation
				cupcell_image.setImage('/images/civ/cupcell/cupcell_open.png');
				food_arr.push(Ti.UI.createImageView({
					image : '/images/civ/food/apple.png',
					width : 'auto',
					height : 'auto',
					center : {
						x : width * 0.5,
						y : height * 0.4
					}
				}));
				view.add(food_arr[0]);

				var disappear_time = setTimeout(function(e) {
					//cupcell_image.setCenter({x:width * 0.5,y:-1 * height});
					cupcell_image.setImage('/images/civ/cupcell/cupcell.png');
					cupcell_image.animate({
						center : {
							x : width * 0.5,
							y : -1 * height
						},
						duration : 500
					})
					item_button.setTouchEnabled(true);

					clearTimeout(disappear_time);

				}, 2000);

				var item_disappear_time = setTimeout(function(e) {
					//STUB的処理
					view.remove(food_arr[0]);
					clearTimeout(item_disappear_time);
				}, 2500);
			})
		})
	}

	var invest_button = Titanium.UI.createButton({
		backgroundImage : '/images/button/invest/investment.png',
		height : height * 0.1,
		width : width * 0.3,

		center : {
			x : width * 0.3,
			y : height * 0.9
		}

	});

	invest_button.addEventListener('click', function(e) {
		//背景黒のビューを設定
		var invest_view = require('/ui/common/SelectBoard/SelectBoard').openView(view);
		var invest_label = Titanium.UI.createLabel({
			text : 'これはてすとです',
			textAlign : 'center',
			color : 'black',
			width : invest_view.width * 0.9,
			height : invest_view.height * 0.7
		});
		invest_view.add(invest_label);

	});

	view.add(invest_button);

	//ボードに関する設定
	var board = require('/ui/common/CivBoard/Board').createBoard();

	view.add(board);

	return view;
}
<|endoftext|>


<commit_before>// Copyright 2021, University of Colorado Boulder

/**
 * Trying out a single listener to be added to Display that will manage all input related to the voicing
 * feature. Will actually speak content when a Node that composes Voicing receives a down/click event. Also
 * updates the Display's pointerFocusProperty when Pointers move over Nodes that compose Voicing.
 *
 * A work in progress, don't use yet.
 *
 * @author Jesse Greenberg (PhET Interactive Simulations)
 */

import scenery from '../../scenery.js';
import Focus from '../Focus.js';
import ReadingBlock from './ReadingBlock.js';
import voicingManager from './voicingManager.js';

class VoicingInputListener {

  /**
   * @param {BooleanProperty} voicingEnabledProperty
   * @param {Display} display
   */
  constructor( display, voicingEnabledProperty ) {

    // @private {Display}
    this.display = display;

    // @private {Trail|null} - reference to the active trail under DOM focus, updated in response to getting the trail
    // for those events
    this.activeFocusTrail = null;

    // @private {Trail|null} - references to the active trail under the mouse/touch pointer, used on down and over
    // to get responses for those events
    this.activePointerTrail = null;

    // @private {BooleanProperty}
    this.voicingEnabledProperty = voicingEnabledProperty;
  }

  /**
   * Called in response to a change of focus.
   * @public (part of the scenery listener API)
   *
   * @param event
   */
  focus( event ) {
    const voicingNode = this.findVoicingNode( event.trail );
    if ( voicingNode ) {
      this.activeFocusTrail = event.trail;

      // there is never a context response on focus
      this.speakVoicingContent( voicingNode, event );
    }
    else {
      this.activeFocusTrail = null;
    }
  }

  /**
   * Called in response to loss of focus.
   * @public
   * @param event
   */
  blur( event ) {
    this.activeFocusTrail = null;
  }

  /**
   * Called in response to a Pointer move event.
   * @public (part of the scenery listener API)
   *
   * @param {SceneryEvent} event
   */
  move( event ) {
    let hitNode = null;

    // only search for VoicingHitShapes if voicing is enabled
    if ( this.voicingEnabledProperty.value && this.display.readingBlockHighlightsVisibleProperty.value ) {
      ReadingBlock.ReadingBlockHitShapes.forEach( ( readingBlockHitShape, voicingNode ) => {
        const localToGlobalMatrix = voicingNode.getLocalToGlobalMatrix();

        const transformedHitShape = readingBlockHitShape.transformed( localToGlobalMatrix );
        if ( transformedHitShape.containsPoint( event.pointer.point ) ) {

          // now to a hit test on the Node itself to determine if it is would be hittable
          const transformedMouseArea = voicingNode.mouseArea.transformed( localToGlobalMatrix );
          const hitTrail = this.display.rootNode.hitTest( transformedMouseArea.bounds.center, true );
          if ( hitTrail && hitTrail.containsNode( voicingNode ) ) {
            hitNode = voicingNode;
          }
        }
      } );
    }

    // if we haven't found a hit yet, search for Nodes that compose Voicing that don't use a hit shape - these
    // will be interactive
    if ( !hitNode ) {

      // check for interactive Nodes that compose voicing
      for ( let i = event.trail.nodes.length - 1; i >= 0; i-- ) {
        const node = event.trail.nodes[ i ];
        if ( node.voicing ) {
          hitNode = node;
          break;
        }
      }
    }

    if ( hitNode ) {
      const uniqueTrail = hitNode.getUniqueTrail();
      if ( this.activePointerTrail === null || !uniqueTrail.equals( this.activePointerTrail ) ) {
        this.activePointerTrail = uniqueTrail;
        this.display.pointerFocusProperty.set( new Focus( this.display, uniqueTrail ) );
      }
    }
    else if ( this.activePointerTrail !== null ) {
      this.activePointerTrail = null;
      this.display.pointerFocusProperty.set( null );
    }
  }

  /**
   * Called in response to the down input event.
   * @public (part of scenery listener API)
   *
   * @param {SceneryEvent} event
   */
  down( event ) {
    this.respondToActivation( event );
  }

  /**
   * Called in response to the click input event.
   * @public (part of scenery listener API)
   *
   * @param {SceneryEvent} event
   */
  click( event ) {
    this.respondToActivation( event );
  }

  /**
   * Collect responses that would come from an activation event (pointer down or alternative input click).
   * @private
   */
  respondToActivation( event ) {
    const activeTrail = this.activePointerTrail || this.activeFocusTrail;
    if ( activeTrail ) {
      const voicingNode = activeTrail.lastNode();
      if ( voicingNode ) {
        this.speakVoicingContent( voicingNode, event );
      }
    }
  }

  /**
   * Speek the content from the VoicingNod in response to input.
   * @private
   *
   * @param {Node} voicingNode
   * @param {SceneryEvent} event
   */
  speakVoicingContent( voicingNode, event ) {
    const response = voicingManager.collectResponses( {
      objectResponse: voicingNode.voicingCreateObjectResponse( event ),
      interactionHint: voicingNode.voicingCreateHintResponse( event ),
      contextResponse: voicingNode.voicingCreateContextResponse( event ),
      overrideResponse: voicingNode.voicingCreateOverrideResponse( event )
    } );

    // don't send to utteranceQueue if response is empty
    if ( response ) {
      const utteranceQueue = voicingNode.utteranceQueue || this.display.voicingUtteranceQueue;
      utteranceQueue.addToBack( response );
    }
  }

  /**
   * Given a trail, find the Node that composes Voicing.
   * @private
   *
   * @param {Trail} trail
   * @returns {null|Node}
   */
  findVoicingNode( trail ) {
    let voicingNode = null;
    for ( let i = 0; i < trail.length; i++ ) {
      if ( trail.nodes[ i ].voicing ) {
        voicingNode = trail.nodes[ i ];
      }
    }

    return voicingNode;
  }

  /**
   * @private
   * @param voicingNode
   */
  speakVoicingNodeContent( voicingNode ) {

  }
}

scenery.register( 'VoicingInputListener', VoicingInputListener );
export default VoicingInputListener;
<commit_msg>speak voicing content only if the event target uses Voicing<commit_after>// Copyright 2021, University of Colorado Boulder

/**
 * Trying out a single listener to be added to Display that will manage all input related to the voicing
 * feature. Will actually speak content when a Node that composes Voicing receives a down/click event. Also
 * updates the Display's pointerFocusProperty when Pointers move over Nodes that compose Voicing.
 *
 * A work in progress, don't use yet.
 *
 * @author Jesse Greenberg (PhET Interactive Simulations)
 */

import scenery from '../../scenery.js';
import Focus from '../Focus.js';
import ReadingBlock from './ReadingBlock.js';
import voicingManager from './voicingManager.js';

class VoicingInputListener {

  /**
   * @param {BooleanProperty} voicingEnabledProperty
   * @param {Display} display
   */
  constructor( display, voicingEnabledProperty ) {

    // @private {Display}
    this.display = display;

    // @private {Trail|null} - reference to the active trail under DOM focus, updated in response to getting the trail
    // for those events
    this.activeFocusTrail = null;

    // @private {Trail|null} - references to the active trail under the mouse/touch pointer, used on down and over
    // to get responses for those events
    this.activePointerTrail = null;

    // @private {BooleanProperty}
    this.voicingEnabledProperty = voicingEnabledProperty;
  }

  /**
   * Called in response to a change of focus.
   * @public (part of the scenery listener API)
   *
   * @param event
   */
  focus( event ) {
    const voicingNode = this.findVoicingNode( event.trail );
    if ( voicingNode ) {
      this.activeFocusTrail = event.trail;

      // there is never a context response on focus
      this.speakVoicingContent( voicingNode, event );
    }
    else {
      this.activeFocusTrail = null;
    }
  }

  /**
   * Called in response to loss of focus.
   * @public
   * @param event
   */
  blur( event ) {
    this.activeFocusTrail = null;
  }

  /**
   * Called in response to a Pointer move event.
   * @public (part of the scenery listener API)
   *
   * @param {SceneryEvent} event
   */
  move( event ) {
    let hitNode = null;

    // only search for VoicingHitShapes if voicing is enabled
    if ( this.voicingEnabledProperty.value && this.display.readingBlockHighlightsVisibleProperty.value ) {
      ReadingBlock.ReadingBlockHitShapes.forEach( ( readingBlockHitShape, voicingNode ) => {
        const localToGlobalMatrix = voicingNode.getLocalToGlobalMatrix();

        const transformedHitShape = readingBlockHitShape.transformed( localToGlobalMatrix );
        if ( transformedHitShape.containsPoint( event.pointer.point ) ) {

          // now to a hit test on the Node itself to determine if it is would be hittable
          const transformedMouseArea = voicingNode.mouseArea.transformed( localToGlobalMatrix );
          const hitTrail = this.display.rootNode.hitTest( transformedMouseArea.bounds.center, true );
          if ( hitTrail && hitTrail.containsNode( voicingNode ) ) {
            hitNode = voicingNode;
          }
        }
      } );
    }

    // if we haven't found a hit yet, search for Nodes that compose Voicing that don't use a hit shape - these
    // will be interactive
    if ( !hitNode ) {

      // check for interactive Nodes that compose voicing
      for ( let i = event.trail.nodes.length - 1; i >= 0; i-- ) {
        const node = event.trail.nodes[ i ];
        if ( node.voicing ) {
          hitNode = node;
          break;
        }
      }
    }

    if ( hitNode ) {
      const uniqueTrail = hitNode.getUniqueTrail();
      if ( this.activePointerTrail === null || !uniqueTrail.equals( this.activePointerTrail ) ) {
        this.activePointerTrail = uniqueTrail;
        this.display.pointerFocusProperty.set( new Focus( this.display, uniqueTrail ) );
      }
    }
    else if ( this.activePointerTrail !== null ) {
      this.activePointerTrail = null;
      this.display.pointerFocusProperty.set( null );
    }
  }

  /**
   * Called in response to the down input event.
   * @public (part of scenery listener API)
   *
   * @param {SceneryEvent} event
   */
  down( event ) {
    this.respondToActivation( event );
  }

  /**
   * Called in response to the click input event.
   * @public (part of scenery listener API)
   *
   * @param {SceneryEvent} event
   */
  click( event ) {
    this.respondToActivation( event );
  }

  /**
   * Collect responses that would come from an activation event (pointer down or alternative input click).
   * @private
   */
  respondToActivation( event ) {
    const activeTrail = this.activePointerTrail || this.activeFocusTrail;
    if ( activeTrail ) {
      const voicingNode = activeTrail.lastNode();
      if ( voicingNode && voicingNode.voicing ) {
        this.speakVoicingContent( voicingNode, event );
      }
    }
  }

  /**
   * Speek the content from the VoicingNod in response to input.
   * @private
   *
   * @param {Node} voicingNode
   * @param {SceneryEvent} event
   */
  speakVoicingContent( voicingNode, event ) {
    const response = voicingManager.collectResponses( {
      objectResponse: voicingNode.voicingCreateObjectResponse( event ),
      interactionHint: voicingNode.voicingCreateHintResponse( event ),
      contextResponse: voicingNode.voicingCreateContextResponse( event ),
      overrideResponse: voicingNode.voicingCreateOverrideResponse( event )
    } );

    // don't send to utteranceQueue if response is empty
    if ( response ) {
      const utteranceQueue = voicingNode.utteranceQueue || this.display.voicingUtteranceQueue;
      utteranceQueue.addToBack( response );
    }
  }

  /**
   * Given a trail, find the Node that composes Voicing.
   * @private
   *
   * @param {Trail} trail
   * @returns {null|Node}
   */
  findVoicingNode( trail ) {
    let voicingNode = null;
    for ( let i = 0; i < trail.length; i++ ) {
      if ( trail.nodes[ i ].voicing ) {
        voicingNode = trail.nodes[ i ];
      }
    }

    return voicingNode;
  }

  /**
   * @private
   * @param voicingNode
   */
  speakVoicingNodeContent( voicingNode ) {

  }
}

scenery.register( 'VoicingInputListener', VoicingInputListener );
export default VoicingInputListener;
<|endoftext|>


<commit_before>const fs = require('fs')
const path = require('path')

const help = `
  usage:
    node docker-tag.js path/to/config.js $CIRCLE_TAG
`

if (process.argv.length !== 4) {
  if (process.argv[2] === 'help') {
    console.log(help)
    return
  } else if (process.argv.length === 3) {
    console.log('Skipping because tag is empty')
    return
  }

  console.error(help)
  process.exit(1)
  return
}

const config = require(path.resolve(process.argv[2]))
const next = process.argv[3]

const replace = (path, replacer) =>
  new Promise((resolve, reject) => {
    fs.readFile(path, 'utf8', (err, data) => {
      if (err) {
        return reject(err)
      }

      fs.writeFile(path, replacer(data), 'utf8', (err) => {
        if (err) {
          return reject(err)
        }
        resolve()
      })
    })
  })

config.updateTags.forEach(({ files, image, replacer }) => {
  files.forEach((loc) => {
    replace(loc, (content) => {
      if (replacer) {
        return replacer({
          content,
          next,
          semverRegex: new RegExp(
            /v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?/gi
          )
        })
      }

      return content.replace(
        new RegExp(`${image}:v[0-9a-zA-Z\\.\\+\\_\\-]+`, 'g'),
        `${image}:${next}`
      )
    })
      .then(() => {
        console.log('Done!')
      })
      .catch((err) => {
        console.error(err)
        process.exit(1)
      })
  })
})
<commit_msg>chore: update docusaurus template<commit_after>const fs = require('fs')
const path = require('path')

const help = `
  usage:
    node docker-tag.js path/to/config.js $CIRCLE_TAG
`

if (process.argv.length !== 4) {
  if (process.argv[2] === 'help') {
    console.log(help)
    return
  } else if (process.argv.length === 3) {
    console.log('Skipping because tag is empty')
    return
  }

  console.error(help)
  process.exit(1)
  return
}

const config = require(path.resolve(process.argv[2]))
const next = process.argv[3]

const replace = (path, replacer) =>
  new Promise((resolve, reject) => {
    fs.readFile(path, 'utf8', (err, data) => {
      if (err) {
        return reject(err)
      }

      fs.writeFile(path, replacer(data), 'utf8', (err) => {
        if (err) {
          return reject(err)
        }
        resolve()
      })
    })
  })

config.updateTags.forEach(({ files, image, replacer }) => {
  files.forEach((loc) => {
    replace(loc, (content) => {
      if (replacer) {
        return replacer({
          content,
          next,
          semverRegex: /v[0-9]\.[0-9]\.[0-9](-([0-9a-zA-Z.\-]+)|)/gi
        })
      }

      return content.replace(
        new RegExp(`${image}:v[0-9a-zA-Z\\.\\+\\_\\-]+`, 'g'),
        `${image}:${next}`
      )
    })
      .then(() => {
        console.log('Done!')
      })
      .catch((err) => {
        console.error(err)
        process.exit(1)
      })
  })
})
<|endoftext|>


<commit_before>'use strict';
require('dotenv').config();

const bot = require('./lib/bot.js');

require('./src/releases.js')(bot);
require('./src/releaseAndTag.js')(bot);
require('./src/cheese.js')(bot);
require('./src/conversation.js')(bot);
<commit_msg>Add dog conversation to bot<commit_after>'use strict';
require('dotenv').config();

const bot = require('./lib/bot.js');

require('./src/releases.js')(bot);
require('./src/releaseAndTag.js')(bot);
require('./src/cheese.js')(bot);
require('./src/dogs.js')(bot);
require('./src/conversation.js')(bot);
<|endoftext|>


<commit_before>var dataGetter = {
    urls: {}, // All the urls to get data from in the format  'http://.../': [triggerFunctions], where triggerFunctions is a list of functions to be called IF the data has changed since the last update.
    data: {}, // Latest data obtained from urls by url
    updatedSources: 0,

    addNew: function(url,triggerFunction) { // A function to be called when registring a new trigegrFunction for a given url.
        if (url in dataGetter.urls) {
            // The url has been registered already. Add the trigegr fucntion to this datagetter and call the trigegr function with the latest data obtained from the url.
            dataGetter.urls[url].push(triggerFunction);
            triggerFunction(dataGetter.data[url]);
        } else {
            dataGetter.urls[url] = [triggerFunction];
            dataGetter.getData(url);
        }
    },

    getData: function(url) { // Get new data from a specific url.
        jQuery.get(url, function(response) {
            if (!_.isEqual(dataGetter.data[url], response)) { // Only if the data is different than what was obtained from the same URL previously, call the trigger functions.
                dataGetter.data[url] = response;
                _.each(dataGetter.urls[url],function(triggerFunction){
                    triggerFunction(dataGetter.data[url]);
                })
            } else {
                console.log('no change for '+url);
            }
            dataGetter.updatedSources++;
            if (dataGetter.updatedSources===Object.keys(dataGetter.urls).length) {
                dataGetter.lastUpdate = new Date();
            }
        })
    },

    getAll: function() {// Function to iniate getting data from all registered urls.
        dataGetter.updatedSources = 0;
        _.each(_.keys(dataGetter.urls), dataGetter.getData);
    },
    lastUpdate: false,
    drawTimer : function () {
        if (dataGetter.lastUpdate) {
          var totalSeconds = parseInt((new Date()-dataGetter.lastUpdate)/1000),
            minutes = Math.floor(totalSeconds / 60),
            seconds = totalSeconds - minutes * 60;
          if (seconds<10) {
            seconds = '0'+seconds;
          }
          jQuery('#last_update span.ui-button-text').html(minutes+':'+seconds);
       }
    },
    setTimer: function () {// Set the timer to get data from URLs every X minutes;
        setInterval(dataGetter.getAll,5*60000); // Timer set to X*60000 milliseconds (X is minutes)
        setInterval(dataGetter.drawTimer,1000); // Redraw timer every second
    }

};

dataGetter.setTimer();
<commit_msg>resetauto get timer when hitting the get button<commit_after>var dataGetter = {
    urls: {}, // All the urls to get data from in the format  'http://.../': [triggerFunctions], where triggerFunctions is a list of functions to be called IF the data has changed since the last update.
    data: {}, // Latest data obtained from urls by url
    updatedSources: 0,

    addNew: function(url,triggerFunction) { // A function to be called when registring a new trigegrFunction for a given url.
        if (url in dataGetter.urls) {
            // The url has been registered already. Add the trigegr fucntion to this datagetter and call the trigegr function with the latest data obtained from the url.
            dataGetter.urls[url].push(triggerFunction);
            triggerFunction(dataGetter.data[url]);
        } else {
            dataGetter.urls[url] = [triggerFunction];
            dataGetter.getData(url);
        }
    },

    getData: function(url) { // Get new data from a specific url.
        jQuery.get(url, function(response) {
            if (!_.isEqual(dataGetter.data[url], response)) { // Only if the data is different than what was obtained from the same URL previously, call the trigger functions.
                dataGetter.data[url] = response;
                _.each(dataGetter.urls[url],function(triggerFunction){
                    triggerFunction(dataGetter.data[url]);
                })
            } else {
                console.log('no change for '+url);
            }
            dataGetter.updatedSources++;
            if (dataGetter.updatedSources===Object.keys(dataGetter.urls).length) {
                dataGetter.lastUpdate = new Date();
                dataGetter.setTimer();
            }
        })
    },

    getAll: function() {// Function to iniate getting data from all registered urls.
        dataGetter.updatedSources = 0;
        _.each(_.keys(dataGetter.urls), dataGetter.getData);
    },
    lastUpdate: false,
    drawTimer : function () {
        if (dataGetter.lastUpdate) {
          var totalSeconds = parseInt((new Date()-dataGetter.lastUpdate)/1000),
            minutes = Math.floor(totalSeconds / 60),
            seconds = totalSeconds - minutes * 60;
          if (seconds<10) {
            seconds = '0'+seconds;
          }
          jQuery('#last_update span.ui-button-text').html(minutes+':'+seconds);
       }
    },
    getterInterval: false,
    timerInterval: false,
    setTimer: function () {// Set the timer to get data from URLs every X minutes;
        clearInterval(dataGetter.getterInterval);
        dataGetter.getterInterval = setInterval(dataGetter.getAll,5*60000); // Timer set to X*60000 milliseconds (X is minutes)
        clearInterval(dataGetter.timerInterval);
        dataGetter.timerInterval = setInterval(dataGetter.drawTimer,1000); // Redraw timer every second
    }

};

dataGetter.getAll();
<|endoftext|>


<commit_before>var userid;
//arrays gebruikt voor autocompletes en selecteren waarde hiervan.
var studentLists = [];
var studentListsid = [];
var teachers = []
var teachersid = []

function pageViewModel(gvm) {
    gvm.projecttitle = ko.observable("");
    gvm.userId = -1;
    gvm.coupledCount = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);

    gvm.addmoduleBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Addmodule");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.getProjectInfo = function() {
        $.getJSON('/api/project/' + $("#projectHeader").data('value'), function(data) {
            gvm.pageHeader(data[0].code + ' - ' + data[0].name);
        });
    };

    gvm.coupledLists = ko.observableArray([]);
    gvm.availableLists = ko.observableArray([]);

    gvm.addCoupledList = function(id, name) {
        // Push data
        var tblOject = {tid: id, tname: name};
        gvm.coupledLists.push(tblOject);

        $("#uncouplebtn-" + id).click(function(){
            showYesNoModal("Bent u zeker dat u dit item wil ontkoppelen?", function(val){
                if(val){
                    $.ajax({
                        url: '/api/project/' + $("#projectHeader").data('value') +'/studentlist/uncouple/' + id,
                        type: "DELETE",
                        success: function() {
                            gvm.coupledCount--;
                            viewModel.coupledLists.remove(tblOject);
                        }
                    });

                }
            });
        });
    }

    gvm.addAvailableLists = function(id, name) {
        var tblOject = {tid: id, tname: name};
        gvm.availableLists.push(tblOject);

        $("#couplebtn-" + id).click(function(){
            if(gvm.coupledCount == 0) {
                $.ajax({
                    url: '/api/project/' + $("#projectHeader").data('value') + '/studentlist/' + id,
                    type: "POST",
                    success: function() {
                        gvm.coupledCount++;
                        viewModel.coupledLists.push(tblOject);
                    }
                });
            } else {
                alert("list already coupled");
            }
        });
    }

    gvm.getCoupledLists = function() {
        $.getJSON('/api/project/' + $("#projectHeader").data('value') + '/coupledlists', function(data) {
            $.each(data, function(i, item) {
                gvm.coupledCount++;
                gvm.addCoupledList(item.id, item.name);
            });
        });
}

    gvm.getAvailableLists = function() {
        $.getJSON('/api/studentlists/' + gvm.userId, function(data) {
            $.each(data, function(i, item) {
                gvm.addAvailableLists(item.id, item.name);
            });
        });
    }

    // The table data observable array
    gvm.tabledata = ko.observableArray([]);

    // Add data to the table
    gvm.addTableData = function(studid, studlist, name) {
        console.log("addTableData")
        // Push data
        var tblOject = {tid: studid, tstudlist: studlist, tteacher: name};
        gvm.tabledata.push(tblOject);

        // Attach delete handler to delete button
        $('#removebtn-' + id).bind('click', function(event, data){
            // Delete the table item
            deleteTableItem(id, tblOject);
            event.stopPropagation();
        });
            }

    gvm.clearTable = function() {
        gvm.tabledata.removeAll();
    }

 }

 function getAllTeachers() {
     teachers = [];
     teachersid = [];
     $.getJSON('/api/getteacherrapport', function(data) {
        $.each(data, function(i, item) {
            teachers.push(item.firstname + " " + item.lastname);
            teachersid.push(item.id);
        });
    });
    return teachers;
 }

function getAllStudentLists() {
    studentLists = [];
    studentListsid = [];
    $.getJSON('/api/studentlistsrapporten/' + userid, function (data) {
        $.each(data, function (i, item) {
            studentLists.push(item.name);
            studentListsid.push(item.id);
        });
    });
    return studentLists;
}

function getTeacherid() {

    // functie voor het opsplitsen van naam indien gewenst.
    // console.log(getTeacherID($('#teachersComplete').val().substr(0,$('#teachersComplete').val().indexOf(' ')), $('#teachersComplete').val().substr($('#teachersComplete').val().indexOf(' ')+1)));

    var i = 0;
    var teacher = 0;
    teachers.forEach(function(entry) {
        if (new String(entry).valueOf() == new String($('#teachersComplete').val()).valueOf()) {
            teacher = teachersid[i];
        }
        i+= 1;
    });
    return teacher
}

function getGroupid() {
    var i = 0;
    var studlijst;
    studentLists.forEach(function(entry) {
        if (new String(entry).valueOf() == new String($('#studentListComplete').val()).valueOf()) {
            studlijst = (studentListsid[i]);
        }
        i+= 1;
    });
    return studlijst;
}

 function addGroup(courseid, teacherid, studlijstid) {
     //TODO if teacher or studlijst = 0 dan bestaat deze niet!
     //TODO momenteel nog mogelijk om meer als 1 maal zelfde velden in te voeren.

         $.ajax({
            url: "/api/coursecouple/" + courseid + "/" + studlijstid + "/" + teacherid,
             type: "POST",
             data: {'course': courseid, 'teacher': teacherid, 'studentlist': teacherid},
             success: function(data) {
                 //console.log(data);
                 //callback(true);
             },
             error: function(data) {
                 console.log('Failed to add new student');
                 //callback(false);
             }
         });

 }

/*
 * Load page of the table
 */
function loadTablePage(pagenr,course)
{
    console.log("loadTablePage");
    $.getJSON('/api/getStudentGroupTeacherByCourseID/page/' + pagenr + '/' + course, function(data){

        /* Clear current table page */
        viewModel.clearTable();

        // Load table data
        $.each(data.data, function(i, item) {
            console.log(data.data);
           viewModel.addTableData(item.studid, item.name , item.firstname + " " + item.lastname);
        });

        /* Let previous en next buttons work */

        if(data.prev == "none"){
            $('#pager-prev-btn').addClass('disabled');
        } else {
            $('#pager-prev-btn').removeClass('disabled');
            $('#pager-prev-btn a').click(function(){
                loadTablePage(data.prev);
            });
        }

        if(data.next == "none"){
            $('#pager-next-btn').addClass('disabled');
        } else {
            $('#pager-next-btn').removeClass('disabled');
            $('#pager-next-btn a').click(function(){
                loadTablePage(data.next);
            });
        }

        // Number of pager buttons
        var numItems = $('.pager-nr-btn').length;

        /* Calculate for the pager buttons */
        var lowPage = Math.floor(pagenr/numItems) + 1;

        $('.pager-nr-btn').each(function() {
            /* calculate current page number */
            var thispagenr = lowPage++;

            /* Add the page number */
            $(this).html('' + thispagenr + '');

            /* Add active class to current page */
            if(thispagenr == pagenr) {
                $(this).addClass('active');
            } else {
                $(this).removeClass('active');
            }

            /* Disable inactive classes and bind handlers to active classes */
            if(thispagenr > data.pagecount) {
                $(this).addClass('disabled');
            } else {
                /* Add click listener for button */
                $(this).click(function() {
                    loadTablePage(thispagenr);
                });
            }
        });
    });
}

/*
 * Delete item from table given the id.
 */
function deleteTableItem(id, tblOject) {
    showYesNoModal("Bent u zeker dat u dit item wil verwijderen? \r\n Let op: verwijderde items blijven in het systeem en kunnen weer actief gezet worden door een administrator. \r\n Gelieve de administrator te contacteren om een vak definitief te verwijderen.", function(val){
        if(val){
            /*
            $.ajax({
                url: "/api/coursedelete/" + id,
                type: "DELETE",
                success: function() {
                    viewModel.tabledata.remove(tblOject);
                }
            });
            */
            console.log(id);
        }
    });
}

function initPage() {
    viewModel.getProjectInfo();
    viewModel.getCoupledLists();

    //Add Course members

    $('#addGroupForm').hide();

    $('#addCoursemembers').click(function() {
        $("#addGroupForm").show();
        $('#teachersComplete').autocomplete({ source: getAllTeachers() });
        $('#studentListComplete').autocomplete({ source: getAllStudentLists() });
    });

    $('#addGroupBtn').click(function() {
         addGroup($('#projectHeader').attr("data-value"), getTeacherid(), getGroupid());

        $('addGroupForm').hide();
    });

    $.getJSON('/api/currentuser', function(data) {
        viewModel.userId = data.id;
        userid = data.id;
        viewModel.getAvailableLists(data.id);
    });
    loadTablePage(1,$('#projectHeader').attr("data-value"));
}
<commit_msg>table load functies coursesstudentsrapporten<commit_after>var userid;
//arrays gebruikt voor autocompletes en selecteren waarde hiervan.
var studentLists = [];
var studentListsid = [];
var teachers = []
var teachersid = []

function pageViewModel(gvm) {
    gvm.projecttitle = ko.observable("");
    gvm.userId = -1;
    gvm.coupledCount = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);

    gvm.addmoduleBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Addmodule");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.getProjectInfo = function() {
        $.getJSON('/api/project/' + $("#projectHeader").data('value'), function(data) {
            gvm.pageHeader(data[0].code + ' - ' + data[0].name);
        });
    };

    gvm.coupledLists = ko.observableArray([]);
    gvm.availableLists = ko.observableArray([]);

    gvm.addCoupledList = function(id, name) {
        // Push data
        var tblOject = {tid: id, tname: name};
        gvm.coupledLists.push(tblOject);

        $("#uncouplebtn-" + id).click(function(){
            showYesNoModal("Bent u zeker dat u dit item wil ontkoppelen?", function(val){
                if(val){
                    $.ajax({
                        url: '/api/project/' + $("#projectHeader").data('value') +'/studentlist/uncouple/' + id,
                        type: "DELETE",
                        success: function() {
                            gvm.coupledCount--;
                            viewModel.coupledLists.remove(tblOject);
                        }
                    });

                }
            });
        });
    }

    gvm.addAvailableLists = function(id, name) {
        var tblOject = {tid: id, tname: name};
        gvm.availableLists.push(tblOject);

        $("#couplebtn-" + id).click(function(){
            if(gvm.coupledCount == 0) {
                $.ajax({
                    url: '/api/project/' + $("#projectHeader").data('value') + '/studentlist/' + id,
                    type: "POST",
                    success: function() {
                        gvm.coupledCount++;
                        viewModel.coupledLists.push(tblOject);
                    }
                });
            } else {
                alert("list already coupled");
            }
        });
    }

    gvm.getCoupledLists = function() {
        $.getJSON('/api/project/' + $("#projectHeader").data('value') + '/coupledlists', function(data) {
            $.each(data, function(i, item) {
                gvm.coupledCount++;
                gvm.addCoupledList(item.id, item.name);
            });
        });
}

    gvm.getAvailableLists = function() {
        $.getJSON('/api/studentlists/' + gvm.userId, function(data) {
            $.each(data, function(i, item) {
                gvm.addAvailableLists(item.id, item.name);
            });
        });
    }

    // The table data observable array
    gvm.tabledata = ko.observableArray([]);

    // Add data to the table
    gvm.addTableData = function(id, studlist, name) {
        console.log("addTableData")
        // Push data
        var tblOject = {tid: id, tstudlist: studlist, tteacher: name};
        gvm.tabledata.push(tblOject);

        // Attach delete handler to delete button
        $('#removebtn-' + id).bind('click', function(event, data){
            // Delete the table item
            deleteTableItem(id, tblOject);
            event.stopPropagation();
        });
            }

    gvm.clearTable = function() {
        gvm.tabledata.removeAll();
    }

 }

 function getAllTeachers() {
     teachers = [];
     teachersid = [];
     $.getJSON('/api/getteacherrapport', function(data) {
        $.each(data, function(i, item) {
            teachers.push(item.firstname + " " + item.lastname);
            teachersid.push(item.id);
        });
    });
    return teachers;
 }

function getAllStudentLists() {
    studentLists = [];
    studentListsid = [];
    $.getJSON('/api/studentlistsrapporten/' + userid, function (data) {
        $.each(data, function (i, item) {
            studentLists.push(item.name);
            studentListsid.push(item.id);
        });
    });
    return studentLists;
}

function getTeacherid() {

    // functie voor het opsplitsen van naam indien gewenst.
    // console.log(getTeacherID($('#teachersComplete').val().substr(0,$('#teachersComplete').val().indexOf(' ')), $('#teachersComplete').val().substr($('#teachersComplete').val().indexOf(' ')+1)));

    var i = 0;
    var teacher = 0;
    teachers.forEach(function(entry) {
        if (new String(entry).valueOf() == new String($('#teachersComplete').val()).valueOf()) {
            teacher = teachersid[i];
        }
        i+= 1;
    });
    return teacher
}

function getGroupid() {
    var i = 0;
    var studlijst;
    studentLists.forEach(function(entry) {
        if (new String(entry).valueOf() == new String($('#studentListComplete').val()).valueOf()) {
            studlijst = (studentListsid[i]);
        }
        i+= 1;
    });
    return studlijst;
}

 function addGroup(courseid, teacherid, studlijstid) {
     //TODO if teacher or studlijst = 0 dan bestaat deze niet!
     //TODO momenteel nog mogelijk om meer als 1 maal zelfde velden in te voeren.

         $.ajax({
            url: "/api/coursecouple/" + courseid + "/" + studlijstid + "/" + teacherid,
             type: "POST",
             data: {'course': courseid, 'teacher': teacherid, 'studentlist': teacherid},
             success: function(data) {
                 //console.log(data);
                 //callback(true);
             },
             error: function(data) {
                 console.log('Failed to add new student');
                 //callback(false);
             }
         });

 }

/*
 * Load page of the table
 */
function loadTablePage(pagenr,course)
{
    console.log("loadTablePage");
    $.getJSON('/api/getStudentGroupTeacherByCourseID/page/' + pagenr + '/' + course, function(data){

        /* Clear current table page */
        viewModel.clearTable();

        // Load table data
        $.each(data.data, function(i, item) {
            console.log(data.data);
           viewModel.addTableData(item.studid, item.name , item.firstname + " " + item.lastname);
        });

        /* Let previous en next buttons work */

        if(data.prev == "none"){
            $('#pager-prev-btn').addClass('disabled');
        } else {
            $('#pager-prev-btn').removeClass('disabled');
            $('#pager-prev-btn a').click(function(){
                loadTablePage(data.prev);
            });
        }

        if(data.next == "none"){
            $('#pager-next-btn').addClass('disabled');
        } else {
            $('#pager-next-btn').removeClass('disabled');
            $('#pager-next-btn a').click(function(){
                loadTablePage(data.next);
            });
        }

        // Number of pager buttons
        var numItems = $('.pager-nr-btn').length;

        /* Calculate for the pager buttons */
        var lowPage = Math.floor(pagenr/numItems) + 1;

        $('.pager-nr-btn').each(function() {
            /* calculate current page number */
            var thispagenr = lowPage++;

            /* Add the page number */
            $(this).html('' + thispagenr + '');

            /* Add active class to current page */
            if(thispagenr == pagenr) {
                $(this).addClass('active');
            } else {
                $(this).removeClass('active');
            }

            /* Disable inactive classes and bind handlers to active classes */
            if(thispagenr > data.pagecount) {
                $(this).addClass('disabled');
            } else {
                /* Add click listener for button */
                $(this).click(function() {
                    loadTablePage(thispagenr);
                });
            }
        });
    });
}

/*
 * Delete item from table given the id.
 */
function deleteTableItem(id, tblOject) {
    showYesNoModal("Bent u zeker dat u dit item wil verwijderen? \r\n Let op: verwijderde items blijven in het systeem en kunnen weer actief gezet worden door een administrator. \r\n Gelieve de administrator te contacteren om een vak definitief te verwijderen.", function(val){
        if(val){
            /*
            $.ajax({
                url: "/api/coursedelete/" + id,
                type: "DELETE",
                success: function() {
                    viewModel.tabledata.remove(tblOject);
                }
            });
            */
            console.log(id);
        }
    });
}

function initPage() {
    viewModel.getProjectInfo();
    viewModel.getCoupledLists();

    //Add Course members

    $('#addGroupForm').hide();

    $('#addCoursemembers').click(function() {
        $("#addGroupForm").show();
        $('#teachersComplete').autocomplete({ source: getAllTeachers() });
        $('#studentListComplete').autocomplete({ source: getAllStudentLists() });
    });

    $('#addGroupBtn').click(function() {
         addGroup($('#projectHeader').attr("data-value"), getTeacherid(), getGroupid());

        $('addGroupForm').hide();
    });

    $.getJSON('/api/currentuser', function(data) {
        viewModel.userId = data.id;
        userid = data.id;
        viewModel.getAvailableLists(data.id);
    });
    loadTablePage(1,$('#projectHeader').attr("data-value"));
}
<|endoftext|>


<commit_before>var action = function(description, callback) {
    if (callback === undefined) {
        // run action
    }
    else {
        // enqueue action
    }
};

var step = function(description, waitFunction, callback) {

};

var runScript = function(client, appSettings) {
    action("Do something", function() {
        client.click("#")
    });

    step("Wait for something", function() {
        client.waitFor("div[data-stickyscrolling-placeholder]", TIMEOUT);
    }, function() {
        // when done
        action("Do something");
    });
}

var ScriptRunner = {
    run: function(namespace, action, userOptions) {
        console.log("running " + namespace + ":" + action + " with " + JSON.stringify(userOptions));

        startSelenium(function(client) {
            runScript(client);
        });
    },
    startSelenium: function(callback) {
        callback(client);
    }
};

exports = module.exports = ScriptRunner;
<commit_msg>selenium server in script_runner<commit_after>var action = function(description, callback) {
    if (callback === undefined) {
        // run action
    }
    else {
        // enqueue action
    }
};

var step = function(description, waitFunction, callback) {

};

var runScript = function(client, appSettings) {
    action("Do something", function() {
        client.click("#")
    });

    step("Wait for something", function() {
        client.waitFor("div[data-stickyscrolling-placeholder]", TIMEOUT);
    }, function() {
        // when done
        action("Do something");
    });
}

var ScriptRunner = {
    run: function(namespace, action, userOptions) {
        console.log("running " + namespace + ":" + action + " with " + JSON.stringify(userOptions));

        startSelenium(function(client) {

            var selenium = require('selenium-standalone');
            var seleniumServer = selenium({stdio: 'pipe'});

            seleniumServer.stdout.on('data', function(output) {
                var val = output.toString().trim();
                console.log(val);
                if(val.indexOf('jetty.jetty.Server')>-1){
                    client = client.init();
                    start();
                }
            });

            seleniumServer.stderr.on('data', function (data) {
              console.log('stderr: ' + data);
            });

            seleniumServer.on('close', function (code) {
              console.log('child process exited with code ' + code);
            });

            function start() {
                runScript(client, userOptions);
            }

        });
    },
    startSelenium: function(callback) {

        var webdriverjs = require('webdriverjs');
        var driverOptions = {
            desiredCapabilities: {
                browserName: 'chrome'
            }
        };
        var client = webdriverjs.remote(driverOptions);

        callback(client);
    }
};

exports = module.exports = ScriptRunner;
<|endoftext|>