<commit_before>Date.CultureInfo = {
    /* Culture Name */
    name: "ar-IQ",
    englishName: "Arabic (Iraq)",
    nativeName: "العربية (العراق)",

    /* Day Name Strings */
    dayNames: ["الأحد", "الإثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت"],
    abbreviatedDayNames: ["أحد", "إثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت"],
    shortestDayNames: ["حد", "ثن", "ثل", "رع", "خم", "جم", "سب"],
    firstLetterDayNames: ["ح", "ن", "ث", "ر", "خ", "ج", "س"],

    /* Month Name Strings */
    monthNames: ["كانون الثاني", "شباط", "آذار", "نيسان", "أيار", "حزيران", "تموز", "آب", "أيلول", "تشرين الأول", "تشرين الثاني", "كانون الأول"],
    abbreviatedMonthNames: ["كانون 2", "شباط", "آذار", "نيسان", "أيار", "حزيران", "تموز", "آب", "أيلول", "تشرين 1", "تشرين 2", "كانون 1"],

    /* AM/PM Designators */
    amDesignator: "ص",
    pmDesignator: "م",

    firstDayOfWeek: 6,
    twoDigitYearMax: 2029,

    /**
     * The dateElementOrder is based on the order of the
     * format specifiers in the formatPatterns.DatePattern.
     *
     * Example:

     shortDatePattern    dateElementOrder
     ------------------  ----------------
     "M/d/yyyy"          "mdy"
     "dd/MM/yyyy"        "dmy"
     "yyyy-MM-dd"        "ymd"

     *
     * The correct dateElementOrder is required by the parser to
     * determine the expected order of the date elements in the
     * string being parsed.
     */
    dateElementOrder: "dmy",

    /* Standard date and time format patterns */
    formatPatterns: {
        shortDate: "dd/MM/yy",
        longDate: "dd/MMMM/yyyy",
        shortTime: "hh:mm tt",
        longTime: "hh:mm:ss tt",
        fullDateTime: "dd/MMMM/yyyy hh:mm:ss tt",
        sortableDateTime: "yyyy-MM-ddTHH:mm:ss",
        universalSortableDateTime: "yyyy-MM-dd HH:mm:ssZ",
        rfc1123: "ddd, dd MMM yyyy HH:mm:ss GMT",
        monthDay: "dd MMMM",
        yearMonth: "MMMM, yyyy"
    },

    /**
     * NOTE: If a string format is not parsing correctly, but
     * you would expect it parse, the problem likely lies below.
     *
     * The following regex patterns control most of the string matching
     * within the parser.
     *
     * The Month name and Day name patterns were automatically generated
     * and in general should be (mostly) correct.
     *
     * Beyond the month and day name patterns are natural language strings.
     * Example: "next", "today", "months"
     *
     * These natural language string may NOT be correct for this culture.
     * If they are not correct, please translate and edit this file
     * providing the correct regular expression pattern.
     *
     * If you modify this file, please post your revised CultureInfo file
     * to the Datejs Forum located at http://www.datejs.com/forums/.
     *
     * Please mark the subject of the post with [CultureInfo]. Example:
     *    Subject: [CultureInfo] Translated "da-DK" Danish(Denmark)
     *
     * We will add the modified patterns to the master source files.
     *
     * As well, please review the list of "Future Strings" section below.
     */
    regexPatterns: {
        jan: /^كانون الثاني/i,
        feb: /^شباط/i,
        mar: /^آذار/i,
        apr: /^نيسان/i,
        may: /^أيار/i,
        jun: /^حزيران/i,
        jul: /^تموز/i,
        aug: /^آب/i,
        sep: /^أيلول/i,
        oct: /^تشرين الأول/i,
        nov: /^تشرين الثاني/i,
        dec: /^كانون الأول/i,

        sun: /^الأحد/i,
        mon: /^الإثنين/i,
        tue: /^الثلاثاء/i,
        wed: /^الأربعاء/i,
        thu: /^الخميس/i,
        fri: /^الجمعة/i,
        sat: /^السبت/i,

        future: /^القادم/i,
        past: /^الماضي/i,
        add: /^(\+|بعد|عقب)/i,
        subtract: /^(\-|قبل|منذ)/i,

        yesterday: /^((ال)?(ا|أ)مس|(ال)?بارح(ة)?)/i,
        today: /^اليوم/i,
        tomorrow: /^(الغد|غد(ا)?)/i,
        now: /^(ال)?آن/i,

        millisecond: /^(ال)?ج(زء(ا))?( من( ال(أ|ا)لف من)? |( )?.( )?)(ال)?ث(انية)?(.)?/i,
	second: /^(ال)?ث(انية|وان(ي)?)?(.)?/i,
	minute: /^(ال)?د(قيقة|قائق)?(.)?/i,
	hour: /^(ال)?س(اعة|اعات)?(.)?/i,
	week: /^(ال)?(إ|ا)س(بوع|ابيع)/i,
	month: /^(ال)?((أ|ا)?شهر|شهور)/i,
	day: /(ال)?(يوم|أيام)/i,
	year: /^(ال)?سن(ة|ين|ون|وات)/i,

	shortMeridian: /^(ص|م)/i,
	longMeridian: /^(صباح(ا)?|مساء(ا)?)/i,
        timezone: /^(((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt|utc|((ب)?توقيت )?(مكة (المكرمة)?|(المملكة العربية)?السعودية|الرياض|ast|arab (standard)? tim(e|ing)))/i,

        ordinalSuffix: /^\s*(st|nd|rd|th)/i,
        timeContext: /^\s*(\:|a(?!u|p)|p)/i
    },

	timezones: [{name:"UTC", offset:"-000"}, {name:"GMT", offset:"-000"}, {name:"AST", offset:"+0300"}]
};

/********************
 ** Future Strings **
 ********************
 *
 * The following list of strings may not be currently being used, but
 * may be incorporated into the Datejs library later.
 *
 * We would appreciate any help translating the strings below.
 *
 * If you modify this file, please post your revised CultureInfo file
 * to the Datejs Forum located at http://www.datejs.com/forums/.
 *
 * Please mark the subject of the post with [CultureInfo]. Example:
 *    Subject: [CultureInfo] Translated "da-DK" Danish(Denmark)b
 *
 * English Name        Translated
 * ------------------  -----------------
 * about               قرابة
 * ago                 مضت
 * date                التاريخ
 * time                الوقت
 * calendar            التقويم
 * show                اظهار
 * hourly              كل ساعة
 * daily               يومياً
 * weekly              اسبوعياً
 * bi-weekly           مرتين بالإسبوع
 * fortnight           اسبوعان
 * monthly             شهرياً
 * bi-monthly          مرتين بالشهر
 * quarter             ربع
 * quarterly           كل ربع سنة
 * yearly              سنوياً
 * annual              سنوي
 * annually            سنوياً
 * annum               عام
 * again               مرة أخرى
 * between             بين
 * after               بعد
 * from now            من الآن
 * repeat              كرر
 * times               مرات
 * per                 كل
 * min (abbrev minute) د.
 * morning             صباح
 * noon                ظهيرة
 * night               ليل
 * midnight            نصف الليل
 * mid-night           نصف الليل
 * evening             مساء
 * final               ختامي
 * future              مستقبل
 * spring              ربيع
 * summer              صيف
 * fall                خريف
 * winter              شتاء
 * end of              نهاية
 * end                 نهاية
 * long                طويل
 * short               قصير
 */
<commit_msg>Fixed TimeZone<commit_after>Date.CultureInfo = {
    /* Culture Name */
    name: "ar-IQ",
    englishName: "Arabic (Iraq)",
    nativeName: "العربية (العراق)",

    /* Day Name Strings */
    dayNames: ["الأحد", "الإثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت"],
    abbreviatedDayNames: ["أحد", "إثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت"],
    shortestDayNames: ["حد", "ثن", "ثل", "رع", "خم", "جم", "سب"],
    firstLetterDayNames: ["ح", "ن", "ث", "ر", "خ", "ج", "س"],

    /* Month Name Strings */
    monthNames: ["كانون الثاني", "شباط", "آذار", "نيسان", "أيار", "حزيران", "تموز", "آب", "أيلول", "تشرين الأول", "تشرين الثاني", "كانون الأول"],
    abbreviatedMonthNames: ["كانون 2", "شباط", "آذار", "نيسان", "أيار", "حزيران", "تموز", "آب", "أيلول", "تشرين 1", "تشرين 2", "كانون 1"],

    /* AM/PM Designators */
    amDesignator: "ص",
    pmDesignator: "م",

    firstDayOfWeek: 6,
    twoDigitYearMax: 2029,

    /**
     * The dateElementOrder is based on the order of the
     * format specifiers in the formatPatterns.DatePattern.
     *
     * Example:

     shortDatePattern    dateElementOrder
     ------------------  ----------------
     "M/d/yyyy"          "mdy"
     "dd/MM/yyyy"        "dmy"
     "yyyy-MM-dd"        "ymd"

     *
     * The correct dateElementOrder is required by the parser to
     * determine the expected order of the date elements in the
     * string being parsed.
     */
    dateElementOrder: "dmy",

    /* Standard date and time format patterns */
    formatPatterns: {
        shortDate: "dd/MM/yy",
        longDate: "dd/MMMM/yyyy",
        shortTime: "hh:mm tt",
        longTime: "hh:mm:ss tt",
        fullDateTime: "dd/MMMM/yyyy hh:mm:ss tt",
        sortableDateTime: "yyyy-MM-ddTHH:mm:ss",
        universalSortableDateTime: "yyyy-MM-dd HH:mm:ssZ",
        rfc1123: "ddd, dd MMM yyyy HH:mm:ss GMT",
        monthDay: "dd MMMM",
        yearMonth: "MMMM, yyyy"
    },

    /**
     * NOTE: If a string format is not parsing correctly, but
     * you would expect it parse, the problem likely lies below.
     *
     * The following regex patterns control most of the string matching
     * within the parser.
     *
     * The Month name and Day name patterns were automatically generated
     * and in general should be (mostly) correct.
     *
     * Beyond the month and day name patterns are natural language strings.
     * Example: "next", "today", "months"
     *
     * These natural language string may NOT be correct for this culture.
     * If they are not correct, please translate and edit this file
     * providing the correct regular expression pattern.
     *
     * If you modify this file, please post your revised CultureInfo file
     * to the Datejs Forum located at http://www.datejs.com/forums/.
     *
     * Please mark the subject of the post with [CultureInfo]. Example:
     *    Subject: [CultureInfo] Translated "da-DK" Danish(Denmark)
     *
     * We will add the modified patterns to the master source files.
     *
     * As well, please review the list of "Future Strings" section below.
     */
    regexPatterns: {
        jan: /^كانون الثاني/i,
        feb: /^شباط/i,
        mar: /^آذار/i,
        apr: /^نيسان/i,
        may: /^أيار/i,
        jun: /^حزيران/i,
        jul: /^تموز/i,
        aug: /^آب/i,
        sep: /^أيلول/i,
        oct: /^تشرين الأول/i,
        nov: /^تشرين الثاني/i,
        dec: /^كانون الأول/i,

        sun: /^الأحد/i,
        mon: /^الإثنين/i,
        tue: /^الثلاثاء/i,
        wed: /^الأربعاء/i,
        thu: /^الخميس/i,
        fri: /^الجمعة/i,
        sat: /^السبت/i,

        future: /^القادم/i,
        past: /^الماضي/i,
        add: /^(\+|بعد|عقب)/i,
        subtract: /^(\-|قبل|منذ)/i,

        yesterday: /^((ال)?(ا|أ)مس|(ال)?بارح(ة)?)/i,
        today: /^اليوم/i,
        tomorrow: /^(الغد|غد(ا)?)/i,
        now: /^(ال)?آن/i,

        millisecond: /^(ال)?ج(زء(ا))?( من( ال(أ|ا)لف من)? |( )?.( )?)(ال)?ث(انية)?(.)?/i,
	second: /^(ال)?ث(انية|وان(ي)?)?(.)?/i,
	minute: /^(ال)?د(قيقة|قائق)?(.)?/i,
	hour: /^(ال)?س(اعة|اعات)?(.)?/i,
	week: /^(ال)?(إ|ا)س(بوع|ابيع)/i,
	month: /^(ال)?((أ|ا)?شهر|شهور)/i,
	day: /(ال)?(يوم|أيام)/i,
	year: /^(ال)?سن(ة|ين|ون|وات)/i,

	shortMeridian: /^(ص|م)/i,
	longMeridian: /^(صباح(ا)?|مساء(ا)?)/i,
	timezone: /^(((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt|utc|((ب(ال)?)?توقيت )?(مكة( المكرمة)?|(جمهورية )?العراق|بغداد|العرب(ي)?( القياسي)?|ast|arabia( standard)? tim(e|ing)))/i,
        ordinalSuffix: /^\s*(st|nd|rd|th)/i,
        timeContext: /^\s*(\:|a(?!u|p)|p)/i
    },

	timezones: [{name:"UTC", offset:"-000"}, {name:"GMT", offset:"-000"}, {name:"AST", offset:"+0300"}]
};

/********************
 ** Future Strings **
 ********************
 *
 * The following list of strings may not be currently being used, but
 * may be incorporated into the Datejs library later.
 *
 * We would appreciate any help translating the strings below.
 *
 * If you modify this file, please post your revised CultureInfo file
 * to the Datejs Forum located at http://www.datejs.com/forums/.
 *
 * Please mark the subject of the post with [CultureInfo]. Example:
 *    Subject: [CultureInfo] Translated "da-DK" Danish(Denmark)b
 *
 * English Name        Translated
 * ------------------  -----------------
 * about               قرابة
 * ago                 مضت
 * date                التاريخ
 * time                الوقت
 * calendar            التقويم
 * show                اظهار
 * hourly              كل ساعة
 * daily               يومياً
 * weekly              اسبوعياً
 * bi-weekly           مرتين بالإسبوع
 * fortnight           اسبوعان
 * monthly             شهرياً
 * bi-monthly          مرتين بالشهر
 * quarter             ربع
 * quarterly           كل ربع سنة
 * yearly              سنوياً
 * annual              سنوي
 * annually            سنوياً
 * annum               عام
 * again               مرة أخرى
 * between             بين
 * after               بعد
 * from now            من الآن
 * repeat              كرر
 * times               مرات
 * per                 كل
 * min (abbrev minute) د.
 * morning             صباح
 * noon                ظهيرة
 * night               ليل
 * midnight            نصف الليل
 * mid-night           نصف الليل
 * evening             مساء
 * final               ختامي
 * future              مستقبل
 * spring              ربيع
 * summer              صيف
 * fall                خريف
 * winter              شتاء
 * end of              نهاية
 * end                 نهاية
 * long                طويل
 * short               قصير
 */
<|endoftext|>


<commit_before>// @flow

import { mediaInfoPropType } from 'lib/types/media-types';
import {
  verticalBoundsPropType,
  layoutCoordinatesPropType,
} from '../types/layout-types';
import type { AppState } from '../redux/redux-setup';
import type { AppNavigationProp } from '../navigation/app-navigator.react';
import type { TooltipRoute } from '../navigation/tooltip.react';

import * as React from 'react';
import Animated from 'react-native-reanimated';
import PropTypes from 'prop-types';
import { View, StyleSheet } from 'react-native';

import { connect } from 'lib/utils/redux-utils';
import { chatMessageItemPropType } from 'lib/selectors/chat-selectors';
import { messageID } from 'lib/shared/message-utils';

import {
  type InputState,
  inputStatePropType,
  withInputState,
} from '../input/input-state';
import InlineMultimedia from './inline-multimedia.react';
import { multimediaMessageBorderRadius } from './multimedia-message.react';
import { getRoundedContainerStyle } from './rounded-corners';
import { MessageHeader } from './message-header.react';

/* eslint-disable import/no-named-as-default-member */
const { Value } = Animated;
/* eslint-enable import/no-named-as-default-member */

type Props = {
  navigation: AppNavigationProp<'MultimediaTooltipModal'>,
  route: TooltipRoute<'MultimediaTooltipModal'>,
  progress: Value,
  // Redux state
  windowWidth: number,
  // withInputState
  inputState: ?InputState,
};
class MultimediaTooltipButton extends React.PureComponent<Props> {
  static propTypes = {
    navigation: PropTypes.shape({
      goBackOnce: PropTypes.func.isRequired,
    }).isRequired,
    route: PropTypes.shape({
      params: PropTypes.shape({
        initialCoordinates: layoutCoordinatesPropType.isRequired,
        verticalBounds: verticalBoundsPropType.isRequired,
        location: PropTypes.oneOf(['above', 'below']),
        margin: PropTypes.number,
        item: chatMessageItemPropType.isRequired,
        mediaInfo: mediaInfoPropType.isRequired,
        verticalOffset: PropTypes.number.isRequired,
      }).isRequired,
    }).isRequired,
    progress: PropTypes.object.isRequired,
    windowWidth: PropTypes.number.isRequired,
    inputState: inputStatePropType,
  };

  get headerStyle() {
    const { initialCoordinates, verticalOffset } = this.props.route.params;
    const bottom = initialCoordinates.height + verticalOffset;
    return {
      opacity: this.props.progress,
      position: 'absolute',
      left: -initialCoordinates.x,
      width: this.props.windowWidth,
      bottom,
    };
  }

  render() {
    const { inputState } = this.props;
    const { mediaInfo, item } = this.props.route.params;

    const { id: mediaID } = mediaInfo;
    const ourMessageID = messageID(item.messageInfo);
    const pendingUploads =
      inputState &&
      inputState.pendingUploads &&
      inputState.pendingUploads[ourMessageID];
    const pendingUpload = pendingUploads && pendingUploads[mediaID];
    const postInProgress = !!pendingUploads;

    const roundedStyle = getRoundedContainerStyle(
      mediaInfo.corners,
      multimediaMessageBorderRadius,
    );

    return (
      <React.Fragment>
        <Animated.View style={this.headerStyle}>
          <MessageHeader item={item} focused={true} display="modal" />
        </Animated.View>
        <View style={[styles.media, roundedStyle]}>
          <InlineMultimedia
            mediaInfo={mediaInfo}
            onPress={this.onPress}
            onLongPress={this.onPress}
            postInProgress={postInProgress}
            pendingUpload={pendingUpload}
            spinnerColor="white"
          />
        </View>
      </React.Fragment>
    );
  }

  onPress = () => {
    this.props.navigation.goBackOnce();
  };
}

const styles = StyleSheet.create({
  media: {
    flex: 1,
    overflow: 'hidden',
  },
});

export default connect((state: AppState) => ({
  windowWidth: state.dimensions.width,
}))(withInputState(MultimediaTooltipButton));
<commit_msg>[native] Use hook instead of connect functions and HOC in MultimediaTooltipButton<commit_after>// @flow

import { mediaInfoPropType } from 'lib/types/media-types';
import {
  verticalBoundsPropType,
  layoutCoordinatesPropType,
} from '../types/layout-types';
import type { AppNavigationProp } from '../navigation/app-navigator.react';
import type { TooltipRoute } from '../navigation/tooltip.react';

import * as React from 'react';
import Animated from 'react-native-reanimated';
import PropTypes from 'prop-types';
import { View, StyleSheet } from 'react-native';
import { useSelector } from 'react-redux';

import { chatMessageItemPropType } from 'lib/selectors/chat-selectors';
import { messageID } from 'lib/shared/message-utils';

import {
  type InputState,
  inputStatePropType,
  InputStateContext,
} from '../input/input-state';
import InlineMultimedia from './inline-multimedia.react';
import { multimediaMessageBorderRadius } from './multimedia-message.react';
import { getRoundedContainerStyle } from './rounded-corners';
import { MessageHeader } from './message-header.react';

/* eslint-disable import/no-named-as-default-member */
const { Value } = Animated;
/* eslint-enable import/no-named-as-default-member */

type BaseProps = {
  +navigation: AppNavigationProp<'MultimediaTooltipModal'>,
  +route: TooltipRoute<'MultimediaTooltipModal'>,
  +progress: Value,
  ...
};
type Props = {
  ...BaseProps,
  // Redux state
  +windowWidth: number,
  // withInputState
  +inputState: ?InputState,
  ...
};
class MultimediaTooltipButton extends React.PureComponent<Props> {
  static propTypes = {
    navigation: PropTypes.shape({
      goBackOnce: PropTypes.func.isRequired,
    }).isRequired,
    route: PropTypes.shape({
      params: PropTypes.shape({
        initialCoordinates: layoutCoordinatesPropType.isRequired,
        verticalBounds: verticalBoundsPropType.isRequired,
        location: PropTypes.oneOf(['above', 'below']),
        margin: PropTypes.number,
        item: chatMessageItemPropType.isRequired,
        mediaInfo: mediaInfoPropType.isRequired,
        verticalOffset: PropTypes.number.isRequired,
      }).isRequired,
    }).isRequired,
    progress: PropTypes.object.isRequired,
    windowWidth: PropTypes.number.isRequired,
    inputState: inputStatePropType,
  };

  get headerStyle() {
    const { initialCoordinates, verticalOffset } = this.props.route.params;
    const bottom = initialCoordinates.height + verticalOffset;
    return {
      opacity: this.props.progress,
      position: 'absolute',
      left: -initialCoordinates.x,
      width: this.props.windowWidth,
      bottom,
    };
  }

  render() {
    const { inputState } = this.props;
    const { mediaInfo, item } = this.props.route.params;

    const { id: mediaID } = mediaInfo;
    const ourMessageID = messageID(item.messageInfo);
    const pendingUploads =
      inputState &&
      inputState.pendingUploads &&
      inputState.pendingUploads[ourMessageID];
    const pendingUpload = pendingUploads && pendingUploads[mediaID];
    const postInProgress = !!pendingUploads;

    const roundedStyle = getRoundedContainerStyle(
      mediaInfo.corners,
      multimediaMessageBorderRadius,
    );

    return (
      <React.Fragment>
        <Animated.View style={this.headerStyle}>
          <MessageHeader item={item} focused={true} display="modal" />
        </Animated.View>
        <View style={[styles.media, roundedStyle]}>
          <InlineMultimedia
            mediaInfo={mediaInfo}
            onPress={this.onPress}
            onLongPress={this.onPress}
            postInProgress={postInProgress}
            pendingUpload={pendingUpload}
            spinnerColor="white"
          />
        </View>
      </React.Fragment>
    );
  }

  onPress = () => {
    this.props.navigation.goBackOnce();
  };
}

const styles = StyleSheet.create({
  media: {
    flex: 1,
    overflow: 'hidden',
  },
});

export default React.memo<BaseProps>(function ConnectedMultimediaTooltipButton(
  props: BaseProps,
) {
  const windowWidth = useSelector(state => state.dimensions.width);
  const inputState = React.useContext(InputStateContext);
  return (
    <MultimediaTooltipButton
      {...props}
      windowWidth={windowWidth}
      inputState={inputState}
    />
  );
});
<|endoftext|>


<commit_before>function getVideoURI(dummy) {
  var bool=function(any){return!(any=="no"||!any)};
  return "../../../content/test." + (bool(document.createElement("video").canPlayType('video/ogg; codecs="theora"')) ? "ogv" : "mp4");
}

function getAudioURI(dummy) {
  return "../../../content/test.wav";
}

function testStep(testFunction){
  try {
    testFunction();
  } catch (e) {
    testFailed('Aborted with exception: ' + e.message);
  }
}

function test(testFunction) {
  description(document.title);
  testStep(testFunction);
}

function async_test(title, options) {
  window.jsTestIsAsync = true;
  description(title);
  return {
    step: testStep,
    done: finishJSTest
  }
}

document.write("

");
document.write("


<commit_before>Bokeh.$(function() {
  linkScript({'url':"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.3/js/bootstrap-select.min.js", 'type':'text/javascript', 'location':'body'});
  $('.plotdiv').each(function(index, element){
    var modelId = findModelID(element.id);
    var tableEl = $(element).find(".bk-data-table")[0];
    var dataTableView = findViewObject(tableEl, Bokeh.index[modelId]);
    var fields = getFieldNames(dataTableView.model.attributes.columns, $(element).data("sortingFields"));
    var dataSource = dataTableView.mget("source");

    $(element).prepend("<form class='column-filters' id="+ element.id +">
<button type='submit' class='btn btn-default'>Sort Data</button>
</form>")

    for (var i = 0; i < fields.length; i++){
      if (fields[i].field != 'name') {
        var optionsString = optionsConstructor(dataSource, fields[i].field)
        $("form#" + element.id + ".column-filters").append("<select class='selectpicker' data-style='btn-primary' multiple title='Sort by "+ fields[i].title +"' name=" + fields[i].field + ">"+ optionsString+"</select>")
      };
    }
  })

  $("form.column-filters").submit(function(e){
    e.preventDefault();
    var options = $(e.target).find("select");
    var workingFilters = [];
    for(var i = 0; i < options.length; i++){
      if(options[i].type !== 'submit' && options[i].selectedOptions[0].value !== ""){
        workingFilters.push({name: options[i].name, value: options[i].selectedOptions[0].value})
      }
    }
    var modelId = findModelID(this.id);
    var dataTableView = findViewObject($(document.getElementById(this.id)).find(".bk-data-table")[0], Bokeh.index[modelId])
    var dataSource = dataTableView.mget("source")
    var columns = dataSource.attributes.data
    var rows = []
    var rowsToSelect = applyValueFilter(workingFilters, columns, rows)

    dataTableView.grid.setSelectedRows(rowsToSelect)
    selectionShift(dataTableView)
  })

  $(".plotdiv").on('click', ".bk-ui-state-default.bk-slick-header-column.bk-ui-sortable-handle", function(e){
    if (this.id.match(/slickgrid_\d+_checkbox_selector/) != null) {
      var columnData = $(this).data("column")
      var parentId = $(this).closest(".plotdiv").get(0).id
      var modelid = findModelID(parentId)
      var dataTableView = findViewObject(tableElement(this), Bokeh.index[modelid])
      selectionShift(dataTableView);
    }
  })
})
var findModelID = function(parentId){
  return $.grep(Object.keys(Bokeh.index), function(k){
    return Bokeh.index[k].el.id === parentId
  })
}
// Used to recursively search Bokeh.index
var findViewObject = function(el, currentNode){
  if (el == currentNode.el ) {
    return currentNode;
  }
  else {
    for(key in currentNode.views){
      currentChild = currentNode.views[key]
      result = findViewObject(el, currentChild);
      if (result !== false){
        return result
      }
    }
    return false;
  }
}
// Grabs the top level parent element of the datatable in the DOM
var tableElement = function(el){
  var result;
  $(el).parents().each(function(i){
    if(this.classList.contains("bk-data-table")){
      result = this
    }
  })
  return result
}

var selectionShift = function(view){

  var selectedRowIndices = view.grid.getSelectedRows()
  var data = view.data.getRecords()

  var rowsToShift = collectRowsToShift(data, selectedRowIndices)

  spliceOutRows(data, rowsToShift);

  for(i = 0; i < rowsToShift.length; i++){
    data.unshift(rowsToShift[i])
  }
  updateData(view, data, selectedRowIndices)
}

var collectRowsToShift = function(data, selectedRowIndices){
  var result = []
  for(i = 0; i < selectedRowIndices.length; i++){
    result.push(data.slice(selectedRowIndices[i], (selectedRowIndices[i] + 1))[0])
  }
  return result;
}

var spliceOutRows = function(data, rowsToSplice){
  var attributeMatcher = $(".plotdiv").data().sortingMatcher
  for(i = 0; i < rowsToSplice.length; i++){
    for(j = 0; j < data.length; j++){
      if(data[j][attributeMatcher] === rowsToSplice[i][attributeMatcher]){
        data.splice(j, 1)
      }
    }
  }
}

var updateData = function(view, data, selectedRowIndices){
  for(i = 0; i < data.length; i++){
    view.data._setItem(i, data[i])
  }
  var updateSel = []
  for(i=0; i < selectedRowIndices.length; i++){
    updateSel.push(i)
  }
  view.data.updateSource()
  view.grid.setSelectedRows(updateSel)
}

var applyValueFilter = function(workingFilters, columns, rows){
  if(workingFilters.length === 0){
    return rows;
  }
  else{
    var filterToApply = workingFilters.pop()
    var column = columns[filterToApply.name]
    if (rows.length > 0) {
      var newRows = []
      for(var j = 0; j < rows.length; j++){
        if(column[rows[j]] == filterToApply.value){
          newRows.push(rows.slice(j,j+1)[0])
        }
      }
      rows = newRows
    }
    else {
      for(var j = 0; j < column.length; j++){
        if(column[j] == filterToApply.value){
          rows.push(j)
        }
      }
    }
    return applyValueFilter(workingFilters, columns, rows);
  }
}

var rowsIndices = function(array){
  var result = []
  for(var i = 0; i < array.length; i++){
    result.push(i)
  }
  return result
}

var getFieldNames = function(columns, sortingFields){
  var result = []
  for(var j = 0; j < sortingFields.length; j++){
    for(var i = 0; i < columns.length; i++){
      var columnData = Bokeh.Collections("TableColumn").get(columns[i].id)
      if (columnData.attributes.field == sortingFields[j]) {
      result.push({field : columnData.attributes.field, title : columnData.attributes.title})
      };
    }
  }
  return result
}

var optionsConstructor = function(source, fieldName){
  var result = "<option value=''></option>";
  var elements = getUniqueElements(source.attributes.data[fieldName])
  for(var i = 0; i < elements.length; i++){
    result += "<option value='"+ elements[i].toString() +"'>" + elements[i] + "</option>"
  }
  return result
}

var getUniqueElements = function(array){
  var u = {}, a = [];
     for(var i = 0; i < array.length; ++i){
        if(u.hasOwnProperty(array[i])) {
           continue;
        }
        a.push(array[i]);
        u[array[i]] = 1;
     }
     return a;
}

var linkScript = function(args){
  var script = document.createElement('script');
  script.type = args.type;
  script.src = args.url
  $(args.location).append(script);
}<commit_msg>creates filters with array of values<commit_after>Bokeh.$(function() {
  linkScript({'url':"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.3/js/bootstrap-select.min.js", 'type':'text/javascript', 'location':'body'});
  $('.plotdiv').each(function(index, element){
    var modelId = findModelID(element.id);
    var tableEl = $(element).find(".bk-data-table")[0];
    var dataTableView = findViewObject(tableEl, Bokeh.index[modelId]);
    var fields = getFieldNames(dataTableView.model.attributes.columns, $(element).data("sortingFields"));
    var dataSource = dataTableView.mget("source");

    $(element).prepend("<form class='column-filters' id="+ element.id +">
<button type='submit' class='btn btn-default'>Sort Data</button>
</form>")

    for (var i = 0; i < fields.length; i++){
      if (fields[i].field != 'name') {
        var optionsString = optionsConstructor(dataSource, fields[i].field)
        $("form#" + element.id + ".column-filters").append("<select class='selectpicker' data-style='btn-primary' multiple title='Sort by "+ fields[i].title +"' name=" + fields[i].field + ">"+ optionsString+"</select>")
      };
    }
  })

  $("form.column-filters").submit(function(e){
    e.preventDefault();
    var options = $(e.target).find("select");
    var workingFilters = [];
    for(var i = 0; i < options.length; i++){
      if(options[i].type !== 'submit' && options[i].selectedOptions.length > 0){
        var filterValues = $(options[i].selectedOptions).map(function(i, e){return e.value})
        workingFilters.push({name: options[i].name, values: filterValues })
      }
    }
    var modelId = findModelID(this.id);
    var dataTableView = findViewObject($(document.getElementById(this.id)).find(".bk-data-table")[0], Bokeh.index[modelId])
    var dataSource = dataTableView.mget("source")
    var columns = dataSource.attributes.data
    var rows = []
    var rowsToSelect = applyValueFilter(workingFilters, columns, rows)

    dataTableView.grid.setSelectedRows(rowsToSelect)
    selectionShift(dataTableView)
  })

  $(".plotdiv").on('click', ".bk-ui-state-default.bk-slick-header-column.bk-ui-sortable-handle", function(e){
    if (this.id.match(/slickgrid_\d+_checkbox_selector/) != null) {
      var columnData = $(this).data("column")
      var parentId = $(this).closest(".plotdiv").get(0).id
      var modelid = findModelID(parentId)
      var dataTableView = findViewObject(tableElement(this), Bokeh.index[modelid])
      selectionShift(dataTableView);
    }
  })
})
var findModelID = function(parentId){
  return $.grep(Object.keys(Bokeh.index), function(k){
    return Bokeh.index[k].el.id === parentId
  })
}
// Used to recursively search Bokeh.index
var findViewObject = function(el, currentNode){
  if (el == currentNode.el ) {
    return currentNode;
  }
  else {
    for(key in currentNode.views){
      currentChild = currentNode.views[key]
      result = findViewObject(el, currentChild);
      if (result !== false){
        return result
      }
    }
    return false;
  }
}
// Grabs the top level parent element of the datatable in the DOM
var tableElement = function(el){
  var result;
  $(el).parents().each(function(i){
    if(this.classList.contains("bk-data-table")){
      result = this
    }
  })
  return result
}

var selectionShift = function(view){

  var selectedRowIndices = view.grid.getSelectedRows()
  var data = view.data.getRecords()

  var rowsToShift = collectRowsToShift(data, selectedRowIndices)

  spliceOutRows(data, rowsToShift);

  for(i = 0; i < rowsToShift.length; i++){
    data.unshift(rowsToShift[i])
  }
  updateData(view, data, selectedRowIndices)
}

var collectRowsToShift = function(data, selectedRowIndices){
  var result = []
  for(i = 0; i < selectedRowIndices.length; i++){
    result.push(data.slice(selectedRowIndices[i], (selectedRowIndices[i] + 1))[0])
  }
  return result;
}

var spliceOutRows = function(data, rowsToSplice){
  var attributeMatcher = $(".plotdiv").data().sortingMatcher
  for(i = 0; i < rowsToSplice.length; i++){
    for(j = 0; j < data.length; j++){
      if(data[j][attributeMatcher] === rowsToSplice[i][attributeMatcher]){
        data.splice(j, 1)
      }
    }
  }
}

var updateData = function(view, data, selectedRowIndices){
  for(i = 0; i < data.length; i++){
    view.data._setItem(i, data[i])
  }
  var updateSel = []
  for(i=0; i < selectedRowIndices.length; i++){
    updateSel.push(i)
  }
  view.data.updateSource()
  view.grid.setSelectedRows(updateSel)
}

var applyValueFilter = function(workingFilters, columns, rows){
  if(workingFilters.length === 0){
    return rows;
  }
  else{
    var filterToApply = workingFilters.pop()
    var column = columns[filterToApply.name]
    if (rows.length > 0) {
      var newRows = []
      for(var j = 0; j < rows.length; j++){
        if(column[rows[j]] == filterToApply.value){
          newRows.push(rows.slice(j,j+1)[0])
        }
      }
      rows = newRows
    }
    else {
      for(var j = 0; j < column.length; j++){
        if(column[j] == filterToApply.value){
          rows.push(j)
        }
      }
    }
    return applyValueFilter(workingFilters, columns, rows);
  }
}

var rowsIndices = function(array){
  var result = []
  for(var i = 0; i < array.length; i++){
    result.push(i)
  }
  return result
}

var getFieldNames = function(columns, sortingFields){
  var result = []
  for(var j = 0; j < sortingFields.length; j++){
    for(var i = 0; i < columns.length; i++){
      var columnData = Bokeh.Collections("TableColumn").get(columns[i].id)
      if (columnData.attributes.field == sortingFields[j]) {
      result.push({field : columnData.attributes.field, title : columnData.attributes.title})
      };
    }
  }
  return result
}

var optionsConstructor = function(source, fieldName){
  var result = "<option value=''></option>";
  var elements = getUniqueElements(source.attributes.data[fieldName])
  for(var i = 0; i < elements.length; i++){
    result += "<option value='"+ elements[i].toString() +"'>" + elements[i] + "</option>"
  }
  return result
}

var getUniqueElements = function(array){
  var u = {}, a = [];
     for(var i = 0; i < array.length; ++i){
        if(u.hasOwnProperty(array[i])) {
           continue;
        }
        a.push(array[i]);
        u[array[i]] = 1;
     }
     return a;
}

var linkScript = function(args){
  var script = document.createElement('script');
  script.type = args.type;
  script.src = args.url
  $(args.location).append(script);
}<|endoftext|>


<commit_before>window.addEvent('domready', function() {
    //setup rounded rectangles
    template.doRoundedBoxes('rounded');
    template.doRoundedBoxes('error');
    template.doRoundedBoxes('success');

    //setup closeable boxes
    template.doCloseableBoxes();

    //setup forms
    template.doForms();
});

var template = {
    doForms: function() {
        $$('form.jsForm').each(function(form) {
            // Prepare form inputs to hold error messages for invalid input
            form.getElements('[type=text], [type=password], textarea').each(function(el) {
                var id = el.get('id') + '_error_msg'
                var dd_error = new Element('dd', {
                    id: id,
                    'class': 'error',
                });
                el.set('class', el.get('class') + " msgPos:'" + id + "'");
                dd_error.inject(el.getParent('dd'), 'after');
            });

            new Form.Validator.Inline(form);
        });

        //theme inputs (only in ff2+ ie7+ chrome safari3 etc)
        if ((Browser.ie && Browser.version >= 6) || Browser.chrome || Browser.safari || Browser.opera || (Browser.gecko && Browser.version >= 18)) {
            $$('input[type=text],input[type=password],textarea,select').each(function(element) {
                //contain the input
                var container = new Element('div',{'style':'display:inline-block;'}).wraps(element);

                //theme the input
                template.roundSingleElement('Input',container);

                //add focus events
                element.addEvents({
                    'focus': function() {
                        container.addClass('skinInputFocusedBox');
                    },
                    'blur': function() {
                        container.removeClass('skinInputFocusedBox');
                    }
                });
            });
        }
    },

    doRoundedBoxes: function(type) {
        //add rounded theme to boxes
        type = type.capitalize();

        $$('.js'+type+'Box').each(function(element) {
            template.roundSingleElement(type,element);
        })
    },

    doCloseableBoxes: function() {
        //add close button to boxes
        $$('.jsCloseableBox').each(function(element) {
            element.addClass('skinCloseIconOff').addEvents({
                'mouseenter':function() {
                    element.removeClass('skinCloseIconOff').addClass('skinCloseIconOn');
                },
                'mouseleave':function() {
                    element.removeClass('skinCloseIconOn').addClass('skinCloseIconOff');
                },
                'click': function() {
                    var fx = new Fx.Tween(element);

                    if (Browser.ie) {
                        //internet explorer
                        if (Browser.version <= 4) {
                            //ie6
                            element.destroy();
                        } else {
                            //newer
                            element.setStyle('overflow','hidden');
                            fx.start('height', '0').chain(function() {
                                element.destroy();
                            });
                        }
                    } else {
                        //others (good browsers)
                        fx.start('opacity', '0').chain(function() {
                            this.start('height', '0')
                        }).chain(function() {
                            element.destroy();
                        });
                    }
                }
            })
        });
    },

    roundSingleElement: function(type,element) {
        element.removeClass('js'+type+'Box');
        var row1 = new Element('div', {'class': 'skin'+type+'Row1'}).adopt(
            new Element('div', {'class': 'skin'+type+'TopLeft'}),
            new Element('div', {'class': 'skin'+type+'TopRight'}),
            new Element('div', {'class': 'skin'+type+'Top'})
        );
        var row2 = new Element('div', {'class': 'skin'+type+'Row2'}).adopt(
            new Element('div',{'class':'skin'+type+'Content'}).adopt(element.childNodes)
        );
        var row3 = Element('div', {'class': 'skin'+type+'Row3'}).adopt(
            new Element('div', {'class': 'skin'+type+'BottomLeft'}),
            new Element('div', {'class': 'skin'+type+'BottomRight'}),
            new Element('div', {'class': 'skin'+type+'Bottom'})
        );
        element.empty().addClass('skin'+type+'Box').adopt(row1,row2,row3);
    }
};

<commit_msg>Also add error message element for select inputs<commit_after>window.addEvent('domready', function() {
    //setup rounded rectangles
    template.doRoundedBoxes('rounded');
    template.doRoundedBoxes('error');
    template.doRoundedBoxes('success');

    //setup closeable boxes
    template.doCloseableBoxes();

    //setup forms
    template.doForms();
});

var template = {
    doForms: function() {
        $$('form.jsForm').each(function(form) {
            // Prepare form inputs to hold error messages for invalid input
            form.getElements('[type=text], [type=password], textarea, select').each(function(el) {
                var id = el.get('id') + '_error_msg'
                var dd_error = new Element('dd', {
                    id: id,
                    'class': 'error',
                });
                el.set('class', el.get('class') + " msgPos:'" + id + "'");
                dd_error.inject(el.getParent('dd'), 'after');
            });

            new Form.Validator.Inline(form);
        });

        //theme inputs (only in ff2+ ie7+ chrome safari3 etc)
        if ((Browser.ie && Browser.version >= 6) || Browser.chrome || Browser.safari || Browser.opera || (Browser.gecko && Browser.version >= 18)) {
            $$('input[type=text],input[type=password],textarea,select').each(function(element) {
                //contain the input
                var container = new Element('div',{'style':'display:inline-block;'}).wraps(element);

                //theme the input
                template.roundSingleElement('Input',container);

                //add focus events
                element.addEvents({
                    'focus': function() {
                        container.addClass('skinInputFocusedBox');
                    },
                    'blur': function() {
                        container.removeClass('skinInputFocusedBox');
                    }
                });
            });
        }
    },

    doRoundedBoxes: function(type) {
        //add rounded theme to boxes
        type = type.capitalize();

        $$('.js'+type+'Box').each(function(element) {
            template.roundSingleElement(type,element);
        })
    },

    doCloseableBoxes: function() {
        //add close button to boxes
        $$('.jsCloseableBox').each(function(element) {
            element.addClass('skinCloseIconOff').addEvents({
                'mouseenter':function() {
                    element.removeClass('skinCloseIconOff').addClass('skinCloseIconOn');
                },
                'mouseleave':function() {
                    element.removeClass('skinCloseIconOn').addClass('skinCloseIconOff');
                },
                'click': function() {
                    var fx = new Fx.Tween(element);

                    if (Browser.ie) {
                        //internet explorer
                        if (Browser.version <= 4) {
                            //ie6
                            element.destroy();
                        } else {
                            //newer
                            element.setStyle('overflow','hidden');
                            fx.start('height', '0').chain(function() {
                                element.destroy();
                            });
                        }
                    } else {
                        //others (good browsers)
                        fx.start('opacity', '0').chain(function() {
                            this.start('height', '0')
                        }).chain(function() {
                            element.destroy();
                        });
                    }
                }
            })
        });
    },

    roundSingleElement: function(type,element) {
        element.removeClass('js'+type+'Box');
        var row1 = new Element('div', {'class': 'skin'+type+'Row1'}).adopt(
            new Element('div', {'class': 'skin'+type+'TopLeft'}),
            new Element('div', {'class': 'skin'+type+'TopRight'}),
            new Element('div', {'class': 'skin'+type+'Top'})
        );
        var row2 = new Element('div', {'class': 'skin'+type+'Row2'}).adopt(
            new Element('div',{'class':'skin'+type+'Content'}).adopt(element.childNodes)
        );
        var row3 = Element('div', {'class': 'skin'+type+'Row3'}).adopt(
            new Element('div', {'class': 'skin'+type+'BottomLeft'}),
            new Element('div', {'class': 'skin'+type+'BottomRight'}),
            new Element('div', {'class': 'skin'+type+'Bottom'})
        );
        element.empty().addClass('skin'+type+'Box').adopt(row1,row2,row3);
    }
};

<|endoftext|>


<commit_before>Date.CultureInfo = {
	/* Culture Name */
    name: "ar-QA",
    englishName: "Arabic (Qatar)",
    nativeName: "العربية (قطر)",

    /* Day Name Strings */
    dayNames: ["الأحد", "الإثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت"],
    abbreviatedDayNames: ["أحد", "إثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت"],
    shortestDayNames: ["حد", "ثن", "ثل", "رع", "خم", "جم", "سب"],
    firstLetterDayNames: ["ح", "ن", "ث", "ر", "خ", "ج", "س"],

    /* Month Name Strings */
    monthNames: ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"],
    abbreviatedMonthNames: ["ينا", "فبر", "مار", "أبر", "ماي", "يون", "يول", "أغس", "سبت", "أكت", "نوف", "ديس"],

	/* AM/PM Designators */
    amDesignator: "ص",
    pmDesignator: "م",

    firstDayOfWeek: 6,
    twoDigitYearMax: 2029,

    /**
     * The dateElementOrder is based on the order of the
     * format specifiers in the formatPatterns.DatePattern.
     *
     * Example:

     shortDatePattern    dateElementOrder
     ------------------  ----------------
     "M/d/yyyy"          "mdy"
     "dd/MM/yyyy"        "dmy"
     "yyyy-MM-dd"        "ymd"

     *
     * The correct dateElementOrder is required by the parser to
     * determine the expected order of the date elements in the
     * string being parsed.
     */
    dateElementOrder: "dmy",

    /* Standard date and time format patterns */
    formatPatterns: {
        shortDate: "dd/MM/yy",
        longDate: "dd/MMMM/yyyy",
        shortTime: "hh:mm tt",
        longTime: "hh:mm:ss tt",
        fullDateTime: "dd/MMMM/yyyy hh:mm:ss tt",
        sortableDateTime: "yyyy-MM-ddTHH:mm:ss",
        universalSortableDateTime: "yyyy-MM-dd HH:mm:ssZ",
        rfc1123: "ddd, dd MMM yyyy HH:mm:ss GMT",
        monthDay: "dd MMMM",
        yearMonth: "MMMM, yyyy"
    },

    /**
     * NOTE: If a string format is not parsing correctly, but
     * you would expect it parse, the problem likely lies below.
     *
     * The following regex patterns control most of the string matching
     * within the parser.
     *
     * The Month name and Day name patterns were automatically generated
     * and in general should be (mostly) correct.
     *
     * Beyond the month and day name patterns are natural language strings.
     * Example: "next", "today", "months"
     *
     * These natural language string may NOT be correct for this culture.
     * If they are not correct, please translate and edit this file
     * providing the correct regular expression pattern.
     *
     * If you modify this file, please post your revised CultureInfo file
     * to the Datejs Forum located at http://www.datejs.com/forums/.
     *
     * Please mark the subject of the post with [CultureInfo]. Example:
     *    Subject: [CultureInfo] Translated "da-DK" Danish(Denmark)
     *
     * We will add the modified patterns to the master source files.
     *
     * As well, please review the list of "Future Strings" section below.
     */
    regexPatterns: {
        jan: /^يناير/i,
        feb: /^فبراير/i,
        mar: /^مارس/i,
        apr: /^أبريل/i,
        may: /^مايو/i,
        jun: /^يونيو/i,
        jul: /^يوليو/i,
        aug: /^أغسطس/i,
        sep: /^سبتمبر/i,
        oct: /^أكتوبر/i,
        nov: /^نوفمبر/i,
        dec: /^ديسمبر/i,

        sun: /^الأحد/i,
        mon: /^الإثنين/i,
        tue: /^الثلاثاء/i,
        wed: /^الأربعاء/i,
        thu: /^الخميس/i,
        fri: /^الجمعة/i,
        sat: /^السبت/i,

        future: /^القادم/i,
        past: /^الماضي/i,
        add: /^(\+|بعد|عقب)/i,
        subtract: /^(\-|قبل|منذ)/i,

        yesterday: /^((ال)?(ا|أ)مس|(ال)?بارح(ة)?)/i,
        today: /^اليوم/i,
        tomorrow: /^(الغد|غد(ا)?)/i,
        now: /^(ال)?آن/i,

        millisecond: /^(ال)?ج(زء(ا))?( من( ال(أ|ا)لف من)? |( )?.( )?)(ال)?ث(انية)?(.)?/i,
	second: /^(ال)?ث(انية|وان(ي)?)?(.)?/i,
	minute: /^(ال)?د(قيقة|قائق)?(.)?/i,
	hour: /^(ال)?س(اعة|اعات)?(.)?/i,
	week: /^(ال)?(إ|ا)س(بوع|ابيع)/i,
	month: /^(ال)?((أ|ا)?شهر|شهور)/i,
	day: /(ال)?(يوم|أيام)/i,
	year: /^(ال)?سن(ة|ين|ون|وات)/i,

	shortMeridian: /^(ص|م)/i,
	longMeridian: /^(صباح(ا)?|مساء(ا)?)/i,
	timezone: /^(((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt|utc|((ب(ال)?)?توقيت )?(مكة( المكرمة)?|(دولة )?قطر|الدوحة|العرب(ي)?( القياسي)?|ast|arabia( standard)? tim(e|ing)))/i,
        ordinalSuffix: /^\s*(st|nd|rd|th)/i,
        timeContext: /^\s*(\:|a(?!u|p)|p)/i
    },

	timezones: [{name:"UTC", offset:"-000"}, {name:"GMT", offset:"-000"}, {name:"AST", offset:"+0300"}]
};

/********************
 ** Future Strings **
 ********************
 *
 * The following list of strings may not be currently being used, but
 * may be incorporated into the Datejs library later.
 *
 * We would appreciate any help translating the strings below.
 *
 * If you modify this file, please post your revised CultureInfo file
 * to the Datejs Forum located at http://www.datejs.com/forums/.
 *
 * Please mark the subject of the post with [CultureInfo]. Example:
 *    Subject: [CultureInfo] Translated "da-DK" Danish(Denmark)b
 *
 * English Name        Translated
 * ------------------  -----------------
 * about               قرابة
 * ago                 مضت
 * date                التاريخ
 * time                الوقت
 * calendar            التقويم
 * show                اظهار
 * hourly              كل ساعة
 * daily               يومياً
 * weekly              اسبوعياً
 * bi-weekly           مرتين بالإسبوع
 * fortnight           اسبوعان
 * monthly             شهرياً
 * bi-monthly          مرتين بالشهر
 * quarter             ربع
 * quarterly           كل ربع سنة
 * yearly              سنوياً
 * annual              سنوي
 * annually            سنوياً
 * annum               عام
 * again               مرة أخرى
 * between             بين
 * after               بعد
 * from now            من الآن
 * repeat              كرر
 * times               مرات
 * per                 كل
 * min (abbrev minute) د.
 * morning             صباح
 * noon                ظهيرة
 * night               ليل
 * midnight            نصف الليل
 * mid-night           نصف الليل
 * evening             مساء
 * final               ختامي
 * future              مستقبل
 * spring              ربيع
 * summer              صيف
 * fall                خريف
 * winter              شتاء
 * end of              نهاية
 * end                 نهاية
 * long                طويل
 * short               قصير
 */
<commit_msg>fixed firstDayOfWeek<commit_after>Date.CultureInfo = {
	/* Culture Name */
    name: "ar-QA",
    englishName: "Arabic (Qatar)",
    nativeName: "العربية (قطر)",

    /* Day Name Strings */
    dayNames: ["الأحد", "الإثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت"],
    abbreviatedDayNames: ["أحد", "إثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت"],
    shortestDayNames: ["حد", "ثن", "ثل", "رع", "خم", "جم", "سب"],
    firstLetterDayNames: ["ح", "ن", "ث", "ر", "خ", "ج", "س"],

    /* Month Name Strings */
    monthNames: ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"],
    abbreviatedMonthNames: ["ينا", "فبر", "مار", "أبر", "ماي", "يون", "يول", "أغس", "سبت", "أكت", "نوف", "ديس"],

	/* AM/PM Designators */
    amDesignator: "ص",
    pmDesignator: "م",

    firstDayOfWeek: 7,
    twoDigitYearMax: 2029,

    /**
     * The dateElementOrder is based on the order of the
     * format specifiers in the formatPatterns.DatePattern.
     *
     * Example:

     shortDatePattern    dateElementOrder
     ------------------  ----------------
     "M/d/yyyy"          "mdy"
     "dd/MM/yyyy"        "dmy"
     "yyyy-MM-dd"        "ymd"

     *
     * The correct dateElementOrder is required by the parser to
     * determine the expected order of the date elements in the
     * string being parsed.
     */
    dateElementOrder: "dmy",

    /* Standard date and time format patterns */
    formatPatterns: {
        shortDate: "dd/MM/yy",
        longDate: "dd/MMMM/yyyy",
        shortTime: "hh:mm tt",
        longTime: "hh:mm:ss tt",
        fullDateTime: "dd/MMMM/yyyy hh:mm:ss tt",
        sortableDateTime: "yyyy-MM-ddTHH:mm:ss",
        universalSortableDateTime: "yyyy-MM-dd HH:mm:ssZ",
        rfc1123: "ddd, dd MMM yyyy HH:mm:ss GMT",
        monthDay: "dd MMMM",
        yearMonth: "MMMM, yyyy"
    },

    /**
     * NOTE: If a string format is not parsing correctly, but
     * you would expect it parse, the problem likely lies below.
     *
     * The following regex patterns control most of the string matching
     * within the parser.
     *
     * The Month name and Day name patterns were automatically generated
     * and in general should be (mostly) correct.
     *
     * Beyond the month and day name patterns are natural language strings.
     * Example: "next", "today", "months"
     *
     * These natural language string may NOT be correct for this culture.
     * If they are not correct, please translate and edit this file
     * providing the correct regular expression pattern.
     *
     * If you modify this file, please post your revised CultureInfo file
     * to the Datejs Forum located at http://www.datejs.com/forums/.
     *
     * Please mark the subject of the post with [CultureInfo]. Example:
     *    Subject: [CultureInfo] Translated "da-DK" Danish(Denmark)
     *
     * We will add the modified patterns to the master source files.
     *
     * As well, please review the list of "Future Strings" section below.
     */
    regexPatterns: {
        jan: /^يناير/i,
        feb: /^فبراير/i,
        mar: /^مارس/i,
        apr: /^أبريل/i,
        may: /^مايو/i,
        jun: /^يونيو/i,
        jul: /^يوليو/i,
        aug: /^أغسطس/i,
        sep: /^سبتمبر/i,
        oct: /^أكتوبر/i,
        nov: /^نوفمبر/i,
        dec: /^ديسمبر/i,

        sun: /^الأحد/i,
        mon: /^الإثنين/i,
        tue: /^الثلاثاء/i,
        wed: /^الأربعاء/i,
        thu: /^الخميس/i,
        fri: /^الجمعة/i,
        sat: /^السبت/i,

        future: /^القادم/i,
        past: /^الماضي/i,
        add: /^(\+|بعد|عقب)/i,
        subtract: /^(\-|قبل|منذ)/i,

        yesterday: /^((ال)?(ا|أ)مس|(ال)?بارح(ة)?)/i,
        today: /^اليوم/i,
        tomorrow: /^(الغد|غد(ا)?)/i,
        now: /^(ال)?آن/i,

        millisecond: /^(ال)?ج(زء(ا))?( من( ال(أ|ا)لف من)? |( )?.( )?)(ال)?ث(انية)?(.)?/i,
	second: /^(ال)?ث(انية|وان(ي)?)?(.)?/i,
	minute: /^(ال)?د(قيقة|قائق)?(.)?/i,
	hour: /^(ال)?س(اعة|اعات)?(.)?/i,
	week: /^(ال)?(إ|ا)س(بوع|ابيع)/i,
	month: /^(ال)?((أ|ا)?شهر|شهور)/i,
	day: /(ال)?(يوم|أيام)/i,
	year: /^(ال)?سن(ة|ين|ون|وات)/i,

	shortMeridian: /^(ص|م)/i,
	longMeridian: /^(صباح(ا)?|مساء(ا)?)/i,
	timezone: /^(((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt|utc|((ب(ال)?)?توقيت )?(مكة( المكرمة)?|(دولة )?قطر|الدوحة|العرب(ي)?( القياسي)?|ast|arabia( standard)? tim(e|ing)))/i,
        ordinalSuffix: /^\s*(st|nd|rd|th)/i,
        timeContext: /^\s*(\:|a(?!u|p)|p)/i
    },

	timezones: [{name:"UTC", offset:"-000"}, {name:"GMT", offset:"-000"}, {name:"AST", offset:"+0300"}]
};

/********************
 ** Future Strings **
 ********************
 *
 * The following list of strings may not be currently being used, but
 * may be incorporated into the Datejs library later.
 *
 * We would appreciate any help translating the strings below.
 *
 * If you modify this file, please post your revised CultureInfo file
 * to the Datejs Forum located at http://www.datejs.com/forums/.
 *
 * Please mark the subject of the post with [CultureInfo]. Example:
 *    Subject: [CultureInfo] Translated "da-DK" Danish(Denmark)b
 *
 * English Name        Translated
 * ------------------  -----------------
 * about               قرابة
 * ago                 مضت
 * date                التاريخ
 * time                الوقت
 * calendar            التقويم
 * show                اظهار
 * hourly              كل ساعة
 * daily               يومياً
 * weekly              اسبوعياً
 * bi-weekly           مرتين بالإسبوع
 * fortnight           اسبوعان
 * monthly             شهرياً
 * bi-monthly          مرتين بالشهر
 * quarter             ربع
 * quarterly           كل ربع سنة
 * yearly              سنوياً
 * annual              سنوي
 * annually            سنوياً
 * annum               عام
 * again               مرة أخرى
 * between             بين
 * after               بعد
 * from now            من الآن
 * repeat              كرر
 * times               مرات
 * per                 كل
 * min (abbrev minute) د.
 * morning             صباح
 * noon                ظهيرة
 * night               ليل
 * midnight            نصف الليل
 * mid-night           نصف الليل
 * evening             مساء
 * final               ختامي
 * future              مستقبل
 * spring              ربيع
 * summer              صيف
 * fall                خريف
 * winter              شتاء
 * end of              نهاية
 * end                 نهاية
 * long                طويل
 * short               قصير
 */
<|endoftext|>


<commit_before>var fs = require('fs');
var selectors;

function writeIconCSS() {
        fs.appendFile('config/custom.css', selectors);
}

exports.commands = {
        ccset: function (target, room, user) {
		if (user.userids !== 'lmaoitsbt','chaotic','opvictreebel','wndo') return this.errorReply('/ccset - PM BT to set your custom color.');
                var args = target.split(',');
                if (args.length < 2) return this.errorReply('/ccset [username], [color] - Sets an custom color to a user for all rooms.');
                var username = toId(args.shift());
                var image = 'color:' + args.shift().trim() + '';
                selectors = '\n\n' + '.chat.chatmessage-' + username +   '  strong';
                selectors += ' { \n' + '    ' + image +  ' !important;\n  }';

                this.privateModCommand("(" + user.name + " has set an custom color to " + username + ")");
                writeIconCSS();
        },
        setcchelp: ["/ccset [username], [color] - Sets an custom color to a user for all rooms."]
};
<commit_msg>Update cc.js<commit_after>var fs = require('fs');
var selectors;

function writeIconCSS() {
        fs.appendFile('config/custom.css', selectors);
}

exports.commands = {
        ccset: function (target, room, user) {
		if (user.userid !== 'wndo') return this.errorReply('/ccset - PM Wando to set your custom color.');
                var args = target.split(',');
                if (args.length < 2) return this.errorReply('/ccset [username], [color] - Sets an custom color to a user for all rooms.');
                var username = toId(args.shift());
                var image = 'color:' + args.shift().trim() + '';
                selectors = '\n\n' + '.chat.chatmessage-' + username +   '  strong';
                selectors += ' { \n' + '    ' + image +  ' !important;\n  }';

                this.privateModCommand("(" + user.name + " has set an custom color to " + username + ")");
                writeIconCSS();
        },
        setcchelp: ["/ccset [username], [color] - Sets an custom color to a user for all rooms."]
};
<|endoftext|>


<commit_before>Bokeh.$(function() {
  linkScript({'url':"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.3/js/bootstrap-select.min.js", 'type':'text/javascript', 'location':'body'});
  $('body').append(noRecordsModal)
  $('.plotdiv').each(function(index, element){
    var modelId = findModelID(element.id);
    var tableEl = $(element).find(".bk-data-table")[0];
    var dataTableView = findViewObject(tableEl, Bokeh.index[modelId]);
    var fields = getFieldNames(dataTableView.model.attributes.columns, $(element).data("sortingFields"));
    var dataSource = dataTableView.mget("source");

    $(element).prepend("<form class='column-filters' id="+ element.id +">
<button type='submit' class='btn btn-xs btn-warning'>Select Data</button>
</form>")

    for (var i = 0; i < fields.length; i++){
      if (fields[i].field != 'name') {
        var optionsString = optionsConstructor(dataSource, fields[i].field)
        $("form#" + element.id + ".column-filters").append("<select class='selectpicker' data-width='100px' data-style='btn-xs' multiple title='"+ fields[i].title +"' name=" + fields[i].field + ">"+ optionsString+"</select>")
      };
    }
  })

  $("form.column-filters").submit(function(e){
    e.preventDefault();
    var options = $(e.target).find("select");
    var workingFilters = [];
    for(var i = 0; i < options.length; i++){
      if(options[i].type !== 'submit' && options[i].selectedOptions.length > 0){
        var filterValues = $(options[i].selectedOptions).map(function(i, e){return e.value})
        workingFilters.push({name: options[i].name, values: filterValues })
      }
    }
    var modelId = findModelID(this.id);
    var dataTableView = findViewObject($(document.getElementById(this.id)).find(".bk-data-table")[0], Bokeh.index[modelId])
    var dataSource = dataTableView.mget("source")
    var columns = dataSource.attributes.data
    var rows = []
    var rowsToSelect = applyValueFilter(workingFilters, columns, rows)
    if(rowsToSelect.length === 0){
      $('#no-records-modal').modal('show')
    }
    else{
      dataTableView.grid.setSelectedRows(rowsToSelect)
      selectionShift(dataTableView)
    }
  })

  $(".plotdiv").on('click', ".bk-ui-state-default.bk-slick-header-column.bk-ui-sortable-handle", function(e){
    if (this.id.match(/slickgrid_\d+_checkbox_selector/) != null) {
      var columnData = $(this).data("column")
      var parentId = $(this).closest(".plotdiv").get(0).id
      var modelid = findModelID(parentId)
      var dataTableView = findViewObject(tableElement(this), Bokeh.index[modelid])
      selectionShift(dataTableView);
    }
  })
})
var findModelID = function(parentId){
  return $.grep(Object.keys(Bokeh.index), function(k){
    return Bokeh.index[k].el.id === parentId
  })
}
// Used to recursively search Bokeh.index
var findViewObject = function(el, currentNode){
  if (el == currentNode.el ) {
    return currentNode;
  }
  else {
    for(key in currentNode.views){
      currentChild = currentNode.views[key]
      result = findViewObject(el, currentChild);
      if (result !== false){
        return result
      }
    }
    return false;
  }
}
// Grabs the top level parent element of the datatable in the DOM
var tableElement = function(el){
  var result;
  $(el).parents().each(function(i){
    if(this.classList.contains("bk-data-table")){
      result = this
    }
  })
  return result
}

var selectionShift = function(view){

  var selectedRowIndices = view.grid.getSelectedRows()
  var data = view.data.getRecords()

  var rowsToShift = collectRowsToShift(data, selectedRowIndices)

  spliceOutRows(data, rowsToShift);

  for(i = 0; i < rowsToShift.length; i++){
    data.unshift(rowsToShift[i])
  }
  updateData(view, data, selectedRowIndices)
}

var collectRowsToShift = function(data, selectedRowIndices){
  var result = []
  for(i = 0; i < selectedRowIndices.length; i++){
    result.push(data.slice(selectedRowIndices[i], (selectedRowIndices[i] + 1))[0])
  }
  return result;
}

var spliceOutRows = function(data, rowsToSplice){
  var attributeMatcher = $(".plotdiv").data().sortingMatcher
  for(i = 0; i < rowsToSplice.length; i++){
    for(j = 0; j < data.length; j++){
      if(data[j][attributeMatcher] === rowsToSplice[i][attributeMatcher]){
        data.splice(j, 1)
      }
    }
  }
}

var updateData = function(view, data, selectedRowIndices){
  for(i = 0; i < data.length; i++){
    view.data._setItem(i, data[i])
  }
  var updateSel = []
  for(i=0; i < selectedRowIndices.length; i++){
    updateSel.push(i)
  }
  view.data.updateSource()
  view.grid.setSelectedRows(updateSel)
}

var applyValueFilter = function(workingFilters, columns, rows){
  if(workingFilters.length === 0){
    return rows;
  }
  else{
    var filterToApply = workingFilters.pop()
    var column = columns[filterToApply.name]
    if (rows.length > 0) {
      var newRows = []
      for(var j = 0; j < rows.length; j++){
        for(var k = 0; k < filterToApply.values.length; k++){
          if(column[rows[j]] == filterToApply.values[k]){
            newRows.push(rows.slice(j,j+1)[0])
          }
        }
      }
      rows = newRows
    }
    else {
      for(var j = 0; j < column.length; j++){
        for(var k = 0; k < filterToApply.values.length; k++){
          if(column[j] == filterToApply.values[k]){
            rows.push(j)
          }
        }
      }
    }
    return applyValueFilter(workingFilters, columns, rows);
  }
}

var rowsIndices = function(array){
  var result = []
  for(var i = 0; i < array.length; i++){
    result.push(i)
  }
  return result
}

var getFieldNames = function(columns, sortingFields){
  var result = []
  for(var j = 0; j < sortingFields.length; j++){
    for(var i = 0; i < columns.length; i++){
      var columnData = Bokeh.Collections("TableColumn").get(columns[i].id)
      if (columnData.attributes.field == sortingFields[j]) {
      result.push({field : columnData.attributes.field, title : columnData.attributes.title})
      };
    }
  }
  return result
}

var optionsConstructor = function(source, fieldName){
  var result = "";
  var elements = getUniqueElements(source.attributes.data[fieldName])
  for(var i = 0; i < elements.length; i++){
    result += "<option value='"+ elements[i].toString() +"'>" + elements[i] + "</option>"
  }
  return result
}

var getUniqueElements = function(array){
  var u = {}, a = [];
     for(var i = 0; i < array.length; ++i){
        if(u.hasOwnProperty(array[i])) {
           continue;
        }
        a.push(array[i]);
        u[array[i]] = 1;
     }
     return a;
}

var linkScript = function(args){
  var script = document.createElement('script');
  script.type = args.type;
  script.src = args.url
  $(args.location).append(script);
}

var noRecordsModal = '

No Matching Records Found

<button type="button" class="btn btn-warning" data-dismiss="modal">Close</button>

'<commit_msg>moves setSelection call before modal.show<commit_after>Bokeh.$(function() {
  linkScript({'url':"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.6.3/js/bootstrap-select.min.js", 'type':'text/javascript', 'location':'body'});

  $('body').append(noRecordsModal)

  $('.plotdiv').each(function(index, element){
    var modelId = findModelID(element.id);
    var tableEl = $(element).find(".bk-data-table")[0];
    var dataTableView = findViewObject(tableEl, Bokeh.index[modelId]);
    var fields = getFieldNames(dataTableView.model.attributes.columns, $(element).data("sortingFields"));
    var dataSource = dataTableView.mget("source");

    $(element).prepend("<form class='column-filters' id="+ element.id +">
<button type='submit' class='btn btn-xs btn-warning'>Select Data</button>
</form>")

    for (var i = 0; i < fields.length; i++){
      if (fields[i].field != 'name') {
        var optionsString = optionsConstructor(dataSource, fields[i].field)
        $("form#" + element.id + ".column-filters").append("<select class='selectpicker' data-width='100px' data-style='btn-xs' multiple title='"+ fields[i].title +"' name=" + fields[i].field + ">"+ optionsString+"</select>")
      };
    }
  })

  $("form.column-filters").submit(function(e){
    e.preventDefault();
    var options = $(e.target).find("select");
    var workingFilters = [];
    for(var i = 0; i < options.length; i++){
      if(options[i].type !== 'submit' && options[i].selectedOptions.length > 0){
        var filterValues = $(options[i].selectedOptions).map(function(i, e){return e.value})
        workingFilters.push({name: options[i].name, values: filterValues })
      }
    }
    var modelId = findModelID(this.id);
    var dataTableView = findViewObject($(document.getElementById(this.id)).find(".bk-data-table")[0], Bokeh.index[modelId])
    var dataSource = dataTableView.mget("source")
    var columns = dataSource.attributes.data
    var rows = []
    var rowsToSelect = applyValueFilter(workingFilters, columns, rows)
      dataTableView.grid.setSelectedRows(rowsToSelect)
    if(rowsToSelect.length === 0){
      $('#no-records-modal').modal('show')
    }
    else{
      selectionShift(dataTableView)
    }
  })

  $(".plotdiv").on('click', ".bk-ui-state-default.bk-slick-header-column.bk-ui-sortable-handle", function(e){
    if (this.id.match(/slickgrid_\d+_checkbox_selector/) != null) {
      var columnData = $(this).data("column")
      var parentId = $(this).closest(".plotdiv").get(0).id
      var modelid = findModelID(parentId)
      var dataTableView = findViewObject(tableElement(this), Bokeh.index[modelid])
      selectionShift(dataTableView);
    }
  })
})
var findModelID = function(parentId){
  return $.grep(Object.keys(Bokeh.index), function(k){
    return Bokeh.index[k].el.id === parentId
  })
}
// Used to recursively search Bokeh.index
var findViewObject = function(el, currentNode){
  if (el == currentNode.el ) {
    return currentNode;
  }
  else {
    for(key in currentNode.views){
      currentChild = currentNode.views[key]
      result = findViewObject(el, currentChild);
      if (result !== false){
        return result
      }
    }
    return false;
  }
}
// Grabs the top level parent element of the datatable in the DOM
var tableElement = function(el){
  var result;
  $(el).parents().each(function(i){
    if(this.classList.contains("bk-data-table")){
      result = this
    }
  })
  return result
}

var selectionShift = function(view){

  var selectedRowIndices = view.grid.getSelectedRows()
  var data = view.data.getRecords()

  var rowsToShift = collectRowsToShift(data, selectedRowIndices)

  spliceOutRows(data, rowsToShift);

  for(i = 0; i < rowsToShift.length; i++){
    data.unshift(rowsToShift[i])
  }
  updateData(view, data, selectedRowIndices)
}

var collectRowsToShift = function(data, selectedRowIndices){
  var result = []
  for(i = 0; i < selectedRowIndices.length; i++){
    result.push(data.slice(selectedRowIndices[i], (selectedRowIndices[i] + 1))[0])
  }
  return result;
}

var spliceOutRows = function(data, rowsToSplice){
  var attributeMatcher = $(".plotdiv").data().sortingMatcher
  for(i = 0; i < rowsToSplice.length; i++){
    for(j = 0; j < data.length; j++){
      if(data[j][attributeMatcher] === rowsToSplice[i][attributeMatcher]){
        data.splice(j, 1)
      }
    }
  }
}

var updateData = function(view, data, selectedRowIndices){
  for(i = 0; i < data.length; i++){
    view.data._setItem(i, data[i])
  }
  var updateSel = []
  for(i=0; i < selectedRowIndices.length; i++){
    updateSel.push(i)
  }
  view.data.updateSource()
  view.grid.setSelectedRows(updateSel)
}

var applyValueFilter = function(workingFilters, columns, rows){
  if(workingFilters.length === 0){
    return rows;
  }
  else{
    var filterToApply = workingFilters.pop()
    var column = columns[filterToApply.name]
    if (rows.length > 0) {
      var newRows = []
      for(var j = 0; j < rows.length; j++){
        for(var k = 0; k < filterToApply.values.length; k++){
          if(column[rows[j]] == filterToApply.values[k]){
            newRows.push(rows.slice(j,j+1)[0])
          }
        }
      }
      rows = newRows
    }
    else {
      for(var j = 0; j < column.length; j++){
        for(var k = 0; k < filterToApply.values.length; k++){
          if(column[j] == filterToApply.values[k]){
            rows.push(j)
          }
        }
      }
    }
    return applyValueFilter(workingFilters, columns, rows);
  }
}

var rowsIndices = function(array){
  var result = []
  for(var i = 0; i < array.length; i++){
    result.push(i)
  }
  return result
}

var getFieldNames = function(columns, sortingFields){
  var result = []
  for(var j = 0; j < sortingFields.length; j++){
    for(var i = 0; i < columns.length; i++){
      var columnData = Bokeh.Collections("TableColumn").get(columns[i].id)
      if (columnData.attributes.field == sortingFields[j]) {
      result.push({field : columnData.attributes.field, title : columnData.attributes.title})
      };
    }
  }
  return result
}

var optionsConstructor = function(source, fieldName){
  var result = "";
  var elements = getUniqueElements(source.attributes.data[fieldName])
  for(var i = 0; i < elements.length; i++){
    result += "<option value='"+ elements[i].toString() +"'>" + elements[i] + "</option>"
  }
  return result
}

var getUniqueElements = function(array){
  var u = {}, a = [];
     for(var i = 0; i < array.length; ++i){
        if(u.hasOwnProperty(array[i])) {
           continue;
        }
        a.push(array[i]);
        u[array[i]] = 1;
     }
     return a;
}

var linkScript = function(args){
  var script = document.createElement('script');
  script.type = args.type;
  script.src = args.url
  $(args.location).append(script);
}

var noRecordsModal = '

No Matching Records Found

<button type="button" class="btn btn-warning" data-dismiss="modal">Close</button>

'<|endoftext|>


<commit_before>define(["js/data/Entity", "sprd/entity/ShippingState", "sprd/entity/Country", "sprd/entity/Person", "sprd/data/validator/LengthValidator", "js/data/validator/RegExValidator", "js/data/transformer/TrimTransformer", "js/data/validator/Validator", "underscore"], function (Entity, ShippingState, Country, Person, LengthValidator, RegExValidator, TrimTransformer, Validator, _) {

    var ADDRESS_TYPES = {
        PACKSTATION: "PACKSTATION",
        PRIVATE: "PRIVATE"
    };

    var MAX_LENGTH = {
        STREET: 50,
        ZIP_CODE: 10,
        CITY: 30,
        STREET_ANNEX: 50
    };

    var MIN_LENGTH = {
        STREET: 3
    };

    var POSTNUMMER = "Postnummer ",
        PACKSTATION = "Packstation ";

    var VatValidator = Validator.inherit({
        _validate: function (entity) {
            var error = entity.fieldError(this.$.field);
            if (error && error.$.code == this.$.errorCode) {
                // return true of the field is empty
                return !entity.get(this.$.field) ? null : this._createFieldError(this.$.field);
            }
            return null;
        }
    });

    var StreetValidator = Validator.inherit({

        _validate: function (entity) {
            var value = entity.get(this.$.field);

            // if its HQ don't validate
            if (value && !/^HQ/.test(value)) {
                // validate minlength, maxlength and that it contains a number
                if (value.length < MIN_LENGTH.STREET || value.length > MAX_LENGTH.STREET ||
                    (!/\d/.test(value) && _.indexOf(["GB", "FR", "IE"], entity.get("country.code")) === -1)
                ) {
                    return this._createFieldError(this.$.field);
                }
            }
        }

    });

    var PackStationValidation = RegExValidator.inherit({
        _validate: function(entity, option) {
            option = option || {};

            if ((option.validationOptions || {}).skipPackStationValidation === true) {
                return;
            }

            return this.callBase();

        }
    });

    var Address = Entity.inherit("sprd.entity.Address", {

        defaults: {
            type: ADDRESS_TYPES.PRIVATE,
            company: null,
            person: Person,
            isBillingAddress: false,
            street: null,
            streetAnnex: null,
            houseNumber: null,
            city: null,
            state: null,
            country: null,
            zipCode: null,
            email: null,
            phone: null,
            fax: null,
            packStationNr: "",
            postNr: "",
            personSalutation: "{person.salutation}",
            isSameAsBillingAddress: true,
            root: null,
            shippingCountries: "{root.shippingCountries()}"
        },

        schema: {
            type: {
                type: String,
                required: true
            },
            company: {
                type: String,
                required: function () {
                    return this.isCompany();
                }
            },

            vatId: {
                type: String,
                required: false
            },

            person: Person,

            street: {
                type: String,
                required: function () {
                    return !this.isPackStation();
                }
            },

            streetAnnex: {
                type: String,
                required: false
            },
            city: String,
            houseNumber: {
                type: String,
                required: false
            },
            state: {
                isReference: true,
                type: ShippingState,
                required: function () {
                    return this.isStateRequired();
                }
            },
            country: {
                type: Country,
                isReference: true
            },
            zipCode: {
                type: String,
                required: function () {
                    // not required for Ireland
                    return this.needsZipCode();
                }
            },
            postNr: {
                type: String,
                required: function () {
                    return this.isPackStation()
                }
            },

            packStationNr: {
                type: String,
                required: function () {
                    return this.isPackStation()
                }
            },

            phone: {
                type: String,
                required: false
            },
            fax: {
                type: String,
                required: false
            }
        },

        transformers: [
            new TrimTransformer()
        ],

        validators: [
            new LengthValidator({
                field: "zipCode",
                maxLength: MAX_LENGTH.ZIP_CODE
            }),
            new LengthValidator({
                field: "city",
                maxLength: MAX_LENGTH.CITY
            }),
            new LengthValidator({
                field: "streetAnnex",
                maxLength: MAX_LENGTH.STREET_ANNEX
            }),
            new RegExValidator({
                field: "street",
                regEx: /postfiliale/i,
                inverse: true,
                errorCode: "postfilialeNotSupported"
            }),
            new PackStationValidation({
                field: "street",
                regEx: /packstation|postnummer/i,
                inverse: true,
                errorCode: "packstationError"
            }),
            new StreetValidator({
                field: "street",
                errorCode: "wrongFormat"
            }),
            new VatValidator({
                field: "vatId",
                errorCode: "vatIdError"
            })
        ],

        _commitChangedAttributes: function ($) {
            this.callBase();

            if ($.hasOwnProperty("country") && this.$.type === ADDRESS_TYPES.PACKSTATION) {
                if ($.country.get('code') != "DE") {
                    this.set('type', ADDRESS_TYPES.PRIVATE);
                }
            }
            if ($.hasOwnProperty("country")) {
                if (!this.isStateRequired()) {
                    this.set('state', null);
                }
            }
        },

        _commitVatId: function (vatId) {
            if (vatId && this.fieldError("vatId")) {
                this.$errors.unset('vatId');
            }
        },

        _commitCountry: function (country) {
            if (country && this.fieldError("vatId")) {
                this.$errors.unset("vatId");
            }
        },

        _commitPersonSalutation: function (salutation) {
            if (salutation === Person.Salutation.COMPANY) {
                this.set('type', ADDRESS_TYPES.PRIVATE);
            }
        },

        parse: function (data) {
            if (data.type === ADDRESS_TYPES.PACKSTATION) {
                data.packStationNr = data.street ? data.street.replace(PACKSTATION, "") : "";
                data.postNr = data.streetAnnex ? data.streetAnnex.replace(POSTNUMMER, "") : "";
                delete data.streetAnnex;
                delete data.street;
            }

            return this.callBase(data);
        },

        compose: function () {
            var data = this.callBase();

            if (!this.isStateRequired()) {
                delete data.state;
            }

            if (!this.needsZipCode() && !data.zipCode) {
                data.zipCode = "-";
            }

            if (this.get('type') === ADDRESS_TYPES.PACKSTATION) {
                data.street = PACKSTATION + (data.packStationNr || "").replace(/packstation/i, " ").replace(/^\s*|\s*$/, "");
                data.streetAnnex = POSTNUMMER + data.postNr;
            } else {
                delete data.packStationNr;
                delete data.postNr;
            }

            if (!this.isCompany()) {
                delete data.company;
                delete data.vatId;
            } else if (data.vatId && !/^[A-Z]{2}/.test(data.vatId)) {
                data.vatId = (this.get("country.code") || "").toUpperCase() + data.vatId.replace(/^[A-Z]*/, "");
                console.dir(data);
            }

            // send empty house number
            data.houseNumber = "";

            return data;
        },

        needsVatId: function (platform) {
            return platform == "EU" && this.isCompany() && (this.$.isBillingAddress || this.$.isSameAsBillingAddress);
        }.onChange('personSalutation', 'isBillingAddress', 'isSameAsBillingAddress'),

        isPackStation: function () {
            return this.$.type == ADDRESS_TYPES.PACKSTATION;
        }.onChange('type'),

        supportsPackStation: function () {
            return this.$.personSalutation !== Person.Salutation.COMPANY && this.get('country.code') === "DE" && !this.$.isBillingAddress;
        }.onChange('country.code', 'personSalutation', 'isBillingAddress'),

        needsCounty: function () {
            return  this.get('country.code') === "IE";
        }.onChange('country'),

        hasStates: function () {
            return this.get("country.shippingStates.length") > 0
        }.onChange("country"),

        isStateRequired: function () {
            return  ["US", "CA"].indexOf(this.get('country.code')) > -1;
        }.onChange('country'),

        needsZipCode: function () {
            // not required for ireland
            return this.get("country.code") !== "IE";
        }.onChange('country'),

        isCompany: function () {
            return this.$.personSalutation === Person.Salutation.COMPANY
        }.onChange('personSalutation'),

        isEqual: function (address) {
            if (!address) {
                return false;
            }
            var field,
                fields = ["type", "company", "vatId", "person.firstName", "person.lastName", "person.salutation", "street", "streetAnnex", "city", "state.code", "country.code", "zipCode", "postNr", "packStationNr", "phone", "fax"];

            for (var i = 0; i < fields.length; i++) {
                field = fields[i];
                var value = this.get(field),
                    compare = address.get(field);

                if (value && value.isEqual) {
                    if (!value.isEqual(compare)) {
                        return false;
                    }
                } else {
                    if (value !== compare) {
                        return false;
                    }
                }
            }
            return true;
        }
    });

    Address.ADDRESS_TYPES = ADDRESS_TYPES;
    Address.MAX_LENGTH = MAX_LENGTH;

    return Address;
});
<commit_msg>remove company salutation, if shipping to Australia<commit_after>define(["js/data/Entity", "sprd/entity/ShippingState", "sprd/entity/Country", "sprd/entity/Person", "sprd/data/validator/LengthValidator", "js/data/validator/RegExValidator", "js/data/transformer/TrimTransformer", "js/data/validator/Validator", "underscore"], function (Entity, ShippingState, Country, Person, LengthValidator, RegExValidator, TrimTransformer, Validator, _) {

    var ADDRESS_TYPES = {
        PACKSTATION: "PACKSTATION",
        PRIVATE: "PRIVATE"
    };

    var MAX_LENGTH = {
        STREET: 50,
        ZIP_CODE: 10,
        CITY: 30,
        STREET_ANNEX: 50
    };

    var MIN_LENGTH = {
        STREET: 3
    };

    var POSTNUMMER = "Postnummer ",
        PACKSTATION = "Packstation ";

    var VatValidator = Validator.inherit({
        _validate: function (entity) {
            var error = entity.fieldError(this.$.field);
            if (error && error.$.code == this.$.errorCode) {
                // return true of the field is empty
                return !entity.get(this.$.field) ? null : this._createFieldError(this.$.field);
            }
            return null;
        }
    });

    var StreetValidator = Validator.inherit({

        _validate: function (entity) {
            var value = entity.get(this.$.field);

            // if its HQ don't validate
            if (value && !/^HQ/.test(value)) {
                // validate minlength, maxlength and that it contains a number
                if (value.length < MIN_LENGTH.STREET || value.length > MAX_LENGTH.STREET ||
                    (!/\d/.test(value) && _.indexOf(["GB", "FR", "IE"], entity.get("country.code")) === -1)
                ) {
                    return this._createFieldError(this.$.field);
                }
            }
        }

    });

    var PackStationValidation = RegExValidator.inherit({
        _validate: function(entity, option) {
            option = option || {};

            if ((option.validationOptions || {}).skipPackStationValidation === true) {
                return;
            }

            return this.callBase();

        }
    });

    var Address = Entity.inherit("sprd.entity.Address", {

        defaults: {
            type: ADDRESS_TYPES.PRIVATE,
            company: null,
            person: Person,
            isBillingAddress: false,
            street: null,
            streetAnnex: null,
            houseNumber: null,
            city: null,
            state: null,
            country: null,
            zipCode: null,
            email: null,
            phone: null,
            fax: null,
            packStationNr: "",
            postNr: "",
            personSalutation: "{person.salutation}",
            isSameAsBillingAddress: true,
            root: null,
            shippingCountries: "{root.shippingCountries()}"
        },

        schema: {
            type: {
                type: String,
                required: true
            },
            company: {
                type: String,
                required: function () {
                    return this.isCompany();
                }
            },

            vatId: {
                type: String,
                required: false
            },

            person: Person,

            street: {
                type: String,
                required: function () {
                    return !this.isPackStation();
                }
            },

            streetAnnex: {
                type: String,
                required: false
            },
            city: String,
            houseNumber: {
                type: String,
                required: false
            },
            state: {
                isReference: true,
                type: ShippingState,
                required: function () {
                    return this.isStateRequired();
                }
            },
            country: {
                type: Country,
                isReference: true
            },
            zipCode: {
                type: String,
                required: function () {
                    // not required for Ireland
                    return this.needsZipCode();
                }
            },
            postNr: {
                type: String,
                required: function () {
                    return this.isPackStation()
                }
            },

            packStationNr: {
                type: String,
                required: function () {
                    return this.isPackStation()
                }
            },

            phone: {
                type: String,
                required: false
            },
            fax: {
                type: String,
                required: false
            }
        },

        transformers: [
            new TrimTransformer()
        ],

        validators: [
            new LengthValidator({
                field: "zipCode",
                maxLength: MAX_LENGTH.ZIP_CODE
            }),
            new LengthValidator({
                field: "city",
                maxLength: MAX_LENGTH.CITY
            }),
            new LengthValidator({
                field: "streetAnnex",
                maxLength: MAX_LENGTH.STREET_ANNEX
            }),
            new RegExValidator({
                field: "street",
                regEx: /postfiliale/i,
                inverse: true,
                errorCode: "postfilialeNotSupported"
            }),
            new PackStationValidation({
                field: "street",
                regEx: /packstation|postnummer/i,
                inverse: true,
                errorCode: "packstationError"
            }),
            new StreetValidator({
                field: "street",
                errorCode: "wrongFormat"
            }),
            new VatValidator({
                field: "vatId",
                errorCode: "vatIdError"
            })
        ],

        _commitChangedAttributes: function ($) {
            this.callBase();

            if ($.hasOwnProperty("country") && this.$.type === ADDRESS_TYPES.PACKSTATION) {
                if ($.country.get('code') != "DE") {
                    this.set('type', ADDRESS_TYPES.PRIVATE);
                }
            }
            if ($.hasOwnProperty("country")) {
                if (!this.isStateRequired()) {
                    this.set('state', null);
                }

                if ($.country && $.country.$.code === "AU" && this.get("person.salutation") == 4) {
                    // company to australia is forbidden, see DEV-134352
                    this.$.person.set("salutation", null);
                }
            }
        },

        _commitVatId: function (vatId) {
            if (vatId && this.fieldError("vatId")) {
                this.$errors.unset('vatId');
            }
        },

        _commitCountry: function (country) {
            if (country && this.fieldError("vatId")) {
                this.$errors.unset("vatId");
            }
        },

        _commitPersonSalutation: function (salutation) {
            if (salutation === Person.Salutation.COMPANY) {
                this.set('type', ADDRESS_TYPES.PRIVATE);
            }
        },

        parse: function (data) {
            if (data.type === ADDRESS_TYPES.PACKSTATION) {
                data.packStationNr = data.street ? data.street.replace(PACKSTATION, "") : "";
                data.postNr = data.streetAnnex ? data.streetAnnex.replace(POSTNUMMER, "") : "";
                delete data.streetAnnex;
                delete data.street;
            }

            return this.callBase(data);
        },

        compose: function () {
            var data = this.callBase();

            if (!this.isStateRequired()) {
                delete data.state;
            }

            if (!this.needsZipCode() && !data.zipCode) {
                data.zipCode = "-";
            }

            if (this.get('type') === ADDRESS_TYPES.PACKSTATION) {
                data.street = PACKSTATION + (data.packStationNr || "").replace(/packstation/i, " ").replace(/^\s*|\s*$/, "");
                data.streetAnnex = POSTNUMMER + data.postNr;
            } else {
                delete data.packStationNr;
                delete data.postNr;
            }

            if (!this.isCompany()) {
                delete data.company;
                delete data.vatId;
            } else if (data.vatId && !/^[A-Z]{2}/.test(data.vatId)) {
                data.vatId = (this.get("country.code") || "").toUpperCase() + data.vatId.replace(/^[A-Z]*/, "");
                console.dir(data);
            }

            // send empty house number
            data.houseNumber = "";

            return data;
        },

        needsVatId: function (platform) {
            return platform == "EU" && this.isCompany() && (this.$.isBillingAddress || this.$.isSameAsBillingAddress);
        }.onChange('personSalutation', 'isBillingAddress', 'isSameAsBillingAddress'),

        isPackStation: function () {
            return this.$.type == ADDRESS_TYPES.PACKSTATION;
        }.onChange('type'),

        supportsPackStation: function () {
            return this.$.personSalutation !== Person.Salutation.COMPANY && this.get('country.code') === "DE" && !this.$.isBillingAddress;
        }.onChange('country.code', 'personSalutation', 'isBillingAddress'),

        needsCounty: function () {
            return  this.get('country.code') === "IE";
        }.onChange('country'),

        hasStates: function () {
            return this.get("country.shippingStates.length") > 0
        }.onChange("country"),

        isStateRequired: function () {
            return  ["US", "CA"].indexOf(this.get('country.code')) > -1;
        }.onChange('country'),

        needsZipCode: function () {
            // not required for ireland
            return this.get("country.code") !== "IE";
        }.onChange('country'),

        isCompany: function () {
            return this.$.personSalutation === Person.Salutation.COMPANY
        }.onChange('personSalutation'),

        isEqual: function (address) {
            if (!address) {
                return false;
            }
            var field,
                fields = ["type", "company", "vatId", "person.firstName", "person.lastName", "person.salutation", "street", "streetAnnex", "city", "state.code", "country.code", "zipCode", "postNr", "packStationNr", "phone", "fax"];

            for (var i = 0; i < fields.length; i++) {
                field = fields[i];
                var value = this.get(field),
                    compare = address.get(field);

                if (value && value.isEqual) {
                    if (!value.isEqual(compare)) {
                        return false;
                    }
                } else {
                    if (value !== compare) {
                        return false;
                    }
                }
            }
            return true;
        }
    });

    Address.ADDRESS_TYPES = ADDRESS_TYPES;
    Address.MAX_LENGTH = MAX_LENGTH;

    return Address;
});
<|endoftext|>