<commit_before>import {
  fonts,
  spacing,
  editionBreakpoints
} from "@times-components/styleguide";

const mediumBreakpointStyles = {
  container: {
    flex: 1,
    paddingVertical: spacing(3),
    paddingHorizontal: spacing(6)
  },
  headline: {
    fontFamily: fonts.headline,
    fontSize: 40,
    lineHeight: 40,
    marginBottom: 0
  },
  imageContainer: {
    width: "100%",
    marginBottom: spacing(2)
  },
  summaryContainer: {
    flex: 1,
    paddingBottom: spacing(2)
  }
};

const wideBreakpointStyles = {
  ...mediumBreakpointStyles,
  container: {
    flex: 1,
    paddingVertical: spacing(3),
    paddingHorizontal: spacing(4)
  }
};

export default breakpoint =>
  breakpoint === editionBreakpoints.medium
    ? mediumBreakpointStyles
    : wideBreakpointStyles;
<commit_msg>feat: REPLAT-8552 Lead 1 Full width 1366 styling (#2282)<commit_after>import {
  fonts,
  spacing,
  editionBreakpoints
} from "@times-components/styleguide";

const mediumBreakpointStyles = {
  container: {
    flex: 1,
    paddingVertical: spacing(3),
    paddingHorizontal: spacing(6)
  },
  headline: {
    fontFamily: fonts.headline,
    fontSize: 40,
    lineHeight: 40,
    marginBottom: 0
  },
  imageContainer: {
    width: "100%",
    marginBottom: spacing(2)
  },
  summaryContainer: {
    flex: 1,
    paddingBottom: spacing(2)
  }
};

const wideBreakpointStyles = {
  ...mediumBreakpointStyles,
  container: {
    flex: 1,
    paddingVertical: spacing(3),
    paddingHorizontal: spacing(4)
  }
};

const hugeBreakpointStyles = {
  ...wideBreakpointStyles,
  headline: {
    fontFamily: fonts.headline,
    fontSize: 45,
    lineHeight: 45,
    marginBottom: 0
  }
};

const stylesResolver = {
  [editionBreakpoints.medium]: mediumBreakpointStyles,
  [editionBreakpoints.wide]: wideBreakpointStyles,
  [editionBreakpoints.huge]: hugeBreakpointStyles
};

export default breakpoint => stylesResolver[breakpoint] || {};
<|endoftext|>


<commit_before>/*
 *  GameoverScene.js
 *  2014/06/23
 *  @auther minimo
 *  This Program is MIT license.
 *
 */

tm.define("shotgun.GameoverScene", {
    superClass: tm.app.Scene,

    init: function() {
        this.superInit();
        this.background = "rgba(0, 0, 0, 0.0)";

        //バックグラウンド
        this.bg = tm.display.Sprite("greenback", SC_W*2, SC_H*2).addChildTo(this);

        //スコア表示
        var lb = this.score = tm.display.OutlineLabel("SCORE: "+app.lastScore, 50).addChildTo(this);
        lb.setPosition(SC_W*0.5, SC_H*0.4);
        lb.fontFamily = "'azuki'";
        lb.align     = "center";
        lb.baseline  = "middle";
        lb.outlineWidth = 2;

        //リトライボタン
        var sh = this.retry = tm.display.RoundRectangleShape(120, 50).addChildTo(this);
        sh.setPosition(SC_W*0.25, SC_H*0.6);
        var lb = this.retryLabel = tm.display.OutlineLabel("RETRY", 50).addChildTo(this);
        lb.setPosition(SC_W*0.25, SC_H*0.6);
        lb.fontFamily = "'azuki'";
        lb.align     = "center";
        lb.baseline  = "middle";
        lb.outlineWidth = 2;

        var lb = this.exitLabel = tm.display.OutlineLabel("EXIT", 50).addChildTo(this);
        lb.setPosition(SC_W*0.75, SC_H*0.6);
        lb.fontFamily = "'azuki'";
        lb.align     = "center";
        lb.baseline  = "middle";
        lb.outlineWidth = 2;

        //マスク
        this.mask = tm.display.Sprite("blackback", SC_W*2, SC_H*2).addChildTo(this);
        this.mask.tweener.clear().fadeOut(200);
    },

    update: function() {
    },

    //タッチorクリック開始処理
    ontouchstart: function(e) {
    },

    //タッチorクリック移動処理
    ontouchmove: function(e) {
    },

    //タッチorクリック終了処理
    ontouchend: function(e) {
        var x = e.x;
        var y = e.y;
        app.replaceScene(shotgun.TitleScene());
    },

});
<commit_msg>game over scene<commit_after>/*
 *  GameoverScene.js
 *  2014/06/23
 *  @auther minimo
 *  This Program is MIT license.
 *
 */

tm.define("shotgun.GameoverScene", {
    superClass: tm.app.Scene,

    init: function() {
        this.superInit();
        this.background = "rgba(0, 0, 0, 0.0)";

        //バックグラウンド
        this.bg = tm.display.Sprite("greenback", SC_W*2, SC_H*2).addChildTo(this);

        //スコア表示
        var lb = this.score = tm.display.OutlineLabel("SCORE: "+app.lastScore, 50).addChildTo(this);
        lb.setPosition(SC_W*0.5, SC_H*0.4);
        lb.fontFamily = "'azuki'";
        lb.align     = "center";
        lb.baseline  = "middle";
        lb.outlineWidth = 2;

        //リトライボタン
        var sh = this.retry = tm.display.RoundRectangleShape(200, 70).addChildTo(this);
        sh.setPosition(SC_W*0.25, SC_H*0.6);
        sh.interactive = true;
        sh.addEventListener("click", function() {
            app.replaceScene(shotgun.MainScene());
        });
        var lb = this.retryLabel = tm.display.OutlineLabel("RETRY", 50).addChildTo(this);
        lb.setPosition(SC_W*0.25, SC_H*0.6);
        lb.fontFamily = "'azuki'";
        lb.align     = "center";
        lb.baseline  = "middle";
        lb.outlineWidth = 2;

        var sh = this.exit = tm.display.RoundRectangleShape(200, 70).addChildTo(this);
        sh.setPosition(SC_W*0.75, SC_H*0.6);
        sh.interactive = true;
        sh.addEventListener("click", function() {
            app.replaceScene(shotgun.TitleScene());
        });
        var lb = this.exitLabel = tm.display.OutlineLabel("EXIT", 50).addChildTo(this);
        lb.setPosition(SC_W*0.75, SC_H*0.6);
        lb.fontFamily = "'azuki'";
        lb.align     = "center";
        lb.baseline  = "middle";
        lb.outlineWidth = 2;

        //マスク
        this.mask = tm.display.Sprite("blackback", SC_W*2, SC_H*2).addChildTo(this);
        this.mask.tweener.clear().fadeOut(200);
    },

    update: function() {
    },

    //タッチorクリック開始処理
    ontouchstart: function(e) {
    },

    //タッチorクリック移動処理
    ontouchmove: function(e) {
    },

    //タッチorクリック終了処理
    ontouchend: function(e) {
    },

});
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015-present, Nicolas Gallagher.
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @providesModule Text
 * @flow
 */

import applyLayout from '../../modules/applyLayout';
import applyNativeMethods from '../../modules/applyNativeMethods';
import { bool } from 'prop-types';
import { Component } from 'react';
import createElement from '../createElement';
import StyleSheet from '../StyleSheet';
import TextPropTypes from './TextPropTypes';

class Text extends Component<*> {
  static displayName = 'Text';

  static propTypes = TextPropTypes;

  static childContextTypes = {
    isInAParentText: bool
  };

  static contextTypes = {
    isInAParentText: bool
  };

  getChildContext() {
    return { isInAParentText: true };
  }

  render() {
    const {
      dir,
      numberOfLines,
      onPress,
      selectable,
      style,
      /* eslint-disable */
      adjustsFontSizeToFit,
      allowFontScaling,
      ellipsizeMode,
      lineBreakMode,
      minimumFontScale,
      onLayout,
      onLongPress,
      pressRetentionOffset,
      selectionColor,
      suppressHighlighting,
      textBreakStrategy,
      tvParallaxProperties,
      /* eslint-enable */
      ...otherProps
    } = this.props;

    const { isInAParentText } = this.context;

    if (onPress) {
      otherProps.accessible = true;
      otherProps.onClick = onPress;
      otherProps.onKeyDown = this._createEnterHandler(onPress);
    }

    // allow browsers to automatically infer the language writing direction
    otherProps.dir = dir !== undefined ? dir : 'auto';
    otherProps.style = [
      styles.initial,
      this.context.isInAParentText === true && styles.isInAParentText,
      style,
      selectable === false && styles.notSelectable,
      numberOfLines === 1 && styles.singleLineStyle,
      onPress && styles.pressable
    ];

    const component = isInAParentText ? 'span' : 'div';

    return createElement(component, otherProps);
  }

  _createEnterHandler(fn) {
    return e => {
      if (e.keyCode === 13) {
        fn && fn(e);
      }
    };
  }
}

const styles = StyleSheet.create({
  initial: {
    borderWidth: 0,
    boxSizing: 'border-box',
    color: 'inherit',
    display: 'inline',
    fontFamily: 'System',
    fontSize: 14,
    fontStyle: 'inherit',
    fontVariant: ['inherit'],
    fontWeight: 'inherit',
    lineHeight: 'inherit',
    margin: 0,
    padding: 0,
    textDecorationLine: 'none',
    whiteSpace: 'pre-wrap',
    wordWrap: 'break-word'
  },
  isInAParentText: {
    // inherit parent font styles
    fontFamily: 'inherit',
    fontSize: 'inherit',
    whiteSpace: 'inherit'
  },
  notSelectable: {
    userSelect: 'none'
  },
  pressable: {
    cursor: 'pointer'
  },
  singleLineStyle: {
    maxWidth: '100%',
    overflow: 'hidden',
    textOverflow: 'ellipsis',
    whiteSpace: 'nowrap'
  }
});

export default applyLayout(applyNativeMethods(Text));
<commit_msg>[fix] Text onPress event propagation<commit_after>/**
 * Copyright (c) 2015-present, Nicolas Gallagher.
 * Copyright (c) 2015-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @providesModule Text
 * @flow
 */

import applyLayout from '../../modules/applyLayout';
import applyNativeMethods from '../../modules/applyNativeMethods';
import { bool } from 'prop-types';
import { Component } from 'react';
import createElement from '../createElement';
import StyleSheet from '../StyleSheet';
import TextPropTypes from './TextPropTypes';

class Text extends Component<*> {
  static displayName = 'Text';

  static propTypes = TextPropTypes;

  static childContextTypes = {
    isInAParentText: bool
  };

  static contextTypes = {
    isInAParentText: bool
  };

  getChildContext() {
    return { isInAParentText: true };
  }

  render() {
    const {
      dir,
      numberOfLines,
      onPress,
      selectable,
      style,
      /* eslint-disable */
      adjustsFontSizeToFit,
      allowFontScaling,
      ellipsizeMode,
      lineBreakMode,
      minimumFontScale,
      onLayout,
      onLongPress,
      pressRetentionOffset,
      selectionColor,
      suppressHighlighting,
      textBreakStrategy,
      tvParallaxProperties,
      /* eslint-enable */
      ...otherProps
    } = this.props;

    const { isInAParentText } = this.context;

    if (onPress) {
      otherProps.accessible = true;
      otherProps.onClick = this._createPressHandler(onPress);
      otherProps.onKeyDown = this._createEnterHandler(onPress);
    }

    // allow browsers to automatically infer the language writing direction
    otherProps.dir = dir !== undefined ? dir : 'auto';
    otherProps.style = [
      styles.initial,
      this.context.isInAParentText === true && styles.isInAParentText,
      style,
      selectable === false && styles.notSelectable,
      numberOfLines === 1 && styles.singleLineStyle,
      onPress && styles.pressable
    ];

    const component = isInAParentText ? 'span' : 'div';

    return createElement(component, otherProps);
  }

  _createEnterHandler(fn) {
    return e => {
      if (e.keyCode === 13) {
        fn && fn(e);
      }
    };
  }

  _createPressHandler(fn) {
    return e => {
      e.stopPropagation();
      fn && fn(e);
    };
  }
}

const styles = StyleSheet.create({
  initial: {
    borderWidth: 0,
    boxSizing: 'border-box',
    color: 'inherit',
    display: 'inline',
    fontFamily: 'System',
    fontSize: 14,
    fontStyle: 'inherit',
    fontVariant: ['inherit'],
    fontWeight: 'inherit',
    lineHeight: 'inherit',
    margin: 0,
    padding: 0,
    textDecorationLine: 'none',
    whiteSpace: 'pre-wrap',
    wordWrap: 'break-word'
  },
  isInAParentText: {
    // inherit parent font styles
    fontFamily: 'inherit',
    fontSize: 'inherit',
    whiteSpace: 'inherit'
  },
  notSelectable: {
    userSelect: 'none'
  },
  pressable: {
    cursor: 'pointer'
  },
  singleLineStyle: {
    maxWidth: '100%',
    overflow: 'hidden',
    textOverflow: 'ellipsis',
    whiteSpace: 'nowrap'
  }
});

export default applyLayout(applyNativeMethods(Text));
<|endoftext|>


<commit_before>// dependencies: module.js

// display course evals in the eval pane
function display_evals(course) {
  // display semesters offered
  evals_semesters(course)

  // refresh
  $('#evals-numeric-body').children().remove()
  $('#evals-comments-body').children().remove()

  // display this semester
  var evaluations = course.evaluations
  evals_comments(evaluations)
  evals_numeric(evaluations)

  evals_autotoggle('comments')
  evals_autotoggle('numeric')
}

// shows/hides sections of no content
var evals_autotoggle = function(section) {
  var div = $('#evals-' + section)
  var body = $('#evals-' + section + '-body')
  var isEmpty = body.is(':empty')

  if (isEmpty) body.append(
    '
'
    + 'No data to display.'
  + '
'
  )
}

// display the semesters in the evals pane
function evals_semesters(course) {
  // refresh
  $('#evals-semesters-body').children().remove()

  // go through semesters
  for (var index in course.semesters) {
    $('#evals-semesters-body').append(newDOMsemesterEval(course.semesters[index]))
  }

  evals_autotoggle('semesters')
}

// display numeric evaluations in evals pane
function evals_numeric(evaluations) {
  // go through numeric evaluations
  for (var field in evaluations.scores) {
    $('#evals-numeric-body').append(newDOMnumericEval(field, evaluations.scores[field]))
  }
}

// display student comment evals in evals pane
function evals_comments(evaluations) {
  // go through student comments
  for (var index in evaluations.comments) {
    var comment = evaluations.comments[index]
    $('#evals-comments-body').append(newDOMcommentEval(comment))
  }
}

// returns a DOM object for a semester entry of the displayed course
function newDOMsemesterEval (semester) {
  // create string of professors
  var professors = []
  for (var instructorIndex in semester.instructors) {
    var professor = semester.instructors[instructorIndex]
    professors.push([professor.name.first, professor.name.last].join(' '))
  }
  professors = professors.join(', ')
  if (professors.length > 0) professors = ' ' + professors

  // extract score (if it exists)
  var hasScore = (semester.hasOwnProperty('scores') && semester.scores.hasOwnProperty('Overall Quality of the Course'))
  if (hasScore) var score = semester.scores['Overall Quality of the Course']

  var htmlString= (
    '
'
    + '
'
      + '' + semester.semester.name + ''
      + professors
    + '
'
    + ''
      + (hasScore ? score.toFixed(2) : 'N/A')
    + ''
  + '
'
  )

  var entry = $.parseHTML(htmlString)[0]       // create DOM object
  entry.semester = semester                    // attach object

  return entry
}

// returns a DOM object for a numeric eval of the displayed course
function newDOMnumericEval(field, value) {
  var width = value*20.0 // as a percentage

  var htmlString= (
    '
'
    + '
'
      + '
'
        + '
' + field + '
'
        + '
'
          + '

'
        + '
'
      + '
'
      + '
'
      + ''
        + value.toFixed(2)
      + ''
    + '
'
  + '
'
  )

  // create and return DOM object
  var entry = $.parseHTML(htmlString)[0]
  return entry
}

// returns a DOM object for an eval of the displayed course
function newDOMcommentEval(evaluation) {
  // detect if user has voted already
  var icon = (evaluation.voted ? 'down-icon' : 'up-icon')

  var htmlString = (
    '
'
    + '
'
      + evaluation.comment
    + '
'
    + '
'
      + ''
        + '' + evaluation.votes + ' '
        + ''
      + ''
    + '
'
  + '
'
  )

  var entry = $.parseHTML(htmlString)[0]
  var count = $(entry).find('.evals-count')
  var icon = $(entry).find('i')

  // Bind the upvote icon to the toggleVote function
  icon.click(function() {return toggleVote(icon, evaluation._id, count)})

  return entry
}

// handles click of voting for evaluation:
// - icon is jQuery object of the corresponding i element
// - evalId is id of the corresponding evaluation
// - count is jQuery object of the corresponding .evals-count element
function toggleVote(icon, evalId, count) {
  // update icon
  var hasVoted = icon.hasClass('down-icon')
  icon.removeClass(hasVoted ? 'down-icon' : 'up-icon')
  icon.addClass(hasVoted ? 'up-icon' : 'down-icon')

  // update count
  var votes = parseInt(count.text())
  votes += (hasVoted ? -1 : 1)
  count.html(votes)

  // update database
  $.ajax({
    url: '/api/evaluations/' + evalId + '/vote',
    type: (hasVoted ? 'DELETE' : 'PUT')
  })

  return false
}
<commit_msg>semester change click functioning<commit_after>// dependencies: module.js

// display course evals in the eval pane
function display_evals(course) {
  // display semesters offered
  evals_semesters(course)

  // refresh
  $('#evals-numeric-body').children().remove()
  $('#evals-comments-body').children().remove()

  // display this semester
  var evaluations = course.evaluations
  evals_comments(evaluations)
  evals_numeric(evaluations)

  evals_autotoggle('comments')
  evals_autotoggle('numeric')
}

// shows/hides sections of no content
var evals_autotoggle = function(section) {
  var div = $('#evals-' + section)
  var body = $('#evals-' + section + '-body')
  var isEmpty = body.is(':empty')

  if (isEmpty) body.append(
    '
'
    + 'No data to display.'
  + '
'
  )
}

// display the semesters in the evals pane
function evals_semesters(course) {
  // refresh
  $('#evals-semesters-body').children().remove()

  // go through semesters
  for (var index in course.semesters) {
    $('#evals-semesters-body').append(newDOMsemesterEval(course.semesters[index]))
  }

  evals_autotoggle('semesters')
}

// display numeric evaluations in evals pane
function evals_numeric(evaluations) {
  // go through numeric evaluations
  for (var field in evaluations.scores) {
    $('#evals-numeric-body').append(newDOMnumericEval(field, evaluations.scores[field]))
  }
}

// display student comment evals in evals pane
function evals_comments(evaluations) {
  // go through student comments
  for (var index in evaluations.comments) {
    var comment = evaluations.comments[index]
    $('#evals-comments-body').append(newDOMcommentEval(comment))
  }
}

// returns a DOM object for a semester entry of the displayed course
function newDOMsemesterEval (semester) {
  // create string of professors
  var professors = []
  for (var instructorIndex in semester.instructors) {
    var professor = semester.instructors[instructorIndex]
    professors.push([professor.name.first, professor.name.last].join(' '))
  }
  professors = professors.join(', ')
  if (professors.length > 0) professors = ' ' + professors

  // extract score (if it exists)
  var hasScore = (semester.hasOwnProperty('scores') && semester.scores.hasOwnProperty('Overall Quality of the Course'))
  if (hasScore) var score = semester.scores['Overall Quality of the Course']

  var htmlString= (
    '
'
    + '
'
      + '' + semester.semester.name + ''
      + professors
    + '
'
    + ''
      + (hasScore ? score.toFixed(2) : 'N/A')
    + ''
  + '
'
  )

  var entry = $.parseHTML(htmlString)[0]                          // create DOM object
  $(entry).click(function() {displayCourseDetails(semester._id)}) // display

  return entry
}

// returns a DOM object for a numeric eval of the displayed course
function newDOMnumericEval(field, value) {
  var width = value*20.0 // as a percentage

  var htmlString= (
    '
'
    + '
'
      + '
'
        + '
' + field + '
'
        + '
'
          + '

'
        + '
'
      + '
'
      + '
'
      + ''
        + value.toFixed(2)
      + ''
    + '
'
  + '
'
  )

  // create and return DOM object
  var entry = $.parseHTML(htmlString)[0]
  return entry
}

// returns a DOM object for an eval of the displayed course
function newDOMcommentEval(evaluation) {
  // detect if user has voted already
  var icon = (evaluation.voted ? 'down-icon' : 'up-icon')

  var htmlString = (
    '
'
    + '
'
      + evaluation.comment
    + '
'
    + '
'
      + ''
        + '' + evaluation.votes + ' '
        + ''
      + ''
    + '
'
  + '
'
  )

  var entry = $.parseHTML(htmlString)[0]
  var count = $(entry).find('.evals-count')
  var icon = $(entry).find('i')

  // Bind the upvote icon to the toggleVote function
  icon.click(function() {return toggleVote(icon, evaluation._id, count)})

  return entry
}

// handles click of voting for evaluation:
// - icon is jQuery object of the corresponding i element
// - evalId is id of the corresponding evaluation
// - count is jQuery object of the corresponding .evals-count element
function toggleVote(icon, evalId, count) {
  // update icon
  var hasVoted = icon.hasClass('down-icon')
  icon.removeClass(hasVoted ? 'down-icon' : 'up-icon')
  icon.addClass(hasVoted ? 'up-icon' : 'down-icon')

  // update count
  var votes = parseInt(count.text())
  votes += (hasVoted ? -1 : 1)
  count.html(votes)

  // update database
  $.ajax({
    url: '/api/evaluations/' + evalId + '/vote',
    type: (hasVoted ? 'DELETE' : 'PUT')
  })

  return false
}
<|endoftext|>


<commit_before>/*!
 * This file is part of me-cms.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright   Copyright (c) Mirko Pagliai
 * @link        https://github.com/mirko-pagliai/me-cms
 * @license     https://opensource.org/licenses/mit-license.php MIT License
 */
/**
 * Gets the maximum height available.
 * The maximum available height is equal to the window height minus the topbar height.
 */
function getAvailableHeight()
{
    return $(window).height() - $("#userbar").outerHeight(true);
}

/**
 * Toggles the filter form
 */
function toggleFilterForm()
{
    var form = $(".filter-form legend");

    $(".fas", form).toggleClass("fa-eye fa-eye-slash");
    $(form).nextAll().toggle();
}

//On windows load and resize, it sets the maximum height available for the content
$(window).on("load resize", function () {
    $("#content").css("min-height", getAvailableHeight());
});

$(function () {
    //Adds the "data-parent" attribute to all "collapse" wrapper of the sidebar
    $("#sidebar:visible .collapse").attr("data-parent', '#sidebar-accordion");

    //Checks if there is the cookie of the last open menu
    if (Cookies.get("sidebar-lastmenu") && $("#sidebar").is(":visible")) {
        //Gets the element (menu) ID
        var id = "#" + Cookies.get("sidebar-lastmenu");

        //Opens the menu
        $(id, "#sidebar").addClass("show").prev("a").removeClass("collapsed").attr("aria-expanded", "true");
    }

    //On click on a sidebar menu
    $("#sidebar a[data-toggle=collapse]").click(function () {
        //Saves the menu ID into a cookie
        Cookies.set("sidebar-lastmenu", $(this).attr("aria-controls"), { path: "" });
    });

    //Gets query string as objects, removing empty values and pagination values
    var queryString = $.map(document.location.search.replace(/(^\?)/, "").split("&"), function (value, key) {
        value = value.split("=");

        if (value[0] === "direction" || value[0] === "page" || value[0] === "render" || value[0] === "sort") {
            return null;
        }

        if (value[1] === "" || value[1] === null || value[1] === undefined) {
            return null;
        }

        var obj = {};
        obj[value[0]] = value[1];

        return obj;
    });

    //If there are no query string values, toggles the filter form
    if (!Object.keys(queryString).length && $(".filter-form legend").length) {
        toggleFilterForm();
    }

    //On click on legend of a filter form, toggles the filter form
    $(".filter-form legend").click(function () {
        toggleFilterForm();
    });
});<commit_msg>fixed typo<commit_after>/*!
 * This file is part of me-cms.
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright   Copyright (c) Mirko Pagliai
 * @link        https://github.com/mirko-pagliai/me-cms
 * @license     https://opensource.org/licenses/mit-license.php MIT License
 */
/**
 * Gets the maximum height available.
 * The maximum available height is equal to the window height minus the topbar height.
 */
function getAvailableHeight()
{
    return $(window).height() - $("#userbar").outerHeight(true);
}

/**
 * Toggles the filter form
 */
function toggleFilterForm()
{
    var form = $(".filter-form legend");

    $(".fas", form).toggleClass("fa-eye fa-eye-slash");
    $(form).nextAll().toggle();
}

//On windows load and resize, it sets the maximum height available for the content
$(window).on("load resize", function () {
    $("#content").css("min-height", getAvailableHeight());
});

$(function () {
    //Adds the "data-parent" attribute to all "collapse" wrapper of the sidebar
    $("#sidebar:visible .collapse").attr("data-parent", "#sidebar-accordion");

    //Checks if there is the cookie of the last open menu
    if (Cookies.get("sidebar-lastmenu") && $("#sidebar").is(":visible")) {
        //Gets the element (menu) ID
        var id = "#" + Cookies.get("sidebar-lastmenu");

        //Opens the menu
        $(id, "#sidebar").addClass("show").prev("a").removeClass("collapsed").attr("aria-expanded", "true");
    }

    //On click on a sidebar menu
    $("#sidebar a[data-toggle=collapse]").click(function () {
        //Saves the menu ID into a cookie
        Cookies.set("sidebar-lastmenu", $(this).attr("aria-controls"), { path: "" });
    });

    //Gets query string as objects, removing empty values and pagination values
    var queryString = $.map(document.location.search.replace(/(^\?)/, "").split("&"), function (value, key) {
        value = value.split("=");

        if (value[0] === "direction" || value[0] === "page" || value[0] === "render" || value[0] === "sort") {
            return null;
        }

        if (value[1] === "" || value[1] === null || value[1] === undefined) {
            return null;
        }

        var obj = {};
        obj[value[0]] = value[1];

        return obj;
    });

    //If there are no query string values, toggles the filter form
    if (!Object.keys(queryString).length && $(".filter-form legend").length) {
        toggleFilterForm();
    }

    //On click on legend of a filter form, toggles the filter form
    $(".filter-form legend").click(function () {
        toggleFilterForm();
    });
});<|endoftext|>


<commit_before>/* @flow */
import type {
  Logger,
  Config,
  Context,
  Request,
  GSConfig,
  UniversalSettings,
  WebpackConfig,
  CompiledConfig,
} from '../../types';

type RenderMethod = (root: Object, styleTags: Object[]) => { body: string; head: Object[] };

const React = require('react');
const clone = require('clone');
const render = require('../render');

class Index extends React.Component {
  render() {
    return
Index
;
  }
}
// eslint-disable-next-line react/no-multi-comp
class EntryWrapper extends React.Component {
  render() {
    return (

EntryWrapper

    );
  }
}
// eslint-disable-next-line react/no-multi-comp
class BodyWrapper extends React.Component {
  render() {
    return (

BodyWrapper

    );
  }
}

describe('renderer/render', () => {
  const logger: Logger = {
    success: () => {},
    info: () => {},
    warn: () => {},
    debug: () => {},
    error: () => {},
  };

  const gsConfig: GSConfig = {
    protocol: '',
    host: '',
    ports: {
      client: 0,
      server: 0,
    },
    buildAssetsPath: '',
    assetsPath: '',
    sourcePath: '',
    sharedPath: '',
    appsPath: '',
    configPath: '',
    entryWrapperPath: '',
    clientEntryInitPath: '',
    serverEntriesPath: '',
    entriesPath: '',
    webpackChunks: '',
    proxyLogLevel: '',
    debugWatchDirectories: [],
    defaultErrorTemplatePath: '',
    customErrorTemplatePath: '',
    autoUpgrade: {
      added: [],
      changed: [],
    },
  };

  const universalSettings: UniversalSettings = {
    server: {
      input: '',
      output: '',
    },
  };

  const client: WebpackConfig = {};
  const server: WebpackConfig = {};

  const webpackConfig: CompiledConfig = {
    universalSettings,
    client,
    server,
  };

  const config: Config = {
    GSConfig: gsConfig,
    webpackConfig,
    plugins: [],
  };

  const context: Context = { config, logger };

  const request: Request = { headers: { 'user-agent': 'Moznota Browser 1.0' }, url: '', hostname: '' };

  const store = {
    getState: jest.fn(() => {}),
  };
  const getRoutes = () => [
    { path: 'hola' },
  ];
  const renderProps = {
    routes: getRoutes(),
  };

  const httpClient = {};
  const entryWrapperConfig = {};
  const envVariables = [];
  const assets = {};
  const cacheManager = { setCacheIfProd: jest.fn() };

  describe('without a custom render method and cache set to true', () => {
    describe('when the route is an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithEmail = clone(renderProps);
        currentRouteWithEmail.email = true;
        currentRouteWithEmail.cache = true;
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithEmail },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          {},
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).toBeNull();
        expect(results.rootElement.props.body.props.html).toBeDefined();
        expect(results.rootElement.props.body.props.html).not.toContain('data-reactid');
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(1);
      });
    });

    describe('when the route is not an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithCache = clone(renderProps);
        currentRouteWithCache.cache = true;
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithCache },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          {},
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).not.toBeNull();
        expect(results.rootElement.props.body.props.html).toContain('data-reactid');
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(1);
      });
    });
  });

  describe('with a custom render method and cache set to true', () => {
    const renderMethod: RenderMethod = (component, styleTags) => {
      expect(component).toBeDefined();
      expect(styleTags).toBeDefined();
      return {
        head: [<meta name="hi" />],
        body: '
That body!
',
      };
    };

    describe('when the route is an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithEmail = clone(renderProps);
        currentRouteWithEmail.email = true;
        currentRouteWithEmail.cache = true;
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithEmail },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          { renderMethod },
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).toBeNull();
        expect(results.rootElement.props.body.props.html).toBeDefined();
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(1);
      });
    });

    describe('when the route is not an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithCache = clone(renderProps);
        currentRouteWithCache.cache = true;
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithCache },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          { renderMethod },
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).not.toBeNull();
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(1);
      });
    });
  });

  describe('without a custom render method and cache set to false', () => {
    describe('when the route is an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithEmail = clone(renderProps);
        currentRouteWithEmail.email = true;
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithEmail },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          {},
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).toBeNull();
        expect(results.rootElement.props.body.props.html).toBeDefined();
        expect(results.rootElement.props.body.props.html).not.toContain('data-reactid');
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(0);
      });
    });

    describe('when the route is not an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithoutCache = clone(renderProps);
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithoutCache },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          {},
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).not.toBeNull();
        expect(results.rootElement.props.body.props.html).toContain('data-reactid');
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(0);
      });
    });
  });

  describe('with a custom render method and cache set to false', () => {
    const renderMethod: RenderMethod = (component, styleTags) => {
      expect(component).toBeDefined();
      expect(styleTags).toBeDefined();
      return {
        head: [(<meta name="hi" />)],
        body: '
That body!
',
      };
    };

    describe('when the route is an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithEmail = clone(renderProps);
        currentRouteWithEmail.email = true;
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithEmail },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          { renderMethod },
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).toBeNull();
        expect(results.rootElement.props.body.props.html).toBeDefined();
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(0);
      });
    });

    describe('when the route is not an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithoutCache = clone(renderProps);
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithoutCache },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          { renderMethod },
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).not.toBeNull();
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(0);
      });
    });
  });
});
<commit_msg>add empty line after flow<commit_after>/* @flow */

import type {
  Logger,
  Config,
  Context,
  Request,
  GSConfig,
  UniversalSettings,
  WebpackConfig,
  CompiledConfig,
} from '../../types';

type RenderMethod = (root: Object, styleTags: Object[]) => { body: string; head: Object[] };

const React = require('react');
const clone = require('clone');
const render = require('../render');

class Index extends React.Component {
  render() {
    return
Index
;
  }
}
// eslint-disable-next-line react/no-multi-comp
class EntryWrapper extends React.Component {
  render() {
    return (

EntryWrapper

    );
  }
}
// eslint-disable-next-line react/no-multi-comp
class BodyWrapper extends React.Component {
  render() {
    return (

BodyWrapper

    );
  }
}

describe('renderer/render', () => {
  const logger: Logger = {
    success: () => {},
    info: () => {},
    warn: () => {},
    debug: () => {},
    error: () => {},
  };

  const gsConfig: GSConfig = {
    protocol: '',
    host: '',
    ports: {
      client: 0,
      server: 0,
    },
    buildAssetsPath: '',
    assetsPath: '',
    sourcePath: '',
    sharedPath: '',
    appsPath: '',
    configPath: '',
    entryWrapperPath: '',
    clientEntryInitPath: '',
    serverEntriesPath: '',
    entriesPath: '',
    webpackChunks: '',
    proxyLogLevel: '',
    debugWatchDirectories: [],
    defaultErrorTemplatePath: '',
    customErrorTemplatePath: '',
    autoUpgrade: {
      added: [],
      changed: [],
    },
  };

  const universalSettings: UniversalSettings = {
    server: {
      input: '',
      output: '',
    },
  };

  const client: WebpackConfig = {};
  const server: WebpackConfig = {};

  const webpackConfig: CompiledConfig = {
    universalSettings,
    client,
    server,
  };

  const config: Config = {
    GSConfig: gsConfig,
    webpackConfig,
    plugins: [],
  };

  const context: Context = { config, logger };

  const request: Request = { headers: { 'user-agent': 'Moznota Browser 1.0' }, url: '', hostname: '' };

  const store = {
    getState: jest.fn(() => {}),
  };
  const getRoutes = () => [
    { path: 'hola' },
  ];
  const renderProps = {
    routes: getRoutes(),
  };

  const httpClient = {};
  const entryWrapperConfig = {};
  const envVariables = [];
  const assets = {};
  const cacheManager = { setCacheIfProd: jest.fn() };

  describe('without a custom render method and cache set to true', () => {
    describe('when the route is an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithEmail = clone(renderProps);
        currentRouteWithEmail.email = true;
        currentRouteWithEmail.cache = true;
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithEmail },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          {},
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).toBeNull();
        expect(results.rootElement.props.body.props.html).toBeDefined();
        expect(results.rootElement.props.body.props.html).not.toContain('data-reactid');
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(1);
      });
    });

    describe('when the route is not an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithCache = clone(renderProps);
        currentRouteWithCache.cache = true;
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithCache },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          {},
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).not.toBeNull();
        expect(results.rootElement.props.body.props.html).toContain('data-reactid');
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(1);
      });
    });
  });

  describe('with a custom render method and cache set to true', () => {
    const renderMethod: RenderMethod = (component, styleTags) => {
      expect(component).toBeDefined();
      expect(styleTags).toBeDefined();
      return {
        head: [<meta name="hi" />],
        body: '
That body!
',
      };
    };

    describe('when the route is an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithEmail = clone(renderProps);
        currentRouteWithEmail.email = true;
        currentRouteWithEmail.cache = true;
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithEmail },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          { renderMethod },
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).toBeNull();
        expect(results.rootElement.props.body.props.html).toBeDefined();
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(1);
      });
    });

    describe('when the route is not an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithCache = clone(renderProps);
        currentRouteWithCache.cache = true;
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithCache },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          { renderMethod },
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).not.toBeNull();
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(1);
      });
    });
  });

  describe('without a custom render method and cache set to false', () => {
    describe('when the route is an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithEmail = clone(renderProps);
        currentRouteWithEmail.email = true;
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithEmail },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          {},
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).toBeNull();
        expect(results.rootElement.props.body.props.html).toBeDefined();
        expect(results.rootElement.props.body.props.html).not.toContain('data-reactid');
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(0);
      });
    });

    describe('when the route is not an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithoutCache = clone(renderProps);
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithoutCache },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          {},
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).not.toBeNull();
        expect(results.rootElement.props.body.props.html).toContain('data-reactid');
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(0);
      });
    });
  });

  describe('with a custom render method and cache set to false', () => {
    const renderMethod: RenderMethod = (component, styleTags) => {
      expect(component).toBeDefined();
      expect(styleTags).toBeDefined();
      return {
        head: [(<meta name="hi" />)],
        body: '
That body!
',
      };
    };

    describe('when the route is an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithEmail = clone(renderProps);
        currentRouteWithEmail.email = true;
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithEmail },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          { renderMethod },
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).toBeNull();
        expect(results.rootElement.props.body.props.html).toBeDefined();
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(0);
      });
    });

    describe('when the route is not an email route', () => {
      it('should render output', async () => {
        cacheManager.setCacheIfProd.mockReset();
        const currentRouteWithoutCache = clone(renderProps);
        const results = await render(
          context,
          request,
          { EntryPoint: Index, entryName: 'main', store, routes: getRoutes, httpClient },
          { renderProps, currentRoute: currentRouteWithoutCache },
          { EntryWrapper, BodyWrapper, entryWrapperConfig, envVariables },
          { assets, cacheManager },
          { renderMethod },
        );
        expect(results.responseString).toBeDefined();
        expect(results.rootElement.props.head).not.toBeNull();
        expect(cacheManager.setCacheIfProd.mock.calls.length).toBe(0);
      });
    });
  });
});
<|endoftext|>


<commit_before>(function () {

  'use strict';

  var x, y, line, svg, xAxis, yAxis, path, tempText, now, temp, margin, width, height, confs, conf, socket, myFormatters, tooltip;

  // Get page width
  function getWidth() {
    var x = 0;
    if (self.innerHeight) {
      x = self.innerWidth;
    }
    else if (document.documentElement && document.documentElement.clientHeight) {
      x = document.documentElement.clientWidth;
    }
    else if (document.body) {
      x = document.body.clientWidth;
    }
    return x;
  }

  // Get page height
  function getHeight() {
    var y = 0;
    if (self.innerHeight) {
      y = self.innerHeight;
    }
    else if (document.documentElement && document.documentElement.clientHeight) {
      y = document.documentElement.clientHeight;
    }
    else if (document.body) {
      y = document.body.clientHeight;
    }
    return y;
  }

  // Create graph
  function setupGraph() {

    // x scale
    if (conf.live === true) {
      x = d3.time.scale()
        .domain([now - (conf.n - 2) * conf.d, now - conf.d])
        .range([0, width]);
    } else {
      x = d3.time.scale()
          .domain([now - (conf.n) * conf.d, now])
          .range([0, width]);
    }

    // y scale
    y = d3.scale.linear()
        .domain([5, 40])
        .range([height, 0]);

    line = d3.svg.line()
        .interpolate('basis')
        .x(function (d, i) { return x(now - (conf.n - 1 - i) * conf.d); })
        .y(function (d) { return y(d); });

    // Destroy previous graph
    $('p').remove();

    tooltip = d3.select('body')
      .append('div')
        //.attr('class', 'tooltip')
        .style('position', 'absolute')
        .style('z-index', '10')
        .style('visibility', 'hidden')
        .style('font-size', '1.2em')
        .style('color', '#e95d4f')
        .style('font-weight', 'bold');

    svg = d3.select('body')
      .append('p')
      .append('svg')
        .attr('width', width + 150)
        .attr('height', height + 200)
      .append('g')
        .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

    svg
      .append('defs')
      .append('clipPath')
        .attr('id', 'clip')
      .append('rect')
        .attr('width', width)
        .attr('height', height);

    tempText = svg
      .append('text')
        .attr('class', 'tempText')
        .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')')
        .text(currentTemp + ' °');

    xAxis = svg
      .append('g')
        .attr('class', 'x axis')
        .attr('transform', 'translate(0,' + height + ')')
        .call(x.axis = d3.svg.axis().scale(x).orient('bottom').tickFormat(conf.timeFormat).ticks(conf.ticks));

    yAxis = svg
      .append('g')
        .attr('class', 'y axis')
        .call(y.axis = d3.svg.axis().scale(y).orient('left'))
        .append('text').text('T (C°)').attr('transform', 'translate(-15, -15)');

    path = svg
      .append('g')
        .attr('id', 'path')
        .attr('clip-path', 'url(#clip)')
        .append('path')
          .data([conf.data])
          .attr('class', 'line')
          .on('mouseover', function(){
            var m = d3.mouse(this);
            tooltip.text(y.invert(m[1]).toFixed(0) + ' °');
            tooltip.style('visibility', 'visible');
          })
          .on('mousemove', function(){
            var m = d3.mouse(this);
            tooltip.text(y.invert(m[1]).toFixed(0) + ' °');
              tooltip.style('top', (event.pageY-25)+'px').style('left',(event.pageX+15)+'px');
          })
          .on('mouseout', function(){
            tooltip.style('visibility', 'hidden');
          });

  }

  function tick() {

    tempText.text(temp + ' °');

    now = new Date();

    if (conf.live === true) {
      x.domain([now - (conf.n - 2) * conf.d, now - conf.d]);
    } else {
      x.domain([now - (conf.n) * conf.d, now]);
    }

    conf.data.push(temp);

    // Redraw the line
    svg.select('.line')
      .attr('d', line)
      .attr('transform', null);

    // Slide the x-axis left
    xAxis.transition()
      .duration(conf.d)
      .ease('linear')
      .call(x.axis);

    // Slide the line left
    path.transition()
      .duration(conf.d)
      .ease('linear')
      .attr('transform', 'translate(' + x(now - (conf.n - 1) * conf.d) + ')')
      .each('end', tick );

    // Pop the old data point off the front
    conf.data.shift();

  }

  // En français, que Diable !
  myFormatters = d3.locale({
    'decimal': ',',
    'thousands': ' ',
    'grouping': [3],
    'currency': ['€', '\''],
    'dateTime': '%a %b %e %X %Y',
    'date': '%d/%m/%Y',
    'time': '%H:%M:%S',
    'periods': ['AM', 'PM'],
    'days': ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],
    'shortDays': ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
    'months': ['Janvier', 'Février', 'Mars', 'Avril', 'Mail', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
    'shortMonths': ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sep', 'Oct', 'Nov', 'Déc']
  });

  d3.time.format = myFormatters.timeFormat;

  // SOCKET EVENTS
  socket = io.connect();
  socket.on('temp', function (data) {
    temp = parseFloat(data);
  });
  socket.on('photo', function (data) {
    console.log('Photo:' + data);
  });

  /*
  * n is the number of values
  * d is the time (in ms) between two values
  */
  confs = {
    /*
    * Every 10 seconds, during 10 minutes
    * n = ( 10 * 60 ) / 10 = 60
    * msIn10mn = 1000 * 60 * 10 = 600000
    * d = msIn10mn / 60 = 10000
    */
    direct: { n: 243, d: 750, data: d3.range(243).map(function () { return currentTemp; }), ticks: 6, live: true,
    timeFormat: function (d) {
      if (d.getSeconds() === 30) {
        return '';
      } else {
        var format = d3.time.format('%H:%M');
        return format(d);
      }
    }},
    /*
    * Every 15 minutes, during 24 hours
    *
    * n = ( 24 * 60 ) / 15 = 96
    * msIn24h = 1000 * 3600 * 24 = 86,400,000
    * d = msIn24h / 96 = 900,000
    */
    temps15mn: { n: 96, d: 900000, data: previousTemps, timeFormat: d3.time.format('%Hh'), ticks: 24, live: false },
    /*
    * Every 360 minutes, during 7 days
    *
    * n = ( 7 * 24 * 60 ) / 360 = 28
    * msIn1week = 1000 * 3600 * 24 * 7 = 604,800,000
    * d = msIn1week / 28 = 21,600,000
    */
    temps360mn: { n: 28, d: 21600000, timeFormat: d3.time.format('%a'), ticks: 7, live: false },
    /*
    * Every 720 minutes, during 30.5 days
    *
    * n = ( 30.5 * 24 * 60 ) / 720 = 61
    * msIn1month = 1000 * 3600 * 24 * 30.5 = 2,635,200,000
    * d = msIn1month / 61 = 43,200,000
    */
    temps720mn: { n: 61, d: 43200000, timeFormat: d3.time.format('%d'), ticks: 31, live: false },
    /*
    * Every 720 minutes, during 365.5 days
    *
    * n = ( 365.5 * 24 * 60 ) / 720 = 731
    * msIn1year = 1000 * 3600 * 24 * 365.5 = 31,579,200,000
    * d = msIn1year / 731 = 43,200,000
    */
    temps720mna: { n: 731, d: 43200000, timeFormat: d3.time.format('%b'), ticks: 12, live: false }
  };

  // Set the 1 day confifuration as default

  now = new Date();
  temp = confs.temps15mn.data[confs.temps15mn.data.length - 1] || 0;

  margin = {top: 150, right: 150, bottom: 150, left: 150};
  width = getWidth() - margin.right - margin.left - 0;
  height = getHeight() - margin.top - margin.bottom - 100; //100 : padding boutons

  // Create first graph, with default 1 day configuration
  conf = confs.temps15mn;
  setupGraph();
  tick();

  /*
  * DOM EVENTS
  */

  // Resize graph on window resize
  var doIt;
  $(window).on('resize', function(){
    clearTimeout(doIt);
    doIt = setTimeout(function () {
      width = getWidth() - margin.right - margin.left - 0;
      height = getHeight() - margin.top - margin.bottom - 100;
      $('.active').click();
    }, 500);
  });

  // Button events
  $('button').on('click', function () {

    var resourceName, variableName;

    $(this).siblings().removeClass('active');
    $(this).addClass('active');

    resourceName = $(this).attr('data-temps');
    variableName = $(this).attr('data-temps-name');

    if (resourceName === 'direct') {
      conf = confs.direct;
      setupGraph();
      tick();
    } else {
      $.ajax({
        url: '/data/' + resourceName
      }).done(function (data) {
        conf = confs[variableName];
        conf.data = data;
        setupGraph();
        tick();
      });
    }

  });

})();
<commit_msg>graph correction<commit_after>(function () {

  'use strict';

  var x, y, line, svg, xAxis, yAxis, path, tempText, now, temp, margin, width, height, confs, conf, socket, myFormatters, tooltip;

  // Get page width
  function getWidth() {
    var x = 0;
    if (self.innerHeight) {
      x = self.innerWidth;
    }
    else if (document.documentElement && document.documentElement.clientHeight) {
      x = document.documentElement.clientWidth;
    }
    else if (document.body) {
      x = document.body.clientWidth;
    }
    return x;
  }

  // Get page height
  function getHeight() {
    var y = 0;
    if (self.innerHeight) {
      y = self.innerHeight;
    }
    else if (document.documentElement && document.documentElement.clientHeight) {
      y = document.documentElement.clientHeight;
    }
    else if (document.body) {
      y = document.body.clientHeight;
    }
    return y;
  }

  // Create graph
  function setupGraph() {

    // x scale
    if (conf.live === true) {
      x = d3.time.scale()
        .domain([now - (conf.n - 2) * conf.d, now - conf.d])
        .range([0, width]);
    } else {
      x = d3.time.scale()
          .domain([now - (conf.n) * conf.d, now])
          .range([0, width]);
    }

    // y scale
    y = d3.scale.linear()
        .domain([5, 40])
        .range([height, 0]);

    if (conf.live) {
      line = d3.svg.line()
        .interpolate('basis')
        .x(function (d, i) { return x(now - (conf.n - 1 - i) * conf.d); })
        .y(function (d) { return y(d); });
    } else {
      line = d3.svg.line()
        .interpolate('basis')
        .x(function (d, i) { return x(now - (conf.n - i) * conf.d); })
        .y(function (d) { return y(d); });
    }

    // Destroy previous graph
    $('p').remove();

    tooltip = d3.select('body')
      .append('div')
        //.attr('class', 'tooltip')
        .style('position', 'absolute')
        .style('z-index', '10')
        .style('visibility', 'hidden')
        .style('font-size', '1.2em')
        .style('color', '#e95d4f')
        .style('font-weight', 'bold');

    svg = d3.select('body')
      .append('p')
      .append('svg')
        .attr('width', width + 150)
        .attr('height', height + 200)
      .append('g')
        .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

    svg
      .append('defs')
      .append('clipPath')
        .attr('id', 'clip')
      .append('rect')
        .attr('width', width)
        .attr('height', height);

    tempText = svg
      .append('text')
        .attr('class', 'tempText')
        .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')')
        .text(currentTemp + ' °');

    xAxis = svg
      .append('g')
        .attr('class', 'x axis')
        .attr('transform', 'translate(0,' + height + ')')
        .call(x.axis = d3.svg.axis().scale(x).orient('bottom').tickFormat(conf.timeFormat).ticks(conf.ticks));

    yAxis = svg
      .append('g')
        .attr('class', 'y axis')
        .call(y.axis = d3.svg.axis().scale(y).orient('left'))
        .append('text').text('T (C°)').attr('transform', 'translate(-15, -15)');

    path = svg
      .append('g')
        .attr('id', 'path')
        .attr('clip-path', 'url(#clip)')
        .append('path')
          .data([conf.data])
          .attr('class', 'line')
          .on('mouseover', function(){
            var m = d3.mouse(this);
            tooltip.text(y.invert(m[1]).toFixed(0) + ' °');
            tooltip.style('visibility', 'visible');
          })
          .on('mousemove', function(){
            var m = d3.mouse(this);
            tooltip.text(y.invert(m[1]).toFixed(0) + ' °');
              tooltip.style('top', (event.pageY-25)+'px').style('left',(event.pageX+15)+'px');
          })
          .on('mouseout', function(){
            tooltip.style('visibility', 'hidden');
          });

  }

  function tick() {

    tempText.text(temp + ' °');

    now = new Date();

    if (conf.live === true) {
      x.domain([now - (conf.n - 2) * conf.d, now - conf.d]);
    } else {
      x.domain([now - (conf.n) * conf.d, now]);
    }

    conf.data.push(temp);

    // Redraw the line
    svg.select('.line')
      .attr('d', line)
      .attr('transform', null);

    // Slide the x-axis left
    xAxis.transition()
      .duration(conf.d)
      .ease('linear')
      .call(x.axis);

    // Slide the line left
    if( conf.live ){
      path.transition()
        .duration(conf.d)
        .ease('linear')
        .attr('transform', 'translate(' + x(now - (conf.n - 1) * conf.d) + ')')
        .each('end', tick );
    } else {
      path.transition()
        .duration(conf.d)
        .ease('linear')
        .attr('transform', 'translate(' + x(now - conf.n * conf.d) + ')')
        .each('end', tick );
    }

    // Pop the old data point off the front
    conf.data.shift();

  }

  // En français, que Diable !
  myFormatters = d3.locale({
    'decimal': ',',
    'thousands': ' ',
    'grouping': [3],
    'currency': ['€', '\''],
    'dateTime': '%a %b %e %X %Y',
    'date': '%d/%m/%Y',
    'time': '%H:%M:%S',
    'periods': ['AM', 'PM'],
    'days': ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],
    'shortDays': ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
    'months': ['Janvier', 'Février', 'Mars', 'Avril', 'Mail', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
    'shortMonths': ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sep', 'Oct', 'Nov', 'Déc']
  });

  d3.time.format = myFormatters.timeFormat;

  // SOCKET EVENTS
  socket = io.connect();
  socket.on('temp', function (data) {
    temp = parseFloat(data);
  });
  socket.on('photo', function (data) {
    console.log('Photo:' + data);
  });

  /*
  * n is the number of values
  * d is the time (in ms) between two values
  */
  confs = {
    /*
    * Every 10 seconds, during 10 minutes
    * n = ( 10 * 60 ) / 10 = 60
    * msIn10mn = 1000 * 60 * 10 = 600000
    * d = msIn10mn / 60 = 10000
    */
    direct: { n: 243, d: 750, data: d3.range(243).map(function () { return currentTemp; }), ticks: 6, live: true,
    timeFormat: function (d) {
      if (d.getSeconds() === 30) {
        return '';
      } else {
        var format = d3.time.format('%H:%M');
        return format(d);
      }
    }},
    /*
    * Every 15 minutes, during 24 hours
    *
    * n = ( 24 * 60 ) / 15 = 96
    * msIn24h = 1000 * 3600 * 24 = 86,400,000
    * d = msIn24h / 96 = 900,000
    */
    temps15mn: { n: 96, d: 900000, data: previousTemps, timeFormat: d3.time.format('%Hh'), ticks: 24, live: false },
    /*
    * Every 360 minutes, during 7 days
    *
    * n = ( 7 * 24 * 60 ) / 360 = 28
    * msIn1week = 1000 * 3600 * 24 * 7 = 604,800,000
    * d = msIn1week / 28 = 21,600,000
    */
    temps360mn: { n: 28, d: 21600000, timeFormat: d3.time.format('%a'), ticks: 7, live: false },
    /*
    * Every 720 minutes, during 30.5 days
    *
    * n = ( 30.5 * 24 * 60 ) / 720 = 61
    * msIn1month = 1000 * 3600 * 24 * 30.5 = 2,635,200,000
    * d = msIn1month / 61 = 43,200,000
    */
    temps720mn: { n: 61, d: 43200000, timeFormat: d3.time.format('%d'), ticks: 31, live: false },
    /*
    * Every 720 minutes, during 365.5 days
    *
    * n = ( 365.5 * 24 * 60 ) / 720 = 731
    * msIn1year = 1000 * 3600 * 24 * 365.5 = 31,579,200,000
    * d = msIn1year / 731 = 43,200,000
    */
    temps720mna: { n: 731, d: 43200000, timeFormat: d3.time.format('%b'), ticks: 12, live: false }
  };

  // Set the 1 day confifuration as default

  now = new Date();
  temp = confs.temps15mn.data[confs.temps15mn.data.length - 1] || 0;

  margin = {top: 150, right: 150, bottom: 150, left: 150};
  width = getWidth() - margin.right - margin.left - 0;
  height = getHeight() - margin.top - margin.bottom - 100; //100 : padding boutons

  // Create first graph, with default 1 day configuration
  conf = confs.temps15mn;
  setupGraph();
  tick();

  /*
  * DOM EVENTS
  */

  // Resize graph on window resize
  var doIt;
  $(window).on('resize', function(){
    clearTimeout(doIt);
    doIt = setTimeout(function () {
      width = getWidth() - margin.right - margin.left - 0;
      height = getHeight() - margin.top - margin.bottom - 100;
      $('.active').click();
    }, 500);
  });

  // Button events
  $('button').on('click', function () {

    var resourceName, variableName;

    $(this).siblings().removeClass('active');
    $(this).addClass('active');

    resourceName = $(this).attr('data-temps');
    variableName = $(this).attr('data-temps-name');

    if (resourceName === 'direct') {
      conf = confs.direct;
      setupGraph();
      tick();
    } else {
      $.ajax({
        url: '/data/' + resourceName
      }).done(function (data) {
        conf = confs[variableName];
        conf.data = data;
        setupGraph();
        tick();
      });
    }

  });

})();
<|endoftext|>


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

    /**
     * Chart initializer.
     */
    function Chart(chart)
    {
        this.id = chart.options.element;
        this.type = chart.chart;
        this.options = chart.options;
        this.ajax = chart.ajax;

        this.init();

        return this;
    }

    Chart.prototype = {

        /**
         * Initialize method.
         *
         * @return {undefined}
         */
        init: function () {
            if (0 < this.options.data.length) {
                this.draw();
            } else {
                this.getData();
            }
        },

        /**
         * Draw method.
         *
         * @return {undefined}
         */
        draw: function () {
            var that = this;

            switch (this.type) {
                case 'barChart':
                    Morris.Bar(this.options);
                    break;
                case 'lineChart':
                    Morris.Line(this.options);
                    break;
                case 'donutChart':
                    Morris.Donut(this.options);
                    break;
                case 'knobChart':
                    $('.knob-graph').knob({
                        'width': 85,
                        'height': 85,
                        'linecap': 'round',
                        'thickness': '.2',
                        'readOnly': true,
                        'cursor': false,
                        'draw': function () {
                            var colorGradients = [
                                '#05497d', '#043b64', '#032c4c', //blue
                                '#1e3302', '#2c4c03', '#3b6404', '#497d05', '#579606', '#66ae07', '#74c708', //green
                                '#a7a60e', '#bfbd0f', '#d6d411', //yellow
                                '#a70e0f', '#bf0f11', '#d61113', '#ec1517', //red
                            ];
                            var randomColor = Math.floor(Math.random() * colorGradients.length);
                            this.o.fgColor = colorGradients[randomColor];
                        }
                    });
                    break;
                case 'funnelChart':
                    this.options.data.sort(function (a, b) {
                        return (a.value < b.value) ? 1 : ((b.value < a.value) ? -1 : 0);
                    });

                    var d3chart = new D3Funnel('#' + this.id);
                    d3chart.draw(this.options.data, {
                        block: {
                            dynamicHeight: true
                        }
                    });
                    break;
            }
        },

        getData: function () {
            var that = this;

            if (!this.ajax) {
                console.log('No ajax information, cannot fetch chart data.');

                return;
            }

            var placeholder = this.getPlaceholder();
            // add loading placeholder
            $('#' + this.id).append(placeholder.element);

            $.ajax({
                url: this.ajax.url,
                type: 'get',
                dataType: 'json',
                contentType: 'application/json',
                success: function (data, textStatus, jqXHR) {
                    // remove placeholder
                    $('#' + placeholder.id).remove();

                    var chartData = that.normalizeData(data.data);

                    that.options.data = chartData;
                    console.log(that.options);

                    that.draw();
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    console.log(jqXHR);
                    console.log(textStatus);
                    console.log(errorThrown);
                }
            });
        },

        normalizeData: function (data) {
            var that = this;

            switch (this.type) {
                case 'funnelChart':
                case 'donutChart':
                    data.forEach(function (v, k) {
                        var label = data[k][that.options.xkey[0]];
                        var value = data[k][that.options.ykeys[0]];
                        data[k].label = $('
').html(label).text();
                        data[k].value = parseInt(value);
                    });
                    break;
                case 'barChart':
                    data.forEach(function (v, k) {
                        var key = that.options.xkey[0];
                        var value = data[k][key];
                        data[k][key] = $('
').html(value).text();
                    });
                    break;
            }

            return data;
        },

        getPlaceholder: function () {
            var result = {};

            // random id
            result.id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
            result.element = $('
', {id: result.id, style: 'height:350px;padding-top:160px;'});
            result.element.html(
                '
 Processing...
'
            );

            return result;
        }
    };

    if (!window.chartsData) {
        console.log('No charts to initialize');

        return;
    }

    var charts = [];
    window.chartsData.forEach(function (data) {
        var id = data.options.element;
        var isVisible = (!$('a[href="#' + id + '"]').data('toggle') || $('#' + id).hasClass('active'));

        // initialize visible charts
        if (isVisible) {
            // init chart
            new Chart(data);
            charts.push('#' + data.options.element);
        }
    });

    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
        var chartId = $(e.target).attr('href');

        // chart already initialized
        if (-1 !== charts.indexOf(chartId)) {
            return;
        }

        // get chart data
        var data = $.grep(window.chartsData, function (v) {
            return '#' + v.options.element === chartId;
        });

        if (!data.length) {
            return;
        }

        data = data[0];
        // init chart
        new Chart(data);
        charts.push('#' + data.options.element);
    });

})(jQuery, document, window);<commit_msg>Remove debug (task #5096)<commit_after>;(function ($, document, window) {
    'use strict';

    /**
     * Chart initializer.
     */
    function Chart(chart)
    {
        this.id = chart.options.element;
        this.type = chart.chart;
        this.options = chart.options;
        this.ajax = chart.ajax;

        this.init();

        return this;
    }

    Chart.prototype = {

        /**
         * Initialize method.
         *
         * @return {undefined}
         */
        init: function () {
            if (0 < this.options.data.length) {
                this.draw();
            } else {
                this.getData();
            }
        },

        /**
         * Draw method.
         *
         * @return {undefined}
         */
        draw: function () {
            var that = this;

            switch (this.type) {
                case 'barChart':
                    Morris.Bar(this.options);
                    break;
                case 'lineChart':
                    Morris.Line(this.options);
                    break;
                case 'donutChart':
                    Morris.Donut(this.options);
                    break;
                case 'knobChart':
                    $('.knob-graph').knob({
                        'width': 85,
                        'height': 85,
                        'linecap': 'round',
                        'thickness': '.2',
                        'readOnly': true,
                        'cursor': false,
                        'draw': function () {
                            var colorGradients = [
                                '#05497d', '#043b64', '#032c4c', //blue
                                '#1e3302', '#2c4c03', '#3b6404', '#497d05', '#579606', '#66ae07', '#74c708', //green
                                '#a7a60e', '#bfbd0f', '#d6d411', //yellow
                                '#a70e0f', '#bf0f11', '#d61113', '#ec1517', //red
                            ];
                            var randomColor = Math.floor(Math.random() * colorGradients.length);
                            this.o.fgColor = colorGradients[randomColor];
                        }
                    });
                    break;
                case 'funnelChart':
                    this.options.data.sort(function (a, b) {
                        return (a.value < b.value) ? 1 : ((b.value < a.value) ? -1 : 0);
                    });

                    var d3chart = new D3Funnel('#' + this.id);
                    d3chart.draw(this.options.data, {
                        block: {
                            dynamicHeight: true
                        }
                    });
                    break;
            }
        },

        getData: function () {
            var that = this;

            if (!this.ajax) {
                console.log('No ajax information, cannot fetch chart data.');

                return;
            }

            var placeholder = this.getPlaceholder();
            // add loading placeholder
            $('#' + this.id).append(placeholder.element);

            $.ajax({
                url: this.ajax.url,
                type: 'get',
                dataType: 'json',
                contentType: 'application/json',
                success: function (data, textStatus, jqXHR) {
                    // remove placeholder
                    $('#' + placeholder.id).remove();

                    var chartData = that.normalizeData(data.data);

                    that.options.data = chartData;

                    that.draw();
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    console.log(jqXHR);
                    console.log(textStatus);
                    console.log(errorThrown);
                }
            });
        },

        normalizeData: function (data) {
            var that = this;

            switch (this.type) {
                case 'funnelChart':
                case 'donutChart':
                    data.forEach(function (v, k) {
                        var label = data[k][that.options.xkey[0]];
                        var value = data[k][that.options.ykeys[0]];
                        data[k].label = $('
').html(label).text();
                        data[k].value = parseInt(value);
                    });
                    break;
                case 'barChart':
                    data.forEach(function (v, k) {
                        var key = that.options.xkey[0];
                        var value = data[k][key];
                        data[k][key] = $('
').html(value).text();
                    });
                    break;
            }

            return data;
        },

        getPlaceholder: function () {
            var result = {};

            // random id
            result.id = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
            result.element = $('
', {id: result.id, style: 'height:350px;padding-top:160px;'});
            result.element.html(
                '
 Processing...
'
            );

            return result;
        }
    };

    if (!window.chartsData) {
        console.log('No charts to initialize');

        return;
    }

    var charts = [];
    window.chartsData.forEach(function (data) {
        var id = data.options.element;
        var isVisible = (!$('a[href="#' + id + '"]').data('toggle') || $('#' + id).hasClass('active'));

        // initialize visible charts
        if (isVisible) {
            // init chart
            new Chart(data);
            charts.push('#' + data.options.element);
        }
    });

    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
        var chartId = $(e.target).attr('href');

        // chart already initialized
        if (-1 !== charts.indexOf(chartId)) {
            return;
        }

        // get chart data
        var data = $.grep(window.chartsData, function (v) {
            return '#' + v.options.element === chartId;
        });

        if (!data.length) {
            return;
        }

        data = data[0];
        // init chart
        new Chart(data);
        charts.push('#' + data.options.element);
    });

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


<commit_before>var arrayChangeEventName = 'arrayChange';
ko.extenders['trackArrayChanges'] = function(target, options) {
    // Use the provided options--each call to trackArrayChanges overwrites the previously set options
    target.compareArrayOptions = {};
    if (options && typeof options == "object") {
        ko.utils.extend(target.compareArrayOptions, options);
    }
    target.compareArrayOptions['sparse'] = true;

    // Only modify the target observable once
    if (target.cacheDiffForKnownOperation) {
        return;
    }
    var trackingChanges = false,
        cachedDiff = null,
        arrayChangeSubscription,
        pendingNotifications = 0,
        underlyingNotifySubscribersFunction,
        underlyingBeforeSubscriptionAddFunction = target.beforeSubscriptionAdd,
        underlyingAfterSubscriptionRemoveFunction = target.afterSubscriptionRemove;

    // Watch "subscribe" calls, and for array change events, ensure change tracking is enabled
    target.beforeSubscriptionAdd = function (event) {
        if (underlyingBeforeSubscriptionAddFunction)
            underlyingBeforeSubscriptionAddFunction.call(target, event);
        if (event === arrayChangeEventName) {
            trackChanges();
        }
    };
    // Watch "dispose" calls, and for array change events, ensure change tracking is disabled when all are disposed
    target.afterSubscriptionRemove = function (event) {
        if (underlyingAfterSubscriptionRemoveFunction)
            underlyingAfterSubscriptionRemoveFunction.call(target, event);
        if (event === arrayChangeEventName && !target.hasSubscriptionsForEvent(arrayChangeEventName)) {
            if (underlyingNotifySubscribersFunction) {
                target['notifySubscribers'] = underlyingNotifySubscribersFunction;
                underlyingNotifySubscribersFunction = undefined;
            }
            arrayChangeSubscription.dispose();
            trackingChanges = false;
        }
    };

    function trackChanges() {
        // Calling 'trackChanges' multiple times is the same as calling it once
        if (trackingChanges) {
            return;
        }

        trackingChanges = true;

        // Intercept "notifySubscribers" to track how many times it was called.
        underlyingNotifySubscribersFunction = target['notifySubscribers'];
        target['notifySubscribers'] = function(valueToNotify, event) {
            if (!event || event === defaultEvent) {
                ++pendingNotifications;
            }
            return underlyingNotifySubscribersFunction.apply(this, arguments);
        };

        // Each time the array changes value, capture a clone so that on the next
        // change it's possible to produce a diff
        var previousContents = [].concat(target.peek() || []);
        cachedDiff = null;
        arrayChangeSubscription = target.subscribe(function(currentContents) {
            // Make a copy of the current contents and ensure it's an array
            currentContents = [].concat(currentContents || []);

            // Compute the diff and issue notifications, but only if someone is listening
            if (target.hasSubscriptionsForEvent(arrayChangeEventName)) {
                var changes = getChanges(previousContents, currentContents);
            }

            // Eliminate references to the old, removed items, so they can be GCed
            previousContents = currentContents;
            cachedDiff = null;
            pendingNotifications = 0;

            if (changes && changes.length) {
                target['notifySubscribers'](changes, arrayChangeEventName);
            }
        });
    }

    function getChanges(previousContents, currentContents) {
        // We try to re-use cached diffs.
        // The scenarios where pendingNotifications > 1 are when using rate-limiting or the Deferred Updates
        // plugin, which without this check would not be compatible with arrayChange notifications. Normally,
        // notifications are issued immediately so we wouldn't be queueing up more than one.
        if (!cachedDiff || pendingNotifications > 1) {
            cachedDiff = ko.utils.compareArrays(previousContents, currentContents, target.compareArrayOptions);
        }

        return cachedDiff;
    }

    target.cacheDiffForKnownOperation = function(rawArray, operationName, args) {
        // Only run if we're currently tracking changes for this observable array
        // and there aren't any pending deferred notifications.
        if (!trackingChanges || pendingNotifications) {
            return;
        }
        var diff = [],
            arrayLength = rawArray.length,
            argsLength = args.length,
            offset = 0;

        function pushDiff(status, value, index) {
            return diff[diff.length] = { 'status': status, 'value': value, 'index': index };
        }
        switch (operationName) {
            case 'push':
                offset = arrayLength;
            case 'unshift':
                for (var index = 0; index < argsLength; index++) {
                    pushDiff('added', args[index], offset + index);
                }
                break;

            case 'pop':
                offset = arrayLength - 1;
            case 'shift':
                if (arrayLength) {
                    pushDiff('deleted', rawArray[offset], offset);
                }
                break;

            case 'splice':
                // Negative start index means 'from end of array'. After that we clamp to [0...arrayLength].
                // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
                var startIndex = Math.min(Math.max(0, args[0] < 0 ? arrayLength + args[0] : args[0]), arrayLength),
                    endDeleteIndex = argsLength === 1 ? arrayLength : Math.min(startIndex + (args[1] || 0), arrayLength),
                    endAddIndex = startIndex + argsLength - 2,
                    endIndex = Math.max(endDeleteIndex, endAddIndex),
                    additions = [], deletions = [];
                for (var index = startIndex, argsIndex = 2; index < endIndex; ++index, ++argsIndex) {
                    if (index < endDeleteIndex)
                        deletions.push(pushDiff('deleted', rawArray[index], index));
                    if (index < endAddIndex)
                        additions.push(pushDiff('added', args[argsIndex], index));
                }
                ko.utils.findMovesInArrayComparison(deletions, additions);
                break;

            default:
                return;
        }
        cachedDiff = diff;
    };
};
<commit_msg>Fixed leaking when tracking array changes<commit_after>var arrayChangeEventName = 'arrayChange';
ko.extenders['trackArrayChanges'] = function(target, options) {
    // Use the provided options--each call to trackArrayChanges overwrites the previously set options
    target.compareArrayOptions = {};
    if (options && typeof options == "object") {
        ko.utils.extend(target.compareArrayOptions, options);
    }
    target.compareArrayOptions['sparse'] = true;

    // Only modify the target observable once
    if (target.cacheDiffForKnownOperation) {
        return;
    }
    var trackingChanges = false,
        cachedDiff = null,
        arrayChangeSubscription,
        pendingNotifications = 0,
        underlyingNotifySubscribersFunction,
        underlyingBeforeSubscriptionAddFunction = target.beforeSubscriptionAdd,
        underlyingAfterSubscriptionRemoveFunction = target.afterSubscriptionRemove;

    // Watch "subscribe" calls, and for array change events, ensure change tracking is enabled
    target.beforeSubscriptionAdd = function (event) {
        if (underlyingBeforeSubscriptionAddFunction)
            underlyingBeforeSubscriptionAddFunction.call(target, event);
        if (event === arrayChangeEventName) {
            trackChanges();
        }
    };
    // Watch "dispose" calls, and for array change events, ensure change tracking is disabled when all are disposed
    target.afterSubscriptionRemove = function (event) {
        if (underlyingAfterSubscriptionRemoveFunction)
            underlyingAfterSubscriptionRemoveFunction.call(target, event);
        if (event === arrayChangeEventName && !target.hasSubscriptionsForEvent(arrayChangeEventName)) {
            if (underlyingNotifySubscribersFunction) {
                target['notifySubscribers'] = underlyingNotifySubscribersFunction;
                underlyingNotifySubscribersFunction = undefined;
            }
            arrayChangeSubscription.dispose();
            arrayChangeSubscription = null;
            trackingChanges = false;
        }
    };

    function trackChanges() {
        // Calling 'trackChanges' multiple times is the same as calling it once
        if (trackingChanges) {
            return;
        }

        trackingChanges = true;

        // Intercept "notifySubscribers" to track how many times it was called.
        underlyingNotifySubscribersFunction = target['notifySubscribers'];
        target['notifySubscribers'] = function(valueToNotify, event) {
            if (!event || event === defaultEvent) {
                ++pendingNotifications;
            }
            return underlyingNotifySubscribersFunction.apply(this, arguments);
        };

        // Each time the array changes value, capture a clone so that on the next
        // change it's possible to produce a diff
        var previousContents = [].concat(target.peek() || []);
        cachedDiff = null;
        arrayChangeSubscription = target.subscribe(function(currentContents) {
            // Make a copy of the current contents and ensure it's an array
            currentContents = [].concat(currentContents || []);

            // Compute the diff and issue notifications, but only if someone is listening
            if (target.hasSubscriptionsForEvent(arrayChangeEventName)) {
                var changes = getChanges(previousContents, currentContents);
            }

            // Eliminate references to the old, removed items, so they can be GCed
            previousContents = currentContents;
            cachedDiff = null;
            pendingNotifications = 0;

            if (changes && changes.length) {
                target['notifySubscribers'](changes, arrayChangeEventName);
            }
        });
    }

    function getChanges(previousContents, currentContents) {
        // We try to re-use cached diffs.
        // The scenarios where pendingNotifications > 1 are when using rate-limiting or the Deferred Updates
        // plugin, which without this check would not be compatible with arrayChange notifications. Normally,
        // notifications are issued immediately so we wouldn't be queueing up more than one.
        if (!cachedDiff || pendingNotifications > 1) {
            cachedDiff = ko.utils.compareArrays(previousContents, currentContents, target.compareArrayOptions);
        }

        return cachedDiff;
    }

    target.cacheDiffForKnownOperation = function(rawArray, operationName, args) {
        // Only run if we're currently tracking changes for this observable array
        // and there aren't any pending deferred notifications.
        if (!trackingChanges || pendingNotifications) {
            return;
        }
        var diff = [],
            arrayLength = rawArray.length,
            argsLength = args.length,
            offset = 0;

        function pushDiff(status, value, index) {
            return diff[diff.length] = { 'status': status, 'value': value, 'index': index };
        }
        switch (operationName) {
            case 'push':
                offset = arrayLength;
            case 'unshift':
                for (var index = 0; index < argsLength; index++) {
                    pushDiff('added', args[index], offset + index);
                }
                break;

            case 'pop':
                offset = arrayLength - 1;
            case 'shift':
                if (arrayLength) {
                    pushDiff('deleted', rawArray[offset], offset);
                }
                break;

            case 'splice':
                // Negative start index means 'from end of array'. After that we clamp to [0...arrayLength].
                // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
                var startIndex = Math.min(Math.max(0, args[0] < 0 ? arrayLength + args[0] : args[0]), arrayLength),
                    endDeleteIndex = argsLength === 1 ? arrayLength : Math.min(startIndex + (args[1] || 0), arrayLength),
                    endAddIndex = startIndex + argsLength - 2,
                    endIndex = Math.max(endDeleteIndex, endAddIndex),
                    additions = [], deletions = [];
                for (var index = startIndex, argsIndex = 2; index < endIndex; ++index, ++argsIndex) {
                    if (index < endDeleteIndex)
                        deletions.push(pushDiff('deleted', rawArray[index], index));
                    if (index < endAddIndex)
                        additions.push(pushDiff('added', args[argsIndex], index));
                }
                ko.utils.findMovesInArrayComparison(deletions, additions);
                break;

            default:
                return;
        }
        cachedDiff = diff;
    };
};
<|endoftext|>


<commit_before>/**
 * Copyright 2018, Google, Inc.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

// [START tts_quickstart]
const fs = require('fs');

// Imports the Google Cloud client library
const textToSpeech = require('@google-cloud/text-to-speech');

// Creates a client
const client = new textToSpeech.TextToSpeechClient();

// The text to synthesize
const text = 'Hello, world!';

// Construct the request
const request = {
  input: {text: text},
  // Select the language and SSML Voice Gender (optional)
  voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
  // Select the type of audio encoding
  audioConfig: {audioEncoding: 'MP3'},
};

// Performs the Text-to-Speech request
client.synthesizeSpeech(request, (err, response) => {
  if (err) {
    console.error('ERROR:', err);
    return;
  }

  // Write the binary audio content to a local file
  fs.writeFile('output.mp3', response.audioContent, 'binary', err => {
    if (err) {
      console.error('ERROR:', err);
      return;
    }
    console.log('Audio content written to file: output.mp3');
  });
});
// [END tts_quickstart]
<commit_msg>docs(samples): updated samples code to use async await (#118)<commit_after>/**
 * Copyright 2018, Google, Inc.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

async function main() {
  // [START tts_quickstart]
  const fs = require('fs');
  const util = require('util');

  // Imports the Google Cloud client library
  const textToSpeech = require('@google-cloud/text-to-speech');

  // Creates a client
  const client = new textToSpeech.TextToSpeechClient();

  // The text to synthesize
  const text = 'Hello, world!';

  // Construct the request
  const request = {
    input: {text: text},
    // Select the language and SSML Voice Gender (optional)
    voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
    // Select the type of audio encoding
    audioConfig: {audioEncoding: 'MP3'},
  };

  // Performs the Text-to-Speech request
  const [response] = await client.synthesizeSpeech(request);
  // Write the binary audio content to a local file
  const writeFile = util.promisify(fs.writeFile);
  await writeFile('output.mp3', response.audioContent, 'binary');
  console.log('Audio content written to file: output.mp3');
  // [END tts_quickstart]
}

main().catch(console.error);
<|endoftext|>