<commit_before>'use strict';
/* jshint camelcase: false */

angular.module('webClientApp')
  .controller('EditArticleCtrl', ['$rootScope', '$scope', '$routeParams', '$location', '$analytics', '$window', '$interval', '$timeout', 'Article',
      function ($rootScope, $scope, $routeParams, $location, $analytics, $window, $interval, $timeout, Article) {

    var confirmEditMessage = ('هذه العملية ستنقل المقال إلى مسوداتك. يمكنك' +
        ' نشرها مجدداً بالضغط على نشر. هل تود نقل المقال للمسودات؟');

    var lastSavedArticle = {};

    /**
     * Checks if the article has been changed since the last time it was saved.
     * @return {boolean} True if the article has been changed.
     */
    var isDirty = function () {
      // Check if the article has been updated since last edited.
      var maybeUpdatedArticle = angular.copy($scope.article);
      // To avoid updating the $scope.article model just remove updated_at
      // to make sure the updated_at is not compared when checking for changes.
      delete maybeUpdatedArticle.updated_at;
      delete lastSavedArticle.updated_at;
      return !angular.equals(maybeUpdatedArticle, lastSavedArticle);
    };

    /**
     * If the current user is not the owner redirect the user to view.
     */
    var authorizeUser = function (article) {
      if (!$rootScope.isOwner($rootScope.user, article)) {
        $location.path('/articles/' + article.id);
      }
    };

    // Update the page title when the title of the article changes.
    $scope.$watch('article.title', function(){
      $rootScope.page.title = $scope.article.title || 'مقال جديد';
    });

    // Load the article if we are editing.
    $scope.article = {};
    if($routeParams.articleId) {
      Article.get({'articleId': $routeParams.articleId}, function (resource) {
        authorizeUser(resource);
        lastSavedArticle = angular.copy(resource);
        $scope.article = resource;
        // Warn the user that editing an article will move it to draft until
        // they publish it again.
        $timeout(function () {
          if (resource.published) {
            if (!$window.confirm(confirmEditMessage)) {
              $location.path('/articles/' + resource.id);
            } else {
              $scope.article.published = false;
            }
          }
        });
      });
    }

    var updateSuccess = function (resource) {
      lastSavedArticle = angular.copy(resource);
      $timeout(function () {
        $scope.isSaving = false;
      }, 1000);
      $scope.inProgress = null;

      if (resource.published) {
        // First time this gets published.
        if (!$scope.article.published_at) {
          $scope.article.published_at = resource.published_at;
          $scope.article.topic = resource.topic;
          $analytics.eventTrack('New Article Published', {
            category: 'Article',
            label: resource.title
          });
        } else {
          // The article has been already published, moved to draft and now
          // republished again.
          $analytics.eventTrack('Article Re-Published', {
            category: 'Article',
            label: resource.title
          });
        }
      }

      if (resource.published) {
        $location.path('/articles/' + resource.id);
      }
    };

    var updateError = function (response) {
      $scope.inProgress = null;
      $analytics.eventTrack('Article Update Error', {
        category: 'Article',
        label: angular.toJson(response.errors)
      });
      $scope.error = 'حدث خطأ في حفظ المقال.';
    };

    var deleteSuccess = function () {
      $analytics.eventTrack('Article Deleted', {
        category: 'Article'
      });
      $location.path('/profiles/' + $rootScope.user.id);
    };

    var deleteError = function (response) {
      $scope.inProgress = null;
      $analytics.eventTrack('Delete Article Error', {
        category: 'Article',
        label: angular.toJson(response.errors)
      });
      $scope.error = 'حدث خطأ في حذف المقال.';
    };

    var publishingAfterTopicPicked = false;
    /**
     * Saves/Updates article data.
     * @param {Object} article Article data.
     * @param {boolean} published Whether to publish the article or save as a draft.
     * @param {boolean} silent Whether to flash the controls or not.
     */
    $scope.saveArticle = function(article, published, silent) {
      // Clear autosave interval before sitting published
      if(autoSavePromise) {
        $interval.cancel(autoSavePromise);
      }
      article.published = published;
      var formError = $scope.articleForm.$error;
      if(published && formError && formError.required) {
        $window.alert('تأكد من ادخال جميع المعلومات المطلوبة');
        return;
      }

      // First time publishing article.
      if (published && !article.published_at && !article.topic) {
        publishingAfterTopicPicked = published;
        $rootScope.$emit('openTopicPicker', {allowCreateTopics: true});
      } else {
        if (!silent) {
          $scope.inProgress = published ? 'publish' : 'save';
        }

        Article.update(
            { 'articleId': article.id }, { article: article },
            updateSuccess, updateError, {ignoreLoadingBar: !published});
      }
    };

    /**
     * Deletes an article.
     * @param {Object} article Article data.
     */
    $scope.deleteArticle = function(article) {
      $scope.inProgress = 'delete';
      if ($window.confirm('متأكد من حذف المقال؟')) {
        Article.delete({ 'articleId': article.id }, {}, deleteSuccess, deleteError);
      } else {
        $scope.inProgress = null;
      }
    };

    /**
     * Cancel creating an article.
     */
    $scope.cancel = function() {
      $scope.inProgress = 'cancel';
      // Warn the user when canceling editing an existing article or when
      // canceling a new article with changed properties.
      if (!isDirty() || $window.confirm('متأكد من إلغاء المقال؟')) {
        $location.path('/');
      } else {
        $scope.inProgress = null;
      }
    };

    $scope.changeTopic = function() {
      $rootScope.$emit('openTopicPicker', {allowCreateTopics: true});
    };

    /**
     * Start the auto save interval and save its promise to destroy it when the
     * user is done editing.
     * @return {!angular.$promise} A promise to be notified on each iteration.
     */
    var autoSavePromise = $interval(function () {
      if (!isDirty()) {
        return;
      }

      $scope.isSaving = true;
      $scope.saveArticle($scope.article, false, true);
    }, 5000);

    var topicSelectedUnbind = $rootScope.$on('topicSelected', function(event, data) {
      if (data.topic && data.topic.id) {
        $scope.article.topic = data.topic;
        $scope.article.topic_id = data.topic.id;
        $scope.article.category = data.topic.category;
        $scope.article.category_id = data.topic.category.id;
      }
      $scope.article.published_at = publishingAfterTopicPicked;
      $scope.saveArticle($scope.article, publishingAfterTopicPicked);
    });

    /**
     * When the user logout while in edit mode redirect the user,
     */
    var loggedOutUnbined = $rootScope.$on('auth:logout-success', function () {
      if ($scope.article.published) {
        var location = '/articles/' + $routeParams.articleId;
        $location.path(location);
      } else {
        $location.path('/');
      }
    });

    /**
     * Make sure to cleanup the binded events and intervals when the user
     * leaves to another controller.
     */
    var onDestroy = function () {
      $interval.cancel(autoSavePromise);
      loggedOutUnbined();
      topicSelectedUnbind();
    };

    // Make sure to cleanup the binding. Otherwise the event listener will
    // be added everytime the controller load and when the controller is
    // still loaded it would still listen to the event.
    $scope.$on('$destroy', onDestroy);

  }]);
<commit_msg>Fixes the broken autosave for drafts.<commit_after>'use strict';
/* jshint camelcase: false */

angular.module('webClientApp')
  .controller('EditArticleCtrl', ['$rootScope', '$scope', '$routeParams', '$location', '$analytics', '$window', '$interval', '$timeout', 'Article',
      function ($rootScope, $scope, $routeParams, $location, $analytics, $window, $interval, $timeout, Article) {

    var confirmEditMessage = ('هذه العملية ستنقل المقال إلى مسوداتك. يمكنك' +
        ' نشرها مجدداً بالضغط على نشر. هل تود نقل المقال للمسودات؟');

    var lastSavedArticle = {};

    /**
     * Checks if the article has been changed since the last time it was saved.
     * @return {boolean} True if the article has been changed.
     */
    var isDirty = function () {
      // Check if the article has been updated since last edited.
      var maybeUpdatedArticle = angular.copy($scope.article);
      // To avoid updating the $scope.article model just remove updated_at
      // to make sure the updated_at is not compared when checking for changes.
      delete maybeUpdatedArticle.updated_at;
      delete lastSavedArticle.updated_at;
      return !angular.equals(maybeUpdatedArticle, lastSavedArticle);
    };

    /**
     * If the current user is not the owner redirect the user to view.
     */
    var authorizeUser = function (article) {
      if (!$rootScope.isOwner($rootScope.user, article)) {
        $location.path('/articles/' + article.id);
      }
    };

    // Update the page title when the title of the article changes.
    $scope.$watch('article.title', function(){
      $rootScope.page.title = $scope.article.title || 'مقال جديد';
    });

    // Load the article if we are editing.
    $scope.article = {};
    if($routeParams.articleId) {
      Article.get({'articleId': $routeParams.articleId}, function (resource) {
        authorizeUser(resource);
        lastSavedArticle = angular.copy(resource);
        $scope.article = resource;
        // Warn the user that editing an article will move it to draft until
        // they publish it again.
        $timeout(function () {
          if (resource.published) {
            if (!$window.confirm(confirmEditMessage)) {
              $location.path('/articles/' + resource.id);
            } else {
              $scope.article.published = false;
            }
          }
        });
      });
    }

    var updateSuccess = function (resource) {
      lastSavedArticle = angular.copy(resource);
      $timeout(function () {
        $scope.isSaving = false;
      }, 1000);
      $scope.inProgress = null;

      if (resource.published) {
        // First time this gets published.
        if (!$scope.article.published_at) {
          $scope.article.published_at = resource.published_at;
          $scope.article.topic = resource.topic;
          $analytics.eventTrack('New Article Published', {
            category: 'Article',
            label: resource.title
          });
        } else {
          // The article has been already published, moved to draft and now
          // republished again.
          $analytics.eventTrack('Article Re-Published', {
            category: 'Article',
            label: resource.title
          });
        }
      }

      if (resource.published) {
        $location.path('/articles/' + resource.id);
      }
    };

    var updateError = function (response) {
      $scope.inProgress = null;
      $analytics.eventTrack('Article Update Error', {
        category: 'Article',
        label: angular.toJson(response.errors)
      });
      $scope.error = 'حدث خطأ في حفظ المقال.';
    };

    var deleteSuccess = function () {
      $analytics.eventTrack('Article Deleted', {
        category: 'Article'
      });
      $location.path('/profiles/' + $rootScope.user.id);
    };

    var deleteError = function (response) {
      $scope.inProgress = null;
      $analytics.eventTrack('Delete Article Error', {
        category: 'Article',
        label: angular.toJson(response.errors)
      });
      $scope.error = 'حدث خطأ في حذف المقال.';
    };

    var publishingAfterTopicPicked = false;
    /**
     * Saves/Updates article data.
     * @param {Object} article Article data.
     * @param {boolean} published Whether to publish the article or save as a draft.
     * @param {boolean} silent Whether to flash the controls or not.
     */
    $scope.saveArticle = function(article, published, silent) {
      // Clear autosave interval before sitting published.
      if(autoSavePromise && published) {
        $interval.cancel(autoSavePromise);
      }
      article.published = published;
      var formError = $scope.articleForm.$error;
      if(published && formError && formError.required) {
        $window.alert('تأكد من ادخال جميع المعلومات المطلوبة');
        return;
      }

      // First time publishing article.
      if (published && !article.published_at && !article.topic) {
        publishingAfterTopicPicked = published;
        $rootScope.$emit('openTopicPicker', {allowCreateTopics: true});
      } else {
        if (!silent) {
          $scope.inProgress = published ? 'publish' : 'save';
        }

        Article.update(
            { 'articleId': article.id }, { article: article },
            updateSuccess, updateError, {ignoreLoadingBar: !published});
      }
    };

    /**
     * Deletes an article.
     * @param {Object} article Article data.
     */
    $scope.deleteArticle = function(article) {
      $scope.inProgress = 'delete';
      if ($window.confirm('متأكد من حذف المقال؟')) {
        Article.delete({ 'articleId': article.id }, {}, deleteSuccess, deleteError);
      } else {
        $scope.inProgress = null;
      }
    };

    /**
     * Cancel creating an article.
     */
    $scope.cancel = function() {
      $scope.inProgress = 'cancel';
      // Warn the user when canceling editing an existing article or when
      // canceling a new article with changed properties.
      if (!isDirty() || $window.confirm('متأكد من إلغاء المقال؟')) {
        $location.path('/');
      } else {
        $scope.inProgress = null;
      }
    };

    $scope.changeTopic = function() {
      $rootScope.$emit('openTopicPicker', {allowCreateTopics: true});
    };

    /**
     * Start the auto save interval and save its promise to destroy it when the
     * user is done editing.
     * @return {!angular.$promise} A promise to be notified on each iteration.
     */
    var autoSavePromise = $interval(function () {
      if (!isDirty()) {
        return;
      }

      $scope.isSaving = true;
      $scope.saveArticle($scope.article, false, true);
    }, 5000);

    var topicSelectedUnbind = $rootScope.$on('topicSelected', function(event, data) {
      if (data.topic && data.topic.id) {
        $scope.article.topic = data.topic;
        $scope.article.topic_id = data.topic.id;
        $scope.article.category = data.topic.category;
        $scope.article.category_id = data.topic.category.id;
      }
      $scope.article.published_at = publishingAfterTopicPicked;
      $scope.saveArticle($scope.article, publishingAfterTopicPicked);
    });

    /**
     * When the user logout while in edit mode redirect the user,
     */
    var loggedOutUnbined = $rootScope.$on('auth:logout-success', function () {
      if ($scope.article.published) {
        var location = '/articles/' + $routeParams.articleId;
        $location.path(location);
      } else {
        $location.path('/');
      }
    });

    /**
     * Make sure to cleanup the binded events and intervals when the user
     * leaves to another controller.
     */
    var onDestroy = function () {
      $interval.cancel(autoSavePromise);
      loggedOutUnbined();
      topicSelectedUnbind();
    };

    // Make sure to cleanup the binding. Otherwise the event listener will
    // be added everytime the controller load and when the controller is
    // still loaded it would still listen to the event.
    $scope.$on('$destroy', onDestroy);

  }]);
<|endoftext|>


<commit_before>/**
 *    Copyright (C) 2015 Deco Software Inc.
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

import _ from 'lodash'
import React from 'react'
import ReactDOM from 'react-dom'
import CodeMirror from 'codemirror'

const FlowController = Electron.remote.require('./process/flowController.js')
import Middleware from '../Middleware'
import { EventTypes } from '../../constants/CodeMirrorTypes'
import Pos from '../../models/editor/CodeMirrorPos'
import { AutocompleteHint } from '../../components'
import * as ChangeUtils from '../../utils/Editor/ChangeUtils'

/**
 * Middleware for showing autocompletion hints while typing.
 *
 * We use a combination of 2 sources for hints:
 * - "basic" completions provided by CodeMirror's anyword plugin
 * - "flow" completions provided by a local flow-bin node_modules, if one exists
 *
 * If basic and flow both offer the same completion for a word, we show the flow
 * completion, since it will likely have detailed type information.
 *
 * In the case that flow doesn't exist, we show only basic completions.
 */
export default class AutocompleteMiddleware extends Middleware {

  constructor() {
    super()

    this.completionActive = false
    this.currentWord = ''

    // In order to keep completions from spontaneously disappearing as we type,
    // we cache the previous completion shown. We continue to show it as we
    // wait for a new set of completions, updating the highlighted portion of
    // the hints immediately.
    this.cachedCompletions = {}

    this.eventListeners = {
      [EventTypes.changes]: this.changes,
    }
  }

  renderHint(item, wordToComplete, node) {
    const root = (
      <AutocompleteHint
        text={item.name}
        type={item.type}
        wordToComplete={wordToComplete}
        functionDetails={item.func_details}
      />
    )
    ReactDOM.render(root, node)
  }

  // If base = initialString
  // strToCheck = ini returns true
  // strToCheck = iNtsr returns true
  // strToCheck = initsa returns false
  containsLettersInOrder(base, strToCheck) {
    // base = base.toLowerCase()
    // strToCheck = strToCheck.toLowerCase()
    let highestMatchedIndex = -1
    for (let i=0; i < strToCheck.length; i++) {
      const workingIndex = highestMatchedIndex + 1
      const index = base.substring(workingIndex).indexOf(strToCheck[i]) + workingIndex
      console.log("base", base)
      console.log("base.substring(workingIndex)", base.substring(workingIndex))
      console.log("strToCheck", strToCheck)
      console.log("strToCheck[i]", strToCheck[i])
      console.log("workingIndex", workingIndex)
      console.log("index", index)
      console.log("highestMatchedIndex", highestMatchedIndex)
      if (index <= highestMatchedIndex)
        return false
      highestMatchedIndex = index
    }
    return true
  }

  prepareHint(pos, wordToComplete, completion) {

    // Get basic completions from nearby text
    const cmDoc = this.decoDoc.cmDoc
    const basic = CodeMirror.hint.anyword(cmDoc).list.map(item => ({name: item}))

    // Join flow completions and basic completions
    const list = _.chain([...completion.result, ...basic])

      // Filter word being typed and irrelevant completions,
      // disregarding case
      .filter((item) => {
        return item.name !== wordToComplete &&
        this.containsLettersInOrder(item.name.toLowerCase(), wordToComplete.toLowerCase())
        // item.name.toLowerCase().startsWith(wordToComplete.toLowerCase())
      })

      // Remove duplicates
      .uniqBy('name')
      .sortBy('name')

      .map(item => {
        return {
          text: item.name,
          render: this.renderHint.bind(this, item, wordToComplete),
        }
      })
      .value()

    return {
      list,
      from: new Pos(pos.line, pos.ch - wordToComplete.length),
      to: pos,
    }
  }

  getHint(pos, wordToComplete) {
    const {decoDoc} = this

    FlowController.startServer()

    return FlowController.getCompletion(decoDoc.code, pos, decoDoc.id)
      .then(completion => {
        this.cachedCompletions[decoDoc.id] = {wordToComplete, completion}
        return this.prepareHint(pos, wordToComplete, completion)
      })

      // If Flow is unavailable, we still may show basic completions
      .catch(e => {
        return this.prepareHint(pos, wordToComplete, {result: []})
      })
  }

  showHint(cm, hint) {
    cm.showHint({
      completeSingle: false,
      shown: () => this.completionActive = true,
      close: () => this.completionActive = false,
      hint: () => hint,
    })
  }

  changes = (cm, changes) => {
    const {decoDoc} = this

    // Only show popup in the linked doc in the active tab
    if (!cm.hasFocus()) return

    // Do nothing if popup is already open
    if (this.completionActive) return

    // Only show popup if the last change was a user input event
    if (!ChangeUtils.containsUserInputChange(changes)) return

    const range = cm.listSelections()[0]
    const from = range.from()

    if (range.empty()) {
      const textBefore = cm.getRange(new Pos(from.line, 0), from)

      // Show popup if the user has typed at least 1 characters
      const match = textBefore.match(/[\w$]{1,}$/)

      if (match) {
        const word = match[0]
        const cached = this.cachedCompletions[decoDoc.id]

        this.currentWord = word

        // Show existing cached completion, but update highlighted portion
        if (cached && word.startsWith(cached.wordToComplete)) {
          this.showHint(cm, this.prepareHint(from, word, cached.completion))
        }

        // Fetch new completion
        this.getHint(from, word).then((hint) => {

          // Since this is async, make sure we're still completing the correct word
          if (word === this.currentWord) {
            this.showHint(cm, hint)
          }
        })
      }
    }
  }

}
<commit_msg>remove comments<commit_after>/**
 *    Copyright (C) 2015 Deco Software Inc.
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

import _ from 'lodash'
import React from 'react'
import ReactDOM from 'react-dom'
import CodeMirror from 'codemirror'

const FlowController = Electron.remote.require('./process/flowController.js')
import Middleware from '../Middleware'
import { EventTypes } from '../../constants/CodeMirrorTypes'
import Pos from '../../models/editor/CodeMirrorPos'
import { AutocompleteHint } from '../../components'
import * as ChangeUtils from '../../utils/Editor/ChangeUtils'

/**
 * Middleware for showing autocompletion hints while typing.
 *
 * We use a combination of 2 sources for hints:
 * - "basic" completions provided by CodeMirror's anyword plugin
 * - "flow" completions provided by a local flow-bin node_modules, if one exists
 *
 * If basic and flow both offer the same completion for a word, we show the flow
 * completion, since it will likely have detailed type information.
 *
 * In the case that flow doesn't exist, we show only basic completions.
 */
export default class AutocompleteMiddleware extends Middleware {

  constructor() {
    super()

    this.completionActive = false
    this.currentWord = ''

    // In order to keep completions from spontaneously disappearing as we type,
    // we cache the previous completion shown. We continue to show it as we
    // wait for a new set of completions, updating the highlighted portion of
    // the hints immediately.
    this.cachedCompletions = {}

    this.eventListeners = {
      [EventTypes.changes]: this.changes,
    }
  }

  renderHint(item, wordToComplete, node) {
    const root = (
      <AutocompleteHint
        text={item.name}
        type={item.type}
        wordToComplete={wordToComplete}
        functionDetails={item.func_details}
      />
    )
    ReactDOM.render(root, node)
  }

  // If base = initialString
  // strToCheck = ini returns true
  // strToCheck = iNtsr returns true
  // strToCheck = initsa returns false
  containsLettersInOrder(base, strToCheck) {
    let highestMatchedIndex = -1
    for (let i=0; i < strToCheck.length; i++) {
      const workingIndex = highestMatchedIndex + 1
      const index = base.substring(workingIndex).indexOf(strToCheck[i]) + workingIndex
      if (index <= highestMatchedIndex)
        return false
      highestMatchedIndex = index
    }
    return true
  }

  prepareHint(pos, wordToComplete, completion) {

    // Get basic completions from nearby text
    const cmDoc = this.decoDoc.cmDoc
    const basic = CodeMirror.hint.anyword(cmDoc).list.map(item => ({name: item}))

    // Join flow completions and basic completions
    const list = _.chain([...completion.result, ...basic])

      // Filter word being typed and irrelevant completions,
      // disregarding case
      .filter((item) => {
        return item.name !== wordToComplete &&
        this.containsLettersInOrder(item.name.toLowerCase(), wordToComplete.toLowerCase())
      })

      // Remove duplicates
      .uniqBy('name')
      .sortBy('name')

      .map(item => {
        return {
          text: item.name,
          render: this.renderHint.bind(this, item, wordToComplete),
        }
      })
      .value()

    return {
      list,
      from: new Pos(pos.line, pos.ch - wordToComplete.length),
      to: pos,
    }
  }

  getHint(pos, wordToComplete) {
    const {decoDoc} = this

    FlowController.startServer()

    return FlowController.getCompletion(decoDoc.code, pos, decoDoc.id)
      .then(completion => {
        this.cachedCompletions[decoDoc.id] = {wordToComplete, completion}
        return this.prepareHint(pos, wordToComplete, completion)
      })

      // If Flow is unavailable, we still may show basic completions
      .catch(e => {
        return this.prepareHint(pos, wordToComplete, {result: []})
      })
  }

  showHint(cm, hint) {
    cm.showHint({
      completeSingle: false,
      shown: () => this.completionActive = true,
      close: () => this.completionActive = false,
      hint: () => hint,
    })
  }

  changes = (cm, changes) => {
    const {decoDoc} = this

    // Only show popup in the linked doc in the active tab
    if (!cm.hasFocus()) return

    // Do nothing if popup is already open
    if (this.completionActive) return

    // Only show popup if the last change was a user input event
    if (!ChangeUtils.containsUserInputChange(changes)) return

    const range = cm.listSelections()[0]
    const from = range.from()

    if (range.empty()) {
      const textBefore = cm.getRange(new Pos(from.line, 0), from)

      // Show popup if the user has typed at least 1 characters
      const match = textBefore.match(/[\w$]{1,}$/)

      if (match) {
        const word = match[0]
        const cached = this.cachedCompletions[decoDoc.id]

        this.currentWord = word

        // Show existing cached completion, but update highlighted portion
        if (cached && word.startsWith(cached.wordToComplete)) {
          this.showHint(cm, this.prepareHint(from, word, cached.completion))
        }

        // Fetch new completion
        this.getHint(from, word).then((hint) => {

          // Since this is async, make sure we're still completing the correct word
          if (word === this.currentWord) {
            this.showHint(cm, hint)
          }
        })
      }
    }
  }

}
<|endoftext|>


<commit_before>import ChromePromise from 'chrome-promise';

const chromep = new ChromePromise();

/* Action Type Constants: */

const UPDATE_CATEGORIES = 'UPDATE_CATEGORIES';
const UPDATE_CATEGORY = 'UPDATE_CATEGORY';

/* Action Creators: */

const getAllCategories = (dispatch) => {
  // start chrome promise to get all categories and their tasks
  chromep.storage.sync.get(null).then(function(categories) {

    var categoryArray = [];

    for(var categoryName in categories) {  // for every key
      var data = { [categoryName] : categories[categoryName] }; // assemble object
      categoryArray.push(data); // push to new array
    }

    return {
      categories: categoryArray // return array
    };

  }).then(
    response => dispatch({
      type: UPDATE_CATEGORIES,
      payload: { categories: response.categories },
    }),
    error => dispatch({   // shouldn't ever get here
      type: UPDATE_CATEGORIES,
      error: true,
      payload: error
    })
  );
};

// update all categories in chrome storage
const updateCategories = () => {
  return function(dispatch) {
    getAllCategories(dispatch);
  }
};

// update individual category in chrome storage
const updateCategory = ( categoryName, tasks) => {
  return function(dispatch) {
    var data = { [categoryName]: tasks };
    chromep.storage.sync.set(data).then(getAllCategories(dispatch));
  }
};

export const task_manager_actions = {
  updateCategories, updateCategory
};
<commit_msg>add comments<commit_after>import ChromePromise from 'chrome-promise';

const chromep = new ChromePromise();

/* Action Type Constants: */

const UPDATE_CATEGORIES = 'UPDATE_CATEGORIES';
const UPDATE_CATEGORY = 'UPDATE_CATEGORY';

/* Action Creators: */

// update 'categories' state with new categories and their tasks
const getAllCategories = (dispatch) => {
  // start chrome promise to get all categories and their tasks
  chromep.storage.sync.get(null).then(function(categories) {

    var categoryArray = [];

    for(var categoryName in categories) {  // for every key
      var data = { [categoryName] : categories[categoryName] }; // assemble object
      categoryArray.push(data); // push to new array
    }

    return {
      categories: categoryArray // return array
    };

  }).then(
    response => dispatch({
      type: UPDATE_CATEGORIES,
      payload: { categories: response.categories },
    }),
    error => dispatch({   // shouldn't ever get here
      type: UPDATE_CATEGORIES,
      error: true,
      payload: error
    })
  );
};

// update all categories in chrome storage
const updateCategories = () => {
  return function(dispatch) {
    getAllCategories(dispatch); // call to update all categories
  }
};

// update individual category in chrome storage
const updateCategory = ( categoryName, tasks) => {
  return function(dispatch) {
    var data = { [categoryName]: tasks };

    // update category with new tasks, then update 'categories' state
    chromep.storage.sync.set(data).then(getAllCategories(dispatch));
  }
};

export const task_manager_actions = {
  updateCategories, updateCategory
};
<|endoftext|>


<commit_before>'use strict';

(function() {
  var module = angular.module('redash.visualization');

  module.config(['VisualizationProvider', function(VisualizationProvider) {
    var renderTemplate =
      '<map-renderer ' +
      'options="visualization.options" query-result="queryResult">' +
      '</map-renderer>';

    var editTemplate = '<map-editor></map-editor>';
    var defaultOptions = {
      'height': 500,
      'draw': 'Marker',
      'classify':'none'
    };

    VisualizationProvider.registerVisualization({
      type: 'MAP',
      name: 'Map',
      renderTemplate: renderTemplate,
      editorTemplate: editTemplate,
      defaultOptions: defaultOptions
    });
  }
  ]);

  module.directive('mapRenderer', function() {
    return {
      restrict: 'E',
      templateUrl: '/views/visualizations/map.html',
      link: function($scope, elm, attrs) {

        var setBounds = function(){
          var b = $scope.visualization.options.bounds;

          if(b){
            $scope.map.fitBounds([[b._southWest.lat, b._southWest.lng],[b._northEast.lat, b._northEast.lng]]);
          } else if ($scope.features.length > 0){
            var group= new L.featureGroup($scope.features);
            $scope.map.fitBounds(group.getBounds());
          }
        };

        $scope.$watch('[queryResult && queryResult.getData(), visualization.options.draw,visualization.options.latColName,'+
            'visualization.options.lonColName,visualization.options.classify,visualization.options.classify]',
          function() {
            var marker = function(lat,lon){
              if (lat == null || lon == null) return;

              return L.marker([lat, lon]);
            };

            var heatpoint = function(lat,lon,obj){
              if (lat == null || lon == null) return;

              var color = 'red';

              if (obj &&
                obj[$scope.visualization.options.classify] &&
                $scope.visualization.options.classification){
                var v =  $.grep($scope.visualization.options.classification,function(e){
                  return e.value == obj[$scope.visualization.options.classify];
                });
                if (v.length >0) color = v[0].color;
              }

              var style = {
                fillColor:color,
                fillOpacity:0.5,
                stroke:false
              };

              return L.circleMarker([lat,lon],style)
            };

            var color = function(val){
              // taken from http://jsfiddle.net/xgJ2e/2/

              var h= Math.floor((100 - val) * 120 / 100);
              var s = Math.abs(val - 50)/50;
              var v = 1;

              var rgb, i, data = [];
              if (s === 0) {
                rgb = [v,v,v];
              } else {
                h = h / 60;
                i = Math.floor(h);
                data = [v*(1-s), v*(1-s*(h-i)), v*(1-s*(1-(h-i)))];
                switch(i) {
                  case 0:
                    rgb = [v, data[2], data[0]];
                    break;
                  case 1:
                    rgb = [data[1], v, data[0]];
                    break;
                  case 2:
                    rgb = [data[0], v, data[2]];
                    break;
                  case 3:
                    rgb = [data[0], data[1], v];
                    break;
                  case 4:
                    rgb = [data[2], data[0], v];
                    break;
                  default:
                    rgb = [v, data[0], data[1]];
                    break;
                }
              }
              return '#' + rgb.map(function(x){
                return ("0" + Math.round(x*255).toString(16)).slice(-2);
              }).join('');
            };

            // Following line is used to avoid "Couldn't autodetect L.Icon.Default.imagePath" error
            // https://github.com/Leaflet/Leaflet/issues/766#issuecomment-7741039
            L.Icon.Default.imagePath = L.Icon.Default.imagePath || "//api.tiles.mapbox.com/mapbox.js/v2.2.1/images";

            function getBounds(e) {
              $scope.visualization.options.bounds = $scope.map.getBounds();
            }

            var queryData = $scope.queryResult.getData();
            var classify = $scope.visualization.options.classify;

            if (queryData) {
              $scope.visualization.options.classification = [];

              for (var row in queryData) {
                if (queryData[row][classify] &&
                  $.grep($scope.visualization.options.classification, function (e) {
                    return e.value == queryData[row][classify]
                  }).length == 0) {
                  $scope.visualization.options.classification.push({value: queryData[row][classify], color: null});
                }
              }

              $.each($scope.visualization.options.classification, function (i, c) {
                c.color = color(parseInt((i / $scope.visualization.options.classification.length) * 100));
              });

              if (!$scope.map) {
                $scope.map = L.map(elm[0].children[0].children[0])
              }

              L.tileLayer('//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                attribution: '© OpenStreetMap contributors'
              }).addTo($scope.map);

              $scope.features = $scope.features || [];

              var tmp_features = [];

              var lat_col = $scope.visualization.options.latColName || 'lat';
              var lon_col = $scope.visualization.options.lonColName || 'lon';

              for (var row in queryData) {
                var feature;

                if ($scope.visualization.options.draw == 'Marker') {
                  feature = marker(queryData[row][lat_col], queryData[row][lon_col])
                } else if ($scope.visualization.options.draw == 'Color') {
                  feature = heatpoint(queryData[row][lat_col], queryData[row][lon_col], queryData[row])
                }

                if (!feature) continue;

                var obj_description = '
';
                for (var k in queryData[row]){
                  obj_description += "
" + k + ": " + queryData[row][k] + "
";
                }
                obj_description += '
';
                feature.bindPopup(obj_description);
                tmp_features.push(feature);
              }

              $.each($scope.features, function (i, f) {
                $scope.map.removeLayer(f);
              });

              $scope.features = tmp_features;

              $.each($scope.features, function (i, f) {
                f.addTo($scope.map)
              });

              setBounds();

              $scope.map.on('focus',function(){
                $scope.map.on('moveend', getBounds);
              });

              $scope.map.on('blur',function(){
                $scope.map.off('moveend', getBounds);
              });

              // We redraw the map if it was loaded in a hidden tab
              if ($('a[href="#'+$scope.visualization.id+'"]').length > 0) {

                $('a[href="#'+$scope.visualization.id+'"]').on('click', function () {
                  setTimeout(function() {
                    $scope.map.invalidateSize(false);

                    setBounds();
                  },500);
                });
              }

            }
          }, true);

        $scope.$watch('visualization.options.height', function() {

          if (!$scope.map) return;
          $scope.map.invalidateSize(false);
          setBounds();

        });
      }
    }
  });

  module.directive('mapEditor', function() {
    return {
      restrict: 'E',
      templateUrl: '/views/visualizations/map_editor.html',
      link: function($scope, elm, attrs) {
        $scope.draw_options = ['Marker','Color'];
        $scope.classify_columns = $scope.queryResult.columnNames.concat('none');
      }
    }
  });

})();
<commit_msg>Remove unnecessary code.<commit_after>'use strict';

(function() {
  var module = angular.module('redash.visualization');

  module.config(['VisualizationProvider', function(VisualizationProvider) {
    var renderTemplate =
      '<map-renderer ' +
      'options="visualization.options" query-result="queryResult">' +
      '</map-renderer>';

    var editTemplate = '<map-editor></map-editor>';
    var defaultOptions = {
      'height': 500,
      'draw': 'Marker',
      'classify':'none'
    };

    VisualizationProvider.registerVisualization({
      type: 'MAP',
      name: 'Map',
      renderTemplate: renderTemplate,
      editorTemplate: editTemplate,
      defaultOptions: defaultOptions
    });
  }
  ]);

  module.directive('mapRenderer', function() {
    return {
      restrict: 'E',
      templateUrl: '/views/visualizations/map.html',
      link: function($scope, elm, attrs) {

        var setBounds = function(){
          var b = $scope.visualization.options.bounds;

          if(b){
            $scope.map.fitBounds([[b._southWest.lat, b._southWest.lng],[b._northEast.lat, b._northEast.lng]]);
          } else if ($scope.features.length > 0){
            var group= new L.featureGroup($scope.features);
            $scope.map.fitBounds(group.getBounds());
          }
        };

        $scope.$watch('[queryResult && queryResult.getData(), visualization.options.draw,visualization.options.latColName,'+
            'visualization.options.lonColName,visualization.options.classify,visualization.options.classify]',
          function() {
            var marker = function(lat,lon){
              if (lat == null || lon == null) return;

              return L.marker([lat, lon]);
            };

            var heatpoint = function(lat,lon,obj){
              if (lat == null || lon == null) return;

              var color = 'red';

              if (obj &&
                obj[$scope.visualization.options.classify] &&
                $scope.visualization.options.classification){
                var v =  $.grep($scope.visualization.options.classification,function(e){
                  return e.value == obj[$scope.visualization.options.classify];
                });
                if (v.length >0) color = v[0].color;
              }

              var style = {
                fillColor:color,
                fillOpacity:0.5,
                stroke:false
              };

              return L.circleMarker([lat,lon],style)
            };

            var color = function(val){
              // taken from http://jsfiddle.net/xgJ2e/2/

              var h= Math.floor((100 - val) * 120 / 100);
              var s = Math.abs(val - 50)/50;
              var v = 1;

              var rgb, i, data = [];
              if (s === 0) {
                rgb = [v,v,v];
              } else {
                h = h / 60;
                i = Math.floor(h);
                data = [v*(1-s), v*(1-s*(h-i)), v*(1-s*(1-(h-i)))];
                switch(i) {
                  case 0:
                    rgb = [v, data[2], data[0]];
                    break;
                  case 1:
                    rgb = [data[1], v, data[0]];
                    break;
                  case 2:
                    rgb = [data[0], v, data[2]];
                    break;
                  case 3:
                    rgb = [data[0], data[1], v];
                    break;
                  case 4:
                    rgb = [data[2], data[0], v];
                    break;
                  default:
                    rgb = [v, data[0], data[1]];
                    break;
                }
              }
              return '#' + rgb.map(function(x){
                return ("0" + Math.round(x*255).toString(16)).slice(-2);
              }).join('');
            };

            // Following line is used to avoid "Couldn't autodetect L.Icon.Default.imagePath" error
            // https://github.com/Leaflet/Leaflet/issues/766#issuecomment-7741039
            L.Icon.Default.imagePath = L.Icon.Default.imagePath || "//api.tiles.mapbox.com/mapbox.js/v2.2.1/images";

            function getBounds(e) {
              $scope.visualization.options.bounds = $scope.map.getBounds();
            }

            var queryData = $scope.queryResult.getData();
            var classify = $scope.visualization.options.classify;

            if (queryData) {
              $scope.visualization.options.classification = [];

              for (var row in queryData) {
                if (queryData[row][classify] &&
                  $.grep($scope.visualization.options.classification, function (e) {
                    return e.value == queryData[row][classify]
                  }).length == 0) {
                  $scope.visualization.options.classification.push({value: queryData[row][classify], color: null});
                }
              }

              $.each($scope.visualization.options.classification, function (i, c) {
                c.color = color(parseInt((i / $scope.visualization.options.classification.length) * 100));
              });

              if (!$scope.map) {
                $scope.map = L.map(elm[0].children[0].children[0])
              }

              L.tileLayer('//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                attribution: '© OpenStreetMap contributors'
              }).addTo($scope.map);

              $scope.features = $scope.features || [];

              var tmp_features = [];

              var lat_col = $scope.visualization.options.latColName || 'lat';
              var lon_col = $scope.visualization.options.lonColName || 'lon';

              for (var row in queryData) {
                var feature;

                if ($scope.visualization.options.draw == 'Marker') {
                  feature = marker(queryData[row][lat_col], queryData[row][lon_col])
                } else if ($scope.visualization.options.draw == 'Color') {
                  feature = heatpoint(queryData[row][lat_col], queryData[row][lon_col], queryData[row])
                }

                if (!feature) continue;

                var obj_description = '
';
                for (var k in queryData[row]){
                  obj_description += "
" + k + ": " + queryData[row][k] + "
";
                }
                obj_description += '
';
                feature.bindPopup(obj_description);
                tmp_features.push(feature);
              }

              $.each($scope.features, function (i, f) {
                $scope.map.removeLayer(f);
              });

              $scope.features = tmp_features;

              $.each($scope.features, function (i, f) {
                f.addTo($scope.map)
              });

              setBounds();

              $scope.map.on('focus',function(){
                $scope.map.on('moveend', getBounds);
              });

              $scope.map.on('blur',function(){
                $scope.map.off('moveend', getBounds);
              });
            }
          }, true);

        $scope.$watch('visualization.options.height', function() {

          if (!$scope.map) return;
          $scope.map.invalidateSize(false);
          setBounds();

        });
      }
    }
  });

  module.directive('mapEditor', function() {
    return {
      restrict: 'E',
      templateUrl: '/views/visualizations/map_editor.html',
      link: function($scope, elm, attrs) {
        $scope.draw_options = ['Marker','Color'];
        $scope.classify_columns = $scope.queryResult.columnNames.concat('none');
      }
    }
  });

})();
<|endoftext|>


<commit_before>/* @flow */

import { AppState } from 'react-native';
import type { Dispatch } from 'redux';

import {
    _setAppStateListener,
    appStateChanged,
    setBackgroundVideoMuted
} from './actions';
import {
    _SET_APP_STATE_LISTENER,
    APP_STATE_CHANGED
} from './actionTypes';

import {
    APP_WILL_MOUNT,
    APP_WILL_UNMOUNT
} from '../app';
import { MiddlewareRegistry } from '../base/redux';

/**
 * Middleware that captures App lifetime actions and subscribes to application
 * state changes. When the application state changes it will fire the action
 * requred to mute or unmute the local video in case the application goes to
 * the backgound or comes back from it.
 *
 * @see https://facebook.github.io/react-native/docs/appstate.html
 * @param {Store} store - Redux store.
 * @returns {Function}
 */
MiddlewareRegistry.register(store => next => action => {
    switch (action.type) {
    case _SET_APP_STATE_LISTENER: {
        const bgState = store.getState()['features/background'];

        if (bgState.appStateListener) {
            AppState.removeEventListener('change', bgState.listener);
        }
        if (action.listener) {
            AppState.addEventListener('change', action.listener);
        }
        break;
    }
    case APP_STATE_CHANGED:
        _handleAppStateChange(store.dispatch, action.appState);
        break;
    case APP_WILL_MOUNT: {
        const listener
            = __onAppStateChanged.bind(undefined, store.dispatch);

        store.dispatch(_setAppStateListener(listener));
        break;
    }
    case APP_WILL_UNMOUNT:
        store.dispatch(_setAppStateListener(null));
        break;
    }

    return next(action);
});

/**
 * Handler for app state changes. If will fire the necessary actions for
 * local video to be muted when the app goes to the background, and to
 * unmute it when it comes back.
 *
 * @param  {Dispatch} dispatch - Redux dispatch function.
 * @param  {string} appState - Current app state.
 * @private
 * @returns {void}
 */
function _handleAppStateChange(dispatch: Dispatch<*>, appState: string) {
    // XXX: we purposely don't handle the 'inactive' state.
    if (appState === 'background') {
        dispatch(setBackgroundVideoMuted(true));
    } else if (appState === 'active') {
        dispatch(setBackgroundVideoMuted(false));
    }
}

/**
 * Handler called by React's AppState API indicating that the application state
 * has changed.
 *
 * @param  {Dispatch} dispatch - Redux dispatch function.
 * @param  {string} appState - The current application execution state.
 * @private
 * @returns {void}
 */
function __onAppStateChanged(dispatch: Dispatch<*>, appState: string) {
    dispatch(appStateChanged(appState));
}
<commit_msg>Fix a possible undefined state usage<commit_after>/* @flow */

import { AppState } from 'react-native';
import type { Dispatch } from 'redux';

import {
    _setAppStateListener,
    appStateChanged,
    setBackgroundVideoMuted
} from './actions';
import {
    _SET_APP_STATE_LISTENER,
    APP_STATE_CHANGED
} from './actionTypes';

import {
    APP_WILL_MOUNT,
    APP_WILL_UNMOUNT
} from '../app';
import { MiddlewareRegistry } from '../base/redux';

/**
 * Middleware that captures App lifetime actions and subscribes to application
 * state changes. When the application state changes it will fire the action
 * requred to mute or unmute the local video in case the application goes to
 * the backgound or comes back from it.
 *
 * @see https://facebook.github.io/react-native/docs/appstate.html
 * @param {Store} store - Redux store.
 * @returns {Function}
 */
MiddlewareRegistry.register(store => next => action => {
    switch (action.type) {
    case _SET_APP_STATE_LISTENER: {
        const { appStateListener } = store.getState()['features/background'];

        if (appStateListener) {
            AppState.removeEventListener('change', appStateListener);
        }
        if (action.listener) {
            AppState.addEventListener('change', action.listener);
        }
        break;
    }
    case APP_STATE_CHANGED:
        _handleAppStateChange(store.dispatch, action.appState);
        break;
    case APP_WILL_MOUNT: {
        const listener
            = __onAppStateChanged.bind(undefined, store.dispatch);

        store.dispatch(_setAppStateListener(listener));
        break;
    }
    case APP_WILL_UNMOUNT:
        store.dispatch(_setAppStateListener(null));
        break;
    }

    return next(action);
});

/**
 * Handler for app state changes. If will fire the necessary actions for
 * local video to be muted when the app goes to the background, and to
 * unmute it when it comes back.
 *
 * @param  {Dispatch} dispatch - Redux dispatch function.
 * @param  {string} appState - Current app state.
 * @private
 * @returns {void}
 */
function _handleAppStateChange(dispatch: Dispatch<*>, appState: string) {
    // XXX: we purposely don't handle the 'inactive' state.
    if (appState === 'background') {
        dispatch(setBackgroundVideoMuted(true));
    } else if (appState === 'active') {
        dispatch(setBackgroundVideoMuted(false));
    }
}

/**
 * Handler called by React's AppState API indicating that the application state
 * has changed.
 *
 * @param  {Dispatch} dispatch - Redux dispatch function.
 * @param  {string} appState - The current application execution state.
 * @private
 * @returns {void}
 */
function __onAppStateChanged(dispatch: Dispatch<*>, appState: string) {
    dispatch(appStateChanged(appState));
}
<|endoftext|>


<commit_before>var gameTime = 0;
var elapsedtime = 0;

function initGameTime(sports) {
	switch (sports) {
		case 'soccer':
			gameTime = 45 * 60;
			break;
		case 'fencing':
			gameTime = 3 * 60;
			break;
		default:
			gameTime = 1 * 60;
			// alert('競技が不明です。');
			// location.href = './';
			break;
	}
	elapsedtime = 0;
}

function showElapsedTime() {
	elapsedtime++;
	if (elapsedtime <= gameTime) {
		return elapsedtime;
	} else {
		elapsedtime = 0;
		return -1;
	}
}<commit_msg>deleted countelapsedtime.js<commit_after><|endoftext|>


<commit_before>$.fn.signalsTransformsTable.transforms.ULT={
	name:'Unilateral Laplace transform',
	abbr:'ULT',
	wikipedia:'http://en.wikipedia.org/wiki/Laplace_transform',
	timeFnTemplate:['x(t)','y(t)'],
	freqFnTemplate:['X(s)','Y(s)'],
	freqDomainName:'S-domain',
	sections:{
		definitions:function(t,T,x,X,y,Y,ctx){
			var TR=ctx.letter(['sigma','varsigma']);
			var TI=ctx.letter(['omega','theta','xi']);
		return{
			time:[
				{formula:{
					// but we can't restore stuff before 0
					item:x(t)+' = \\frac{1}{2\\pi j} \\lim_{'+TI+'\\to\\infty} '+ctx.int(X(T)+'e^{'+T+t+'}',T,TR+'-j'+TI,TR+'+j'+TI),
					notes:{
						t:'synthesis formula;
 the contour path of integration is in the '+RoC+' of \\('+X(T)+'\\)',
						b:'function \\('+x(t)+'\\) of continuous variable \\('+t+'\\);
\\('+x(t)+'=0\\) for \\('+t+'<0\\) usually assumed'
					}
				}}
			],
			freq:[
				{formula:{
					item:X(T)+' = '+ctx.int(x(t)+'e^{-'+T+t+'}',t,'0^-','+\\infty'),
					notes:{b:'function \\('+X(T)+'\\) of complex variable \\('+T+'\\)'}
				}}
			]
		}},
		linearity:function(t,T,x,X,y,Y,ctx){
			var t1=ctx.letter(['t','tau','u']);
			var T1=ctx.letter(['s','lambda']);
			var TR=ctx.letter(['sigma','varsigma']);
		return{
			time:[
				{},{},{},
				{formula:{
					// sometimes limits are -inf..+inf, but then causality of x(t) and y(t) is required
					item:x(t)+'*'+y(t)+' \\equiv '+ctx.int(x(t1)+y(t+'-'+t1),t1,'0',t), // TODO what about limits? is it 0- .. t+ ?
					notes:{
						// t:'\\('+x(t)+'='+y(t)+'=0\\) required for \\('+t+'<0\\)',
						// b:'linear convolution'
					}
				}},
				{formula:{item:x(t)+' \\cdot '+y(t)}}
			],
			freq:[
				{formula:{notes:{b:RoC+' = \\(R_'+ctx.letters.X+'\\)'}}},
				{formula:{notes:{b:RoC+' = \\(R_'+ctx.letters.Y+'\\)'}}},
				{formula:{notes:{b:RoC+' includes \\(R_'+ctx.letters.X+' \\cap R_'+ctx.letters.Y+'\\)'}}},
				{formula:{
					item:X(T)+' \\cdot '+Y(T),
					notes:{b:RoC+' includes \\(R_'+ctx.letters.X+' \\cap R_'+ctx.letters.Y+'\\)'}
				}},
				// see [The Handbook of Formulas and Tables for Signal Processing. Ed. Alexander D. Poularikas] for the definition of complex convolution
				{formula:{ // [Wai-Kai Chen, section 3.3.5]
					item:'\\frac{1}{2\\pi j} '+X(T)+'*'+Y(T)+' \\equiv \\frac{1}{2\\pi j} '+ctx.int(X(T1)+Y(T+'-'+T1),T1,TR+'-j\\infty',TR+'+j\\infty'),
					notes:{
						t:'s-domain convolution',
						b:RoC+' includes \\(R_'+ctx.letters.X+' \\cap R_'+ctx.letters.Y+'\\)' // [Mandal, p. 283]
					}
				}}
			]
		}},
		conjrev:function(t,T,x,X){return{
			cells:
				'+|*|+',
			time:[
				{
					formula:{
						item:'-'+x(t,'*')
					}
				},{
					formula:{
						item:x(t)
					},
					relations:{
						l:{notes:{t:'imaginary'}},
						r:{notes:{t:'real'}}
					}
				},{
					formula:{
						item:x(t,'*'),
						notes:{b:'conjugation'}
					}
				}
			],
			freq:[
				{
					formula:{
						item:'-'+X(T+'^*','*'),
						notes:{b:RoC+' = \\(R\\)'}
					}
				},{
					formula:{
						item:X(T),
						notes:{b:RoC+' = \\(R\\)'}
					},
					relations:{
						l:{},
						r:{}
					}
				},{
					formula:{
						item:X(T+'^*','*'),
						notes:{b:RoC+' = \\(R\\)'}
					}
				}
			]
		}},
		modshift:function(t,T,x,X,y,Y,ctx){return{
			cells:
				'+ + +'+'/'+
				'+|*|+'+'/'+
				'+ + +',
			time:[
				{formula:{
					item:x(t+'+'+t+'_0'),
					notes:{b:'\\('+t+'_0 > 0\\)',t:'time advance'}
				}},
				{formula:{
					item:'e^{-'+T+'_0'+t+'}'+x(t)
				}},
				{formula:{
					item:x(t)
				}},
				{formula:{
					item:'e^{'+T+'_0'+t+'}'+x(t)
				}},
				{formula:{
					item:x(t+'-'+t+'_0'),
					notes:{b:'\\('+t+'_0 > 0\\)',t:'time delay'}
				}}
			],
			freq:[
				{formula:{
					item:'e^{'+T+t+'_0}'+X(T)+'-e^{'+T+t+'_0}'+ctx.int(x(t)+'e^{-'+T+t+'}',t,'0^-',t+'_0^-'),
					notes:{b:RoC+' = \\(R\\)'}
				}},
				{formula:{
					item:X(''+T+'+'+T+'_0'),
					notes:{b:RoC+' = \\(R-\\Re('+T+'_0)\\)'}
				}},
				{formula:{
					item:X(T),
					notes:{b:RoC+' = \\(R\\)'}
				}},
				{formula:{
					item:X(''+T+'-'+T+'_0'),
					notes:{b:RoC+' = \\(R+\\Re('+T+'_0)\\)'}
				}},
				{formula:{
					item:'e^{-'+T+' '+t+'_0}'+X(T)+'+e^{-'+T+' '+t+'_0}'+ctx.int(x(t)+'e^{-'+T+t+'}',t,'(-'+t+'_0)^-','0^-'),
					notes:{b:RoC+' = \\(R\\)'}
				}}
			]
		}},
		intdiff:function(t,T,x,X,y,Y,ctx){
			var t1=ctx.letter(['t','tau','u']);
			var T1=ctx.letter(['s','lambda']);
		return{
			cells:
				'+|+|.'+'/'+
				'+|*|+'+'/'+
				'.|+|.',
			time:[
				{formula:{
					item:ctx.int(x(t1),t1,'-\\infty',t)
				}},
				{formula:{
					item:ctx.int(x(t1),t1,'0^-',t)
				}},
				{formula:{
					item:'\\frac{1}{'+t+'}'+x(t)
				}},
				{formula:{
					item:x(t)
				}},
				{formula:{
					item:'-'+t+' '+x(t)
				}},
				{formula:{
					item:'\\frac{\\mathrm{d}}{\\mathrm{d}'+t+'} '+x(t)
				}}
			],
			freq:[
				{formula:{
					item:'\\frac{'+X(T)+'}{'+T+'}+\\frac{1}{'+T+'}'+ctx.int(x(t),t,'-\\infty','0^-'),
					notes:{b:RoC+' includes \\(R \\cap \\{\\Re('+T+')>0\\}\\)'}
				}},
				{formula:{
					item:'\\frac{1}{'+T+'}'+X(T),
					notes:{b:RoC+' includes \\(R \\cap \\{\\Re('+T+')>0\\}\\)'}
				}},
				{formula:{
					item:ctx.int(X(T1),T1,T,'\\infty')
					// TODO RoC?
				}},
				{formula:{
					item:X(T),
					notes:{b:RoC+' = \\(R\\)'}
				}},
				{formula:{
					item:'\\frac{\\mathrm{d}}{\\mathrm{d}'+T+'} '+X(T),
					notes:{b:RoC+' = \\(R\\)'}
				}},
				{formula:{
					item:T+X(T)+'-'+x('0^-'),
					notes:{b:RoC+' includes \\(R\\)'}
				}}
			]
		}},
		impstep:function(t,T,x,X){return{
			cells:
				'.|+|.'+'/'+
				'.|+|.',
			time:[
				{formula:{
					item:'\\delta('+t+')',
					notes:{b:'Dirac delta'+Wiki('http://en.wikipedia.org/wiki/Dirac_delta_function')}
				}},
				{formula:{
					item:'u('+t+')',
					notes:{b:'unit step'+Wiki('http://en.wikipedia.org/wiki/Heaviside_step_function')}
				}}
			],
			freq:[
				{formula:{
					item:'1',
					notes:{b:RoC+': all \\('+T+'\\)'}
				}},
				{formula:{
					item:'\\frac{1}{'+T+'}',
					notes:{b:RoC+': \\(\\Re('+T+')>0\\)'}
				}}
			]
		}}
	}
};
<commit_msg>ULT 2nd-order derivative<commit_after>$.fn.signalsTransformsTable.transforms.ULT={
	name:'Unilateral Laplace transform',
	abbr:'ULT',
	wikipedia:'http://en.wikipedia.org/wiki/Laplace_transform',
	timeFnTemplate:['x(t)','y(t)'],
	freqFnTemplate:['X(s)','Y(s)'],
	freqDomainName:'S-domain',
	sections:{
		definitions:function(t,T,x,X,y,Y,ctx){
			var TR=ctx.letter(['sigma','varsigma']);
			var TI=ctx.letter(['omega','theta','xi']);
		return{
			time:[
				{formula:{
					// but we can't restore stuff before 0
					item:x(t)+' = \\frac{1}{2\\pi j} \\lim_{'+TI+'\\to\\infty} '+ctx.int(X(T)+'e^{'+T+t+'}',T,TR+'-j'+TI,TR+'+j'+TI),
					notes:{
						t:'synthesis formula;
 the contour path of integration is in the '+RoC+' of \\('+X(T)+'\\)',
						b:'function \\('+x(t)+'\\) of continuous variable \\('+t+'\\);
\\('+x(t)+'=0\\) for \\('+t+'<0\\) usually assumed'
					}
				}}
			],
			freq:[
				{formula:{
					item:X(T)+' = '+ctx.int(x(t)+'e^{-'+T+t+'}',t,'0^-','+\\infty'),
					notes:{b:'function \\('+X(T)+'\\) of complex variable \\('+T+'\\)'}
				}}
			]
		}},
		linearity:function(t,T,x,X,y,Y,ctx){
			var t1=ctx.letter(['t','tau','u']);
			var T1=ctx.letter(['s','lambda']);
			var TR=ctx.letter(['sigma','varsigma']);
		return{
			time:[
				{},{},{},
				{formula:{
					// sometimes limits are -inf..+inf, but then causality of x(t) and y(t) is required
					item:x(t)+'*'+y(t)+' \\equiv '+ctx.int(x(t1)+y(t+'-'+t1),t1,'0',t), // TODO what about limits? is it 0- .. t+ ?
					notes:{
						// t:'\\('+x(t)+'='+y(t)+'=0\\) required for \\('+t+'<0\\)',
						// b:'linear convolution'
					}
				}},
				{formula:{item:x(t)+' \\cdot '+y(t)}}
			],
			freq:[
				{formula:{notes:{b:RoC+' = \\(R_'+ctx.letters.X+'\\)'}}},
				{formula:{notes:{b:RoC+' = \\(R_'+ctx.letters.Y+'\\)'}}},
				{formula:{notes:{b:RoC+' includes \\(R_'+ctx.letters.X+' \\cap R_'+ctx.letters.Y+'\\)'}}},
				{formula:{
					item:X(T)+' \\cdot '+Y(T),
					notes:{b:RoC+' includes \\(R_'+ctx.letters.X+' \\cap R_'+ctx.letters.Y+'\\)'}
				}},
				// see [The Handbook of Formulas and Tables for Signal Processing. Ed. Alexander D. Poularikas] for the definition of complex convolution
				{formula:{ // [Wai-Kai Chen, section 3.3.5]
					item:'\\frac{1}{2\\pi j} '+X(T)+'*'+Y(T)+' \\equiv \\frac{1}{2\\pi j} '+ctx.int(X(T1)+Y(T+'-'+T1),T1,TR+'-j\\infty',TR+'+j\\infty'),
					notes:{
						t:'s-domain convolution',
						b:RoC+' includes \\(R_'+ctx.letters.X+' \\cap R_'+ctx.letters.Y+'\\)' // [Mandal, p. 283]
					}
				}}
			]
		}},
		conjrev:function(t,T,x,X){return{
			cells:
				'+|*|+',
			time:[
				{
					formula:{
						item:'-'+x(t,'*')
					}
				},{
					formula:{
						item:x(t)
					},
					relations:{
						l:{notes:{t:'imaginary'}},
						r:{notes:{t:'real'}}
					}
				},{
					formula:{
						item:x(t,'*'),
						notes:{b:'conjugation'}
					}
				}
			],
			freq:[
				{
					formula:{
						item:'-'+X(T+'^*','*'),
						notes:{b:RoC+' = \\(R\\)'}
					}
				},{
					formula:{
						item:X(T),
						notes:{b:RoC+' = \\(R\\)'}
					},
					relations:{
						l:{},
						r:{}
					}
				},{
					formula:{
						item:X(T+'^*','*'),
						notes:{b:RoC+' = \\(R\\)'}
					}
				}
			]
		}},
		modshift:function(t,T,x,X,y,Y,ctx){return{
			cells:
				'+ + +'+'/'+
				'+|*|+'+'/'+
				'+ + +',
			time:[
				{formula:{
					item:x(t+'+'+t+'_0'),
					notes:{b:'\\('+t+'_0 > 0\\)',t:'time advance'}
				}},
				{formula:{
					item:'e^{-'+T+'_0'+t+'}'+x(t)
				}},
				{formula:{
					item:x(t)
				}},
				{formula:{
					item:'e^{'+T+'_0'+t+'}'+x(t)
				}},
				{formula:{
					item:x(t+'-'+t+'_0'),
					notes:{b:'\\('+t+'_0 > 0\\)',t:'time delay'}
				}}
			],
			freq:[
				{formula:{
					item:'e^{'+T+t+'_0}'+X(T)+'-e^{'+T+t+'_0}'+ctx.int(x(t)+'e^{-'+T+t+'}',t,'0^-',t+'_0^-'),
					notes:{b:RoC+' = \\(R\\)'}
				}},
				{formula:{
					item:X(''+T+'+'+T+'_0'),
					notes:{b:RoC+' = \\(R-\\Re('+T+'_0)\\)'}
				}},
				{formula:{
					item:X(T),
					notes:{b:RoC+' = \\(R\\)'}
				}},
				{formula:{
					item:X(''+T+'-'+T+'_0'),
					notes:{b:RoC+' = \\(R+\\Re('+T+'_0)\\)'}
				}},
				{formula:{
					item:'e^{-'+T+' '+t+'_0}'+X(T)+'+e^{-'+T+' '+t+'_0}'+ctx.int(x(t)+'e^{-'+T+t+'}',t,'(-'+t+'_0)^-','0^-'),
					notes:{b:RoC+' = \\(R\\)'}
				}}
			]
		}},
		intdiff:function(t,T,x,X,y,Y,ctx){
			var t1=ctx.letter(['t','tau','u']);
			var T1=ctx.letter(['s','lambda']);
		return{
			cells:
				'+|+|.'+'/'+
				'+|*|+'+'/'+
				'.|+|.'+'/'+
				'+ + +',
			time:[
				{formula:{
					item:ctx.int(x(t1),t1,'-\\infty',t)
				}},
				{formula:{
					item:ctx.int(x(t1),t1,'0^-',t)
				}},
				{formula:{
					item:'\\frac{1}{'+t+'}'+x(t)
				}},
				{formula:{
					item:x(t)
				}},
				{formula:{
					item:'-'+t+' '+x(t)
				}},
				{formula:{
					item:'\\frac{\\mathrm{d}}{\\mathrm{d}'+t+'} '+x(t)
				}},
				{formula:{
					item:'\\frac{\\mathrm{d}^2}{\\mathrm{d}'+t+'^2} '+x(t)
				}}
			],
			freq:[
				{formula:{
					item:'\\frac{'+X(T)+'}{'+T+'}+\\frac{1}{'+T+'}'+ctx.int(x(t),t,'-\\infty','0^-'),
					notes:{b:RoC+' includes \\(R \\cap \\{\\Re('+T+')>0\\}\\)'}
				}},
				{formula:{
					item:'\\frac{1}{'+T+'}'+X(T),
					notes:{b:RoC+' includes \\(R \\cap \\{\\Re('+T+')>0\\}\\)'}
				}},
				{formula:{
					item:ctx.int(X(T1),T1,T,'\\infty')
					// TODO RoC?
				}},
				{formula:{
					item:X(T),
					notes:{b:RoC+' = \\(R\\)'}
				}},
				{formula:{
					item:'\\frac{\\mathrm{d}}{\\mathrm{d}'+T+'} '+X(T),
					notes:{b:RoC+' = \\(R\\)'}
				}},
				{formula:{
					item:T+X(T)+'-'+x('0^-'),
					notes:{b:RoC+' includes \\(R\\)'}
				}},
				{formula:{
					item:T+'^2'+X(T)+'-'+x('0^-')+T+'-\\frac{\\mathrm{d}}{\\mathrm{d}'+t+'}'+x('0^-'),
					notes:{b:RoC+' includes \\(R\\)'}
				}}
			]
		}},
		impstep:function(t,T,x,X){return{
			cells:
				'.|+|.'+'/'+
				'.|+|.',
			time:[
				{formula:{
					item:'\\delta('+t+')',
					notes:{b:'Dirac delta'+Wiki('http://en.wikipedia.org/wiki/Dirac_delta_function')}
				}},
				{formula:{
					item:'u('+t+')',
					notes:{b:'unit step'+Wiki('http://en.wikipedia.org/wiki/Heaviside_step_function')}
				}}
			],
			freq:[
				{formula:{
					item:'1',
					notes:{b:RoC+': all \\('+T+'\\)'}
				}},
				{formula:{
					item:'\\frac{1}{'+T+'}',
					notes:{b:RoC+': \\(\\Re('+T+')>0\\)'}
				}}
			]
		}}
	}
};
<|endoftext|>


<commit_before>$(document).ready(function(){
	checkCurrentGame();

	$('#new_game').click(newGame);
	$('#send_next_word').unbind('click').click(sendNextWord);
});

function checkCurrentGame(){
	var baseurl = window.URLS.baseurl;

	$.ajax({
		'method': 'GET',
		'url': baseurl + '/games/current',
		'dataType':'json',
		'success' : function(gameData) {
			loadGameData(gameData);
		}
	})
}

function addNewWords(w1,w2) {
	console.log(w1);
	console.log(w2);

	var i1 = $('<li/>').append(w1).hide();
	i1.prependTo('#last_words').fadeIn('slow', function(){
		var i2 = $('<li/>').append(w2).hide();
		i2.prependTo('#last_words').fadeIn('slow');
	});
}

function sendNextWord() {
	var baseurl = window.URLS.baseurl;

	var word = $('#next_word').val();

	var loading = $('#loading');
	loading.show();

	$.ajax({
		'method': 'POST',
		'url': baseurl + '/games/play?word='+word,
		'dataType':'json',
		'success' : function(playData) {
			if (playData.winned) {
				alert('you winned');
				resetGame();
			} else {
				addNewWords(word,playData.last_word);
			}
		},
		'error' : function(info, errorStatus, errorThrown) {
			alert('You lost');
			resetGame();
		},
		'complete': function() {
			loading.hide();
		}
	})
}

function resetGame() {
	$('#total_words').text('');
	$('#current_game').hide();
}

function loadGameData(gameData) {
	$('#total_words').text(gameData.total_words);

	var lastWordsList = $('#last_words');
	lastWordsList.html('');

	for (var i = 0; i < gameData.last_words.length; i++) {
		var element = gameData.last_words[i];
		var e = $('<li/>').append(element);
		lastWordsList.append(e);
	};

	$('#current_game').show();
};

function newGame() {
	var baseurl = window.URLS.baseurl;

	$.ajax({
		'method':'POST',
		'url': baseurl + '/games/create',
		'dataType' : 'json',
		'success' : function(gameData) {
			loadGameData(gameData);
		},
	});
}<commit_msg>show best players on game screen<commit_after>$(document).ready(function(){
	checkCurrentGame();
	getBestGames();

	$('#new_game').click(newGame);
	$('#send_next_word').unbind('click').click(sendNextWord);
});

function getBestGames(){
	var baseurl = window.URLS.baseurl;

	$.ajax({
		'method': 'GET',
		'url': baseurl + '/games/best',
		'dataType':'json',
		'success' : function(data) {
			showBestGames(data);
		}
	})
}

function showBestGames(data) {
	var bP = $('#best_players tbody');
	bP.html('');
	for (var i = 0; i < data.length; i++) {
		var game = data[i];
		var row = $('<tr/>');
		row.append( $('<td/>').append(game.user) );
		row.append( $('<td/>').append(game.total_words) );
		row.append( $('<td/>').append(game.last_word) );
		bP.append(row);
	}
}

function checkCurrentGame(){
	var baseurl = window.URLS.baseurl;

	$.ajax({
		'method': 'GET',
		'url': baseurl + '/games/current',
		'dataType':'json',
		'success' : function(gameData) {
			loadGameData(gameData);
		}
	})
}

function addNewWords(w1,w2) {
	console.log(w1);
	console.log(w2);

	var i1 = $('<li/>').append(w1).hide();
	i1.prependTo('#last_words').fadeIn('slow', function(){
		var i2 = $('<li/>').append(w2).hide();
		i2.prependTo('#last_words').fadeIn('slow');
	});
}

function sendNextWord() {
	var baseurl = window.URLS.baseurl;

	var word = $('#next_word').val();

	var loading = $('#loading');
	loading.show();

	$.ajax({
		'method': 'POST',
		'url': baseurl + '/games/play?word='+word,
		'dataType':'json',
		'success' : function(playData) {
			if (playData.winned) {
				alert('you winned');
				resetGame();
			} else {
				addNewWords(word,playData.last_word);
			}
		},
		'error' : function(info, errorStatus, errorThrown) {
			alert('You lost');
			resetGame();
		},
		'complete': function() {
			loading.hide();
		}
	})
}

function resetGame() {
	$('#total_words').text('');
	$('#current_game').hide();
}

function loadGameData(gameData) {
	$('#total_words').text(gameData.total_words);

	var lastWordsList = $('#last_words');
	lastWordsList.html('');

	for (var i = 0; i < gameData.last_words.length; i++) {
		var element = gameData.last_words[i];
		var e = $('<li/>').append(element);
		lastWordsList.append(e);
	};

	$('#current_game').show();
};

function newGame() {
	var baseurl = window.URLS.baseurl;

	$.ajax({
		'method':'POST',
		'url': baseurl + '/games/create',
		'dataType' : 'json',
		'success' : function(gameData) {
			loadGameData(gameData);
		},
	});
}<|endoftext|>


<commit_before>import { LightningElement, track, wire, api } from "lwc";
import { refreshApex } from "@salesforce/apex";
// Controller for Auto Enrollment Mappings
import getProgramSettingsVModel from "@salesforce/apex/ProgramSettingsController.getProgramSettingsVModel";

// Controller for Affiliations created with Program Enrollment
import getAffiliationsWithProgramEnrollmentVModel from "@salesforce/apex/AffiliationsWithProgramEnrollController.getAffiliationsWithProgramEnrollmentVModel";

//Custom labels for Affiliations created with Program Enrollment
import stgHelpAfflCreateFromProgramEnrollmentHeader from "@salesforce/label/c.stgHelpAfflCreateFromProgramEnrollmentHeader";
import stgHelpAfflCreateFromProgramEnrollmentInfo from "@salesforce/label/c.stgHelpAfflCreateFromProgramEnrollmentInfo";
import stgAfflProgramEnrollmentSettingsTitle from "@salesforce/label/c.stgAfflProgramEnrollmentSettingsTitle";
import stgAfflProgEnrollSetRoleValue from "@salesforce/label/c.stgAfflProgEnrollSetRoleValue";
import stgHelpAfflProgEnrollSetRoleValue from "@salesforce/label/c.stgHelpAfflProgEnrollSetRoleValue";
import stgAfflProgEnrollSetStatusValue from "@salesforce/label/c.stgAfflProgEnrollSetStatusValue";
import stgHelpAfflProgEnrollSetStatusValue from "@salesforce/label/c.stgHelpAfflProgEnrollSetStatusValue";
import stgAfflCopyProgramEnrollmentEndDate from "@salesforce/label/c.stgAfflCopyProgramEnrollmentEndDate";
import stgHelpAfflCopyProgramEnrollmentEndDate from "@salesforce/label/c.stgHelpAfflCopyProgramEnrollmentEndDate";
import stgAfflCopyProgramEnrollmentStartDate from "@salesforce/label/c.stgAfflCopyProgramEnrollmentStartDate";
import stgHelpAfflCopyProgramEnrollmentStartDate from "@salesforce/label/c.stgHelpAfflCopyProgramEnrollmentStartDate";
import stgOptSelect from "@salesforce/label/c.stgOptSelect";

//custom labels for Auto Enrollment Mappings
import stgProgramsSettingsTitle from "@salesforce/label/c.stgProgramsSettingsTitle";
import stgBtnEdit from "@salesforce/label/c.stgBtnEdit";
import stgBtnDelete from "@salesforce/label/c.stgBtnDelete";
import autoEnrollmentMappingsTitle from "@salesforce/label/c.stgAutoEnrollmentProgramTitle";
import autoEnrollmentMappingsDescription from "@salesforce/label/c.stgAutoEnrollmentProgramDesc";
import stgColAccountRecordType from "@salesforce/label/c.stgColAccountRecordType";
import stgColAutoEnrollmentStatus from "@salesforce/label/c.stgColAutoEnrollmentStatus";
import stgColAutoEnrollmentRole from "@salesforce/label/c.stgColAutoEnrollmentRole";
import stgBtnAddMapping from "@salesforce/label/c.stgBtnAddMapping";
import stgTellMeMoreLink from "@salesforce/label/c.stgTellMeMoreLink";
export default class programSettings extends LightningElement {
    isEditMode = false;
    affordancesDisabledToggle = false;

    @track affiliationsWithProgramEnrollmentVModel;
    @track affiliationsWithProgramEnrollVModelWireResult;
    @track programSettingsVModel;
    @track programSettingsVModelWireResult;

    labelReference = {
        programsSettingsTitle: stgProgramsSettingsTitle,
        newButton: stgBtnAddMapping,
        afflCreateFromPrgrmHeading: stgHelpAfflCreateFromProgramEnrollmentHeader,
        afflCreateFromPrgrmInfo: stgHelpAfflCreateFromProgramEnrollmentInfo,
        afflProgramEnrollmentSettingsTitle: stgAfflProgramEnrollmentSettingsTitle,
        afflProgEnrollSetRoleValue: stgAfflProgEnrollSetRoleValue,
        helpAfflProgEnrollSetRoleValue: stgHelpAfflProgEnrollSetRoleValue,
        afflProgEnrollSetStatusValue: stgAfflProgEnrollSetStatusValue,
        helpAfflProgEnrollSetStatusValue: stgHelpAfflProgEnrollSetStatusValue,
        afflCopyProgramEnrollmentEndDate: stgAfflCopyProgramEnrollmentEndDate,
        helpAfflCopyProgramEnrollmentEndDate: stgHelpAfflCopyProgramEnrollmentEndDate,
        afflCopyProgramEnrollmentStartDate: stgAfflCopyProgramEnrollmentStartDate,
        helpAfflCopyProgramEnrollmentStartDate: stgHelpAfflCopyProgramEnrollmentStartDate,
        placeHolderText: stgOptSelect,
        autoEnrollmentMappingsTable: {
            autoEnrollmentMappingsTitle: autoEnrollmentMappingsTitle,
            autoEnrollmentMappingsDescription: autoEnrollmentMappingsDescription,
            accountRecordTypeColumn: stgColAccountRecordType,
            autoEnrollmentStatusColumn: stgColAutoEnrollmentStatus,
            autoEnrollmentRoleColumn: stgColAutoEnrollmentRole,
            editAction: stgBtnEdit,
            deleteAction: stgBtnDelete,
        },
        tellMeMoreLink: stgTellMeMoreLink,
    };

    inputAttributeReference = {
        createdAfflRoleComboboxId: "createdAfflRole",
        createdAfflStatusComboboxId: "createdAfflStatus",
        copyEndDateComboboxId: "copyEndDate",
        copyStartDateComboboxId: "copyStartDate",
    };

    get affordancesDisabled() {
        if (!this.isEditMode || this.affordancesDisabledToggle === true) {
            return true;
        }
        return undefined;
    }

    @api
    handleSaveCanvasRender() {
        this.template.querySelector("c-settings-save-canvas").focusOnTitle();
    }

    @wire(getProgramSettingsVModel)
    programSettingsVModelWire(result) {
        this.programSettingsVModelWireResult = result;

        if (result.data) {
            this.programSettingsVModel = result.data;
        } else if (result.error) {
            //console.log("error retrieving preferredContactInfoSettingsVModel");
        }
    }

    @wire(getAffiliationsWithProgramEnrollmentVModel)
    affiliationsWithProgramEnrollmentVModelWire(result) {
        this.affiliationsWithProgramEnrollVModelWireResult = result;

        if (result.data) {
            this.affiliationsWithProgramEnrollmentVModel = result.data;
        } else if (result.error) {
            //console.log("error retrieving preferredContactInfoSettingsVModel");
        }
    }

    handleRoleForCreatedAfflChange(event) {
        this.handleSpecifyRoleForCreatedAffiliaitons(event);
        var affiliationRole = event.detail.value;
        if (event.detail.value === '""') {
            // set Hierarchy Settings field to a blank value (not "")
            affiliationRole = "";
        }
        // add updated setting to hierarchySettingsChanges object
        let hierarchySettingsChange = {
            settingsType: "string",
            settingsName: "Affl_ProgEnroll_Role_Map__c",
            settingsValue: affiliationRole,
        };

        this.template.querySelector("c-settings-save-canvas").handleHierarchySettingsChange(hierarchySettingsChange);
    }

    handleSpecifyRoleForCreatedAffiliaitons(event) {
        var specifyRoleForCreatedAffl = event.detail.value;
        if (event.detail.value === '""') {
            // set Hierarchy Settings field to a blank value (not "")
            specifyRoleForCreatedAffl = false;
        } else {
            specifyRoleForCreatedAffl = true;
        }
        // add updated setting to hierarchySettingsChanges object
        let hierarchySettingsChange = {
            settingsType: "boolean",
            settingsName: "Affl_ProgEnroll_Set_Role__c",
            settingsValue: specifyRoleForCreatedAffl,
        };

        this.template.querySelector("c-settings-save-canvas").handleHierarchySettingsChange(hierarchySettingsChange);
    }

    handleStatusForCreatedAfflChange(event) {
        var affiliationStatus = event.detail.value;
        if (event.detail.value === '""') {
            // set Hierarchy Settings field to a blank value (not "")
            affiliationStatus = "";
        }
        // add updated setting to hierarchySettingsChanges object
        let hierarchySettingsChange = {
            settingsType: "string",
            settingsName: "Affl_ProgEnroll_Status_Map__c",
            settingsValue: affiliationStatus,
        };

        this.template.querySelector("c-settings-save-canvas").handleHierarchySettingsChange(hierarchySettingsChange);
    }

    handleCopyEndDateChange(event) {
        // add updated setting to hierarchySettingsChanges object
        let hierarchySettingsChange = {
            settingsType: "boolean",
            settingsName: "Affl_ProgEnroll_Copy_End_Date__c",
            settingsValue: event.detail.value,
        };

        this.template.querySelector("c-settings-save-canvas").handleHierarchySettingsChange(hierarchySettingsChange);
    }

    handleCopyStartDateChange(event) {
        // add updated setting to hierarchySettingsChanges object
        let hierarchySettingsChange = {
            settingsType: "boolean",
            settingsName: "Affl_ProgEnroll_Copy_Start_Date__c",
            settingsValue: event.detail.value,
        };

        this.template.querySelector("c-settings-save-canvas").handleHierarchySettingsChange(hierarchySettingsChange);
    }

    get autoEnrollmentMappingsTableColumns() {
        return [
            {
                label: this.labelReference.autoEnrollmentMappingsTable.accountRecordTypeColumn,
                fieldName: "accountRecordTypeLabel",
            },
            {
                label: this.labelReference.autoEnrollmentMappingsTable.autoEnrollmentStatusColumn,
                fieldName: "autoProgramEnrollmentStatus",
            },
            {
                label: this.labelReference.autoEnrollmentMappingsTable.autoEnrollmentRoleColumn,
                fieldName: "autoProgramEnrollmentRole",
            },
            {
                type: "action",
                typeAttributes: {
                    rowActions: [
                        { label: this.labelReference.autoEnrollmentMappingsTable.editAction, name: "edit" },
                        { label: this.labelReference.autoEnrollmentMappingsTable.deleteAction, name: "delete" },
                    ],
                },
            },
        ];
    }

    handleSettingsEditModeChange(event) {
        this.isEditMode = !event.detail;
        this.affordancesDisabledToggle = event.detail;
    }

    handleSettingsSaving(event) {
        this.affordancesDisabledToggle = true;
        // TODO: perform client side validation

        // if validation fails, call this.handleValidationFailure()
        //this.template.querySelector("c-settings-save-canvas").handleValidationFailure();

        // else, update hierarchy settings
        this.template.querySelector("c-settings-save-canvas").updateHierarchySettings();
    }

    handleSettingsSaveCompleted(event) {
        this.affordancesDisabledToggle = false;
        this.refreshAllApex();
    }

    handleSettingsSaveCancel(event) {
        this.refreshAllApex();
    }

    refreshAllApex() {
        Promise.all([
            refreshApex(this.programSettingsVModelWireResult),
            refreshApex(this.affiliationsWithProgramEnrollVModelWireResult),
        ]).then(() => {
            this.template.querySelectorAll("c-settings-row-input").forEach((input) => {
                input.resetValue();
            });
        });
    }

    get autoEnrollmentMappingsDescriptionRichText() {
        return (
            this.labelReference.autoEnrollmentMappingsTable.autoEnrollmentMappingsDescription +
            " " +
            this.autoEnrollmentHyperLink
        );
    }

    @api
    handleSaveCanvasRender() {
        this.template.querySelector("c-settings-save-canvas").focusOnTitle();
    }
    handleNewAutoEnrollmentMappingClick(event) {}
    handleAutoEnrollmentMappingRowAction(event) {}

    autoEnrollmentHyperLink =
        '' +
        this.labelReference.tellMeMoreLink +
        "";
}
<commit_msg>rsolving conflicts2<commit_after>import { LightningElement, track, wire, api } from "lwc";
import { refreshApex } from "@salesforce/apex";
// Controller for Auto Enrollment Mappings
import getProgramSettingsVModel from "@salesforce/apex/ProgramSettingsController.getProgramSettingsVModel";

// Controller for Affiliations created with Program Enrollment
import getAffiliationsWithProgramEnrollmentVModel from "@salesforce/apex/AffiliationsWithProgramEnrollController.getAffiliationsWithProgramEnrollmentVModel";

//Custom labels for Affiliations created with Program Enrollment
import stgHelpAfflCreateFromProgramEnrollmentHeader from "@salesforce/label/c.stgHelpAfflCreateFromProgramEnrollmentHeader";
import stgHelpAfflCreateFromProgramEnrollmentInfo from "@salesforce/label/c.stgHelpAfflCreateFromProgramEnrollmentInfo";
import stgAfflProgramEnrollmentSettingsTitle from "@salesforce/label/c.stgAfflProgramEnrollmentSettingsTitle";
import stgAfflProgEnrollSetRoleValue from "@salesforce/label/c.stgAfflProgEnrollSetRoleValue";
import stgHelpAfflProgEnrollSetRoleValue from "@salesforce/label/c.stgHelpAfflProgEnrollSetRoleValue";
import stgAfflProgEnrollSetStatusValue from "@salesforce/label/c.stgAfflProgEnrollSetStatusValue";
import stgHelpAfflProgEnrollSetStatusValue from "@salesforce/label/c.stgHelpAfflProgEnrollSetStatusValue";
import stgAfflCopyProgramEnrollmentEndDate from "@salesforce/label/c.stgAfflCopyProgramEnrollmentEndDate";
import stgHelpAfflCopyProgramEnrollmentEndDate from "@salesforce/label/c.stgHelpAfflCopyProgramEnrollmentEndDate";
import stgAfflCopyProgramEnrollmentStartDate from "@salesforce/label/c.stgAfflCopyProgramEnrollmentStartDate";
import stgHelpAfflCopyProgramEnrollmentStartDate from "@salesforce/label/c.stgHelpAfflCopyProgramEnrollmentStartDate";
import stgOptSelect from "@salesforce/label/c.stgOptSelect";

//custom labels for Auto Enrollment Mappings
import stgProgramsSettingsTitle from "@salesforce/label/c.stgProgramsSettingsTitle";
import stgBtnEdit from "@salesforce/label/c.stgBtnEdit";
import stgBtnDelete from "@salesforce/label/c.stgBtnDelete";
import autoEnrollmentMappingsTitle from "@salesforce/label/c.stgAutoEnrollmentProgramTitle";
import autoEnrollmentMappingsDescription from "@salesforce/label/c.stgAutoEnrollmentProgramDesc";
import stgColAccountRecordType from "@salesforce/label/c.stgColAccountRecordType";
import stgColAutoEnrollmentStatus from "@salesforce/label/c.stgColAutoEnrollmentStatus";
import stgColAutoEnrollmentRole from "@salesforce/label/c.stgColAutoEnrollmentRole";
import stgBtnAddMapping from "@salesforce/label/c.stgBtnAddMapping";
import stgTellMeMoreLink from "@salesforce/label/c.stgTellMeMoreLink";
export default class programSettings extends LightningElement {
    isEditMode = false;
    affordancesDisabledToggle = false;

    @track affiliationsWithProgramEnrollmentVModel;
    @track affiliationsWithProgramEnrollVModelWireResult;
    @track programSettingsVModel;
    @track programSettingsVModelWireResult;

    labelReference = {
        programsSettingsTitle: stgProgramsSettingsTitle,
        newButton: stgBtnAddMapping,
        afflCreateFromPrgrmHeading: stgHelpAfflCreateFromProgramEnrollmentHeader,
        afflCreateFromPrgrmInfo: stgHelpAfflCreateFromProgramEnrollmentInfo,
        afflProgramEnrollmentSettingsTitle: stgAfflProgramEnrollmentSettingsTitle,
        afflProgEnrollSetRoleValue: stgAfflProgEnrollSetRoleValue,
        helpAfflProgEnrollSetRoleValue: stgHelpAfflProgEnrollSetRoleValue,
        afflProgEnrollSetStatusValue: stgAfflProgEnrollSetStatusValue,
        helpAfflProgEnrollSetStatusValue: stgHelpAfflProgEnrollSetStatusValue,
        afflCopyProgramEnrollmentEndDate: stgAfflCopyProgramEnrollmentEndDate,
        helpAfflCopyProgramEnrollmentEndDate: stgHelpAfflCopyProgramEnrollmentEndDate,
        afflCopyProgramEnrollmentStartDate: stgAfflCopyProgramEnrollmentStartDate,
        helpAfflCopyProgramEnrollmentStartDate: stgHelpAfflCopyProgramEnrollmentStartDate,
        placeHolderText: stgOptSelect,
        autoEnrollmentMappingsTable: {
            autoEnrollmentMappingsTitle: autoEnrollmentMappingsTitle,
            autoEnrollmentMappingsDescription: autoEnrollmentMappingsDescription,
            accountRecordTypeColumn: stgColAccountRecordType,
            autoEnrollmentStatusColumn: stgColAutoEnrollmentStatus,
            autoEnrollmentRoleColumn: stgColAutoEnrollmentRole,
            editAction: stgBtnEdit,
            deleteAction: stgBtnDelete,
        },
        tellMeMoreLink: stgTellMeMoreLink,
    };

    inputAttributeReference = {
        createdAfflRoleComboboxId: "createdAfflRole",
        createdAfflStatusComboboxId: "createdAfflStatus",
        copyEndDateComboboxId: "copyEndDate",
        copyStartDateComboboxId: "copyStartDate",
    };

    get affordancesDisabled() {
        if (!this.isEditMode || this.affordancesDisabledToggle === true) {
            return true;
        }
        return undefined;
    }

    @api
    handleSaveCanvasRender() {
        this.template.querySelector("c-settings-save-canvas").focusOnTitle();
    }

    @wire(getProgramSettingsVModel)
    programSettingsVModelWire(result) {
        this.programSettingsVModelWireResult = result;

        if (result.data) {
            this.programSettingsVModel = result.data;
        } else if (result.error) {
            //console.log("error retrieving preferredContactInfoSettingsVModel");
        }
    }

    @wire(getAffiliationsWithProgramEnrollmentVModel)
    affiliationsWithProgramEnrollmentVModelWire(result) {
        this.affiliationsWithProgramEnrollVModelWireResult = result;

        if (result.data) {
            this.affiliationsWithProgramEnrollmentVModel = result.data;
        } else if (result.error) {
            //console.log("error retrieving preferredContactInfoSettingsVModel");
        }
    }

    handleRoleForCreatedAfflChange(event) {
        this.handleSpecifyRoleForCreatedAffiliaitons(event);
        var affiliationRole = event.detail.value;
        if (event.detail.value === '""') {
            // set Hierarchy Settings field to a blank value (not "")
            affiliationRole = "";
        }
        // add updated setting to hierarchySettingsChanges object
        let hierarchySettingsChange = {
            settingsType: "string",
            settingsName: "Affl_ProgEnroll_Role_Map__c",
            settingsValue: affiliationRole,
        };

        this.template.querySelector("c-settings-save-canvas").handleHierarchySettingsChange(hierarchySettingsChange);
    }

    handleSpecifyRoleForCreatedAffiliaitons(event) {
        var specifyRoleForCreatedAffl = event.detail.value;
        if (event.detail.value === '""') {
            // set Hierarchy Settings field to a blank value (not "")
            specifyRoleForCreatedAffl = false;
        } else {
            specifyRoleForCreatedAffl = true;
        }
        // add updated setting to hierarchySettingsChanges object
        let hierarchySettingsChange = {
            settingsType: "boolean",
            settingsName: "Affl_ProgEnroll_Set_Role__c",
            settingsValue: specifyRoleForCreatedAffl,
        };

        this.template.querySelector("c-settings-save-canvas").handleHierarchySettingsChange(hierarchySettingsChange);
    }

    handleStatusForCreatedAfflChange(event) {
        var affiliationStatus = event.detail.value;
        if (event.detail.value === '""') {
            // set Hierarchy Settings field to a blank value (not "")
            affiliationStatus = "";
        }
        // add updated setting to hierarchySettingsChanges object
        let hierarchySettingsChange = {
            settingsType: "string",
            settingsName: "Affl_ProgEnroll_Status_Map__c",
            settingsValue: affiliationStatus,
        };

        this.template.querySelector("c-settings-save-canvas").handleHierarchySettingsChange(hierarchySettingsChange);
    }

    handleCopyEndDateChange(event) {
        // add updated setting to hierarchySettingsChanges object
        let hierarchySettingsChange = {
            settingsType: "boolean",
            settingsName: "Affl_ProgEnroll_Copy_End_Date__c",
            settingsValue: event.detail.value,
        };

        this.template.querySelector("c-settings-save-canvas").handleHierarchySettingsChange(hierarchySettingsChange);
    }

    handleCopyStartDateChange(event) {
        // add updated setting to hierarchySettingsChanges object
        let hierarchySettingsChange = {
            settingsType: "boolean",
            settingsName: "Affl_ProgEnroll_Copy_Start_Date__c",
            settingsValue: event.detail.value,
        };

        this.template.querySelector("c-settings-save-canvas").handleHierarchySettingsChange(hierarchySettingsChange);
    }

    get autoEnrollmentMappingsTableColumns() {
        return [
            {
                label: this.labelReference.autoEnrollmentMappingsTable.accountRecordTypeColumn,
                fieldName: "accountRecordTypeLabel",
            },
            {
                label: this.labelReference.autoEnrollmentMappingsTable.autoEnrollmentStatusColumn,
                fieldName: "autoProgramEnrollmentStatus",
            },
            {
                label: this.labelReference.autoEnrollmentMappingsTable.autoEnrollmentRoleColumn,
                fieldName: "autoProgramEnrollmentRole",
            },
            {
                type: "action",
                typeAttributes: {
                    rowActions: [
                        { label: this.labelReference.autoEnrollmentMappingsTable.editAction, name: "edit" },
                        { label: this.labelReference.autoEnrollmentMappingsTable.deleteAction, name: "delete" },
                    ],
                },
            },
        ];
    }

    handleSettingsEditModeChange(event) {
        this.isEditMode = !event.detail;
        this.affordancesDisabledToggle = event.detail;
    }

    handleSettingsSaving(event) {
        this.affordancesDisabledToggle = true;
        // TODO: perform client side validation

        // if validation fails, call this.handleValidationFailure()
        //this.template.querySelector("c-settings-save-canvas").handleValidationFailure();

        // else, update hierarchy settings
        this.template.querySelector("c-settings-save-canvas").updateHierarchySettings();
    }

    handleSettingsSaveCompleted(event) {
        this.affordancesDisabledToggle = false;
        this.refreshAllApex();
    }

    handleSettingsSaveCancel(event) {
        this.refreshAllApex();
    }

    refreshAllApex() {
        Promise.all([
            refreshApex(this.programSettingsVModelWireResult),
            refreshApex(this.affiliationsWithProgramEnrollVModelWireResult),
        ]).then(() => {
            this.template.querySelectorAll("c-settings-row-input").forEach((input) => {
                input.resetValue();
            });
        });
    }

    get autoEnrollmentMappingsDescriptionRichText() {
        return (
            this.labelReference.autoEnrollmentMappingsTable.autoEnrollmentMappingsDescription +
            " " +
            this.autoEnrollmentHyperLink
        );
    }

    handleNewAutoEnrollmentMappingClick(event) {}
    handleAutoEnrollmentMappingRowAction(event) {}

    autoEnrollmentHyperLink =
        '' +
        this.labelReference.tellMeMoreLink +
        "";
}
<|endoftext|>


<commit_before>var getGetParam = function(search) {
    if ('' === search) {
        return [];
    }
    var querystring = search.substr(1);
    var querys = querystring.split('&');
    var obj = [];
    for (var i = 0; i < querys.length; i++) {
        var query = querys[i].split('=');
        obj[query[0]] = query[1];

    }

    return obj;
};
<commit_msg>Add getQueryString function to example.js<commit_after>var getGetParam = function(search) {
    if ('' === search) {
        return [];
    }
    var querystring = search.substr(1);
    var querys = querystring.split('&');
    var obj = [];
    for (var i = 0; i < querys.length; i++) {
        var query = querys[i].split('=');
        obj[query[0]] = query[1];

    }

    return obj;
};

var getQueryString = function(array) {
    var querystring = '';
    for (var key in array) {
        if ('' === querystring) {
            querystring = key + '=' + array[key];
            continue;
        }
        querystring = querystring + '&' + key + '=' + array[key];
    }

    return '?' + querystring;
};
<|endoftext|>