<commit_before>import { useLazyQuery, useMutation } from '@apollo/react-hooks'
import { makeStyles, Box } from '@material-ui/core'
import BigNumber from 'bignumber.js'
import { add, differenceInYears, format, sub, parse } from 'date-fns/fp'
import FileSaver from 'file-saver'
import gql from 'graphql-tag'
import JSZip from 'jszip'
import { utils as coinUtils } from 'lamassu-coins'
import * as R from 'ramda'
import React, { memo, useState } from 'react'

import { ConfirmDialog } from 'src/components/ConfirmDialog'
import { HoverableTooltip } from 'src/components/Tooltip'
import { IDButton, ActionButton } from 'src/components/buttons'
import { P, Label1 } from 'src/components/typography'
import { ReactComponent as CardIdInverseIcon } from 'src/styling/icons/ID/card/white.svg'
import { ReactComponent as CardIdIcon } from 'src/styling/icons/ID/card/zodiac.svg'
import { ReactComponent as PhoneIdInverseIcon } from 'src/styling/icons/ID/phone/white.svg'
import { ReactComponent as PhoneIdIcon } from 'src/styling/icons/ID/phone/zodiac.svg'
import { ReactComponent as CamIdInverseIcon } from 'src/styling/icons/ID/photo/white.svg'
import { ReactComponent as CamIdIcon } from 'src/styling/icons/ID/photo/zodiac.svg'
import { ReactComponent as CancelInverseIcon } from 'src/styling/icons/button/cancel/white.svg'
import { ReactComponent as CancelIcon } from 'src/styling/icons/button/cancel/zodiac.svg'
import { ReactComponent as DownloadInverseIcon } from 'src/styling/icons/button/download/white.svg'
import { ReactComponent as Download } from 'src/styling/icons/button/download/zodiac.svg'
import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'
import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'
import { URI } from 'src/utils/apollo'
import { onlyFirstToUpper } from 'src/utils/string'

import CopyToClipboard from './CopyToClipboard'
import styles from './DetailsCard.styles'
import { getStatus, getStatusDetails } from './helper'

const useStyles = makeStyles(styles)
const MINUTES_OFFSET = 3
const TX_SUMMARY = gql`
  query txSummaryAndLogs(
    $txId: ID!
    $deviceId: ID!
    $limit: Int
    $from: Date
    $until: Date
    $txClass: String
    $timezone: String
  ) {
    serverLogsCsv(
      limit: $limit
      from: $from
      until: $until
      timezone: $timezone
    )
    machineLogsCsv(
      deviceId: $deviceId
      limit: $limit
      from: $from
      until: $until
      timezone: $timezone
    )
    transactionCsv(id: $txId, txClass: $txClass, timezone: $timezone)
    txAssociatedDataCsv(id: $txId, txClass: $txClass, timezone: $timezone)
  }
`

const CANCEL_CASH_OUT_TRANSACTION = gql`
  mutation cancelCashOutTransaction($id: ID!) {
    cancelCashOutTransaction(id: $id) {
      id
    }
  }
`

const CANCEL_CASH_IN_TRANSACTION = gql`
  mutation cancelCashInTransaction($id: ID!) {
    cancelCashInTransaction(id: $id) {
      id
    }
  }
`

const formatAddress = (cryptoCode = '', address = '') =>
  coinUtils.formatCryptoAddress(cryptoCode, address).replace(/(.{5})/g, '$1 ')

const Label = ({ children }) => {
  const classes = useStyles()
  return <Label1 className={classes.label}>{children}</Label1>
}

const DetailsRow = ({ it: tx, timezone }) => {
  const classes = useStyles()
  const [action, setAction] = useState({ command: null })
  const [errorMessage, setErrorMessage] = useState('')

  const isCashIn = tx.txClass === 'cashIn'

  const zip = new JSZip()

  const [fetchSummary] = useLazyQuery(TX_SUMMARY, {
    onCompleted: data => createCsv(data)
  })

  const [cancelTransaction] = useMutation(
    isCashIn ? CANCEL_CASH_IN_TRANSACTION : CANCEL_CASH_OUT_TRANSACTION,
    {
      onError: ({ message }) =>
        setErrorMessage(message ?? 'An error occurred.'),
      refetchQueries: () => ['transactions']
    }
  )

  const fiat = Number.parseFloat(tx.fiat)
  const crypto = coinUtils.toUnit(new BigNumber(tx.cryptoAtoms), tx.cryptoCode)
  const commissionPercentage = Number.parseFloat(tx.commissionPercentage, 2)
  const commission = Number(fiat * commissionPercentage).toFixed(2)
  const discount = tx.discount ? `-${tx.discount}%` : null
  const exchangeRate = BigNumber(fiat / crypto).toFormat(2)
  const displayExRate = `1 ${tx.cryptoCode} = ${exchangeRate} ${tx.fiatCode}`

  const customer = tx.customerIdCardData && {
    name: `${onlyFirstToUpper(
      tx.customerIdCardData.firstName
    )} ${onlyFirstToUpper(tx.customerIdCardData.lastName)}`,
    age: differenceInYears(tx.customerIdCardData.dateOfBirth, new Date()),
    country: tx.customerIdCardData.country,
    idCardNumber: tx.customerIdCardData.documentNumber,
    idCardExpirationDate: format('yyyy-MM-dd')(
      parse(new Date(), 'yyyyMMdd', tx.customerIdCardData.expirationDate)
    )
  }

  const from = sub({ minutes: MINUTES_OFFSET }, tx.created)
  const until = add({ minutes: MINUTES_OFFSET }, tx.created)

  const downloadRawLogs = ({ id: txId, deviceId, txClass }, timezone) => {
    fetchSummary({
      variables: { txId, from, until, deviceId, txClass, timezone }
    })
  }

  const createCsv = async logs => {
    const zipFilename = `tx_${tx.id}_summary.zip`
    const filesNames = R.keys(logs)
    R.map(name => zip.file(name + '.csv', logs[name]), filesNames)
    const content = await zip.generateAsync({ type: 'blob' })
    FileSaver.saveAs(content, zipFilename)
  }

  const errorElements = (
    <>
      Transaction status
      {getStatus(tx)}
    </>
  )

  const getCancelMessage = () => {
    const cashInMessage = `The user will not be able to redeem the inserted bills, even if they subsequently confirm the transaction. If they've already deposited bills, you'll need to reconcile this transaction with them manually.`
    const cashOutMessage = `The user will not be able to redeem the cash, even if they subsequently send the required coins. If they've already sent you coins, you'll need to reconcile this transaction with them manually.`

    return isCashIn ? cashInMessage : cashOutMessage
  }

  return (

          Direction

              {!isCashIn ? <TxOutIcon /> : <TxInIcon />}

            {!isCashIn ? 'Cash-out' : 'Cash-in'}

          Available IDs
          <Box display="flex" flexDirection="row">
            {tx.customerPhone && (
              <IDButton
                className={classes.idButton}
                name="phone"
                Icon={PhoneIdIcon}
                InverseIcon={PhoneIdInverseIcon}>
                {tx.customerPhone}
              </IDButton>
            )}
            {tx.customerIdCardPhotoPath && !tx.customerIdCardData && (
              <IDButton
                popoverClassname={classes.clipboardPopover}
                className={classes.idButton}
                name="card"
                Icon={CardIdIcon}
                InverseIcon={CardIdInverseIcon}>
                <img
                  className={classes.idCardPhoto}
                  src={`${URI}/id-card-photo/${tx.customerIdCardPhotoPath}`}
                  alt=""
                />
              </IDButton>
            )}
            {tx.customerIdCardData && (
              <IDButton
                className={classes.idButton}
                name="card"
                Icon={CardIdIcon}
                InverseIcon={CardIdInverseIcon}>

                      Name

{customer.name}

                      Age

{customer.age}

                      Country

{customer.country}

                      ID number

{customer.idCardNumber}

                      Expiration date

{customer.idCardExpirationDate}

              </IDButton>
            )}
            {tx.customerFrontCameraPath && (
              <IDButton
                name="cam"
                Icon={CamIdIcon}
                InverseIcon={CamIdInverseIcon}>
                <img
                  src={`${URI}/front-camera-photo/${tx.customerFrontCameraPath}`}
                  alt=""
                />
              </IDButton>
            )}
          </Box>

          Exchange rate

{crypto > 0 ? displayExRate : '-'}

          Commission

            {`${commission} ${tx.fiatCode} (${commissionPercentage * 100} %)`}
            {discount && (

                <Label1 className={classes.chipLabel}>{discount}</Label1>

            )}

          Fixed fee

            {isCashIn
              ? `${Number.parseFloat(tx.cashInFee)} ${tx.fiatCode}`
              : 'N/A'}

          Address

            <CopyToClipboard>
              {formatAddress(tx.cryptoCode, tx.toAddress)}
            </CopyToClipboard>

          Transaction ID

            {tx.txClass === 'cashOut' ? (
              'N/A'
            ) : (
              <CopyToClipboard>{tx.txHash}</CopyToClipboard>
            )}

          Session ID
          <CopyToClipboard>{tx.id}</CopyToClipboard>

          {getStatusDetails(tx) ? (
            <HoverableTooltip parentElements={errorElements} width={200}>

{getStatusDetails(tx)}

            </HoverableTooltip>
          ) : (
            errorElements
          )}
          {tx.txClass === 'cashOut' && getStatus(tx) === 'Pending' && (
            <ActionButton
              color="primary"
              Icon={CancelIcon}
              InverseIcon={CancelInverseIcon}
              className={classes.cancelTransaction}
              onClick={() =>
                setAction({
                  command: 'cancelTx'
                })
              }>
              Cancel transaction
            </ActionButton>
          )}

          Other actions

            <ActionButton
              color="primary"
              Icon={Download}
              InverseIcon={DownloadInverseIcon}
              className={classes.downloadRawLogs}
              onClick={() => downloadRawLogs(tx, timezone)}>
              Download raw logs
            </ActionButton>

      <ConfirmDialog
        open={action.command === 'cancelTx'}
        title={`Cancel this transaction?`}
        errorMessage={errorMessage}
        toBeConfirmed={tx.machineName}
        message={getCancelMessage()}
        onConfirmed={() => {
          setErrorMessage(null)
          setAction({ command: null })
          cancelTransaction({
            variables: {
              id: tx.id
            }
          })
        }}
        onDismissed={() => {
          setAction({ command: null })
          setErrorMessage(null)
        }}
      />

  )
}

export default memo(
  DetailsRow,
  (prev, next) =>
    prev.it.id === next.it.id &&
    prev.it.hasError === next.it.hasError &&
    getStatus(prev.it) === getStatus(next.it)
)
<commit_msg>fix: guard against null `expirationDate`<commit_after>import { useLazyQuery, useMutation } from '@apollo/react-hooks'
import { makeStyles, Box } from '@material-ui/core'
import BigNumber from 'bignumber.js'
import { add, differenceInYears, format, sub, parse } from 'date-fns/fp'
import FileSaver from 'file-saver'
import gql from 'graphql-tag'
import JSZip from 'jszip'
import { utils as coinUtils } from 'lamassu-coins'
import * as R from 'ramda'
import React, { memo, useState } from 'react'

import { ConfirmDialog } from 'src/components/ConfirmDialog'
import { HoverableTooltip } from 'src/components/Tooltip'
import { IDButton, ActionButton } from 'src/components/buttons'
import { P, Label1 } from 'src/components/typography'
import { ReactComponent as CardIdInverseIcon } from 'src/styling/icons/ID/card/white.svg'
import { ReactComponent as CardIdIcon } from 'src/styling/icons/ID/card/zodiac.svg'
import { ReactComponent as PhoneIdInverseIcon } from 'src/styling/icons/ID/phone/white.svg'
import { ReactComponent as PhoneIdIcon } from 'src/styling/icons/ID/phone/zodiac.svg'
import { ReactComponent as CamIdInverseIcon } from 'src/styling/icons/ID/photo/white.svg'
import { ReactComponent as CamIdIcon } from 'src/styling/icons/ID/photo/zodiac.svg'
import { ReactComponent as CancelInverseIcon } from 'src/styling/icons/button/cancel/white.svg'
import { ReactComponent as CancelIcon } from 'src/styling/icons/button/cancel/zodiac.svg'
import { ReactComponent as DownloadInverseIcon } from 'src/styling/icons/button/download/white.svg'
import { ReactComponent as Download } from 'src/styling/icons/button/download/zodiac.svg'
import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'
import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'
import { URI } from 'src/utils/apollo'
import { onlyFirstToUpper } from 'src/utils/string'

import CopyToClipboard from './CopyToClipboard'
import styles from './DetailsCard.styles'
import { getStatus, getStatusDetails } from './helper'

const useStyles = makeStyles(styles)
const MINUTES_OFFSET = 3
const TX_SUMMARY = gql`
  query txSummaryAndLogs(
    $txId: ID!
    $deviceId: ID!
    $limit: Int
    $from: Date
    $until: Date
    $txClass: String
    $timezone: String
  ) {
    serverLogsCsv(
      limit: $limit
      from: $from
      until: $until
      timezone: $timezone
    )
    machineLogsCsv(
      deviceId: $deviceId
      limit: $limit
      from: $from
      until: $until
      timezone: $timezone
    )
    transactionCsv(id: $txId, txClass: $txClass, timezone: $timezone)
    txAssociatedDataCsv(id: $txId, txClass: $txClass, timezone: $timezone)
  }
`

const CANCEL_CASH_OUT_TRANSACTION = gql`
  mutation cancelCashOutTransaction($id: ID!) {
    cancelCashOutTransaction(id: $id) {
      id
    }
  }
`

const CANCEL_CASH_IN_TRANSACTION = gql`
  mutation cancelCashInTransaction($id: ID!) {
    cancelCashInTransaction(id: $id) {
      id
    }
  }
`

const formatAddress = (cryptoCode = '', address = '') =>
  coinUtils.formatCryptoAddress(cryptoCode, address).replace(/(.{5})/g, '$1 ')

const Label = ({ children }) => {
  const classes = useStyles()
  return <Label1 className={classes.label}>{children}</Label1>
}

const DetailsRow = ({ it: tx, timezone }) => {
  const classes = useStyles()
  const [action, setAction] = useState({ command: null })
  const [errorMessage, setErrorMessage] = useState('')

  const isCashIn = tx.txClass === 'cashIn'

  const zip = new JSZip()

  const [fetchSummary] = useLazyQuery(TX_SUMMARY, {
    onCompleted: data => createCsv(data)
  })

  const [cancelTransaction] = useMutation(
    isCashIn ? CANCEL_CASH_IN_TRANSACTION : CANCEL_CASH_OUT_TRANSACTION,
    {
      onError: ({ message }) =>
        setErrorMessage(message ?? 'An error occurred.'),
      refetchQueries: () => ['transactions']
    }
  )

  const fiat = Number.parseFloat(tx.fiat)
  const crypto = coinUtils.toUnit(new BigNumber(tx.cryptoAtoms), tx.cryptoCode)
  const commissionPercentage = Number.parseFloat(tx.commissionPercentage, 2)
  const commission = Number(fiat * commissionPercentage).toFixed(2)
  const discount = tx.discount ? `-${tx.discount}%` : null
  const exchangeRate = BigNumber(fiat / crypto).toFormat(2)
  const displayExRate = `1 ${tx.cryptoCode} = ${exchangeRate} ${tx.fiatCode}`

  const parseDateString = d => parse(new Date(), 'yyyyMMdd', d)

  const customer = tx.customerIdCardData && {
    name: `${onlyFirstToUpper(
      tx.customerIdCardData.firstName
    )} ${onlyFirstToUpper(tx.customerIdCardData.lastName)}`,
    age:
      (tx.customerIdCardData.dateOfBirth &&
        differenceInYears(
          parseDateString(tx.customerIdCardData.dateOfBirth),
          new Date()
        )) ??
      '',
    country: tx.customerIdCardData.country,
    idCardNumber: tx.customerIdCardData.documentNumber,
    idCardExpirationDate:
      (tx.customerIdCardData.expirationDate &&
        format('yyyy-MM-dd')(
          parseDateString(tx.customerIdCardData.expirationDate)
        )) ??
      ''
  }

  const from = sub({ minutes: MINUTES_OFFSET }, tx.created)
  const until = add({ minutes: MINUTES_OFFSET }, tx.created)

  const downloadRawLogs = ({ id: txId, deviceId, txClass }, timezone) => {
    fetchSummary({
      variables: { txId, from, until, deviceId, txClass, timezone }
    })
  }

  const createCsv = async logs => {
    const zipFilename = `tx_${tx.id}_summary.zip`
    const filesNames = R.keys(logs)
    R.map(name => zip.file(name + '.csv', logs[name]), filesNames)
    const content = await zip.generateAsync({ type: 'blob' })
    FileSaver.saveAs(content, zipFilename)
  }

  const errorElements = (
    <>
      Transaction status
      {getStatus(tx)}
    </>
  )

  const getCancelMessage = () => {
    const cashInMessage = `The user will not be able to redeem the inserted bills, even if they subsequently confirm the transaction. If they've already deposited bills, you'll need to reconcile this transaction with them manually.`
    const cashOutMessage = `The user will not be able to redeem the cash, even if they subsequently send the required coins. If they've already sent you coins, you'll need to reconcile this transaction with them manually.`

    return isCashIn ? cashInMessage : cashOutMessage
  }

  return (

          Direction

              {!isCashIn ? <TxOutIcon /> : <TxInIcon />}

            {!isCashIn ? 'Cash-out' : 'Cash-in'}

          Available IDs
          <Box display="flex" flexDirection="row">
            {tx.customerPhone && (
              <IDButton
                className={classes.idButton}
                name="phone"
                Icon={PhoneIdIcon}
                InverseIcon={PhoneIdInverseIcon}>
                {tx.customerPhone}
              </IDButton>
            )}
            {tx.customerIdCardPhotoPath && !tx.customerIdCardData && (
              <IDButton
                popoverClassname={classes.clipboardPopover}
                className={classes.idButton}
                name="card"
                Icon={CardIdIcon}
                InverseIcon={CardIdInverseIcon}>
                <img
                  className={classes.idCardPhoto}
                  src={`${URI}/id-card-photo/${tx.customerIdCardPhotoPath}`}
                  alt=""
                />
              </IDButton>
            )}
            {tx.customerIdCardData && (
              <IDButton
                className={classes.idButton}
                name="card"
                Icon={CardIdIcon}
                InverseIcon={CardIdInverseIcon}>

                      Name

{customer.name}

                      Age

{customer.age}

                      Country

{customer.country}

                      ID number

{customer.idCardNumber}

                      Expiration date

{customer.idCardExpirationDate}

              </IDButton>
            )}
            {tx.customerFrontCameraPath && (
              <IDButton
                name="cam"
                Icon={CamIdIcon}
                InverseIcon={CamIdInverseIcon}>
                <img
                  src={`${URI}/front-camera-photo/${tx.customerFrontCameraPath}`}
                  alt=""
                />
              </IDButton>
            )}
          </Box>

          Exchange rate

{crypto > 0 ? displayExRate : '-'}

          Commission

            {`${commission} ${tx.fiatCode} (${commissionPercentage * 100} %)`}
            {discount && (

                <Label1 className={classes.chipLabel}>{discount}</Label1>

            )}

          Fixed fee

            {isCashIn
              ? `${Number.parseFloat(tx.cashInFee)} ${tx.fiatCode}`
              : 'N/A'}

          Address

            <CopyToClipboard>
              {formatAddress(tx.cryptoCode, tx.toAddress)}
            </CopyToClipboard>

          Transaction ID

            {tx.txClass === 'cashOut' ? (
              'N/A'
            ) : (
              <CopyToClipboard>{tx.txHash}</CopyToClipboard>
            )}

          Session ID
          <CopyToClipboard>{tx.id}</CopyToClipboard>

          {getStatusDetails(tx) ? (
            <HoverableTooltip parentElements={errorElements} width={200}>

{getStatusDetails(tx)}

            </HoverableTooltip>
          ) : (
            errorElements
          )}
          {tx.txClass === 'cashOut' && getStatus(tx) === 'Pending' && (
            <ActionButton
              color="primary"
              Icon={CancelIcon}
              InverseIcon={CancelInverseIcon}
              className={classes.cancelTransaction}
              onClick={() =>
                setAction({
                  command: 'cancelTx'
                })
              }>
              Cancel transaction
            </ActionButton>
          )}

          Other actions

            <ActionButton
              color="primary"
              Icon={Download}
              InverseIcon={DownloadInverseIcon}
              className={classes.downloadRawLogs}
              onClick={() => downloadRawLogs(tx, timezone)}>
              Download raw logs
            </ActionButton>

      <ConfirmDialog
        open={action.command === 'cancelTx'}
        title={`Cancel this transaction?`}
        errorMessage={errorMessage}
        toBeConfirmed={tx.machineName}
        message={getCancelMessage()}
        onConfirmed={() => {
          setErrorMessage(null)
          setAction({ command: null })
          cancelTransaction({
            variables: {
              id: tx.id
            }
          })
        }}
        onDismissed={() => {
          setAction({ command: null })
          setErrorMessage(null)
        }}
      />

  )
}

export default memo(
  DetailsRow,
  (prev, next) =>
    prev.it.id === next.it.id &&
    prev.it.hasError === next.it.hasError &&
    getStatus(prev.it) === getStatus(next.it)
)
<|endoftext|>


<commit_before>var util = require('util');
var Promise = require('./index');

exports.pif = pif;
exports.when = when;
exports.unless = unless;
exports.and = and;

function identity(a) {
	return a;
}

function pif(test, consequent, alternate) {
	return function(value) {
		return test(value) ? consequent(value) : alternate(value);
	};
}

function when(test, f) {
	return pif(test, f, identity);
}

function unless(test, f) {
	return pif(test, identity, f);
}

function and(fn) {
	return function(arg) {
		if (!util.isArray(arg)) {
			arg = [arg];
		}

		return Promise.all(arg.concat([fn.apply(this, arg)]));
	};
}

<commit_msg>Only chain arguments created by _and_ function.<commit_after>var util = require('util');
var Promise = require('./index');

exports.pif = pif;
exports.when = when;
exports.unless = unless;
exports.and = and;

function identity(a) {
	return a;
}

function pif(test, consequent, alternate) {
	return function(value) {
		return test(value) ? consequent(value) : alternate(value);
	};
}

function when(test, f) {
	return pif(test, f, identity);
}

function unless(test, f) {
	return pif(test, identity, f);
}

function and(fn) {
	return function(arg) {
		if (!arg || !util.isArray(arg) || arg.__ff_and_sig !== true) {
			arg = [arg];
			arg.__ff_and_sig = true;
		}

		return Promise.all(arg.concat([fn.apply(this, arg)]));
	};
}

<|endoftext|>


<commit_before>// Copyright (c) 2017 Patrick Quist
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

define(function (require) {
    'use strict';
    var jquery = require('jquery');
    var monaco = require('monaco');

    function definition() {
      // Object-Pascal language definition

      return {
        keywords: [
          'unit', 'interface', 'implementation', 'uses',
          'function', 'procedure', 'const', 'begin', 'end', 'not', 'while',
          'as', 'for', 'with',
          'else', 'if',
          'break', 'except', 'on',
          'class', 'exec', 'in', 'throw', 'continue', 'finally', 'is',
          'for', 'try', 'then', 'do',
          ':','=', 'var',
          'strict', 'private', 'protected', 'public', 'published',
        ],
        operators: [
          '+', '-', '*', '/', 'div', 'mod',
          'shl', 'shr', 'and', 'or', 'xor', 'not',
          '<', '>', '<=', '>=', '==', '<>',
          '+=', '-=', '*=', '/=',
        ],
        brackets: [
          ['(',')','delimiter.parenthesis'],
          ['[',']','delimiter.square']
        ],
        symbols:    /[=><!~&|+\-*\/\^%]+/,
        delimiters: /[;=.@:,`]/,
        escapes: /\\(?:[abfnrtv\\'\n\r]|x[0-9A-Fa-f]{2}|[0-7]{3}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8}|N\{\w+\})/,
        rawpre: /(?:[rR]|ur|Ur|uR|UR|br|Br|bR|BR)/,
        strpre: /(?:[buBU])/,

        // The main tokenizer for our languages
        tokenizer: {
          root: [
            // strings: need to check first due to the prefix
            [/@strpre?(''')/, { token: 'string.delim', bracket: '@open', next: '@mstring.$1' } ],
            [/@strpre?'([^'\\]|\\.)*$/, 'string.invalid' ],  // non-teminated string
            [/@strpre?(['])/,  { token: 'string.delim', bracket: '@open', next: '@string.$1' } ],
            [/@rawpre(''')/, { token: 'string.delim', bracket: '@open', next: '@mrawstring.$1' } ],
            [/@rawpre'([^'\\]|\\.)*$/, 'string.invalid' ],  // non-teminated string
            [/@rawpre(['])/,  { token: 'string.delim', bracket: '@open', next: '@rawstring.$1' } ],
            [/__[\w$]*/, 'predefined' ],
            [/[a-z_$][\w$]*/, { cases: { '@keywords': 'keyword',
                                         '@default': 'identifier' } }],
            [/[A-Z][\w]*/, { cases: { '~[A-Z0-9_]+': 'constructor.identifier',
                                      '@default'   : 'namespace.identifier' }}],  // to show class names nicely
            { include: '@whitespace' },
            [/[{}()\[\]]/, '@brackets'],
            [/@symbols/, { cases: { '@keywords' : 'keyword',
                                    '@operators': 'operator',
                                    '@default'  : '' } } ],
            [/\d*\.\d+([eE][\-+]?\d+)?/,   'number.float'],
            [/#$[0-9a-fA-F]+[lL]?/,        'number.hexchar'],
            [/#[bB][0-1]+[lL]?/,           'number.char'],
            [/(0|[1-9]\d*)[lL]?/,          'number'],
            [':', { token: 'keyword', bracket: '@open' }], // bracket for indentation
            [/@delimiters/, { cases: { '@keywords': 'keyword',
                                       '@default': 'delimiter' }}],
          ],
          comment: [
            [/[^\/*]+/, 'comment' ],
            [/\/\*/,    'comment', '@push' ],    // nested comment
            ["\\*/",    'comment', '@pop'  ],
            [/[\/*]/,   'comment' ]
          ],
          mstring: [
            { include: '@strcontent' },
            [/'''/,  { cases: { '$#==$S2':  { token: 'string.delim', bracket: '@close', next: '@pop' },
                                '@default': { token: 'string' } } }],
            [/["']/, 'string' ],
            [/./,    'string.invalid'],
          ],
          string: [
            { include: '@strcontent' },
            [/[']/, { cases: { '$#==$S2': { token: 'string.delim', bracket: '@close', next: '@pop' },
                               '@default': { token: 'string' } } } ],
            [/./, 'string.invalid'],
          ],
          strcontent: [
            [/[^\\']+/,  'string'],
            [/\\$/,      'string.escape'],
            [/@escapes/, 'string.escape'],
            [/\\./,      'string.escape.invalid'],
          ],
          mrawstring: [
            { include: '@rawstrcontent' },
            [/'''/,  { cases: { '$#==$S2':  { token: 'string.delim', bracket: '@close', next: '@pop' },
                                '@default': { token: 'string' } } }],
            [/["']/, 'string' ],
            [/./,    'string.invalid'],
          ],
          rawstring: [
            { include: '@rawstrcontent' },
            [/[']/, { cases: { '$#==$S2': { token: 'string.delim', bracket: '@close', next: '@pop' },
                               '@default': { token: 'string' } } } ],
            [/./, 'string.invalid'],
          ],
          rawstrcontent: [
            [/[^\\']+/, 'string'],
            [/\\[']/,   'string'],
            [/\\/,      'string' ],
          ],
          whitespace: [
            [/[ \t\r\n]+/, 'white'],
            [/#.*$/,       'comment'],
          ],
        },
      };
    }

    monaco.languages.register({id: 'fpc'});
    monaco.languages.setMonarchTokensProvider('fpc', definition());
});
<commit_msg>bugfix fpc syntax highlighting configuration<commit_after>// Copyright (c) 2017 Patrick Quist
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

define(function (require) {
    'use strict';
    var jquery = require('jquery');
    var monaco = require('monaco');

    function definition() {
      // Object-Pascal language definition

      return {
        keywords: [
          'unit', 'interface', 'implementation', 'uses',
          'function', 'procedure', 'const', 'begin', 'end', 'not', 'while',
          'as', 'for', 'with',
          'else', 'if',
          'break', 'except', 'on',
          'class', 'exec', 'in', 'throw', 'continue', 'finally', 'is',
          'for', 'try', 'then', 'do',
          ':','=', 'var',
          'strict', 'private', 'protected', 'public', 'published',
        ],
        operators: [
          '+', '-', '*', '/', 'div', 'mod',
          'shl', 'shr', 'and', 'or', 'xor', 'not',
          '<', '>', '<=', '>=', '==', '<>',
          '+=', '-=', '*=', '/=',
        ],
        brackets: [
          ['(',')','delimiter.parenthesis'],
          ['[',']','delimiter.square']
        ],
        symbols:    /[=><!~&|+\-*\/\^%]+/,
        delimiters: /[;=.@:,`]/,
        escapes: /\\(?:[abfnrtv\\'\n\r]|x[0-9A-Fa-f]{2}|[0-7]{3}|u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8}|N\{\w+\})/,
        rawpre: /(?:[rR]|ur|Ur|uR|UR|br|Br|bR|BR)/,
        strpre: /(?:[buBU])/,

        // The main tokenizer for our languages
        tokenizer: {
          root: [
            // strings: need to check first due to the prefix
            [/@strpre?(''')/, { token: 'string.delim', bracket: '@open', next: '@mstring.$1' } ],
            [/@strpre?'([^'\\]|\\.)*$/, 'string.invalid' ],  // non-teminated string
            [/@strpre?(['])/,  { token: 'string.delim', bracket: '@open', next: '@string.$1' } ],
            [/@rawpre(''')/, { token: 'string.delim', bracket: '@open', next: '@mrawstring.$1' } ],
            [/@rawpre'([^'\\]|\\.)*$/, 'string.invalid' ],  // non-teminated string
            [/@rawpre(['])/,  { token: 'string.delim', bracket: '@open', next: '@rawstring.$1' } ],
            [/__[\w$]*/, 'predefined' ],
            [/[a-z_$][\w$]*/, { cases: { '@keywords': 'keyword',
                                         '@default': 'identifier' } }],
            [/[A-Z][\w]*/, { cases: { '~[A-Z0-9_]+': 'constructor.identifier',
                                      '@default'   : 'namespace.identifier' }}],  // to show class names nicely
            { include: '@whitespace' },
            [/[()\[\]]/, '@brackets'],
            [/@symbols/, { cases: { '@keywords' : 'keyword',
                                    '@operators': 'operator',
                                    '@default'  : '' } } ],
            [/\d*\.\d+([eE][\-+]?\d+)?/,   'number.float'],
            [/#$[0-9a-fA-F]+[lL]?/,        'number.hexchar'],
            [/#[bB][0-1]+[lL]?/,           'number.char'],
            [/(0|[1-9]\d*)[lL]?/,          'number'],
            [':', { token: 'keyword', bracket: '@open' }], // bracket for indentation
            [/@delimiters/, { cases: { '@keywords': 'keyword',
                                       '@default': 'delimiter' }}],
          ],
          comment: [
            [/[^\/*]+/, 'comment' ],
            [/\/\*/,    'comment', '@push' ],    // nested comment
            ["\\*/",    'comment', '@pop'  ],
            [/[\/*]/,   'comment' ]
          ],
          mstring: [
            { include: '@strcontent' },
            [/'''/,  { cases: { '$#==$S2':  { token: 'string.delim', bracket: '@close', next: '@pop' },
                                '@default': { token: 'string' } } }],
            [/["']/, 'string' ],
            [/./,    'string.invalid'],
          ],
          string: [
            { include: '@strcontent' },
            [/[']/, { cases: { '$#==$S2': { token: 'string.delim', bracket: '@close', next: '@pop' },
                               '@default': { token: 'string' } } } ],
            [/./, 'string.invalid'],
          ],
          strcontent: [
            [/[^\\']+/,  'string'],
            [/\\$/,      'string.escape'],
            [/@escapes/, 'string.escape'],
            [/\\./,      'string.escape.invalid'],
          ],
          mrawstring: [
            { include: '@rawstrcontent' },
            [/'''/,  { cases: { '$#==$S2':  { token: 'string.delim', bracket: '@close', next: '@pop' },
                                '@default': { token: 'string' } } }],
            [/["']/, 'string' ],
            [/./,    'string.invalid'],
          ],
          rawstring: [
            { include: '@rawstrcontent' },
            [/[']/, { cases: { '$#==$S2': { token: 'string.delim', bracket: '@close', next: '@pop' },
                               '@default': { token: 'string' } } } ],
            [/./, 'string.invalid'],
          ],
          rawstrcontent: [
            [/[^\\']+/, 'string'],
            [/\\[']/,   'string'],
            [/\\/,      'string' ],
          ],
          whitespace: [
            [/[ \t\r\n]+/, 'white'],
            [/#.*$/,       'comment'],
          ],
        },
      };
    }

    monaco.languages.register({id: 'fpc'});
    monaco.languages.setMonarchTokensProvider('fpc', definition());
});
<|endoftext|>


<commit_before>/**
 * @file This is a classic javascript file for loading real (specified) worker
 * body module javascript file.
 *
 * In module (non-classic) web worker, static import is available. But the function
 * importScripts() will not be avbailable. For solving this problem, using
 * classic (non-module) web worker so that some global library (e.g. tensorflow.js)
 * can be loaded by importScripts(). And use dynamic import() to load ourselves
 * modules because import() can be used in classic (non-module) script.
 */

// Import the module URL specified in the query parameter.
{
  let theURLSearchParams = new URLSearchParams( location.search );
  let workerModuleURL = theURLSearchParams.get( "workerModuleURL" );
  import( workerModuleURL );
}

AsyncWorker_Body_temporaryMessageQueue = []; // Create a temporary message queue.

// Collect all messages before AsyncWorker_Proxy.onmessage_from_AsyncWorker_Body()
// be registered as message handler.
onmessage = ( e ) => {
  AsyncWorker_Body_temporaryMessageQueue.push( e );
}
<commit_msg>AsyncWorker_Body.onmessage_from_AsyncWorker_Proxy<commit_after>/**
 * @file This is a classic javascript file for loading real (specified) worker
 * body module javascript file.
 *
 * In module (non-classic) web worker, static import is available. But the function
 * importScripts() will not be avbailable. For solving this problem, using
 * classic (non-module) web worker so that some global library (e.g. tensorflow.js)
 * can be loaded by importScripts(). And use dynamic import() to load ourselves
 * modules because import() can be used in classic (non-module) script.
 */

// Import the module URL specified in the query parameter.
{
  let theURLSearchParams = new URLSearchParams( location.search );
  let workerModuleURL = theURLSearchParams.get( "workerModuleURL" );
  import( workerModuleURL );
}

AsyncWorker_Body_temporaryMessageQueue = []; // Create a temporary message queue.

// Collect all messages before AsyncWorker_Body.onmessage_from_AsyncWorker_Proxy()
// be registered as message handler.
onmessage = ( e ) => {
  AsyncWorker_Body_temporaryMessageQueue.push( e );
}
<|endoftext|>


<commit_before>/* If the current page shows errors, set the focus to the error messages */
/* globals require, exports */

'use strict';

var $ = require('jquery');

exports.FocusErrorSummary = {
  init: function() {
    var $errorSummary = $('.error-summary');
    // If there is an error summary, set focus to the summary
    if ($errorSummary.length === 1) {
      $errorSummary.focus();
      $errorSummary.on('click', 'a', function(e) {
        e.preventDefault();
        var href = $(this).attr('href');
        $(href).focus();
      });
    }
    // Otherwise, set focus to the field with the error
    else {
      $('.error input:first').focus();
    }
  }
};
<commit_msg>Find ID from error summary even if page appears within string<commit_after>/* If the current page shows errors, set the focus to the error messages */
/* globals require, exports */

'use strict';

var $ = require('jquery');

exports.FocusErrorSummary = {
  init: function() {
    var $errorSummary = $('.error-summary');
    // If there is an error summary, set focus to the summary
    if ($errorSummary.length === 1) {
      $errorSummary.focus();
      $errorSummary.on('click', 'a', function(e) {
        e.preventDefault();
        var href = $(this).attr('href');
        var id = href.substr(href.indexOf('#'));
        $(id).focus();
      });
    }
    // Otherwise, set focus to the field with the error
    else {
      $('.error input:first').focus();
    }
  }
};
<|endoftext|>


<commit_before>define(["utils", "grid-utils", "datepicker/datepicker", "kladr/kladr"], function(utils, gridUtils, datepicker, kladr) {

    function drawParam(data, for_saving) {
        console.log("drawParam");

        var block;

        if (data["type"] === "region"
            || data["type"] === "district"
            || data["type"] === "city"
            || data["type"] === "street"
            || data["type"] === "building"
            || data["type"] === "text"
            || data["type"] === "email"
            || data["type"] === "password"
            || data["type"] === "phon") {
            block = $("<input/>", {type: data["type"]});
            block.attr("id", data["param_id"]);
            if (data["value"]) { block.val(data["value"]); block.attr("param_val_id", data["param_val_id"]); }
            block.attr("for-saving", for_saving);

        } else if (data["type"] === "textarea") {
            block = $("<textarea/>", {});
            block.attr("id", data["param_id"]);
            if (data["value"]) { block.val(data["value"]); block.attr("param_val_id", data["param_val_id"]); }
            block.attr("for-saving", for_saving);

        } else if (data["type"] === "date") {
            block = $("<input/>", {type: "date"});
            block.attr("id", data["param_id"]);
            block.attr("for-saving", for_saving);
            if (data["value"]) { block.val(data["value"]); block.attr("param_val_id", data["param_val_id"]); }
            datepicker.initDatePicker(block);
        }

        var lable = $("<label/>", {
            text: data["param_name"]
        });

        return $("<p/>").append(lable).append(block);
    }

    function getFormData(name) {
        console.log("getFormData");

        var values = [];
        var empty = false;

        $("#"+name+" [for-saving=true]").each(function() {
            if ($(this).val() == "") {
                empty = true;
            }

            values.push({
                "value": $(this).val(),
                "param_val_id": $(this).attr("param_val_id"),
                "id": $(this).attr("id"),
            });
        });

        return empty ? false : values;
    }

    function getListHistoryEvents(historyDiv, F_ids) {
        console.log("getListHistoryEvents: F_ids: ", F_ids);

        utils.postRequest(
            { "form_ids": F_ids, },
            function(response) {
                console.log("getListHistoryEvents: ", response);

                if (response["data"]) {
                    var data = response["data"];
                    for (var i = 0; i < data.length; ++i) {
                        $("#"+historyDiv+" select").append($("<option></option>")
                            .attr("value", data[i]["id"])
                            .text(data[i]["name"])
                        );
                    }
                    $("#"+historyDiv).show();
                }
            },
            "/handler/getlisthistoryevents"
        );
    }

    function ShowPersonBlankFromGroup(group_reg_id, dialogId, gridId) {
        console.log("ShowPersonBlankFromGroup");

        var person_id = gridUtils.getCurrRowId(gridId);
        if (person_id == -1) return false;

        var data = { "group_reg_id": group_reg_id, "person_id": person_id };
        console.log("ShowPersonBlankFromGroup: ", data);

        $("#"+dialogId).empty();

        utils.postRequest(
            data,
            function(data) {
                ShowBlank(data["data"], dialogId);
                $("#"+dialogId+" #history").hide();
            },
            "/gridhandler/getpersonrequestfromgroup"
        );

        $("#"+dialogId).dialog({
            modal: true,
            toTop: "150",
            height: "auto",
            width: "auto",
            buttons: {
                "Сохранить изменения": function() {
                    var values = getFormData(dialogId+" div");
                    if (values == false) {
                        alert("Не все поля заполнены.");
                        return;
                    }

                    utils.postRequest(
                        { "data": values },
                        function(data) { gridUtils.showServerPromtInDialog($("#"+dialogId), data["result"]); },
                        "/gridhandler/editparams"
                    );
                },
                "Отмена": function() {
                    $(this).empty();
                    $(this).dialog("close");
                },
            }
        });
    }

    function ShowBlank(d, dialogId) {
        console.log("ShowBlank data: ", d);

        if (d.length == 0) {
            alert("Нет данных.");
            return;
        }

        var history = $("<p/>", {id: "history"})
            .append($("<h5/>", {text: "Ранее заполненные анкеты"}))
            .append($("<select/>", {}))
            .append($("<input/>", {type: "button", value: "выбрать", id: "send-btn", name: "submit"}));

        $("#"+dialogId).append(history).append($("<h1/>")).append($("<div/>"));

        var F_ids = {};

        $("#" + dialogId + " h1").text(d[0]["event_name"]);

        var div_forms = $("<div/>", {id: "event-" + d[0]["event_id"]});
        var ul_forms = $("<ul/>", {});

        $(div_forms).append(ul_forms);
        $(div_forms).appendTo("#" + dialogId + " div");

        F_ids["form_id"] = [];

        for (i = 0; i < d.length; ++i) {
            if ($("#" + dialogId +" div#form-" + d[i]["form_id"]).attr("id") == undefined) {
                var li_form = $("<li/>", {});
                var a_form = $("<a/>", {href: "#" + "form-" + d[i]["form_id"]}).text(d[i]["form_name"]);

                $(li_form).append(a_form);
                $(ul_forms).append(li_form);

                var div_tab_form = $("<div/>", {id: "form-" + d[i]["form_id"]});
                $(div_forms).append(div_tab_form);

                F_ids["form_id"].push(parseInt(d[i]["form_id"]));

                var div_params = $("<div/>", {id: "params-" + d[i]["form_id"]});
                $(div_tab_form).append(div_params);

                var table = $("<table/>");
                div_params.append(table);

            }

            var tr = $("<tr/>").appendTo($("#" + dialogId +" div#form-" + d[i]["form_id"] + " table"));
            var td_1 = $("<td/>").appendTo(tr);
            $(td_1).append(drawParam(d[i], true));
            tr.append($("<td/>", {id: "export-param-"+d[i]["param_id"]}));
            tr.append($("<td/>", {id: "export-val-"+d[i]["param_id"]}));
        }

        $("#" + dialogId + " #" + "event-" + d[0]["event_id"]).tabs();

        console.log("F_ids: ", F_ids);

        $("#"+dialogId+" #history #send-btn").click(function() {
            utils.postRequest(
                {
                    "event_id": $("#"+dialogId+" #history select").find(":selected").attr("value")
                },
                function(response) {
                    if (response["result"] !== "ok") {
                        ShowServerAns(-1, response, "now #server-answer");
                        return;
                    }
                    ExportDataLoad(response["data"], dialogId);
                },
                "/handler/gethistoryrequest"
            );
        });

        kladr.kladr();

        return F_ids;
    }

    function ShowServerAns(event_id, data, responseId) {
        console.log("ShowServerAns");

        if (data.result === "ok") {
            var msg = "Запрос успешно выполнен.";
            if (event_id != 1) {
                msg += " Ваша заявка на участие будет рассмотрена.";
            } else {
                msg += " Проверьте, пожалуйста, свою почту.";
            }
            $("#"+responseId).text(msg).css("color", "green");

        } else if (data.result === "loginExists") {
            $("#"+responseId).text("Такой логин уже существует.").css("color", "red");

        } else if (data.result === "badLogin") {
            $("#"+responseId).text("Логин может содержать латинские буквы и/или "
                + "цифры и иметь длину от 2 до 36 символов.").css("color", "red");

        } else if (data.result === "badPassword") {
            $("#"+responseId).text("Пароль должен иметь длину от 6 "
                + "до 36 символов.").css("color", "red");

        } else if (data.result === "Unauthorized") {
            $("#"+responseId).text("Пользователь не авторизован.").css("color", "red");

        } else if (data.result === "authorized") {
            $("#"+responseId).text("Пользователь уже авторизован.").css("color", "red");

        } else if (data.result === "badEmail") {
            $("#"+responseId).text("Проверьте правильность введенного Вами email.").css("color", "red");

        } else {
            $("#"+responseId).text(data.result).css("color", "red");
        }
    }

    function ShowPersonBlank(dialogId, regId) {
        console.log("ShowPersonBlank");

        console.log("reg_id", regId)

        $("#"+dialogId).empty();

        utils.postRequest(
            { "reg_id": regId },
            function(data) {
                var f_ids = ShowBlank(data["data"], dialogId);
                getListHistoryEvents(dialogId+" #history", f_ids);
            },
            "/gridhandler/getpersonrequest"
        );

        $("#"+dialogId).dialog({
            modal: true,
            toTop: "150",
            height: "auto",
            width: "auto",
            buttons: {
                "Сохранить изменения": function() {
                    var values = getFormData(dialogId+" div");
                    if (values == false) {
                        alert("Не все поля заполнены.");
                        return;
                    }

                    utils.postRequest(
                        { "data": values },
                        function(data) { gridUtils.showServerPromtInDialog($("#"+dialogId), data["result"]); },
                        "/gridhandler/editparams"
                    );

                },
                "Отмена": function() {
                    $(this).empty();
                    $(this).dialog("close");
                },
            }
        });
    }

    function ExportDataLoad(data, dialogId) {
        console.log("ExportDataLoad: ", data);

        for (var i = 0; i < data.length; ++i) {
            var f_id = data[i]["form_id"];
            var p_id = data[i]["param_id"];
            var p_v = data[i]["value"];

            $("#"+dialogId+" #params-"+f_id +" table #export-param-"+p_id+" input").remove();
            $("#"+dialogId+" #params-"+f_id +" table #export-val-"+p_id+" p").remove();
            if (data[i]["value"] != "") {
                $("#"+dialogId+" #params-"+f_id +" table #export-val-"+p_id).append(drawParam(data[i], 0, false));

                $("<input/>", {
                    "id": "export-btn-"+f_id+"-"+p_id,
                    "type": "button",
                    "value": "экспорт",
                    "data-event-type-id": f_id,
                    "data-param-id": p_id,
                    "data-param-val": p_v,
                }).appendTo("#"+dialogId+" #params-"+f_id+" table #export-param-"+p_id);

                $("#export-btn-"+f_id+"-"+p_id).click(function() {
                    var f_id = $(this).attr("data-event-type-id");
                    var p_id = $(this).attr("data-param-id");
                    var p_v = $(this).attr("data-param-val");
                    $("#"+dialogId+" #params-"+f_id+" table #"+p_id).val(p_v);
                });
            }
        }
    }

    return {
        drawParam: drawParam,
        getFormData: getFormData,
        getListHistoryEvents: getListHistoryEvents,
        ShowBlank: ShowBlank,
        ExportDataLoad: ExportDataLoad,

        ShowPersonBlankFromGroup: ShowPersonBlankFromGroup,
        ShowServerAns: ShowServerAns,
        ShowPersonBlank: ShowPersonBlank,
    };

});
<commit_msg>blank.js: fix msg of server<commit_after>define(["utils", "grid-utils", "datepicker/datepicker", "kladr/kladr"], function(utils, gridUtils, datepicker, kladr) {

    function drawParam(data, for_saving) {
        console.log("drawParam");

        var block;

        if (data["type"] === "region"
            || data["type"] === "district"
            || data["type"] === "city"
            || data["type"] === "street"
            || data["type"] === "building"
            || data["type"] === "text"
            || data["type"] === "email"
            || data["type"] === "password"
            || data["type"] === "phon") {
            block = $("<input/>", {type: data["type"]});
            block.attr("id", data["param_id"]);
            if (data["value"]) { block.val(data["value"]); block.attr("param_val_id", data["param_val_id"]); }
            block.attr("for-saving", for_saving);

        } else if (data["type"] === "textarea") {
            block = $("<textarea/>", {});
            block.attr("id", data["param_id"]);
            if (data["value"]) { block.val(data["value"]); block.attr("param_val_id", data["param_val_id"]); }
            block.attr("for-saving", for_saving);

        } else if (data["type"] === "date") {
            block = $("<input/>", {type: "date"});
            block.attr("id", data["param_id"]);
            block.attr("for-saving", for_saving);
            if (data["value"]) { block.val(data["value"]); block.attr("param_val_id", data["param_val_id"]); }
            datepicker.initDatePicker(block);
        }

        var lable = $("<label/>", {
            text: data["param_name"]
        });

        return $("<p/>").append(lable).append(block);
    }

    function getFormData(name) {
        console.log("getFormData");

        var values = [];
        var empty = false;

        $("#"+name+" [for-saving=true]").each(function() {
            if ($(this).val() == "") {
                empty = true;
            }

            values.push({
                "value": $(this).val(),
                "param_val_id": $(this).attr("param_val_id"),
                "id": $(this).attr("id"),
            });
        });

        return empty ? false : values;
    }

    function getListHistoryEvents(historyDiv, F_ids) {
        console.log("getListHistoryEvents: F_ids: ", F_ids);

        utils.postRequest(
            { "form_ids": F_ids, },
            function(response) {
                console.log("getListHistoryEvents: ", response);

                if (response["data"]) {
                    var data = response["data"];
                    for (var i = 0; i < data.length; ++i) {
                        $("#"+historyDiv+" select").append($("<option></option>")
                            .attr("value", data[i]["id"])
                            .text(data[i]["name"])
                        );
                    }
                    $("#"+historyDiv).show();
                }
            },
            "/handler/getlisthistoryevents"
        );
    }

    function ShowPersonBlankFromGroup(group_reg_id, dialogId, gridId) {
        console.log("ShowPersonBlankFromGroup");

        var person_id = gridUtils.getCurrRowId(gridId);
        if (person_id == -1) return false;

        var data = { "group_reg_id": group_reg_id, "person_id": person_id };
        console.log("ShowPersonBlankFromGroup: ", data);

        $("#"+dialogId).empty();

        utils.postRequest(
            data,
            function(data) {
                ShowBlank(data["data"], dialogId);
                $("#"+dialogId+" #history").hide();
            },
            "/gridhandler/getpersonrequestfromgroup"
        );

        $("#"+dialogId).dialog({
            modal: true,
            toTop: "150",
            height: "auto",
            width: "auto",
            buttons: {
                "Сохранить изменения": function() {
                    var values = getFormData(dialogId+" div");
                    if (values == false) {
                        alert("Не все поля заполнены.");
                        return;
                    }

                    utils.postRequest(
                        { "data": values },
                        function(data) { gridUtils.showServerPromtInDialog($("#"+dialogId), data["result"]); },
                        "/gridhandler/editparams"
                    );
                },
                "Отмена": function() {
                    $(this).empty();
                    $(this).dialog("close");
                },
            }
        });
    }

    function ShowBlank(d, dialogId) {
        console.log("ShowBlank data: ", d);

        if (d.length == 0) {
            alert("Нет данных.");
            return;
        }

        var history = $("<p/>", {id: "history"})
            .append($("<h5/>", {text: "Ранее заполненные анкеты"}))
            .append($("<select/>", {}))
            .append($("<input/>", {type: "button", value: "выбрать", id: "send-btn", name: "submit"}));

        $("#"+dialogId).append(history).append($("<h1/>")).append($("<div/>"));

        var F_ids = {};

        $("#" + dialogId + " h1").text(d[0]["event_name"]);

        var div_forms = $("<div/>", {id: "event-" + d[0]["event_id"]});
        var ul_forms = $("<ul/>", {});

        $(div_forms).append(ul_forms);
        $(div_forms).appendTo("#" + dialogId + " div");

        F_ids["form_id"] = [];

        for (i = 0; i < d.length; ++i) {
            if ($("#" + dialogId +" div#form-" + d[i]["form_id"]).attr("id") == undefined) {
                var li_form = $("<li/>", {});
                var a_form = $("<a/>", {href: "#" + "form-" + d[i]["form_id"]}).text(d[i]["form_name"]);

                $(li_form).append(a_form);
                $(ul_forms).append(li_form);

                var div_tab_form = $("<div/>", {id: "form-" + d[i]["form_id"]});
                $(div_forms).append(div_tab_form);

                F_ids["form_id"].push(parseInt(d[i]["form_id"]));

                var div_params = $("<div/>", {id: "params-" + d[i]["form_id"]});
                $(div_tab_form).append(div_params);

                var table = $("<table/>");
                div_params.append(table);

            }

            var tr = $("<tr/>").appendTo($("#" + dialogId +" div#form-" + d[i]["form_id"] + " table"));
            var td_1 = $("<td/>").appendTo(tr);
            $(td_1).append(drawParam(d[i], true));
            tr.append($("<td/>", {id: "export-param-"+d[i]["param_id"]}));
            tr.append($("<td/>", {id: "export-val-"+d[i]["param_id"]}));
        }

        $("#" + dialogId + " #" + "event-" + d[0]["event_id"]).tabs();

        console.log("F_ids: ", F_ids);

        $("#"+dialogId+" #history #send-btn").click(function() {
            utils.postRequest(
                {
                    "event_id": $("#"+dialogId+" #history select").find(":selected").attr("value")
                },
                function(response) {
                    if (response["result"] !== "ok") {
                        ShowServerAns(-1, response, "now #server-answer");
                        return;
                    }
                    ExportDataLoad(response["data"], dialogId);
                },
                "/handler/gethistoryrequest"
            );
        });

        kladr.kladr();

        return F_ids;
    }

    function ShowServerAns(event_id, data, responseId) {
        console.log("ShowServerAns");

        if (data.result === "ok") {
            var msg = "Запрос успешно выполнен.";
            if (event_id != 1) {
                msg += " Ваша заявка на участие будет рассмотрена.";
            } else {
                msg += " На вашу электронную почту было отправлено письмо, содержащее ссылку для подтверждения регистрации. "
                + "Воспользуйтесь этой ссылкой, для продолжения работы.";
            }
            $("#"+responseId).text(msg).css("color", "green");

        } else if (data.result === "loginExists") {
            $("#"+responseId).text("Такой логин уже существует.").css("color", "red");

        } else if (data.result === "badLogin") {
            $("#"+responseId).text("Логин может содержать латинские буквы и/или "
                + "цифры и иметь длину от 2 до 36 символов.").css("color", "red");

        } else if (data.result === "badPassword") {
            $("#"+responseId).text("Пароль должен иметь длину от 6 "
                + "до 36 символов.").css("color", "red");

        } else if (data.result === "Unauthorized") {
            $("#"+responseId).text("Пользователь не авторизован.").css("color", "red");

        } else if (data.result === "authorized") {
            $("#"+responseId).text("Пользователь уже авторизован.").css("color", "red");

        } else if (data.result === "badEmail") {
            $("#"+responseId).text("Проверьте правильность введенного Вами email.").css("color", "red");

        } else {
            $("#"+responseId).text(data.result).css("color", "red");
        }
    }

    function ShowPersonBlank(dialogId, regId) {
        console.log("ShowPersonBlank");

        console.log("reg_id", regId)

        $("#"+dialogId).empty();

        utils.postRequest(
            { "reg_id": regId },
            function(data) {
                var f_ids = ShowBlank(data["data"], dialogId);
                getListHistoryEvents(dialogId+" #history", f_ids);
            },
            "/gridhandler/getpersonrequest"
        );

        $("#"+dialogId).dialog({
            modal: true,
            toTop: "150",
            height: "auto",
            width: "auto",
            buttons: {
                "Сохранить изменения": function() {
                    var values = getFormData(dialogId+" div");
                    if (values == false) {
                        alert("Не все поля заполнены.");
                        return;
                    }

                    utils.postRequest(
                        { "data": values },
                        function(data) { gridUtils.showServerPromtInDialog($("#"+dialogId), data["result"]); },
                        "/gridhandler/editparams"
                    );

                },
                "Отмена": function() {
                    $(this).empty();
                    $(this).dialog("close");
                },
            }
        });
    }

    function ExportDataLoad(data, dialogId) {
        console.log("ExportDataLoad: ", data);

        for (var i = 0; i < data.length; ++i) {
            var f_id = data[i]["form_id"];
            var p_id = data[i]["param_id"];
            var p_v = data[i]["value"];

            $("#"+dialogId+" #params-"+f_id +" table #export-param-"+p_id+" input").remove();
            $("#"+dialogId+" #params-"+f_id +" table #export-val-"+p_id+" p").remove();
            if (data[i]["value"] != "") {
                $("#"+dialogId+" #params-"+f_id +" table #export-val-"+p_id).append(drawParam(data[i], 0, false));

                $("<input/>", {
                    "id": "export-btn-"+f_id+"-"+p_id,
                    "type": "button",
                    "value": "экспорт",
                    "data-event-type-id": f_id,
                    "data-param-id": p_id,
                    "data-param-val": p_v,
                }).appendTo("#"+dialogId+" #params-"+f_id+" table #export-param-"+p_id);

                $("#export-btn-"+f_id+"-"+p_id).click(function() {
                    var f_id = $(this).attr("data-event-type-id");
                    var p_id = $(this).attr("data-param-id");
                    var p_v = $(this).attr("data-param-val");
                    $("#"+dialogId+" #params-"+f_id+" table #"+p_id).val(p_v);
                });
            }
        }
    }

    return {
        drawParam: drawParam,
        getFormData: getFormData,
        getListHistoryEvents: getListHistoryEvents,
        ShowBlank: ShowBlank,
        ExportDataLoad: ExportDataLoad,

        ShowPersonBlankFromGroup: ShowPersonBlankFromGroup,
        ShowServerAns: ShowServerAns,
        ShowPersonBlank: ShowPersonBlank,
    };

});
<|endoftext|>


<commit_before>const postcss = require('postcss')

const plugin = 'postcss-import-export-parser'

module.exports = postcss.plugin(
  plugin,
  () => async function process(css, result) {
    let scope = ''
    css.walkAtRules('kaliber-scoped', rule => { scope = rule.params })
    if (!scope) return

    css.each(x => {
      if (x.type !== 'rule') return
      x.selector = `${scope} ${x.selector}`
    })
  }
)
<commit_msg>Update postcss-kaliber-scoped.js<commit_after>const postcss = require('postcss')

const plugin = 'postcss-kaliber-scoped'

module.exports = postcss.plugin(
  plugin,
  () => async function process(css, result) {
    let scope = ''
    css.walkAtRules('kaliber-scoped', rule => { scope = rule.params })
    if (!scope) return

    css.each(x => {
      if (x.type !== 'rule') return
      x.selector = `${scope} ${x.selector}`
    })
  }
)
<|endoftext|>


<commit_before>
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is guacamole-common-js.
 *
 * The Initial Developer of the Original Code is
 * Michael Jumper.
 * Portions created by the Initial Developer are Copyright (C) 2010
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

// Guacamole namespace
var Guacamole = Guacamole || {};

/**
 * Guacamole protocol client. Given a display element and {@link Guacamole.Tunnel},
 * automatically handles incoming and outgoing Guacamole instructions via the
 * provided tunnel, updating the display using one or more canvas elements.
 *
 * @constructor
 * @param {Element} display The display element to add canvas elements to.
 * @param {Guacamole.Tunnel} tunnel The tunnel to use to send and receive
 *                                  Guacamole instructions.
 */
Guacamole.Client = function(display, tunnel) {

    var guac_client = this;

    var STATE_IDLE          = 0;
    var STATE_CONNECTING    = 1;
    var STATE_WAITING       = 2;
    var STATE_CONNECTED     = 3;
    var STATE_DISCONNECTING = 4;
    var STATE_DISCONNECTED  = 5;

    var currentState = STATE_IDLE;

    tunnel.onerror = function(message) {
        if (guac_client.onerror)
            guac_client.onerror(message);
    };

    // Display must be relatively positioned for mouse to be handled properly
    display.style.position = "relative";

    function setState(state) {
        if (state != currentState) {
            currentState = state;
            if (guac_client.onstatechange)
                guac_client.onstatechange(currentState);
        }
    }

    function isConnected() {
        return currentState == STATE_CONNECTED
            || currentState == STATE_WAITING;
    }

    var cursorImage = null;
    var cursorHotspotX = 0;
    var cursorHotspotY = 0;

    var cursorRectX = 0;
    var cursorRectY = 0;
    var cursorRectW = 0;
    var cursorRectH = 0;

    var cursorHidden = 0;

    function redrawCursor(x, y) {

        // Hide hardware cursor
        if (cursorHidden == 0) {
            display.className += " guac-hide-cursor";
            cursorHidden = 1;
        }

        // Erase old cursor
        cursor.clearRect(cursorRectX, cursorRectY, cursorRectW, cursorRectH);

        // Update rect
        cursorRectX = x - cursorHotspotX;
        cursorRectY = y - cursorHotspotY;
        cursorRectW = cursorImage.width;
        cursorRectH = cursorImage.height;

        // Draw new cursor
        cursor.drawImage(cursorRectX, cursorRectY, cursorImage);
    }

    guac_client.sendKeyEvent = function(pressed, keysym) {
        // Do not send requests if not connected
        if (!isConnected())
            return;

        tunnel.sendMessage("key", keysym, pressed);
    };

    guac_client.sendMouseState = function(mouseState) {

        // Do not send requests if not connected
        if (!isConnected())
            return;

        // Draw client-side cursor
        if (cursorImage != null) {
            redrawCursor(
                mouseState.x,
                mouseState.y
            );
        }

        // Build mask
        var buttonMask = 0;
        if (mouseState.left)   buttonMask |= 1;
        if (mouseState.middle) buttonMask |= 2;
        if (mouseState.right)  buttonMask |= 4;
        if (mouseState.up)     buttonMask |= 8;
        if (mouseState.down)   buttonMask |= 16;

        // Send message
        tunnel.sendMessage("mouse", mouseState.x, mouseState.y, buttonMask);
    };

    guac_client.setClipboard = function(data) {

        // Do not send requests if not connected
        if (!isConnected())
            return;

        tunnel.sendMessage("clipboard", data);
    };

    // Handlers
    guac_client.onstatechange = null;
    guac_client.onname = null;
    guac_client.onerror = null;
    guac_client.onclipboard = null;

    // Layers
    var displayWidth = 0;
    var displayHeight = 0;

    var layers = new Array();
    var buffers = new Array();
    var cursor = null;

    guac_client.getLayers = function() {
        return layers;
    };

    function getLayer(index) {

        // If negative index, use buffer
        if (index < 0) {

            index = -1 - index;
            var buffer = buffers[index];

            // Create buffer if necessary
            if (buffer == null) {
                buffer = new Guacamole.Layer(0, 0);
                buffer.autosize = 1;
                buffers[index] = buffer;
            }

            return buffer;
        }

        // If non-negative, use visible layer
        else {

            var layer = layers[index];
            if (layer == null) {

                // Add new layer
                layer = new Guacamole.Layer(displayWidth, displayHeight);

                // Set layer position
                var canvas = layer.getCanvas();
                canvas.style.position = "absolute";
                canvas.style.left = "0px";
                canvas.style.top = "0px";

                layers[index] = layer;

                // (Re)-add existing layers in order
                for (var i=0; i<layers.length; i++) {
                    if (layers[i]) {

                        // If already present, remove
                        if (layers[i].parentNode === display)
                            display.removeChild(layers[i].getCanvas());

                        // Add to end
                        display.appendChild(layers[i].getCanvas());
                    }
                }

                // Add cursor layer last
                if (cursor != null) {
                    if (cursor.parentNode === display)
                        display.removeChild(cursor.getCanvas());
                    display.appendChild(cursor.getCanvas());
                }

            }
            else {
                // Reset size
                layer.resize(displayWidth, displayHeight);
            }

            return layer;
        }

    }

    var instructionHandlers = {

        "error": function(parameters) {
            if (guac_client.onerror) guac_client.onerror(parameters[0]);
            guac_client.disconnect();
        },

        "name": function(parameters) {
            if (guac_client.onname) guac_client.onname(parameters[0]);
        },

        "clipboard": function(parameters) {
            if (guac_client.onclipboard) guac_client.onclipboard(parameters[0]);
        },

        "size": function(parameters) {

            displayWidth = parseInt(parameters[0]);
            displayHeight = parseInt(parameters[1]);

            // Update (set) display size
            display.style.width = displayWidth + "px";
            display.style.height = displayHeight + "px";

            // Set cursor layer width/height
            if (cursor != null)
                cursor.resize(displayWidth, displayHeight);

        },

        "png": function(parameters) {

            var channelMask = parseInt(parameters[0]);
            var layer = getLayer(parseInt(parameters[1]));
            var x = parseInt(parameters[2]);
            var y = parseInt(parameters[3]);
            var data = parameters[4];

            layer.setChannelMask(channelMask);

            layer.draw(
                x,
                y,
                "data:image/png;base64," + data
            );

            // If received first update, no longer waiting.
            if (currentState == STATE_WAITING)
                setState(STATE_CONNECTED);

        },

        "copy": function(parameters) {

            var srcL = getLayer(parseInt(parameters[0]));
            var srcX = parseInt(parameters[1]);
            var srcY = parseInt(parameters[2]);
            var srcWidth = parseInt(parameters[3]);
            var srcHeight = parseInt(parameters[4]);
            var channelMask = parseInt(parameters[5]);
            var dstL = getLayer(parseInt(parameters[6]));
            var dstX = parseInt(parameters[7]);
            var dstY = parseInt(parameters[8]);

            dstL.setChannelMask(channelMask);

            dstL.copyRect(
                srcL,
                srcX,
                srcY,
                srcWidth,
                srcHeight,
                dstX,
                dstY
            );

        },

        "rect": function(parameters) {

            var channelMask = parseInt(parameters[0]);
            var layer = getLayer(parseInt(parameters[1]));
            var x = parseInt(parameters[2]);
            var y = parseInt(parameters[3]);
            var w = parseInt(parameters[4]);
            var h = parseInt(parameters[5]);
            var r = parseInt(parameters[6]);
            var g = parseInt(parameters[7]);
            var b = parseInt(parameters[8]);
            var a = parseInt(parameters[9]);

            layer.setChannelMask(channelMask);

            layer.drawRect(
                x, y, w, h,
                r, g, b, a
            );

        },

        "clip": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));
            var x = parseInt(parameters[1]);
            var y = parseInt(parameters[2]);
            var w = parseInt(parameters[3]);
            var h = parseInt(parameters[4]);

            layer.clipRect(x, y, w, h);

        },

        "cursor": function(parameters) {

            var x = parseInt(parameters[0]);
            var y = parseInt(parameters[1]);
            var data = parameters[2];

            if (cursor == null) {
                cursor = new Guacamole.Layer(displayWidth, displayHeight);

                var canvas = cursor.getCanvas();
                canvas.style.position = "absolute";
                canvas.style.left = "0px";
                canvas.style.top = "0px";

                display.appendChild(canvas);
            }

            // Start cursor image load
            var image = new Image();
            image.onload = function() {
                cursorImage = image;

                var cursorX = cursorRectX + cursorHotspotX;
                var cursorY = cursorRectY + cursorHotspotY;

                cursorHotspotX = x;
                cursorHotspotY = y;

                redrawCursor(cursorX, cursorY);
            };
            image.src = "data:image/png;base64," + data

        },

        "sync": function(parameters) {

            var timestamp = parameters[0];

            // When all layers have finished rendering all instructions
            // UP TO THIS POINT IN TIME, send sync response.

            var layersToSync = 0;
            function syncLayer() {

                layersToSync--;

                // Send sync response when layers are finished
                if (layersToSync == 0)
                    tunnel.sendMessage("sync", timestamp);

            }

            // Count active, not-ready layers and install sync tracking hooks
            for (var i=0; i<layers.length; i++) {

                var layer = layers[i];
                if (layer && !layer.isReady()) {
                    layersToSync++;
                    layer.sync(syncLayer);
                }

            }

            // If all layers are ready, then we didn't install any hooks.
            // Send sync message now,
            if (layersToSync == 0)
                tunnel.sendMessage("sync", timestamp);

        }

    };

    tunnel.oninstruction = function(opcode, parameters) {

        var handler = instructionHandlers[opcode];
        if (handler)
            handler(parameters);

    };

    guac_client.disconnect = function() {

        // Only attempt disconnection not disconnected.
        if (currentState != STATE_DISCONNECTED
                && currentState != STATE_DISCONNECTING) {

            setState(STATE_DISCONNECTING);
            tunnel.sendMessage("disconnect");
            tunnel.disconnect();
            setState(STATE_DISCONNECTED);
        }

    };

    guac_client.connect = function(data) {

        setState(STATE_CONNECTING);

        try {
            tunnel.connect(data);
        }
        catch (e) {
            setState(STATE_IDLE);
            throw e;
        }

        setState(STATE_WAITING);
    };

};

<commit_msg>Automatically ping every 5 seconds.<commit_after>
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is guacamole-common-js.
 *
 * The Initial Developer of the Original Code is
 * Michael Jumper.
 * Portions created by the Initial Developer are Copyright (C) 2010
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

// Guacamole namespace
var Guacamole = Guacamole || {};

/**
 * Guacamole protocol client. Given a display element and {@link Guacamole.Tunnel},
 * automatically handles incoming and outgoing Guacamole instructions via the
 * provided tunnel, updating the display using one or more canvas elements.
 *
 * @constructor
 * @param {Element} display The display element to add canvas elements to.
 * @param {Guacamole.Tunnel} tunnel The tunnel to use to send and receive
 *                                  Guacamole instructions.
 */
Guacamole.Client = function(display, tunnel) {

    var guac_client = this;

    var STATE_IDLE          = 0;
    var STATE_CONNECTING    = 1;
    var STATE_WAITING       = 2;
    var STATE_CONNECTED     = 3;
    var STATE_DISCONNECTING = 4;
    var STATE_DISCONNECTED  = 5;

    var currentState = STATE_IDLE;

    var currentTimestamp = 0;
    var pingInterval = null;

    tunnel.onerror = function(message) {
        if (guac_client.onerror)
            guac_client.onerror(message);
    };

    // Display must be relatively positioned for mouse to be handled properly
    display.style.position = "relative";

    function setState(state) {
        if (state != currentState) {
            currentState = state;
            if (guac_client.onstatechange)
                guac_client.onstatechange(currentState);
        }
    }

    function isConnected() {
        return currentState == STATE_CONNECTED
            || currentState == STATE_WAITING;
    }

    var cursorImage = null;
    var cursorHotspotX = 0;
    var cursorHotspotY = 0;

    var cursorRectX = 0;
    var cursorRectY = 0;
    var cursorRectW = 0;
    var cursorRectH = 0;

    var cursorHidden = 0;

    function redrawCursor(x, y) {

        // Hide hardware cursor
        if (cursorHidden == 0) {
            display.className += " guac-hide-cursor";
            cursorHidden = 1;
        }

        // Erase old cursor
        cursor.clearRect(cursorRectX, cursorRectY, cursorRectW, cursorRectH);

        // Update rect
        cursorRectX = x - cursorHotspotX;
        cursorRectY = y - cursorHotspotY;
        cursorRectW = cursorImage.width;
        cursorRectH = cursorImage.height;

        // Draw new cursor
        cursor.drawImage(cursorRectX, cursorRectY, cursorImage);
    }

    guac_client.sendKeyEvent = function(pressed, keysym) {
        // Do not send requests if not connected
        if (!isConnected())
            return;

        tunnel.sendMessage("key", keysym, pressed);
    };

    guac_client.sendMouseState = function(mouseState) {

        // Do not send requests if not connected
        if (!isConnected())
            return;

        // Draw client-side cursor
        if (cursorImage != null) {
            redrawCursor(
                mouseState.x,
                mouseState.y
            );
        }

        // Build mask
        var buttonMask = 0;
        if (mouseState.left)   buttonMask |= 1;
        if (mouseState.middle) buttonMask |= 2;
        if (mouseState.right)  buttonMask |= 4;
        if (mouseState.up)     buttonMask |= 8;
        if (mouseState.down)   buttonMask |= 16;

        // Send message
        tunnel.sendMessage("mouse", mouseState.x, mouseState.y, buttonMask);
    };

    guac_client.setClipboard = function(data) {

        // Do not send requests if not connected
        if (!isConnected())
            return;

        tunnel.sendMessage("clipboard", data);
    };

    // Handlers
    guac_client.onstatechange = null;
    guac_client.onname = null;
    guac_client.onerror = null;
    guac_client.onclipboard = null;

    // Layers
    var displayWidth = 0;
    var displayHeight = 0;

    var layers = new Array();
    var buffers = new Array();
    var cursor = null;

    guac_client.getLayers = function() {
        return layers;
    };

    function getLayer(index) {

        // If negative index, use buffer
        if (index < 0) {

            index = -1 - index;
            var buffer = buffers[index];

            // Create buffer if necessary
            if (buffer == null) {
                buffer = new Guacamole.Layer(0, 0);
                buffer.autosize = 1;
                buffers[index] = buffer;
            }

            return buffer;
        }

        // If non-negative, use visible layer
        else {

            var layer = layers[index];
            if (layer == null) {

                // Add new layer
                layer = new Guacamole.Layer(displayWidth, displayHeight);

                // Set layer position
                var canvas = layer.getCanvas();
                canvas.style.position = "absolute";
                canvas.style.left = "0px";
                canvas.style.top = "0px";

                layers[index] = layer;

                // (Re)-add existing layers in order
                for (var i=0; i<layers.length; i++) {
                    if (layers[i]) {

                        // If already present, remove
                        if (layers[i].parentNode === display)
                            display.removeChild(layers[i].getCanvas());

                        // Add to end
                        display.appendChild(layers[i].getCanvas());
                    }
                }

                // Add cursor layer last
                if (cursor != null) {
                    if (cursor.parentNode === display)
                        display.removeChild(cursor.getCanvas());
                    display.appendChild(cursor.getCanvas());
                }

            }
            else {
                // Reset size
                layer.resize(displayWidth, displayHeight);
            }

            return layer;
        }

    }

    var instructionHandlers = {

        "error": function(parameters) {
            if (guac_client.onerror) guac_client.onerror(parameters[0]);
            guac_client.disconnect();
        },

        "name": function(parameters) {
            if (guac_client.onname) guac_client.onname(parameters[0]);
        },

        "clipboard": function(parameters) {
            if (guac_client.onclipboard) guac_client.onclipboard(parameters[0]);
        },

        "size": function(parameters) {

            displayWidth = parseInt(parameters[0]);
            displayHeight = parseInt(parameters[1]);

            // Update (set) display size
            display.style.width = displayWidth + "px";
            display.style.height = displayHeight + "px";

            // Set cursor layer width/height
            if (cursor != null)
                cursor.resize(displayWidth, displayHeight);

        },

        "png": function(parameters) {

            var channelMask = parseInt(parameters[0]);
            var layer = getLayer(parseInt(parameters[1]));
            var x = parseInt(parameters[2]);
            var y = parseInt(parameters[3]);
            var data = parameters[4];

            layer.setChannelMask(channelMask);

            layer.draw(
                x,
                y,
                "data:image/png;base64," + data
            );

            // If received first update, no longer waiting.
            if (currentState == STATE_WAITING)
                setState(STATE_CONNECTED);

        },

        "copy": function(parameters) {

            var srcL = getLayer(parseInt(parameters[0]));
            var srcX = parseInt(parameters[1]);
            var srcY = parseInt(parameters[2]);
            var srcWidth = parseInt(parameters[3]);
            var srcHeight = parseInt(parameters[4]);
            var channelMask = parseInt(parameters[5]);
            var dstL = getLayer(parseInt(parameters[6]));
            var dstX = parseInt(parameters[7]);
            var dstY = parseInt(parameters[8]);

            dstL.setChannelMask(channelMask);

            dstL.copyRect(
                srcL,
                srcX,
                srcY,
                srcWidth,
                srcHeight,
                dstX,
                dstY
            );

        },

        "rect": function(parameters) {

            var channelMask = parseInt(parameters[0]);
            var layer = getLayer(parseInt(parameters[1]));
            var x = parseInt(parameters[2]);
            var y = parseInt(parameters[3]);
            var w = parseInt(parameters[4]);
            var h = parseInt(parameters[5]);
            var r = parseInt(parameters[6]);
            var g = parseInt(parameters[7]);
            var b = parseInt(parameters[8]);
            var a = parseInt(parameters[9]);

            layer.setChannelMask(channelMask);

            layer.drawRect(
                x, y, w, h,
                r, g, b, a
            );

        },

        "clip": function(parameters) {

            var layer = getLayer(parseInt(parameters[0]));
            var x = parseInt(parameters[1]);
            var y = parseInt(parameters[2]);
            var w = parseInt(parameters[3]);
            var h = parseInt(parameters[4]);

            layer.clipRect(x, y, w, h);

        },

        "cursor": function(parameters) {

            var x = parseInt(parameters[0]);
            var y = parseInt(parameters[1]);
            var data = parameters[2];

            if (cursor == null) {
                cursor = new Guacamole.Layer(displayWidth, displayHeight);

                var canvas = cursor.getCanvas();
                canvas.style.position = "absolute";
                canvas.style.left = "0px";
                canvas.style.top = "0px";

                display.appendChild(canvas);
            }

            // Start cursor image load
            var image = new Image();
            image.onload = function() {
                cursorImage = image;

                var cursorX = cursorRectX + cursorHotspotX;
                var cursorY = cursorRectY + cursorHotspotY;

                cursorHotspotX = x;
                cursorHotspotY = y;

                redrawCursor(cursorX, cursorY);
            };
            image.src = "data:image/png;base64," + data

        },

        "sync": function(parameters) {

            var timestamp = parameters[0];

            // When all layers have finished rendering all instructions
            // UP TO THIS POINT IN TIME, send sync response.

            var layersToSync = 0;
            function syncLayer() {

                layersToSync--;

                // Send sync response when layers are finished
                if (layersToSync == 0) {
                    tunnel.sendMessage("sync", timestamp);
                    currentTimestamp = timestamp;
                }

            }

            // Count active, not-ready layers and install sync tracking hooks
            for (var i=0; i<layers.length; i++) {

                var layer = layers[i];
                if (layer && !layer.isReady()) {
                    layersToSync++;
                    layer.sync(syncLayer);
                }

            }

            // If all layers are ready, then we didn't install any hooks.
            // Send sync message now,
            if (layersToSync == 0) {
                tunnel.sendMessage("sync", timestamp);
                currentTimestamp = timestamp;
            }

        }

    };

    tunnel.oninstruction = function(opcode, parameters) {

        var handler = instructionHandlers[opcode];
        if (handler)
            handler(parameters);

    };

    guac_client.disconnect = function() {

        // Only attempt disconnection not disconnected.
        if (currentState != STATE_DISCONNECTED
                && currentState != STATE_DISCONNECTING) {

            setState(STATE_DISCONNECTING);

            // Stop ping
            if (pingInterval)
                window.clearInterval(pingInterval);

            // Send disconnect message and disconnect
            tunnel.sendMessage("disconnect");
            tunnel.disconnect();
            setState(STATE_DISCONNECTED);

        }

    };

    guac_client.connect = function(data) {

        setState(STATE_CONNECTING);

        try {
            tunnel.connect(data);
        }
        catch (e) {
            setState(STATE_IDLE);
            throw e;
        }

        // Ping every 5 seconds (ensure connection alive)
        pingInterval = window.setInterval(function() {
            tunnel.sendMessage("sync", currentTimestamp);
        }, 5000);

        setState(STATE_WAITING);
    };

};

<|endoftext|>


<commit_before>import React from 'react'

const Organizations = ({label, organizations}) => {
  const styles = {
    list: {
      paddingTop: "2em",
      paddingBottom: "2em",
    },
  }
  return (

{label}

        {Object.keys(organizations).map( key =>

{key}

{organizations[key]}

      )}

  )
}

export default Organizations
<commit_msg>Fix single quotes issues of Organizations.js<commit_after>import React from 'react'

const Organizations = ({label, organizations}) => {
  const styles = {
    list: {
      paddingTop: '2em',
      paddingBottom: '2em',
    },
  }
  return (

{label}

        {Object.keys(organizations).map( key =>

{key}

{organizations[key]}

      )}

  )
}

export default Organizations
<|endoftext|>


<commit_before>import { default as urlJobPopulator } from './urlJobPopulator.js';
import { default as urlJobProcessor } from './urlJobProcessor.js';
import { default as dataStore } from '../dataStore/dataStore.js';
import { default as kue } from 'kue';

// TODO: Clean up jobs

let addingNewJobs = false;
const queue = kue.createQueue({ jobEvents: false });

queue.on('error', (err) => {
  console.error(`UNCAUGHT ERROR: ${err}`);
});

process.on('SIGINT', () => {
  queue.shutdown(5000, (err) => {
    console.log('URL job queue shutdown initiated');
    if (err) {
      console.error(`Error shutting down Kue: ${err}`);
      return process.exit(1);
    }
    console.log('URL job queue shutdown complete');
    return process.exit(0);
  });
});

function populateJobs() {
  if (addingNewJobs) {
    return;
  }

  addingNewJobs = true;
  urlJobPopulator.populate();
}

function addJobs(urls) {
  urls.forEach((url) => {
    // TODO: Configurable retry attempts
    queue.create('url', url).attempts(5).backoff(true).save((err) => {
      if (err) {
        console.error(`FAILED to add job: ${url}`);
      }
    });
  });
}

function startProcessingJobs() {
  // TODO: Configurable number of urls processing concurrently
  queue.process('url', 50, (job, done) => {
    urlJobProcessor.processUrlJob(job.data).then((result) => {
      return dataStore.updateWithCurrentCrawlResult(result).then(() => {
        done(null, result);
      });
    }).catch((err) => {
      done(err);
    });
  });
}

// TODO Configure from a config file

const configPromises = [];

configPromises.push(urlJobPopulator.configure({
  backendName: 'static',
  progressCallback: addJobs,
  finishedCallback: () => { addingNewJobs = false; },
}));

configPromises.push(dataStore.configure({
  backendName: 'redis',
  backendOpts: {
    url: 'redis://localhost:6379',
  },
}));

configPromises.push(urlJobProcessor.configure({

}));

Promise.all(configPromises).then(() => {
  queue.inactiveCount((err, total) => {
    if (err) {
      return console.error(`inactiveCount failure: ${err}`);
    }

    // FIXME: We need to also look at completeCount and failedCount
    if (total === 0) {
      console.log('No crawl in progress, starting new crawl');
      populateJobs();
    } else {
      console.log('Resuming previous crawl');
    }

    startProcessingJobs();
  });
}).catch((err) => {
  console.error(err);
  return process.exit(1);
});
<commit_msg>crawler driver changes<commit_after>import { default as urlJobPopulator } from './urlJobPopulator.js';
import { default as urlJobProcessor } from './urlJobProcessor.js';
import { default as dataStore } from '../dataStore/dataStore.js';
import { default as kue } from 'kue';

// TODO: Clean up jobs

let addingNewJobs = false;
const queue = kue.createQueue({ jobEvents: false });

queue.on('error', (err) => {
  console.error(`UNCAUGHT ERROR: ${err}`);
});

process.on('SIGINT', () => {
  queue.shutdown(5000, (err) => {
    console.log('URL job queue shutdown initiated');
    if (err) {
      console.error(`Error shutting down Kue: ${err}`);
      return process.exit(1);
    }
    console.log('URL job queue shutdown complete');
    return process.exit(0);
  });
});

function populateJobs() {
  if (addingNewJobs) {
    return;
  }

  addingNewJobs = true;
  urlJobPopulator.populate();
}

function addJobs(urls) {
  urls.forEach((url) => {
    // TODO: Configurable retry attempts
    queue.create('url', url).attempts(5).backoff(true).save((err) => {
      if (err) {
        console.error(`FAILED to add job: ${url}`);
      }
    });
  });
}

function startProcessingJobs() {
  // TODO: Configurable number of urls processing concurrently
  queue.process('url', 50, (job, done) => {
    urlJobProcessor.processUrlJob(job.data).then((result) => {
      return dataStore.updateWithCurrentCrawlResult(job.data, result).then(() => {
        done(null, result);
      });
    }).catch((err) => {
      done(err);
    });
  });
}

// TODO Configure from a config file

const configPromises = [];

configPromises.push(urlJobPopulator.configure({
  backendName: 'static',
  progressCallback: addJobs,
  finishedCallback: () => { addingNewJobs = false; },
}));

configPromises.push(dataStore.configure({
  backendName: 'redis',
  backendOpts: {
    url: 'redis://localhost:6379',
  },
}));

configPromises.push(urlJobProcessor.configure({
  probes: [
    {
      name: 'totalRecords',
    }
  ],
}));

Promise.all(configPromises).then(() => {
  queue.inactiveCount((err, total) => {
    if (err) {
      return console.error(`inactiveCount failure: ${err}`);
    }

    // FIXME: We need to also look at completeCount and failedCount
    if (total === 0) {
      console.log('No crawl in progress, starting new crawl');
      populateJobs();
    } else {
      console.log('Resuming previous crawl');
    }

    startProcessingJobs();
  });
}).catch((err) => {
  console.error(err);
  return process.exit(1);
});
<|endoftext|>