<commit_before>/* eslint-disable react/forbid-prop-types */
import React, { useReducer, useEffect, useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import { StyleSheet, View } from 'react-native';

import { PageContentModal } from './PageContentModal';
import { AutocompleteSelector, ToggleBar, PageButton, TextEditor, Step } from '..';
import globalStyles, { DARK_GREY, WARM_GREY, SUSSOL_ORANGE } from '../../globalStyles';
import { SETTINGS_KEYS } from '../../settings';
import { getAllPrograms, getAllPeriodsForProgram } from '../../utilities';
import { programStrings, navStrings } from '../../localization';

import {
  selectProgram,
  selectSupplier,
  selectOrderType,
  selectPeriod,
  setStoreTags,
  setSteps,
  setModalClosed,
  setModalOpen,
  setToggle,
  setName,
  byProgramReducer,
  initialState,
} from '../../reducers/ByProgramReducer';

const { THIS_STORE_TAGS } = SETTINGS_KEYS;

const modalProps = ({ dispatch, program, orderType }) => ({
  program: {
    queryStringSecondary: 'name CONTAINS[c] $0',
    onSelect: value => dispatch(selectProgram(value)),
  },
  supplier: {
    secondaryFilterProperty: 'code',
    onSelect: value => dispatch(selectSupplier(value)),
  },
  orderType: {
    secondaryFilterProperty: 'code',
    onSelect: value => dispatch(selectOrderType(value)),
    renderRightText: item => {
      const { maxMOS, maxOPP, threshMOS } = getLocalizedStrings();
      const { maxOrdersPerPeriod: maxOrders, maxMOS: itemMOS } = item;
      const mosText = `${maxMOS}: ${item.maxMOS}`;
      const thresholdText = `${threshMOS}: ${itemMOS}`;
      const maxOrdersText = `${maxOPP}: ${maxOrders}`;
      return `${mosText} - ${thresholdText} - ${maxOrdersText}`;
    },
  },
  period: {
    onSelect: value => dispatch(selectPeriod(value)),
    renderRightText: item => {
      const { requisitions } = getLocalizedStrings();
      const { maxOrdersPerPeriod } = orderType;
      const requisitionsInPeriod = item.requisitionsForOrderType(program, orderType);
      const periodText = `${requisitionsInPeriod}/${maxOrdersPerPeriod} ${requisitions}`;
      return `${item.toString()} - ${periodText}`;
    },
  },
});

export const ByProgramModal = ({ settings, database, transactionType, onConfirm, ...props }) => {
  const [state, dispatch] = useReducer(byProgramReducer, {}, () =>
    initialState({ transactionType })
  );
  const { steps, modalData, program, orderType, period, supplier, storeTags, name } = state;
  const strings = useMemo(() => getLocalizedStrings({ transactionType }), [transactionType]);
  const mounting = () => {
    dispatch(setStoreTags(settings.get(THIS_STORE_TAGS)));
    dispatch(setSteps(transactionType));
  };
  useEffect(mounting, []);

  /** Helpers */
  // Calculates the current state of a step, according to what data is currently
  // stored in state, where the current step the user should perform is CURRENT,
  // data which is stored is COMPLETE and steps which can't be done yet are INCOMPLETE.
  const getStatusCallback = key =>
    steps.reduceRight((status, value, i) => {
      const previousStepIsCurrent = state[value] && steps[i + 1] === key;
      const firstStepIsCurrent = status === 'INCOMPLETE' && steps[0] === key;
      if (state[key]) return 'COMPLETE';
      if (previousStepIsCurrent || firstStepIsCurrent) return 'CURRENT';
      return status;
    }, 'INCOMPLETE');
  const getStatus = useCallback(getStatusCallback, [
    program,
    orderType,
    supplier,
    name,
    period,
    steps,
    state.isProgramBased,
  ]);

  // Helper methods for fetching modal data for user selection
  const getPrograms = () => getAllPrograms(settings, database);
  const getSuppliers = () => database.objects('InternalSupplier');
  const getOrderTypes = () => program && program.getStoreTagObject(storeTags).orderTypes;
  const getPeriods = () => {
    if (!(program && orderType)) return null;
    const { periodScheduleName } = program.getStoreTagObject(storeTags);
    return getAllPeriodsForProgram(database, program, periodScheduleName, orderType);
  };

  /** Call backs */

  // Dispatcher on clicking a step. Opens the modal and sets the passed data as modalData
  const onOpenModal = ({ key, selection }) => dispatch(setModalOpen({ key, selection }));
  // Closed the currently ooen modal
  const onCloseModal = () => dispatch(setModalClosed());
  // Switches from program <-> general, resetting the state.
  const onToggle = () => dispatch(setToggle());
  const onCreate = () => onConfirm({ otherStoreName: supplier, program, period, orderType, name });
  /** Inner components */

  // Togglebar for switching between general <-> program. Resets state on toggle.
  const ProgramToggleBar = () => {
    const { toggleContainer } = localStyles;
    const { isProgramBased } = state;
    const { programToggleText, generalToggleText } = strings;
    return (
      <View style={toggleContainer}>
        <ToggleBar
          toggles={[
            { text: programToggleText, onPress: onToggle, isOn: isProgramBased },
            { text: generalToggleText, onPress: onToggle, isOn: !isProgramBased },
          ]}
        />
      </View>
    );
  };

  // Modal component, for user selection
  const ByProgramSelector = () => {
    const { isModalOpen, currentKey } = state;
    return (
      <PageContentModal isOpen={isModalOpen} onClose={onCloseModal} coverScreen>
        {currentKey !== 'name' ? (
          <AutocompleteSelector
            queryString="code CONTAINS[c] $0"
            sortByString="name"
            primaryFilterProperty="name"
            renderLeftText={item => `${item.name}`}
            options={modalData}
            {...modalProps({ dispatch, program, orderType })[currentKey]}
          />
        ) : (
          <TextEditor text={name} onEndEditing={value => dispatch(setName(value))} />
        )}
      </PageContentModal>
    );
  };

  const stepProps = {
    program: useMemo(
      () => ({
        data: program,
        getModalData: getPrograms,
        onPress: onOpenModal,
        status: getStatus('program'),
        stepKey: 'program',
        type: 'select',
        field: 'name',
      }),
      [program, state.isProgramBased]
    ),
    supplier: useMemo(
      () => ({
        data: supplier,
        getModalData: getSuppliers,
        onPress: onOpenModal,
        status: getStatus('supplier'),
        stepKey: 'supplier',
        type: 'select',
        field: 'name',
      }),
      [program, supplier, state.isProgramBased]
    ),
    orderType: useMemo(
      () => ({
        data: orderType,
        getModalData: getOrderTypes,
        onPress: onOpenModal,
        status: getStatus('orderType'),
        stepKey: 'orderType',
        type: 'select',
        field: 'name',
      }),
      [supplier, orderType]
    ),
    period: useMemo(
      () => ({
        data: period,
        getModalData: getPeriods,
        onPress: onOpenModal,
        status: getStatus('period'),
        stepKey: 'period',
        type: 'select',
        field: 'name',
      }),
      [orderType, period]
    ),
    name: useMemo(
      () => ({
        data: name,
        status: getStatus('name'),
        onPress: onOpenModal,
        stepKey: 'name',
        type: 'input',
      }),
      [program, state.isProgramBased, name]
    ),
  };

  /** Render */
  const { modalStyle, okButton, pageButtonTextStyle } = localStyles;
  const { isModalOpen } = state;
  const { isOpen, onCancel } = props;
  const { currentKey } = state;
  return (
    <PageContentModal isOpen={isOpen} style={modalStyle} swipeToClose={false} onClose={onCancel}>
      <ProgramToggleBar />

      {steps.map(stepKey => (
        <Step key={stepKey} {...stepProps[stepKey]} />
      ))}

      <PageButton
        text="OK"
        onPress={onCreate}
        isDisabled={!(steps[steps.length - 1] === currentKey)}
        disabledColor={WARM_GREY}
        style={okButton}
        textStyle={pageButtonTextStyle}
      />
      {isModalOpen && <ByProgramSelector />}
    </PageContentModal>
  );
};

const localStyles = StyleSheet.create({
  modalStyle: {
    ...globalStyles.modal,
    backgroundColor: DARK_GREY,
  },
  toggleContainer: {
    width: 292,
    alignSelf: 'center',
    marginVertical: 20,
  },
  okButton: {
    ...globalStyles.button,
    backgroundColor: SUSSOL_ORANGE,
    alignSelf: 'center',
    marginTop: 60,
  },
  pageButtonTextStyle: {
    ...globalStyles.buttonText,
    color: 'white',
    fontSize: 14,
  },
});

const getTitleString = transactionType =>
  `${transactionType === 'stocktake' ? programStrings.stock_take : navStrings.requisition} ${
    programStrings.details
  }`;

const getProgramToggle = transactionType =>
  transactionType === 'stocktake' ? programStrings.program_stocktake : programStrings.program_order;

const getGeneralToggle = transactionType =>
  transactionType === 'stocktake' ? programStrings.general_stocktake : programStrings.general_order;

const getLocalizedStrings = ({ transactionType } = {}) => ({
  title: getTitleString(transactionType),
  programToggleText: getProgramToggle(transactionType),
  generalToggleText: getGeneralToggle(transactionType),
  maxMOS: programStrings.max_mos,
  threshMOS: programStrings.threshold_mos,
  maxOPP: programStrings.max_orders_per_period,
  requisitions: programStrings.requisitions,
});

ByProgramModal.defaultProps = {
  transactionType: 'requisition',
};

ByProgramModal.propTypes = {
  isOpen: PropTypes.bool.isRequired,
  onCancel: PropTypes.func.isRequired,
  onConfirm: PropTypes.func.isRequired,
  settings: PropTypes.object.isRequired,
  database: PropTypes.object.isRequired,
  transactionType: PropTypes.string,
};

export default ByProgramModal;
<commit_msg>Add remove toString<commit_after>/* eslint-disable react/forbid-prop-types */
import React, { useReducer, useEffect, useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import { StyleSheet, View } from 'react-native';

import { PageContentModal } from './PageContentModal';
import { AutocompleteSelector, ToggleBar, PageButton, TextEditor, Step } from '..';
import globalStyles, { DARK_GREY, WARM_GREY, SUSSOL_ORANGE } from '../../globalStyles';
import { SETTINGS_KEYS } from '../../settings';
import { getAllPrograms, getAllPeriodsForProgram } from '../../utilities';
import { programStrings, navStrings } from '../../localization';

import {
  selectProgram,
  selectSupplier,
  selectOrderType,
  selectPeriod,
  setStoreTags,
  setSteps,
  setModalClosed,
  setModalOpen,
  setToggle,
  setName,
  byProgramReducer,
  initialState,
} from '../../reducers/ByProgramReducer';

const { THIS_STORE_TAGS } = SETTINGS_KEYS;

const modalProps = ({ dispatch, program, orderType }) => ({
  program: {
    queryStringSecondary: 'name CONTAINS[c] $0',
    onSelect: value => dispatch(selectProgram(value)),
  },
  supplier: {
    secondaryFilterProperty: 'code',
    onSelect: value => dispatch(selectSupplier(value)),
  },
  orderType: {
    secondaryFilterProperty: 'code',
    onSelect: value => dispatch(selectOrderType(value)),
    renderRightText: item => {
      const { maxMOS, maxOPP, threshMOS } = getLocalizedStrings();
      const { maxOrdersPerPeriod: maxOrders, maxMOS: itemMOS } = item;
      const mosText = `${maxMOS}: ${item.maxMOS}`;
      const thresholdText = `${threshMOS}: ${itemMOS}`;
      const maxOrdersText = `${maxOPP}: ${maxOrders}`;
      return `${mosText} - ${thresholdText} - ${maxOrdersText}`;
    },
  },
  period: {
    onSelect: value => dispatch(selectPeriod(value)),
    renderRightText: item => {
      const { requisitions } = getLocalizedStrings();
      const { maxOrdersPerPeriod } = orderType;
      const requisitionsInPeriod = item.requisitionsForOrderType(program, orderType);
      const periodText = `${requisitionsInPeriod}/${maxOrdersPerPeriod} ${requisitions}`;
      return `${item} - ${periodText}`;
    },
  },
});

export const ByProgramModal = ({ settings, database, transactionType, onConfirm, ...props }) => {
  const [state, dispatch] = useReducer(byProgramReducer, {}, () =>
    initialState({ transactionType })
  );
  const { steps, modalData, program, orderType, period, supplier, storeTags, name } = state;
  const strings = useMemo(() => getLocalizedStrings({ transactionType }), [transactionType]);
  const mounting = () => {
    dispatch(setStoreTags(settings.get(THIS_STORE_TAGS)));
    dispatch(setSteps(transactionType));
  };
  useEffect(mounting, []);

  /** Helpers */
  // Calculates the current state of a step, according to what data is currently
  // stored in state, where the current step the user should perform is CURRENT,
  // data which is stored is COMPLETE and steps which can't be done yet are INCOMPLETE.
  const getStatusCallback = key =>
    steps.reduceRight((status, value, i) => {
      const previousStepIsCurrent = state[value] && steps[i + 1] === key;
      const firstStepIsCurrent = status === 'INCOMPLETE' && steps[0] === key;
      if (state[key]) return 'COMPLETE';
      if (previousStepIsCurrent || firstStepIsCurrent) return 'CURRENT';
      return status;
    }, 'INCOMPLETE');
  const getStatus = useCallback(getStatusCallback, [
    program,
    orderType,
    supplier,
    name,
    period,
    steps,
    state.isProgramBased,
  ]);

  // Helper methods for fetching modal data for user selection
  const getPrograms = () => getAllPrograms(settings, database);
  const getSuppliers = () => database.objects('InternalSupplier');
  const getOrderTypes = () => program && program.getStoreTagObject(storeTags).orderTypes;
  const getPeriods = () => {
    if (!(program && orderType)) return null;
    const { periodScheduleName } = program.getStoreTagObject(storeTags);
    return getAllPeriodsForProgram(database, program, periodScheduleName, orderType);
  };

  /** Call backs */

  // Dispatcher on clicking a step. Opens the modal and sets the passed data as modalData
  const onOpenModal = ({ key, selection }) => dispatch(setModalOpen({ key, selection }));
  // Closed the currently ooen modal
  const onCloseModal = () => dispatch(setModalClosed());
  // Switches from program <-> general, resetting the state.
  const onToggle = () => dispatch(setToggle());
  const onCreate = () => onConfirm({ otherStoreName: supplier, program, period, orderType, name });
  /** Inner components */

  // Togglebar for switching between general <-> program. Resets state on toggle.
  const ProgramToggleBar = () => {
    const { toggleContainer } = localStyles;
    const { isProgramBased } = state;
    const { programToggleText, generalToggleText } = strings;
    return (
      <View style={toggleContainer}>
        <ToggleBar
          toggles={[
            { text: programToggleText, onPress: onToggle, isOn: isProgramBased },
            { text: generalToggleText, onPress: onToggle, isOn: !isProgramBased },
          ]}
        />
      </View>
    );
  };

  // Modal component, for user selection
  const ByProgramSelector = () => {
    const { isModalOpen, currentKey } = state;
    return (
      <PageContentModal isOpen={isModalOpen} onClose={onCloseModal} coverScreen>
        {currentKey !== 'name' ? (
          <AutocompleteSelector
            queryString="code CONTAINS[c] $0"
            sortByString="name"
            primaryFilterProperty="name"
            renderLeftText={item => `${item.name}`}
            options={modalData}
            {...modalProps({ dispatch, program, orderType })[currentKey]}
          />
        ) : (
          <TextEditor text={name} onEndEditing={value => dispatch(setName(value))} />
        )}
      </PageContentModal>
    );
  };

  const stepProps = {
    program: useMemo(
      () => ({
        data: program,
        getModalData: getPrograms,
        onPress: onOpenModal,
        status: getStatus('program'),
        stepKey: 'program',
        type: 'select',
        field: 'name',
      }),
      [program, state.isProgramBased]
    ),
    supplier: useMemo(
      () => ({
        data: supplier,
        getModalData: getSuppliers,
        onPress: onOpenModal,
        status: getStatus('supplier'),
        stepKey: 'supplier',
        type: 'select',
        field: 'name',
      }),
      [program, supplier, state.isProgramBased]
    ),
    orderType: useMemo(
      () => ({
        data: orderType,
        getModalData: getOrderTypes,
        onPress: onOpenModal,
        status: getStatus('orderType'),
        stepKey: 'orderType',
        type: 'select',
        field: 'name',
      }),
      [supplier, orderType]
    ),
    period: useMemo(
      () => ({
        data: period,
        getModalData: getPeriods,
        onPress: onOpenModal,
        status: getStatus('period'),
        stepKey: 'period',
        type: 'select',
        field: 'name',
      }),
      [orderType, period]
    ),
    name: useMemo(
      () => ({
        data: name,
        status: getStatus('name'),
        onPress: onOpenModal,
        stepKey: 'name',
        type: 'input',
      }),
      [program, state.isProgramBased, name]
    ),
  };

  /** Render */
  const { modalStyle, okButton, pageButtonTextStyle } = localStyles;
  const { isModalOpen } = state;
  const { isOpen, onCancel } = props;
  const { currentKey } = state;
  return (
    <PageContentModal isOpen={isOpen} style={modalStyle} swipeToClose={false} onClose={onCancel}>
      <ProgramToggleBar />

      {steps.map(stepKey => (
        <Step key={stepKey} {...stepProps[stepKey]} />
      ))}

      <PageButton
        text="OK"
        onPress={onCreate}
        isDisabled={!(steps[steps.length - 1] === currentKey)}
        disabledColor={WARM_GREY}
        style={okButton}
        textStyle={pageButtonTextStyle}
      />
      {isModalOpen && <ByProgramSelector />}
    </PageContentModal>
  );
};

const localStyles = StyleSheet.create({
  modalStyle: {
    ...globalStyles.modal,
    backgroundColor: DARK_GREY,
  },
  toggleContainer: {
    width: 292,
    alignSelf: 'center',
    marginVertical: 20,
  },
  okButton: {
    ...globalStyles.button,
    backgroundColor: SUSSOL_ORANGE,
    alignSelf: 'center',
    marginTop: 60,
  },
  pageButtonTextStyle: {
    ...globalStyles.buttonText,
    color: 'white',
    fontSize: 14,
  },
});

const getTitleString = transactionType =>
  `${transactionType === 'stocktake' ? programStrings.stock_take : navStrings.requisition} ${
    programStrings.details
  }`;

const getProgramToggle = transactionType =>
  transactionType === 'stocktake' ? programStrings.program_stocktake : programStrings.program_order;

const getGeneralToggle = transactionType =>
  transactionType === 'stocktake' ? programStrings.general_stocktake : programStrings.general_order;

const getLocalizedStrings = ({ transactionType } = {}) => ({
  title: getTitleString(transactionType),
  programToggleText: getProgramToggle(transactionType),
  generalToggleText: getGeneralToggle(transactionType),
  maxMOS: programStrings.max_mos,
  threshMOS: programStrings.threshold_mos,
  maxOPP: programStrings.max_orders_per_period,
  requisitions: programStrings.requisitions,
});

ByProgramModal.defaultProps = {
  transactionType: 'requisition',
};

ByProgramModal.propTypes = {
  isOpen: PropTypes.bool.isRequired,
  onCancel: PropTypes.func.isRequired,
  onConfirm: PropTypes.func.isRequired,
  settings: PropTypes.object.isRequired,
  database: PropTypes.object.isRequired,
  transactionType: PropTypes.string,
};

export default ByProgramModal;
<|endoftext|>


<commit_before>const ENTER_KEY = 13;
const ESCAPE = 27;

class Chat {
    constructor(connection, inputController) {
        this.connection = connection;
        this.inputController = inputController;

        this.createDocumentStructure();
        this.addEventListeners();
    }

    createDocumentStructure() {
        const chatFrame = document.createElement('div');
        chatFrame.classList.add('chat-frame');

        const messagesPane = document.createElement('div');
        messagesPane.classList.add('messages-pane');

        const messageInput = document.createElement('input');
        messageInput.classList.add('message-input');
        messageInput.setAttribute('type', 'text');
        messageInput.setAttribute('placeholder', 'Send message');

        this.pane = messagesPane;
        this.input = messageInput;

        chatFrame.appendChild(messagesPane);
        chatFrame.appendChild(messageInput);
        document.querySelector('body').appendChild(chatFrame);
    }

    addEventListeners() {
        this.connection.subscribe('chat-message', (...args) => this.newMessageEvent(...args));

        this.input.addEventListener('keypress', (...args) => this.keyPress(...args));
        this.input.addEventListener('keyup', (...args) => this.keyUp(...args));
        this.input.addEventListener('focus', (...args) => this.focus(...args));
        this.input.addEventListener('blur', (...args) => this.blur(...args));
    }

    newMessageEvent({message, from}) {
        const classList = from === this.accountName ? 'user me' : 'user';
        const messageDiv = document.createElement('div');
        messageDiv.classList.add('message');
        messageDiv.innerHTML = `<span class="${classList}">${from}</span>${message}`;

        this.pane.appendChild(messageDiv);

        this.scrollToBottom();
    }

    scrollToBottom() {
        this.pane.scrollTop = this.pane.scrollHeight;
    }

    keyPress(event) {
        if (event.keyCode === ENTER_KEY) {
            event.preventDefault();
            event.stopPropagation();

            const message = this.input.value;
            this.input.value = "";
            this.connection.sendImmediate('chat-message', {message});
        }
    }

    keyUp(event) {
        if (event.keyCode === ESCAPE) {
            this.input.blur();
        }
    }

    focus(event) {
        this.inputController.pauseInputCapture();
    }

    blur(event) {
        this.inputController.resumeInputCapture();
    }
}

export default Chat;
<commit_msg>cleanup<commit_after>const ENTER_KEY = 13;
const ESCAPE = 27;

class Chat {
    constructor(connection, inputController) {
        this.connection = connection;
        this.inputController = inputController;

        this.createDocumentStructure();
        this.addEventListeners();
    }

    createDocumentStructure() {
        const chatFrame = document.createElement('div');
        chatFrame.classList.add('chat-frame');

        const messagesPane = document.createElement('div');
        messagesPane.classList.add('messages-pane');

        const messageInput = document.createElement('input');
        messageInput.classList.add('message-input');
        messageInput.setAttribute('type', 'text');
        messageInput.setAttribute('placeholder', 'Send message');

        this.pane = messagesPane;
        this.input = messageInput;

        chatFrame.appendChild(messagesPane);
        chatFrame.appendChild(messageInput);
        document.querySelector('body').appendChild(chatFrame);
    }

    addEventListeners() {
        this.connection.subscribe('chat-message', (...args) => this.newMessageEvent(...args));

        this.input.addEventListener('keypress', (...args) => this.keyPress(...args));
        this.input.addEventListener('keyup', (...args) => this.keyUp(...args));
        this.input.addEventListener('focus', (...args) => this.focus(...args));
        this.input.addEventListener('blur', (...args) => this.blur(...args));
    }

    newMessageEvent({message, from}) {
        const classList = from === this.accountName ? 'user me' : 'user';
        const messageDiv = document.createElement('div');
        messageDiv.classList.add('message');
        messageDiv.innerHTML = `<span class="${classList}">${from}</span>${message}`;

        this.pane.appendChild(messageDiv);

        this.scrollToBottom();
    }

    scrollToBottom() {
        this.pane.scrollTop = this.pane.scrollHeight;
    }

    keyPress(event) {
        if (event.keyCode === ENTER_KEY) {
            event.preventDefault();
            event.stopPropagation();

            const message = this.input.value;
            this.input.value = "";
            this.connection.sendImmediate('chat-message', {message});
        }
    }

    keyUp(event) {
        if (event.keyCode === ESCAPE) {
            this.input.blur();
        }
    }

    focus() {
        this.inputController.pauseInputCapture();
    }

    blur() {
        this.inputController.resumeInputCapture();
    }
}

export default Chat;
<|endoftext|>


<commit_before>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */
import React from 'react';
import PropTypes from 'prop-types';

import { StyleSheet, Text, TouchableOpacity, View, Modal } from 'react-native';

import { CloseIcon } from '../icons';

import { APP_FONT_FAMILY, PAGE_CONTENT_PADDING_HORIZONTAL, DARKER_GREY } from '../../globalStyles';

/**
 * A modal that can be displayed over the page content container, rendering any children
 * about two thirds of the way up, and a cross in the top right to close
 * @prop {Bool}             fullScreen Force the modal to cover the entire screen.
 * @prop {Bool}             isVisible  Whether the modal is open
 * @prop {Func}             onClose    A function to call if the close x is pressed
 * @prop {String}           title      The title to show in within the modal.
 * @prop {React.Element}    children   The components to render within the modal
 */
const ModalContainer = ({ fullScreen, isVisible, onClose, title, children }) => {
  const {
    contentContainer,
    modalContainer,
    titleFont,
    titleBar,
    closeButtonContainer,
    childrenContainer,
    fullScreenChildrenContainer,
    flexSpacer,
    closeButton,
  } = localStyles;

  const internalChildrenContainer = fullScreen ? childrenContainer : fullScreenChildrenContainer;

  const CloseButton = () => (
    <TouchableOpacity onPress={onClose} style={closeButton}>
      <CloseIcon />
    </TouchableOpacity>
  );

  const TitleBar = () => (
    <View style={titleBar}>
      <View style={flexSpacer} />
      <Text style={titleFont}>{title}</Text>
      <View style={closeButtonContainer}>{onClose && <CloseButton />}</View>
    </View>
  );

  return (
    <View style={modalContainer}>
      <Modal
        visible={isVisible}
        animationType="slide"
        fullScreen={false}
        transparent={true}
        hardwareAccelerated={true}
      >
        <View style={contentContainer}>
          <TitleBar />
          <View style={internalChildrenContainer}>{children}</View>
        </View>
      </Modal>
    </View>
  );
};

export default ModalContainer;

ModalContainer.propTypes = {
  fullScreen: PropTypes.bool,
  isVisible: PropTypes.bool.isRequired,
  onClose: PropTypes.func.isRequired,
  title: PropTypes.string.isRequired,
  children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
};

ModalContainer.defaultProps = {
  fullScreen: false,
};

const localStyles = StyleSheet.create({
  modalContainer: { backgroundColor: DARKER_GREY },
  contentContainer: {
    flex: 1,
    backgroundColor: DARKER_GREY,
    marginLeft: PAGE_CONTENT_PADDING_HORIZONTAL,
    marginRight: PAGE_CONTENT_PADDING_HORIZONTAL,
    marginTop: 56,
    opacity: 0.94,
    paddingBottom: 10,
  },
  fullScreenChildrenContainer: {
    flex: 1,
    alignItems: 'stretch',
    paddingLeft: PAGE_CONTENT_PADDING_HORIZONTAL,
    paddingRight: PAGE_CONTENT_PADDING_HORIZONTAL,
  },
  childrenContainer: {
    flex: 1,
    alignItems: 'stretch',
  },
  flexSpacer: {
    flex: 1,
  },
  titleFont: {
    justifyContent: 'center',
    fontFamily: APP_FONT_FAMILY,
    color: 'white',
    fontSize: 20,
  },
  closeButtonContainer: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'flex-end',
  },
  titleBar: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginTop: 15,
  },
  closeButton: {
    width: 75,
    alignItems: 'center',
  },
});
<commit_msg>Add update to ModalContainer styles<commit_after>/**
 * mSupply Mobile
 * Sustainable Solutions (NZ) Ltd. 2019
 */
import React from 'react';
import PropTypes from 'prop-types';

import { StyleSheet, Text, TouchableOpacity, View, Modal } from 'react-native';

import { CloseIcon } from '../icons';

import { APP_FONT_FAMILY, PAGE_CONTENT_PADDING_HORIZONTAL, DARKER_GREY } from '../../globalStyles';

/**
 * A modal that can be displayed over the page content container, rendering any children
 * about two thirds of the way up, and a cross in the top right to close
 * @prop {Bool}             fullScreen Force the modal to cover the entire screen.
 * @prop {Bool}             isVisible  Whether the modal is open
 * @prop {Func}             onClose    A function to call if the close x is pressed
 * @prop {String}           title      The title to show in within the modal.
 * @prop {React.Element}    children   The components to render within the modal
 */
const ModalContainer = ({ fullScreen, isVisible, onClose, title, children }) => {
  const {
    contentContainer,
    modalContainer,
    titleFont,
    titleBar,
    closeButtonContainer,
    childrenContainer,
    fullScreenChildrenContainer,
    flexSpacer,
    closeButton,
  } = localStyles;

  const internalChildrenContainer = fullScreen ? childrenContainer : fullScreenChildrenContainer;

  const CloseButton = () => (
    <TouchableOpacity onPress={onClose} style={closeButton}>
      <CloseIcon />
    </TouchableOpacity>
  );

  const TitleBar = () => (
    <View style={titleBar}>
      <View style={flexSpacer} />
      <Text style={titleFont}>{title}</Text>
      <View style={closeButtonContainer}>{onClose && <CloseButton />}</View>
    </View>
  );

  return (
    <View style={modalContainer}>
      <Modal
        visible={isVisible}
        animationType="slide"
        fullScreen={false}
        transparent={true}
        hardwareAccelerated={true}
      >
        <View style={contentContainer}>
          <TitleBar />
          <View style={internalChildrenContainer}>{children}</View>
        </View>
      </Modal>
    </View>
  );
};

export default ModalContainer;

ModalContainer.propTypes = {
  fullScreen: PropTypes.bool,
  isVisible: PropTypes.bool.isRequired,
  onClose: PropTypes.func.isRequired,
  title: PropTypes.string.isRequired,
  children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
};

ModalContainer.defaultProps = {
  fullScreen: false,
};

const localStyles = StyleSheet.create({
  modalContainer: { backgroundColor: DARKER_GREY },
  contentContainer: {
    flex: 1,
    backgroundColor: DARKER_GREY,
    marginLeft: PAGE_CONTENT_PADDING_HORIZONTAL,
    marginRight: PAGE_CONTENT_PADDING_HORIZONTAL,
    marginBottom: PAGE_CONTENT_PADDING_HORIZONTAL,
    marginTop: 56,
    opacity: 0.94,
    paddingBottom: 10,
  },
  fullScreenChildrenContainer: {
    flex: 1,
    alignItems: 'stretch',
    paddingLeft: PAGE_CONTENT_PADDING_HORIZONTAL,
    paddingRight: PAGE_CONTENT_PADDING_HORIZONTAL,
  },
  childrenContainer: {
    flex: 1,
    alignItems: 'stretch',
  },
  flexSpacer: {
    flex: 1,
  },
  titleFont: {
    justifyContent: 'center',
    fontFamily: APP_FONT_FAMILY,
    color: 'white',
    fontSize: 20,
  },
  closeButtonContainer: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'flex-end',
  },
  titleBar: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginTop: 15,
  },
  closeButton: {
    width: 75,
    alignItems: 'center',
  },
});
<|endoftext|>


<commit_before>var BaseWidget = Backbone.View.extend({

  enableLogging : false

, updateFrequency : 30 * 1000 //30s

, Name : "BaseWidget"

, server : ""

, events : {
             "click .time-period" : "ChangeTimeFrame"
           , "click .go" : "Go"
           }

, init : function () {

      var self = this

      $(document).on("ServerChange", function(e, server){
        self.server = server
      })

      this.timer = setInterval( function () { self.UpdateModel(true) }, this.updateFrequency )

      // set event listners
      this.model
        .on("error", this.error, this)
        .on("change", this.ModelChanged, this)

  }

, UpdateModel : function ( enableTimer ) {

    clearInterval(this.timer)

    this.startTime = new Date()

    this.model.fetch({
        data : {
          // if no from/to are found, provide reasonable defaults of one day ago and now, respectively
          from : this.$el.find('[name=from]').val() || parseInt(new Date(new Date() - 1 * 24 * 60 * 60).getTime())
        , to : this.$el.find('[name=to]').val() || parseInt(new Date().getTime() / 1000)
        , server : this.server
      }
    })

    this.enableTimer = enableTimer

  }

, ModelChanged : function(){

    this.endTime = new Date()
    var timeElapsed = (this.endTime - this.startTime);

    if (this.enableLogging)
      console.log(this.Name + ": Time Elapsed = " + timeElapsed + " ms")

    this.render()

    if(this.enableTimer)
    {
      var self = this
      this.timer = setInterval( function () { self.UpdateModel(true) }, this.updateFrequency )
    }
}

, Go : function( el ) {
    this.UpdateModel(false)
  }

, ChangeTimeFrame : function ( el ) {

    var selectionType = $(el.target).data("type")
      , timeFrame = parseInt( $(el.target).data("time") )

    // update the dropdown's label
    $(el.target)
      .closest(".btn-group")
      .children()
      .first()
      .text($(el.target).text())

    // Custom time frame selected
    if ( selectionType == "custom" ) {
      $(el.target)
        .closest(".btn-group")
        .siblings(".date-control")
        .css("display","inline")
    }
    // real time
    else if ( selectionType == "realtime" ) {
      $(el.target)
        .closest(".btn-group")
        .siblings(".date-control")
        .css("display","none")

      var self = this
      this.$el.find('[name=from]').val("")
      this.$el.find('[name=to]').val("")
      this.timer = setInterval( function () { self.UpdateModel(true) }, this.updateFrequency )
    }
    // one of the template time frame selected
    // example: last 15mins, last 1 day etc
    else {

      $(el.target)
        .closest(".btn-group")
        .siblings(".date-control")
        .css("display","none")

      var endDate = parseInt(new Date().getTime() / 1000)
        , startDate = endDate

      switch(selectionType) {

        case 'minute' :
          startDate = parseInt(new Date(endDate - timeFrame * 60).getTime())
          break

        case 'hour' :
          startDate = parseInt(new Date(endDate - timeFrame * 60 * 60).getTime())
          break

        case 'day' :
          startDate = parseInt(new Date(endDate - timeFrame * 24 * 60 * 60).getTime())
          break

        case 'week' :
          startDate = parseInt(new Date(endDate - timeFrame * 7 * 24 * 60 * 60).getTime())
          break

        case 'month' :
          startDate = parseInt(new Date(endDate - timeFrame * 30 * 24 * 60 * 60).getTime())
          break
      }

      this.$el.find('[name=from]').val(startDate)
      this.$el.find('[name=to]').val(endDate)
      this.UpdateModel(false)

    }
  }

, error: function ( model, error ) {
   if (this.enableLogging)
      console.log(this.Name + ": Error Occured \n" + error + "\n" + model )

  }

})
<commit_msg>fix time bug<commit_after>var BaseWidget = Backbone.View.extend({

  enableLogging : false

, updateFrequency : 30 * 1000 //30s

, Name : "BaseWidget"

, server : ""

, events : {
             "click .time-period" : "ChangeTimeFrame"
           , "click .go" : "Go"
           }

, init : function () {

      var self = this

      $(document).on("ServerChange", function(e, server){
        self.server = server
      })

      this.timer = setInterval( function () { self.UpdateModel(true) }, this.updateFrequency )

      // set event listners
      this.model
        .on("error", this.error, this)
        .on("change", this.ModelChanged, this)

  }

, UpdateModel : function ( enableTimer ) {

    clearInterval(this.timer)

    this.startTime = new Date()

    this.model.fetch({
        data : {
          // if no from/to are found, provide reasonable defaults of one day ago and now, respectively
          from : this.$el.find('[name=from]').val() || parseInt(new Date(new Date() - 1 * 24 * 60 * 60 * 1000).getTime() / 1000)
        , to : this.$el.find('[name=to]').val() || parseInt(new Date().getTime() / 1000)
        , server : this.server
      }
    })

    this.enableTimer = enableTimer

  }

, ModelChanged : function(){

    this.endTime = new Date()
    var timeElapsed = (this.endTime - this.startTime);

    if (this.enableLogging)
      console.log(this.Name + ": Time Elapsed = " + timeElapsed + " ms")

    this.render()

    if(this.enableTimer)
    {
      var self = this
      this.timer = setInterval( function () { self.UpdateModel(true) }, this.updateFrequency )
    }
}

, Go : function( el ) {
    this.UpdateModel(false)
  }

, ChangeTimeFrame : function ( el ) {

    var selectionType = $(el.target).data("type")
      , timeFrame = parseInt( $(el.target).data("time") )

    // update the dropdown's label
    $(el.target)
      .closest(".btn-group")
      .children()
      .first()
      .text($(el.target).text())

    // Custom time frame selected
    if ( selectionType == "custom" ) {
      $(el.target)
        .closest(".btn-group")
        .siblings(".date-control")
        .css("display","inline")
    }
    // real time
    else if ( selectionType == "realtime" ) {
      $(el.target)
        .closest(".btn-group")
        .siblings(".date-control")
        .css("display","none")

      var self = this
      this.$el.find('[name=from]').val("")
      this.$el.find('[name=to]').val("")
      this.timer = setInterval( function () { self.UpdateModel(true) }, this.updateFrequency )
    }
    // one of the template time frame selected
    // example: last 15mins, last 1 day etc
    else {

      $(el.target)
        .closest(".btn-group")
        .siblings(".date-control")
        .css("display","none")

      var endDate = parseInt(new Date().getTime() / 1000)
        , startDate = endDate

      switch(selectionType) {

        case 'minute' :
          startDate = parseInt(new Date(endDate - timeFrame * 60 * 1000).getTime() / 1000)
          break

        case 'hour' :
          startDate = parseInt(new Date(endDate - timeFrame * 60 * 60 * 100).getTime() / 1000)
          break

        case 'day' :
          startDate = parseInt(new Date(endDate - timeFrame * 24 * 60 * 60 * 1000).getTime() / 1000)
          break

        case 'week' :
          startDate = parseInt(new Date(endDate - timeFrame * 7 * 24 * 60 * 60 * 1000).getTime() / 1000)
          break

        case 'month' :
          startDate = parseInt(new Date(endDate - timeFrame * 30 * 24 * 60 * 60 * 1000).getTime() / 1000)
          break
      }

      this.$el.find('[name=from]').val(startDate)
      this.$el.find('[name=to]').val(endDate)
      this.UpdateModel(false)

    }
  }

, error: function ( model, error ) {
   if (this.enableLogging)
      console.log(this.Name + ": Error Occured \n" + error + "\n" + model )

  }

})
<|endoftext|>


<commit_before>import qs from 'querystring'
import { isEmpty, omit, omitBy, get } from 'lodash'
import { crypto } from 'crypto'

// if you need to check whether the client is a mobile device from the server
// side, use the isMobile reducer in the store
export const isMobile = () => {
  if (typeof window === 'undefined') return
  return document.documentElement.clientWidth < 768 // Bootstrap's screen-sm-min
}

export function isiOSApp () {
  return window.navigator.userAgent.indexOf('Hylo-App') > -1
}

export function iOSAppVersion () {
  return Number(window.navigator.userAgent.split('Hylo-App/')[1])
}

export function isAndroidApp () {
  return typeof AndroidBridge !== 'undefined'
}

export function calliOSBridge (message, callback) {
  if (!isiOSApp()) return

  var randomName = () => {
    return crypto.randomBytes(10).toString('hex')
  }

  if (callback) {
    const callbackIdentifier = randomName()
    if (!window.iOSCallbacks) {
      window.iOSCallbacks = {}
    }
    window.iOSCallbacks[callbackIdentifier] = callback
    message.callbackPath = `window.iOSCallbacks.${callbackIdentifier}`
  }
  const postMessage = get(window, 'webkit.messageHandlers.hylo.postMessage')
  postMessage && postMessage(message)
}

// FIXME this isn't client-specific
export function makeUrl (path, params) {
  params = omitBy(params, x => !x)
  return `${path}${!isEmpty(params) ? '?' + qs.stringify(params) : ''}`
}

export function locationWithoutParams (...names) {
  let params = qs.parse(window.location.search.replace(/^\?/, ''))
  return makeUrl(window.location.pathname, omit(params, ...names))
}

export const loadScript = url => {
  var script = document.createElement('script')
  script.src = url
  const promise = new Promise((resolve, reject) => {
    script.onload = resolve
  })
  document.head.appendChild(script)
  return promise
}

export const loadStylesheet = url => {
  const head = document.getElementsByTagName('head')[0]
  const link = document.createElement('link')
  link.rel = 'stylesheet'
  link.type = 'text/css'
  link.href = url
  link.media = 'all'
  head.appendChild(link)
}
<commit_msg>fix js error calling postMessage outside its class<commit_after>import qs from 'querystring'
import { isEmpty, omit, omitBy, get } from 'lodash'
import { crypto } from 'crypto'

// if you need to check whether the client is a mobile device from the server
// side, use the isMobile reducer in the store
export const isMobile = () => {
  if (typeof window === 'undefined') return
  return document.documentElement.clientWidth < 768 // Bootstrap's screen-sm-min
}

export function isiOSApp () {
  return window.navigator.userAgent.indexOf('Hylo-App') > -1
}

export function iOSAppVersion () {
  return Number(window.navigator.userAgent.split('Hylo-App/')[1])
}

export function isAndroidApp () {
  return typeof AndroidBridge !== 'undefined'
}

export function calliOSBridge (message, callback) {
  if (!isiOSApp()) return

  var randomName = () => {
    return crypto.randomBytes(10).toString('hex')
  }

  if (callback) {
    const callbackIdentifier = randomName()
    if (!window.iOSCallbacks) {
      window.iOSCallbacks = {}
    }
    window.iOSCallbacks[callbackIdentifier] = callback
    message.callbackPath = `window.iOSCallbacks.${callbackIdentifier}`
  }
  if (get(window, 'webkit.messageHandlers.hylo.postMessage')) {
    window.webkit.messageHandlers.hylo.postMessage(message)
  }
}

// FIXME this isn't client-specific
export function makeUrl (path, params) {
  params = omitBy(params, x => !x)
  return `${path}${!isEmpty(params) ? '?' + qs.stringify(params) : ''}`
}

export function locationWithoutParams (...names) {
  let params = qs.parse(window.location.search.replace(/^\?/, ''))
  return makeUrl(window.location.pathname, omit(params, ...names))
}

export const loadScript = url => {
  var script = document.createElement('script')
  script.src = url
  const promise = new Promise((resolve, reject) => {
    script.onload = resolve
  })
  document.head.appendChild(script)
  return promise
}

export const loadStylesheet = url => {
  const head = document.getElementsByTagName('head')[0]
  const link = document.createElement('link')
  link.rel = 'stylesheet'
  link.type = 'text/css'
  link.href = url
  link.media = 'all'
  head.appendChild(link)
}
<|endoftext|>


<commit_before>var ensure   = require('ensure')
  , nock     = require('nock')
  , cfg      = require('../../cfg/tests.js')
  , nano     = require('../../nano')(cfg)
  , db_name  = require('../utils').db_name("att_ge")
  , tests    = exports
  , pixel    = "Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BABgAAAAAAAAAAAATCwAAEwsAAAAAAAAAAAAAWm2CAA=="
  , couch
  ;

couch = nock(cfg.url)
    .put('/' + db_name('a'))
    .reply(201, "{\"ok\":true}\n", { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
    location: cfg.url + '/' + db_name('a'),
    date: 'Fri, 02 Dec 2011 16:34:28 GMT',
    'content-type': 'application/json',
    'content-length': '12',
    'cache-control': 'must-revalidate' })
    .put('/' + db_name('a') + '/new/att', '"Hello"')
    .reply(201, "{\"ok\":true,\"id\":\"new\",\"rev\":\"1-5142a2e74e1ec33e6e5b621418210283\"}\n", { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
    location: cfg.url + '/' + db_name('a') + '/new/att',
    etag: '"1-5142a2e74e1ec33e6e5b621418210283"',
    date: 'Fri, 02 Dec 2011 16:34:29 GMT',
    'content-type': 'text/plain;charset=utf-8',
    'content-length': '66',
    'cache-control': 'must-revalidate' })
    .put('/' + db_name('a') + '/new/att?rev=1-5142a2e74e1ec33e6e5b621418210283'
    , new Buffer(pixel, 'base64').toString())
    .reply(201, "{\"ok\":true,\"id\":\"new\",\"rev\":\"2-3b1f88c637fde74a486cf3ce5558b47e\"}\n", { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
    location: cfg.url + '/' + db_name('a') + '/new/att',
    etag: '"2-3b1f88c637fde74a486cf3ce5558b47e"',
    date: 'Fri, 02 Dec 2011 16:34:29 GMT',
    'content-type': 'text/plain;charset=utf-8',
    'content-length': '66',
    'cache-control': 'must-revalidate' })
    .get('/' + db_name('a') +  '/new/att?rev=2-3b1f88c637fde74a486cf3ce5558b47e')
    .reply(200, new Buffer(pixel, 'base64'), { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
    etag: '"2-3b1f88c637fde74a486cf3ce5558b47e"',
    date: 'Fri, 02 Dec 2011 16:34:30 GMT',
    'content-type': 'image/bmp',
    'content-md5': 'Ow9j2dR0Qm58Qi3z8p2w3A==',
    'content-length': '58',
    'cache-control': 'must-revalidate',
    'accept-ranges': 'bytes' });

function db(i) { return nano.use(db_name(i)); }

tests.att_get = function (callback) {
  var buffer = new Buffer(pixel, 'base64');
  nano.db.create(db_name("a"), function () {
    db("a").attachment.insert("new", "att", "Hello", "text/plain",
      function(e,b) {
        if(e) { callback(e); }
        db("a").attachment.insert("new", "att", buffer, "image/bmp", {rev: b.rev},
          function (e2,b2) {
          if(e2) { callback(e2); }
          db("a").attachment.get("new", "att", {rev: b2.rev}, callback);
        });
    });
  });
};

tests.att_get_ok = function (e,b) {
  this.t.notOk(e, 'No Error');
  var from_buffer = new Buffer(b, "binary").toString("base64");
  this.t.equal(from_buffer, pixel, 'Buffer is pixel');
  this.t.ok(couch.isDone(), 'Nock is done');
};

ensure(__filename,tests,module,process.argv[2]);<commit_msg>Test for attachments as buffers<commit_after>var ensure   = require('ensure')
  , nock     = require('nock')
  , cfg      = require('../../cfg/tests.js')
  , nano     = require('../../nano')(cfg)
  , db_name  = require('../utils').db_name("att_ge")
  , tests    = exports
  , pixel    = "Qk06AAAAAAAAADYAAAAoAAAAAQAAAP////8BABgAAAAAAAAAAAATCwAAEwsAAAAAAAAAAAAAWm2CAA=="
  , couch
  ;

couch = nock(cfg.url)
    .put('/' + db_name('a'))
    .reply(201, "{\"ok\":true}\n", { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
    location: cfg.url + '/' + db_name('a'),
    date: 'Fri, 02 Dec 2011 16:34:28 GMT',
    'content-type': 'application/json',
    'content-length': '12',
    'cache-control': 'must-revalidate' })
    .put('/' + db_name('a') + '/new/att', '"Hello"')
    .reply(201, "{\"ok\":true,\"id\":\"new\",\"rev\":\"1-5142a2e74e1ec33e6e5b621418210283\"}\n", { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
    location: cfg.url + '/' + db_name('a') + '/new/att',
    etag: '"1-5142a2e74e1ec33e6e5b621418210283"',
    date: 'Fri, 02 Dec 2011 16:34:29 GMT',
    'content-type': 'text/plain;charset=utf-8',
    'content-length': '66',
    'cache-control': 'must-revalidate' })
    .put('/' + db_name('a') + '/new/att?rev=1-5142a2e74e1ec33e6e5b621418210283'
    , new Buffer(pixel, 'base64').toString())
    .reply(201, "{\"ok\":true,\"id\":\"new\",\"rev\":\"2-3b1f88c637fde74a486cf3ce5558b47e\"}\n", { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
    location: cfg.url + '/' + db_name('a') + '/new/att',
    etag: '"2-3b1f88c637fde74a486cf3ce5558b47e"',
    date: 'Fri, 02 Dec 2011 16:34:29 GMT',
    'content-type': 'text/plain;charset=utf-8',
    'content-length': '66',
    'cache-control': 'must-revalidate' })
    .get('/' + db_name('a') +  '/new/att?rev=2-3b1f88c637fde74a486cf3ce5558b47e')
    .reply(200, new Buffer(pixel, 'base64'), { server: 'CouchDB/1.1.1 (Erlang OTP/R14B04)',
    etag: '"2-3b1f88c637fde74a486cf3ce5558b47e"',
    date: 'Fri, 02 Dec 2011 16:34:30 GMT',
    'content-type': 'image/bmp',
    'content-md5': 'Ow9j2dR0Qm58Qi3z8p2w3A==',
    'content-length': '58',
    'cache-control': 'must-revalidate',
    'accept-ranges': 'bytes' });

function db(i) { return nano.use(db_name(i)); }

tests.att_get = function (callback) {
  var buffer = new Buffer(pixel, 'base64');
  nano.db.create(db_name("a"), function () {
    db("a").attachment.insert("new", "att", "Hello", "text/plain",
      function(e,b) {
        if(e) { callback(e); }
        db("a").attachment.insert("new", "att", buffer, "image/bmp", {rev: b.rev},
          function (e2,b2) {
          if(e2) { callback(e2); }
          db("a").attachment.get("new", "att", {rev: b2.rev}, callback);
        });
    });
  });
};

tests.att_get_ok = function (e,b) {
  this.t.notOk(e, 'No Error');
  var from_buffer = new Buffer(b, "binary").toString("base64");
  this.t.equal(from_buffer, pixel, 'Buffer is pixel');
  this.t.equal(b.toString("base64"), pixel, 'Result buffer is pixel');
  this.t.ok(couch.isDone(), 'Nock is done');
};

ensure(__filename,tests,module,process.argv[2]);
<|endoftext|>


<commit_before>define(['srv/core/Handler', 'srv/core/AuthenticationFilter', 'srv/core/HttpError'], function (Handler, AuthenticationFilter, HttpError) {

    return Handler.inherit('srv.handler.SessionHandler', {

        isResponsibleForRequest: function (context) {
            var ret = this.callBase();
            return ret && context.request.urlInfo.pathname === this.$.path;
        },

        handleRequest: function (context, callback) {

            var authenticationFilter = this._getAuthenticationFilter(context);

            if (!authenticationFilter) {
                throw new HttpError("No responsible authentication filter found.");
            }

            authenticationFilter.handleAuthenticationRequest(context, callback);
        },

        _getAuthenticationFilter: function (context) {
            var filters = this.$server.$filters.$filters;

            for (var i = 0; i < filters.length; i++) {
                var filter = filters[i];
                if (filter instanceof AuthenticationFilter && filter.isResponsibleForAuthenticationRequest(context)) {
                    return filter;
                }
            }
        }

    });
});<commit_msg>set default path for authentication handler to "api/authentication"<commit_after>define(['srv/core/Handler', 'srv/core/AuthenticationFilter', 'srv/core/HttpError'], function (Handler, AuthenticationFilter, HttpError) {

    return Handler.inherit('srv.handler.SessionHandler', {

        defaults: {
            path: "api/authentication"
        },

        isResponsibleForRequest: function (context) {
            var ret = this.callBase();
            return ret && context.request.urlInfo.pathname === this.$.path;
        },

        handleRequest: function (context, callback) {

            var authenticationFilter = this._getAuthenticationFilter(context);

            if (!authenticationFilter) {
                throw new HttpError("No responsible authentication filter found.");
            }

            authenticationFilter.handleAuthenticationRequest(context, callback);
        },

        _getAuthenticationFilter: function (context) {
            var filters = this.$server.$filters.$filters;

            for (var i = 0; i < filters.length; i++) {
                var filter = filters[i];
                if (filter instanceof AuthenticationFilter && filter.isResponsibleForAuthenticationRequest(context)) {
                    return filter;
                }
            }
        }

    });
});<|endoftext|>


<commit_before>/**
 *  Custom HTML fallback generator for chessmasterhong.github.io
 *  Author: Kevin Chan
 */

var fs = require('fs'),
    path = require('path');

fs.readFile(path.join(__dirname, 'src', 'index.html'), 'utf8', function(err, data) {
    if(!err) {
        console.log(data);
    } else {
        console.log(err);
    }
});
<commit_msg>Added prototype regexp view insertion.<commit_after>/**
 *  Custom HTML fallback generator for chessmasterhong.github.io
 *  Author: Kevin Chan
 */

var fs = require('fs'),
    path = require('path');

fs.readFile(path.join(__dirname, 'src', 'index.html'), 'utf8', function(err, dataIndex) {
    if(!err) {
        var index = dataIndex.replace(/(ng-cloak|data-ng-cloak)\s*/gi, '');
        fs.readFile(path.join(__dirname, 'src', 'partials', 'views', 'about.html'), 'utf8', function(err, dataView) {
            fs.writeFile(path.join(__dirname, 'about.html'), index.replace(/\sdata-ui-view(>)(?=<\/section>)/g, '$1' + dataView), 'utf8');
        });
    } else {
        console.log(err);
    }
});
<|endoftext|>


<commit_before>'use strict';

const vow = require('vow');
const vowFs = require('vow-fs');
const Vinyl = require('vinyl');
const Readable = require('stream').Readable;
const inherits = require('util').inherits;

function SrcLoader(paths, options) {
    if (!(this instanceof SrcLoader)) {
        return new SrcLoader(paths, options);
    }

    Readable.call(this, options);

    this.__paths = [].concat(paths || []);
}

inherits(SrcLoader, Readable);

SrcLoader.obj = function(paths, options) {
    options = options || {};
    options.objectMode = true;

    return new SrcLoader(paths, options);
};

SrcLoader.prototype._read = function () {
    const stream = this;

    vow.all(this.__paths.map(file => vowFs
            .read(file.fullname, 'utf8')
            .then(content => new Vinyl({
                  path: file.fullname,
                  contents: Buffer.from(content)
            }))
        ))
        .then(vinyls => {
            vinyls.forEach(file => { stream.push(file); });
            stream.push(null);
        });
};

module.exports = SrcLoader;
<commit_msg>enb-src error handler<commit_after>'use strict';

const vow = require('vow');
const vowFs = require('vow-fs');
const Vinyl = require('vinyl');
const Readable = require('stream').Readable;
const inherits = require('util').inherits;

function SrcLoader(paths, options) {
    if (!(this instanceof SrcLoader)) {
        return new SrcLoader(paths, options);
    }

    Readable.call(this, options);

    this.__paths = [].concat(paths || []);
}

inherits(SrcLoader, Readable);

SrcLoader.obj = function(paths, options) {
    options = options || {};
    options.objectMode = true;

    return new SrcLoader(paths, options);
};

SrcLoader.prototype._read = function () {
    vow.all(this.__paths.map(file => vowFs
            .read(file.fullname, 'utf8')
            .then(content => new Vinyl({
                  path: file.fullname,
                  contents: Buffer.from(content)
            }))
        ))
        .then(
            vinyls => {
                vinyls.forEach(file => { this.push(file); });
                this.push(null);
            },
            err => { process.nextTick(() => this.emit('error', err)); });
};

module.exports = SrcLoader;
<|endoftext|>


<commit_before>module.exports = function(skill, info, bot, message) {
    var builtinPhrases = require('../builtins');
    var customPhrases = require('../custom-phrases.json');

    bot.reply(message,'These are my current commands: ' );

    bot.reply(message,'Built-in commands: ' );
    for (var key in builtinPhrases) {
        if (builtinPhrases.hasOwnProperty(key)) {
            bot.reply(message, 'Command: ' + key);
            bot.reply(message, 'Key words/phrases: ' + builtinPhrases[key]);
        }
    }

    bot.reply(message,'Custom-added commands: ' );
    for (var key in customPhrases) {
        if (customPhrases.hasOwnProperty(key)) {
            bot.reply(message, 'Command: ' + key);
            bot.reply(message, 'Key words/phrases: ' + customPhrases[key]);
        }
    }

};
<commit_msg>Update Help.js<commit_after>module.exports = function(skill, info, bot, message) {
    var builtinPhrases = require('../builtins');
    var customPhrases = require('../custom-phrases.json');

    //bot.reply(message,'These are my current commands: ' );

    bot.reply(message,'These are my current built-in commands: ' );
    for (var key in builtinPhrases) {
        if (builtinPhrases.hasOwnProperty(key)) {
            bot.reply(message, '*Command:* ' + key);
            bot.reply(message, '*Key words/phrases:* ' + builtinPhrases[key]);
        }
    }

    bot.reply(message,'These are my current custom-added commands: ' );
    for (var key in customPhrases) {
        if (customPhrases.hasOwnProperty(key)) {
            bot.reply(message, '*Command:* ' + key);
            bot.reply(message, '*Key words/phrases:* ' + customPhrases[key]);
        }
    }

};
<|endoftext|>


<commit_before>(function() {
	document.write( [
		'
',
			'2008 Primary Results (placeholder)',
		'
'
	].join('') );
})();
<commit_msg>Content mockup with sample data<commit_after>var imgBaseUrl = 'http://gmaps-samples.googlecode.com/svn/trunk/elections/2008/images/icons/';

if( ! Array.prototype.forEach ) {
	Array.prototype.forEach = function( fun /*, thisp*/ ) {
		if( typeof fun != 'function' )
			throw new TypeError();

		var thisp = arguments[1];
		for( var i = 0, n = this.length;  i < n;  ++i ) {
			if( i in this )
				fun.call( thisp, this[i], i, this );
		}
	};
}

if( ! Array.prototype.map ) {
	Array.prototype.map = function( fun /*, thisp*/ ) {
		var len = this.length;
		if( typeof fun != 'function' )
			throw new TypeError();

		var res = new Array( len );
		var thisp = arguments[1];
		for( var i = 0;  i < len;  ++i ) {
			if( i in this )
				res[i] = fun.call( thisp, this[i], i, this );
		}

		return res;
	};
}

if( ! Array.prototype.index ) {
	Array.prototype.index = function( field ) {
		this.by = {};
		var by = this.by[field] = {};
		for( var i = 0, n = this.length;  i < n;  ++i ) {
			var obj = this[i];
			by[obj[field]] = obj;
			obj.index = i;
		}
		return this;
	};
}

String.prototype.trim = function() {
	return this.replace( /^\s\s*/, '' ).replace( /\s\s*$/, '' );
};

String.prototype.words = function( fun ) {
	this.split(' ').forEach( fun );
};

function S() {
	return Array.prototype.join.call( arguments, '' );
};

function formatNumber( nStr ) {
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}

var states = [
	{ 'abbr': 'al', 'name': 'Alabama' },
	{ 'abbr': 'ak', 'name': 'Alaska' },
	{ 'abbr': 'az', 'name': 'Arizona' },
	{ 'abbr': 'ar', 'name': 'Arkansas' },
	{ 'abbr': 'ca', 'name': 'California' },
	{ 'abbr': 'co', 'name': 'Colorado' },
	{ 'abbr': 'ct', 'name': 'Connecticut' },
	{ 'abbr': 'de', 'name': 'Delaware' },
	{ 'abbr': 'dc', 'name': 'District Of Columbia' },
	{ 'abbr': 'fl', 'name': 'Florida' },
	{ 'abbr': 'ga', 'name': 'Georgia' },
	{ 'abbr': 'hi', 'name': 'Hawaii' },
	{ 'abbr': 'id', 'name': 'Idaho' },
	{ 'abbr': 'il', 'name': 'Illinois' },
	{ 'abbr': 'in', 'name': 'Indiana' },
	{ 'abbr': 'ia', 'name': 'Iowa' },
	{ 'abbr': 'ks', 'name': 'Kansas' },
	{ 'abbr': 'ky', 'name': 'Kentucky' },
	{ 'abbr': 'la', 'name': 'Louisiana' },
	{ 'abbr': 'me', 'name': 'Maine' },
	{ 'abbr': 'md', 'name': 'Maryland' },
	{ 'abbr': 'ma', 'name': 'Massachusetts' },
	{ 'abbr': 'mi', 'name': 'Michigan',
		"democrat":{"total":592798,"precincts":{"total":"5385","reporting":"5385"},"democrat":[{"votes":328151,"name":"clinton"},{"votes":236723,"name":"uncommitted-d"},{"votes":21708,"name":"kucinich"},{"votes":3853,"name":"dodd"},{"votes":2363,"name":"gravel"}]},
		"republican":{"republican":[{"votes":337847,"name":"romney"},{"votes":257521,"name":"mccain"},{"votes":139699,"name":"huckabee"},{"votes":54434,"name":"paul"},{"votes":32135,"name":"thompson"},{"votes":24706,"name":"giuliani"},{"votes":17971,"name":"uncommitted-r"},{"votes":2823,"name":"hunter"},{"votes":458,"name":"tancredo"},{"votes":354,"name":"brownback"}],"total":867948,"precincts":{"total":"5385","reporting":"5385"}}
	},
	{ 'abbr': 'mn', 'name': 'Minnesota' },
	{ 'abbr': 'ms', 'name': 'Mississippi' },
	{ 'abbr': 'mo', 'name': 'Missouri' },
	{ 'abbr': 'mt', 'name': 'Montana' },
	{ 'abbr': 'ne', 'name': 'Nebraska' },
	{ 'abbr': 'nv', 'name': 'Nevada',
		"democrat":{"total":10560,"precincts":{"total":"1797","reporting":"1762"},"democrat":[{"votes":5355,"name":"clinton"},{"votes":4773,"name":"obama"},{"votes":396,"name":"edwards"},{"votes":31,"name":"uncommitted-d"},{"votes":5,"name":"kucinich"}]},
		"republican":{"republican":[{"votes":22649,"name":"romney"},{"votes":6087,"name":"paul"},{"votes":5651,"name":"mccain"},{"votes":3616,"name":"huckabee"},{"votes":3521,"name":"thompson"},{"votes":1910,"name":"giuliani"},{"votes":890,"name":"hunter"}],"total":44324,"precincts":{"total":"1797","reporting":"1797"}}
	},
	{ 'abbr': 'nh', 'name': 'New Hampshire' },
	{ 'abbr': 'nj', 'name': 'New Jersey' },
	{ 'abbr': 'nm', 'name': 'New Mexico' },
	{ 'abbr': 'ny', 'name': 'New York' },
	{ 'abbr': 'nc', 'name': 'North Carolina' },
	{ 'abbr': 'nd', 'name': 'North Dakota' },
	{ 'abbr': 'oh', 'name': 'Ohio' },
	{ 'abbr': 'ok', 'name': 'Oklahoma' },
	{ 'abbr': 'or', 'name': 'Oregon' },
	{ 'abbr': 'pa', 'name': 'Pennsylvania' },
	{ 'abbr': 'ri', 'name': 'Rhode Island' },
	{ 'abbr': 'sc', 'name': 'South Carolina',
		"democrat":{"total":241010,"precincts":{"total":"2259","reporting":"2259"},"democrat":[{"votes":103158,"name":"kucinich"},{"votes":93751,"name":"uncommitted-d"},{"votes":16689,"name":"gravel"},{"votes":14623,"name":"clinton"},{"votes":12789,"name":"dodd"}]},
		"republican":{"republican":[{"votes":143224,"name":"mccain"},{"votes":128908,"name":"huckabee"},{"votes":67897,"name":"thompson"},{"votes":64970,"name":"romney"},{"votes":15773,"name":"paul"},{"votes":9112,"name":"giuliani"},{"votes":1035,"name":"hunter"},{"votes":115,"name":"tancredo"},{"votes":83,"name":"cox"},{"votes":56,"name":"cort"},{"votes":23,"name":"fendig"}],"total":431196,"precincts":{"total":"2259","reporting":"2249"}}
	},
	{ 'abbr': 'sd', 'name': 'South Dakota' },
	{ 'abbr': 'tn', 'name': 'Tennessee' },
	{ 'abbr': 'tx', 'name': 'Texas' },
	{ 'abbr': 'ut', 'name': 'Utah' },
	{ 'abbr': 'vt', 'name': 'Vermont' },
	{ 'abbr': 'va', 'name': 'Virginia' },
	{ 'abbr': 'wa', 'name': 'Washington' },
	{ 'abbr': 'wv', 'name': 'West Virginia' },
	{ 'abbr': 'wi', 'name': 'Wisconsin' },
	{ 'abbr': 'wy', 'name': 'Wyoming' }
];

var parties = [
	{ name: 'democrat', shortName: 'Democratic', fullName: 'Democratic Party', url:'http://www.iowademocrats.org/' },
	{ name: 'republican', shortName: 'Republican', fullName: 'Republican Party', url:'http://www.iowagop.net/' }
].index('name');

var candidates = {
	'all': [],
	'democrat': [
		{ 'name': 'biden', 'lastName': 'Biden', 'fullName': 'Joe Biden', 'color': '#20FF1F', 'feed': '' },
		{ 'name': 'clinton', 'lastName': 'Clinton', 'fullName': 'Hillary Clinton', 'color': '#FFFA00', 'feed': '2jmb4ula0um5138qnfk621nagg' },
		{ 'name': 'dodd', 'lastName': 'Dodd', 'fullName': 'Chris Dodd', 'color': '#E4Af95', 'feed': 'l06f7eei6qfjns5a4pd5nv6erg' },
		{ 'name': 'edwards', 'lastName': 'Edwards', 'fullName': 'John Edwards', 'color': '#FF1300', 'feed': '46uusesnavfh045mmfjje0fflo' },
		{ 'name': 'gravel', 'lastName': 'Gravel', 'fullName': 'Mike Gravel', 'color': '#8A5C2E', 'feed': '47r7phlvf8e07lga3poj0ntv8g' },
		{ 'name': 'kucinich', 'lastName': 'Kucinich', 'fullName': 'Dennis Kucinich', 'color': '#EE00B5', 'feed': '7c9gellom85djmbl6664s9cclc' },
		{ 'name': 'obama', 'lastName': 'Obama', 'fullName': 'Barack Obama', 'color': '#1700E8', 'feed': 'nkt5atdq7cdbes3ehdfpendpnc' },
		{ 'name': 'richardson', 'lastName': 'Richardson', 'fullName': 'Bill Richardson', 'color': '#336633', 'feed': 'mdgiev7eul12rt1lo6eohg55q0' },
		{ 'name': 'uncommitted-d', 'lastName': 'Uncommitted', 'fullName': 'Uncommitted', 'color': '#DDDDDD', 'feed': '' }
	],
	'republican': [
		{ 'name': 'brownback', 'lastName': 'Brownback', 'fullName': 'Sam Brownback', 'color': '#8080FF', 'feed': 'lm63qmbqunob5gbvratl1bo974' },
		{ 'name': 'cort', 'lastName': 'Cort', 'fullName': 'Hugh Cort', 'color': '#8080FF' },
		{ 'name': 'cox', 'lastName': 'Cox', 'fullName': 'John Cox', 'color': '#808040' },
		{ 'name': 'fendig', 'lastName': 'Fendig', 'fullName': 'Cap Fendig', 'color': '#408080' },
		{ 'name': 'giuliani', 'lastName': 'Giuliani', 'fullName': 'Rudy Giuliani', 'color': '#336633', 'feed': 'g0tkl52ft6nhrlm2e6v6his400' },
		{ 'name': 'huckabee', 'lastName': 'Huckabee', 'fullName': 'Mike Huckabee', 'color': '#1700E8', 'feed': 'h32i31ojgo9vvb3vnggmq1qrh8' },
		{ 'name': 'hunter', 'lastName': 'Hunter', 'fullName': 'Duncan Hunter', 'color': '#8A5C2E', 'feed': '' },
		//{ 'name': 'keyes', 'lastName': 'Keyes', 'fullName': 'Alan Keyes', 'color': '#8080FF', 'feed': '' },
		{ 'name': 'mccain', 'lastName': 'McCain', 'fullName': 'John McCain', 'color': '#FFFA00', 'feed': 'q1du1ju69m8jecsjkhjr538kbs' },
		{ 'name': 'paul', 'lastName': 'Paul', 'fullName': 'Ron Paul', 'color': '#E4Af95', 'feed': '7p20d17uil4ft2qhvattqrjdgg' },
		{ 'name': 'romney', 'lastName': 'Romney', 'fullName': 'Mitt Romney', 'color': '#FF1300', 'feed': '3mv48r8us0rou62c356om8groc' },
		{ 'name': 'tancredo', 'lastName': 'Tancredo', 'fullName': 'Tom Tancredo', 'color': '#EE00B5', 'feed': '' },
		{ 'name': 'thompson', 'lastName': 'Thompson', 'fullName': 'Fred Thompson', 'color': '#20FF1F', 'feed': 'fhg9gjvi7459qaf0ki43ij1g78' },
		{ 'name': 'uncommitted-r', 'lastName': 'Uncommitted', 'fullName': 'Uncommitted', 'color': '#DDDDDD', 'feed': '' }
	]
};
//var preloadCandidates = candidates.all.forEach( function( candidate ) {
//	var img = new Image( 16, 16 );
//	img.src = imgUrl( candidate.name );
//	return img;
//});

var candidateNameList = [];
parties.forEach( function( party ) {
	var list = candidates[party.name];
	list.forEach( function( candidate ) {
		candidate.party = party;
		candidates.all.push( candidate );
		candidateNameList.push( candidate.name );
	});
	list.index( 'name' );
});

candidates.all.index( 'name' );

var reCandidates = new RegExp( candidateNameList.join('|'), 'g' );

function imgUrl( name ) {
	return imgBaseUrl + name + '.png';
}

document.write(
	''
);

(function() {

	function col( state, partyname ) {
		var candidate = state[partyname][partyname][0];
		return S(
			'',
				formatNumber( candidate.votes ),
			'	',
			'',
				'',
			'	',
			'',
				candidates.all.by.name[candidate.name].lastName,
			'	'
		);
	}

	var odd;
	document.write(
		'
',
			'
',
				'',
				'	',
				'',
					'Democratic',
				'	',
				'',
					'Republican',
				'	',
			'
',
			states.map( function( state ) {
				if( ! state.democrat  &&  ! state.republican ) return '';
				odd = ! odd;
				return S(
					'
',
						'',
							'
',
							'
',
						'	',
						'',
							state.abbr.toUpperCase(), ' ',
						'	',
						col( state, 'democrat' ),
						col( state, 'republican' ),
					'
'
				);
			}).join(''),
		'
'
	);

})();
<|endoftext|>


<commit_before>/**
 * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
 *
 * @author Julius Härtl <jus@bitgrid.net>
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */

import Vue from 'vue'
import RoomSelector from './views/RoomSelector'

// eslint-disable-next-line no-unexpected-multiline
(function(OCP, OC) {

	// eslint-disable-next-line
	__webpack_nonce__ = btoa(OC.requestToken)
	// eslint-disable-next-line
	__webpack_public_path__ = OC.linkTo('spreed', 'js/')

	Vue.prototype.t = t
	Vue.prototype.n = n
	Vue.prototype.OC = OC

	OCP.Collaboration.registerType('room', {
		action: () => {
			return new Promise((resolve, reject) => {
				const container = document.createElement('div')
				container.id = 'spreed-room-select'
				const body = document.getElementById('body-user')
				body.appendChild(container)
				const ComponentVM = new Vue({
					render: h => h(RoomSelector),
				})
				ComponentVM.$mount(container)
				ComponentVM.$root.$on('close', () => {
					ComponentVM.$el.remove()
					ComponentVM.$destroy()
					reject(new Error('User cancelled resource selection'))
				})
				ComponentVM.$root.$on('select', (id) => {
					resolve(id)
					ComponentVM.$el.remove()
					ComponentVM.$destroy()
				})
			})
		},
		typeString: t('spreed', 'Link to a conversation'),
		typeIconClass: 'icon-talk',
	})
})(window.OCP, window.OC)
<commit_msg>Use dynamic import for vue component on collections entrypoint<commit_after>/**
 * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net>
 *
 * @author Julius Härtl <jus@bitgrid.net>
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */

import Vue from 'vue'

// eslint-disable-next-line no-unexpected-multiline
(function(OCP, OC) {

	// eslint-disable-next-line
	__webpack_nonce__ = btoa(OC.requestToken)
	// eslint-disable-next-line
	__webpack_public_path__ = OC.linkTo('spreed', 'js/')

	Vue.prototype.t = t
	Vue.prototype.n = n
	Vue.prototype.OC = OC

	OCP.Collaboration.registerType('room', {
		action: () => {
			return new Promise((resolve, reject) => {
				const container = document.createElement('div')
				container.id = 'spreed-room-select'
				const body = document.getElementById('body-user')
				body.appendChild(container)
				const RoomSelector = () => import('./views/RoomSelector')
				const ComponentVM = new Vue({
					render: h => h(RoomSelector),
				})
				ComponentVM.$mount(container)
				ComponentVM.$root.$on('close', () => {
					ComponentVM.$el.remove()
					ComponentVM.$destroy()
					reject(new Error('User cancelled resource selection'))
				})
				ComponentVM.$root.$on('select', (id) => {
					resolve(id)
					ComponentVM.$el.remove()
					ComponentVM.$destroy()
				})
			})
		},
		typeString: t('spreed', 'Link to a conversation'),
		typeIconClass: 'icon-talk',
	})
})(window.OCP, window.OC)
<|endoftext|>


<commit_before><commit_msg>Delete jsonConverthtml.js<commit_after><|endoftext|>


<commit_before>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * All rights reserved.
 */

var Color = this.Color = Base.extend(new function() {

	var components = {
		gray: ['gray'],
		rgb: ['red', 'green', 'blue'],
		hsb: ['hue', 'saturation', 'brightness']
	};

	var colorCache = {},
		colorContext;

	function nameToRGBColor(name) {
		var color = colorCache[name];
		if (color)
			return color.clone();
		// Use a canvas to draw to with the given name and then retrieve rgb
		// values from. Build a cache for all the used colors.
		if (!colorContext) {
			var canvas = CanvasProvider.getCanvas(Size.create(1, 1));
			colorContext = canvas.getContext('2d');
			colorContext.globalCompositeOperation = 'copy';
		}
		// Set the current fillStyle to transparent, so that it will be
		// transparent instead of the previously set color in case the new color
		// can not be interpreted.
		colorContext.fillStyle = 'rgba(0, 0, 0, 0)';
		// Set the fillStyle of the context to the passed name and fill the
		// canvas with it, then retrieve the data for the drawn pixel:
		colorContext.fillStyle = name;
		colorContext.fillRect(0, 0, 1, 1);
		var data = colorContext.getImageData(0, 0, 1, 1).data,
			rgb = [data[0] / 255, data[1] / 255, data[2] / 255];
		return (colorCache[name] = RGBColor.read(rgb)).clone();
	}

	function hexToRGBColor(string) {
		var hex = string.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
		if (hex.length >= 4) {
			var rgb = new Array(3);
			for (var i = 0; i < 3; i++) {
				var channel = hex[i + 1];
				rgb[i] = parseInt(channel.length == 1
						? channel + channel : channel, 16) / 255;
			}
			return RGBColor.read(rgb);
		}
	}

	var converters = {
		'rgb-hsb': function(color) {
			var r = color._red,
				g = color._green,
				b = color._blue,
				alpha = color._alpha,
				max = Math.max(r, g, b),
				min = Math.min(r, g, b),
				delta = max - min,
				hue,
				saturation = (max != 0) ? delta / max : 0,
				brightness = max;
			if (saturation == 0) {
				hue = 0;
			} else {
				var rr = (max - r) / delta,
					gr = (max - g) / delta,
					br = (max - b) / delta;
				hue = r == max
					? br - gr
					: g == max
						? 2 + rr - br
						: 4 + gr - rr;
				hue /= 6;
				if (hue < 0)
					hue++;
			}
			return new HSBColor(hue * 360, saturation, brightness, alpha);
		},

		'hsb-rgb': function(color) {
			var h = color._hue,
				s = color._saturation,
				b = color._brightness,
				a = color._alpha,
				f = h % 60,
				p = (b * (1 - s)) / 1,
				q = (b * (60 - s * f)) / 60,
				t = (b * (60 - s * (60 - f))) / 60;
			switch (Math.floor(h / 60)) {
				case 0: return new RGBColor(b, t, p, a);
				case 1: return new RGBColor(q, b, p, a);
				case 2: return new RGBColor(p, b, t, a);
				case 3: return new RGBColor(p, q, b, a);
				case 4: return new RGBColor(t, p, b, a);
				case 5: return new RGBColor(b, p, q, a);
			}
		},

		'rgb-gray': function(color) {
			// Using the standard NTSC conversion formula that is used for
			// calculating the effective luminance of an RGB color:
			// http://www.mathworks.com/support/solutions/en/data/1-1ASCU/index.html?solution=1-1ASCU
			return new GrayColor(1 -
					(color._red * 0.2989
					+ color._green * 0.587
					+ color._blue * 0.114),
					color._alpha
				);
		},

		'gray-rgb': function(color) {
			var comp = 1 - color.getGray();
			return new RGBColor(comp, comp, comp, color._alpha);
		},

		'hsb-gray': function(color) {
			return converters['rgb-gray'](converters['hsb-rgb'](color));
		},

		'gray-hsb': function(color) {
			return new HSBColor(0, 0, 1 - color._gray, color._alpha);
		}
	};

	var fields = {
		beans: true,
		_readNull: true,

		initialize: function(arg) {
			var isArray = Array.isArray(arg),
				type = this._colorType;
			if (typeof arg === 'object' && !isArray) {
				if (!type) {
					// Called on the abstract Color class. Guess color type
					// from arg
					return arg.red !== undefined
						? new RGBColor(arg.red, arg.green, arg.blue, arg.alpha)
						: arg.gray !== undefined
						? new GrayColor(arg.gray, arg.alpha)
						: arg.hue !== undefined
						? new HSBColor(arg.hue, arg.saturation, arg.brightness,
								arg.alpha)
						: new RGBColor(); // Fallback
				} else {
					// Called on a subclass instance. Return the converted
					// color.
					return Color.read(arguments).convert(type);
				}
			} else if (typeof arg === 'string') {
				var rgbColor = arg.match(/^#[0-9a-f]{3,6}$/i)
						? hexToRGBColor(arg)
						: nameToRGBColor(arg);
				return type
						? rgbColor.convert(type)
						: rgbColor;
			} else {
				var components = isArray ? arg
						: Array.prototype.slice.call(arguments);
				if (!type) {
					// Called on the abstract Color class. Guess color type
					// from arg
					//if (components.length >= 4)
					//	return new CMYKColor(components);
					if (components.length >= 3)
						return new RGBColor(components);
					return new GrayColor(components);
				} else {
					// Called on a subclass instance. Just copy over
					// components.
					Base.each(this._components,
						function(name, i) {
							var value = components[i];
							// Set internal propery directly
							this['_' + name] = value !== undefined
									? value : null;
						},
					this);
				}
			}
		},

		clone: function(color) {
			var ctor = this.constructor,
				copy = new ctor(ctor.dont),
				components = this._components;
			for (var i = 0, l = components.length; i < l; i++) {
				var key = '_' + components[i];
				copy[key] = this[key];
			}
			return copy;
		},

		convert: function(type) {
			return this._colorType == type
				? this.clone()
				: converters[this._colorType + '-' + type](this);
		},

		statics: {
			/**
			 * Override Color.extend() to produce getters and setters based
			 * on the component types defined in _components.
			 */
			extend: function(src) {
				src.beans = true;
				if (src._colorType) {
					var comps = components[src._colorType];
					// Automatically produce the _components field, adding alpha
					src._components = comps.concat(['alpha']);
					Base.each(comps, function(name) {
						var isHue = name === 'hue',
							part = Base.capitalize(name),
							name = '_' + name;
						this['get' + part] = function() {
							return this[name];
						};
						this['set' + part] = function(value) {
							this[name] = isHue
								// Keep negative values within modulo 360 too:
								? ((value % 360) + 360) % 360
								// All other values are 0..1
								: Math.min(Math.max(value, 0), 1);
							this._cssString = null;
							return this;
						};
					}, src);
				}
				return this.base(src);
			}
		}
	};

	// Produce conversion methods for the various color components known by the
	// possible color types. Requesting any of these components on any color
	// internally converts the color to the required type and then returns its
	// component, using bean access.
	Base.each(components, function(comps, type) {
		Base.each(comps, function(component) {
			var part = Base.capitalize(component);
			fields['get' + part] = function() {
				return this.convert(type)[component];
			};
			fields['set' + part] = function(value) {
				var color = this.convert(type);
				color[component] = value;
				color = color.convert(this._colorType);
				for (var i = 0, l = this._components.length; i < l; i++) {
					var key = this._components[i];
					this[key] = color[key];
				}
			};
		});
	});

	return fields;
}, {
	beans: true,

	getType: function() {
		return this._colorType;
	},

	getComponents: function() {
		var length = this._components.length;
		var comps = new Array(length);
		for (var i = 0; i < length; i++)
			comps[i] = this['_' + this._components[i]];
		return comps;
	},

	/**
	 * A value between 0 and 1 that specifies the color's alpha value.
	 * All colors of the different subclasses support alpha values.
	 */
	getAlpha: function() {
		return this._alpha != null ? this._alpha : 1;
	},

	setAlpha: function(alpha) {
		this._alpha = alpha == null ? null : Math.min(Math.max(alpha, 0), 1);
		this._cssString = null;
		return this;
	},

	/**
	 * Checks if the color has an alpha value.
	 *
	 * @return {@true if the color has an alpha value}
	 */
	hasAlpha: function() {
		return this._alpha != null;
	},

	/**
	 * Checks if the component color values of the color are the
	 * same as those of the supplied one.
	 *
	 * @param obj the GrayColor to compare with
	 * @return {@true if the GrayColor is the same}
	 */
	equals: function(color) {
		if (color && color._colorType === this._colorType) {
			for (var i = 0, l = this._components.length; i < l; i++) {
				var component = '_' + this._components[i];
				if (this[component] !== color[component])
					return false;
			}
			return true;
		}
		return false;
	},

	toString: function() {
		var parts = [],
			format = Base.formatNumber;
		for (var i = 0, l = this._components.length; i < l; i++) {
			var component = this._components[i],
				value = this['_' + component];
			if (component === 'alpha' && value == null)
				value = 1;
			parts.push(component + ': ' + format(value));
		}
		return '{ ' + parts.join(', ') + ' }';
	},

	toCssString: function() {
		if (!this._cssString) {
			var color = this.convert('rgb'),
				alpha = color.getAlpha(),
				components = [
					Math.round(color._red * 255),
					Math.round(color._green * 255),
					Math.round(color._blue * 255),
					alpha != null ? alpha : 1
				];
			this._cssString = 'rgba(' + components.join(', ') + ')';
		}
		return this._cssString;
	},

	getCanvasStyle: function() {
		return this.toCssString();
	}
});

var GrayColor = this.GrayColor = Color.extend({
	_colorType: 'gray'
});

var RGBColor = this.RGBColor = Color.extend({
	_colorType: 'rgb'
});

var HSBColor = this.HSBColor = Color.extend({
	_colorType: 'hsb'
});
<commit_msg>Implement Color documentation.<commit_after>/*
 * Paper.js
 *
 * This file is part of Paper.js, a JavaScript Vector Graphics Library,
 * based on Scriptographer.org and designed to be largely API compatible.
 * http://paperjs.org/
 * http://scriptographer.org/
 *
 * Distributed under the MIT license. See LICENSE file for details.
 *
 * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
 * http://lehni.org/ & http://jonathanpuckey.com/
 *
 * All rights reserved.
 */

var Color = this.Color = Base.extend(new function() {

	var components = {
		gray: ['gray'],
		rgb: ['red', 'green', 'blue'],
		hsb: ['hue', 'saturation', 'brightness']
	};

	var colorCache = {},
		colorContext;

	function nameToRGBColor(name) {
		var color = colorCache[name];
		if (color)
			return color.clone();
		// Use a canvas to draw to with the given name and then retrieve rgb
		// values from. Build a cache for all the used colors.
		if (!colorContext) {
			var canvas = CanvasProvider.getCanvas(Size.create(1, 1));
			colorContext = canvas.getContext('2d');
			colorContext.globalCompositeOperation = 'copy';
		}
		// Set the current fillStyle to transparent, so that it will be
		// transparent instead of the previously set color in case the new color
		// can not be interpreted.
		colorContext.fillStyle = 'rgba(0, 0, 0, 0)';
		// Set the fillStyle of the context to the passed name and fill the
		// canvas with it, then retrieve the data for the drawn pixel:
		colorContext.fillStyle = name;
		colorContext.fillRect(0, 0, 1, 1);
		var data = colorContext.getImageData(0, 0, 1, 1).data,
			rgb = [data[0] / 255, data[1] / 255, data[2] / 255];
		return (colorCache[name] = RGBColor.read(rgb)).clone();
	}

	function hexToRGBColor(string) {
		var hex = string.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
		if (hex.length >= 4) {
			var rgb = new Array(3);
			for (var i = 0; i < 3; i++) {
				var channel = hex[i + 1];
				rgb[i] = parseInt(channel.length == 1
						? channel + channel : channel, 16) / 255;
			}
			return RGBColor.read(rgb);
		}
	}

	var converters = {
		'rgb-hsb': function(color) {
			var r = color._red,
				g = color._green,
				b = color._blue,
				alpha = color._alpha,
				max = Math.max(r, g, b),
				min = Math.min(r, g, b),
				delta = max - min,
				hue,
				saturation = (max != 0) ? delta / max : 0,
				brightness = max;
			if (saturation == 0) {
				hue = 0;
			} else {
				var rr = (max - r) / delta,
					gr = (max - g) / delta,
					br = (max - b) / delta;
				hue = r == max
					? br - gr
					: g == max
						? 2 + rr - br
						: 4 + gr - rr;
				hue /= 6;
				if (hue < 0)
					hue++;
			}
			return new HSBColor(hue * 360, saturation, brightness, alpha);
		},

		'hsb-rgb': function(color) {
			var h = color._hue,
				s = color._saturation,
				b = color._brightness,
				a = color._alpha,
				f = h % 60,
				p = (b * (1 - s)) / 1,
				q = (b * (60 - s * f)) / 60,
				t = (b * (60 - s * (60 - f))) / 60;
			switch (Math.floor(h / 60)) {
				case 0: return new RGBColor(b, t, p, a);
				case 1: return new RGBColor(q, b, p, a);
				case 2: return new RGBColor(p, b, t, a);
				case 3: return new RGBColor(p, q, b, a);
				case 4: return new RGBColor(t, p, b, a);
				case 5: return new RGBColor(b, p, q, a);
			}
		},

		'rgb-gray': function(color) {
			// Using the standard NTSC conversion formula that is used for
			// calculating the effective luminance of an RGB color:
			// http://www.mathworks.com/support/solutions/en/data/1-1ASCU/index.html?solution=1-1ASCU
			return new GrayColor(1 -
					(color._red * 0.2989
					+ color._green * 0.587
					+ color._blue * 0.114),
					color._alpha
				);
		},

		'gray-rgb': function(color) {
			var comp = 1 - color.getGray();
			return new RGBColor(comp, comp, comp, color._alpha);
		},

		'hsb-gray': function(color) {
			return converters['rgb-gray'](converters['hsb-rgb'](color));
		},

		'gray-hsb': function(color) {
			return new HSBColor(0, 0, 1 - color._gray, color._alpha);
		}
	};

	var fields = {
	/** @lends Color# */

		beans: true,
		_readNull: true,

		// DOCS: write Color constructor and class documentation.
		/**
		 * @constructs Color
		 * @class
		 */
		initialize: function(arg) {
			var isArray = Array.isArray(arg),
				type = this._colorType;
			if (typeof arg === 'object' && !isArray) {
				if (!type) {
					// Called on the abstract Color class. Guess color type
					// from arg
					return arg.red !== undefined
						? new RGBColor(arg.red, arg.green, arg.blue, arg.alpha)
						: arg.gray !== undefined
						? new GrayColor(arg.gray, arg.alpha)
						: arg.hue !== undefined
						? new HSBColor(arg.hue, arg.saturation, arg.brightness,
								arg.alpha)
						: new RGBColor(); // Fallback
				} else {
					// Called on a subclass instance. Return the converted
					// color.
					return Color.read(arguments).convert(type);
				}
			} else if (typeof arg === 'string') {
				var rgbColor = arg.match(/^#[0-9a-f]{3,6}$/i)
						? hexToRGBColor(arg)
						: nameToRGBColor(arg);
				return type
						? rgbColor.convert(type)
						: rgbColor;
			} else {
				var components = isArray ? arg
						: Array.prototype.slice.call(arguments);
				if (!type) {
					// Called on the abstract Color class. Guess color type
					// from arg
					//if (components.length >= 4)
					//	return new CMYKColor(components);
					if (components.length >= 3)
						return new RGBColor(components);
					return new GrayColor(components);
				} else {
					// Called on a subclass instance. Just copy over
					// components.
					Base.each(this._components,
						function(name, i) {
							var value = components[i];
							// Set internal propery directly
							this['_' + name] = value !== undefined
									? value : null;
						},
					this);
				}
			}
		},

		/**
		 * @return {RGBColor|GrayColor|HSBColor} a copy of the color object
		 */
		clone: function() {
			var ctor = this.constructor,
				copy = new ctor(ctor.dont),
				components = this._components;
			for (var i = 0, l = components.length; i < l; i++) {
				var key = '_' + components[i];
				copy[key] = this[key];
			}
			return copy;
		},

		convert: function(type) {
			return this._colorType == type
				? this.clone()
				: converters[this._colorType + '-' + type](this);
		},

		statics: {
			/**
			 * Override Color.extend() to produce getters and setters based
			 * on the component types defined in _components.
			 */
			extend: function(src) {
				src.beans = true;
				if (src._colorType) {
					var comps = components[src._colorType];
					// Automatically produce the _components field, adding alpha
					src._components = comps.concat(['alpha']);
					Base.each(comps, function(name) {
						var isHue = name === 'hue',
							part = Base.capitalize(name),
							name = '_' + name;
						this['get' + part] = function() {
							return this[name];
						};
						this['set' + part] = function(value) {
							this[name] = isHue
								// Keep negative values within modulo 360 too:
								? ((value % 360) + 360) % 360
								// All other values are 0..1
								: Math.min(Math.max(value, 0), 1);
							this._cssString = null;
							return this;
						};
					}, src);
				}
				return this.base(src);
			}
		}
	};

	// Produce conversion methods for the various color components known by the
	// possible color types. Requesting any of these components on any color
	// internally converts the color to the required type and then returns its
	// component, using bean access.
	Base.each(components, function(comps, type) {
		Base.each(comps, function(component) {
			var part = Base.capitalize(component);
			fields['get' + part] = function() {
				return this.convert(type)[component];
			};
			fields['set' + part] = function(value) {
				var color = this.convert(type);
				color[component] = value;
				color = color.convert(this._colorType);
				for (var i = 0, l = this._components.length; i < l; i++) {
					var key = this._components[i];
					this[key] = color[key];
				}
			};
		});
	});

	return fields;
}, {
	/** @lends Color# */

	beans: true,

	/**
	 * Returns the type of the color as a string.
	 *
	 * Sample code:
	 * <code>
	 * var color = new RGBColor(1, 0, 0);
	 * console.log(color.type); // 'rgb'
	 * </code>
	 *
	 * @type String
	 * @bean
	 */
	getType: function() {
		return this._colorType;
	},

	getComponents: function() {
		var length = this._components.length;
		var comps = new Array(length);
		for (var i = 0; i < length; i++)
			comps[i] = this['_' + this._components[i]];
		return comps;
	},

	/**
	 * A value between 0 and 1 that specifies the color's alpha value.
	 * All colors of the different subclasses support alpha values.
	 *
	 * @type Number
	 * @bean
	 */
	getAlpha: function() {
		return this._alpha != null ? this._alpha : 1;
	},

	setAlpha: function(alpha) {
		this._alpha = alpha == null ? null : Math.min(Math.max(alpha, 0), 1);
		this._cssString = null;
		return this;
	},

	/**
	 * Checks if the color has an alpha value.
	 *
	 * @return {Boolean} {@true if the color has an alpha value}
	 */
	hasAlpha: function() {
		return this._alpha != null;
	},

	/**
	 * Checks if the component color values of the color are the
	 * same as those of the supplied one.
	 *
	 * @param {Color} color the color to compare with
	 * @return {Boolean} {@true if the colors are the same}
	 */
	equals: function(color) {
		if (color && color._colorType === this._colorType) {
			for (var i = 0, l = this._components.length; i < l; i++) {
				var component = '_' + this._components[i];
				if (this[component] !== color[component])
					return false;
			}
			return true;
		}
		return false;
	},

	/**
	 * {@grouptitle String Representations}
	 * @return {String} A string representation of the color.
	 */
	toString: function() {
		var parts = [],
			format = Base.formatNumber;
		for (var i = 0, l = this._components.length; i < l; i++) {
			var component = this._components[i],
				value = this['_' + component];
			if (component === 'alpha' && value == null)
				value = 1;
			parts.push(component + ': ' + format(value));
		}
		return '{ ' + parts.join(', ') + ' }';
	},

	/**
	 * @return {String} A css representation of the color.
	 */
	toCssString: function() {
		if (!this._cssString) {
			var color = this.convert('rgb'),
				alpha = color.getAlpha(),
				components = [
					Math.round(color._red * 255),
					Math.round(color._green * 255),
					Math.round(color._blue * 255),
					alpha != null ? alpha : 1
				];
			this._cssString = 'rgba(' + components.join(', ') + ')';
		}
		return this._cssString;
	},

	getCanvasStyle: function() {
		return this.toCssString();
	}

	/**
	 * {@grouptitle RGB Components}
	 *
	 * The amount of red in the color as a value between {@code 0} and
	 * {@code 1}.
	 *
	 * @name Color#red
	 * @property
	 * @type Number
	 */

	/**
	 * The amount of green in the color as a value between {@code 0} and
	 * {@code 1}.
	 *
	 * @name Color#green
	 * @property
	 * @type Number
	 */

	/**
	 * The amount of blue in the color as a value between {@code 0} and
	 * {@code 1}.
	 *
	 * @name Color#blue
	 * @property
	 * @type Number
	 */

	/**
	 * {@grouptitle Gray Components}
	 *
	 * The amount of gray in the color as a value between {@code 0} and
	 * {@code 1}.
	 *
	 * @name Color#gray
	 * @property
	 * @type Number
	 */

	/**
	 * {@grouptitle HSB Components}
	 *
	 * The hue of the color as a value in degrees between {@code 0} and
	 * {@code 360}.
	 *
	 * @name Color#hue
	 * @property
	 * @type Number
	 */

	/**
	 * The saturation of the color as a value between {@code 0} and {@code 1}.
	 *
	 * @name Color#saturation
	 * @property
	 * @type Number
	 */

	/**
	 * The brightness of the color as a value between {@code 0} and {@code 1}.
	 *
	 * @name Color#brightness
	 * @property
	 * @type Number
	 */

});

var GrayColor = this.GrayColor = Color.extend(/** @scope GrayColor */{
	/**
	 * Creates a GrayColor object
	 *
	 * @param {Number} gray the amount of gray in the color as a value
	 * between {@code 0} and {@code 1}
	 * @constructor
	 * @name GrayColor
	 *
	 * @class A GrayColor object is used to represent any gray color value.
	 * @extends Color
	 */

	_colorType: 'gray'
});

var RGBColor = this.RGBColor = Color.extend(/** @scope RGBColor */{
	/**
	 * Creates an RGBColor object
	 *
	 * @param {Number} red the amount of red in the color as a value
	 * between {@code 0} and {@code 1}
	 * @param {Number} green the amount of green in the color as a value
	 * between {@code 0} and {@code 1}
	 * @param {Number} blue the amount of blue in the color as a value
	 * between {@code 0} and {@code 1}
	 * @constructor
	 * @name RGBColor
	 *
	 * @class An RGBColor object is used to represent any RGB color value.
	 * @extends Color
	 */

	_colorType: 'rgb'
});

var HSBColor = this.HSBColor = Color.extend(/** @scope HSBColor */{
	/**
	 * Creates an HSBColor object
	 *
	 * @param {Number} hue the hue of the color as a value in degrees between
	 * {@code 0} and {@code 360}.
	 * @param {Number} saturation the saturation of the color as a value
	 * between {@code 0} and {@code 1}
	 * @param {Number} brightness the brightness of the color as a value
	 * between {@code 0} and {@code 1}
	 * @constructor
	 * @name HSBColor
	 *
	 * @class An HSBColor object is used to represent any HSB color value.
	 * @extends Color
	 */

	_colorType: 'hsb'
});
<|endoftext|>