<commit_before>/* global QUnit*/

sap.ui.define([
	"sap/ui/dt/DOMUtil",
	'sap/ui/Device'
],
function(
	DOMUtil,
	Device
) {
	"use strict";

	QUnit.module("Given that a container is rendered with a bigger content element (for scrollbars)", {
		beforeEach : function() {
			this.oContent = jQuery("

");
			this.oContainer = jQuery("

");
			this.oContainer.append(this.oContent).appendTo("#qunit-fixture");
		},
		afterEach : function() {
			this.oContainer.remove();
		}
	}, function(){
		QUnit.test("when getOffsetFromParent is called for the content without scrolling", function(assert) {
			var oContentGeometry = DOMUtil.getGeometry(this.oContent.get(0));
			var mOffset = DOMUtil.getOffsetFromParent(oContentGeometry, this.oContainer.get(0));
			//TODO: Remove when bug in Chrome and Safari is fixed
			var iExpectedOffsetLeft = (Device.browser.webkit || Device.browser.blink) ? -47 : -35;
			// in some cases (special physical devices) the offset is returend as decimal value
			// actually we need to round the offset for chrome browser on mac
			assert.strictEqual(Math.round(mOffset.left), iExpectedOffsetLeft, "the left offset is correct");
			assert.strictEqual(mOffset.top, 40, "the top offset is correct");
		});

		QUnit.test("when getOffsetFromParent is called for the content after scrolling on the container", function(assert) {
			var oContainerDomRef = this.oContainer.get(0);
			var oContentGeometry = DOMUtil.getGeometry(this.oContent.get(0));
			var iScrollValue = -50;
			//TODO: Remove when bug in Chrome and Safari is fixed
			var iExpectedOffsetLeft = (Device.browser.webkit || Device.browser.blink) ? -97 : -85;
			// IE and Edge use positive leftScroll
			if (Device.browser.msie || Device.browser.edge) {
				iScrollValue = -iScrollValue;
			}
			// Blink (Chrome) uses positive leftScroll but starts on the extreme left
			if (Device.browser.blink){
				var iMaxScrollWidth = oContainerDomRef.scrollWidth - oContainerDomRef.clientWidth;
				iScrollValue = iMaxScrollWidth + iScrollValue;
			}
			this.oContainer.scrollLeft(iScrollValue);
			this.oContainer.scrollTop(60);
			var mOffset = DOMUtil.getOffsetFromParent(oContentGeometry, oContainerDomRef);
			// round for offset value is actually nedded for chrome browser on mac
			assert.strictEqual(Math.round(mOffset.left), iExpectedOffsetLeft, "the left offset is correct");
			assert.strictEqual(mOffset.top, 100, "the top offset is correct");
		});
	});

	QUnit.module("getScrollLeft()", {
		beforeEach: function() {
			this.$Panel = jQuery('
').css({
				'width': '100px',
				'height': '100px',
				'overflow': 'auto'
			}).appendTo("#qunit-fixture");

			jQuery('
').css({
				'width': '200px',
				'height': '200px'
			}).appendTo(this.$Panel);
		},
		afterEach: function() {
			this.$Panel.remove();
		}
	}, function () {
		QUnit.test("initial position", function (assert) {
			assert.strictEqual(DOMUtil.getScrollLeft(this.$Panel.get(0)), 0);
		});
		QUnit.test("scrolled to the most left position", function (assert) {
			var iMaxScrollLeftValue = this.$Panel.get(0).scrollWidth - this.$Panel.get(0).clientWidth;
			var iScrollValue;

			if (Device.browser.blink) {
				iScrollValue = 0;
			} else if (Device.browser.msie || Device.browser.edge) {
				iScrollValue = iMaxScrollLeftValue;
			} else {
				iScrollValue = -iMaxScrollLeftValue;
			}

			this.$Panel.scrollLeft(iScrollValue);
			assert.strictEqual(DOMUtil.getScrollLeft(this.$Panel.get(0)), -iMaxScrollLeftValue);
		});
	});

	QUnit.done(function() {
		jQuery("#qunit-fixture").hide();
	});
});<commit_msg>[FIX] sap.ui.dt - DomUtilRtl test description changed<commit_after>/* global QUnit*/

sap.ui.define([
	"sap/ui/dt/DOMUtil",
	'sap/ui/Device'
],
function(
	DOMUtil,
	Device
) {
	"use strict";

	QUnit.module("Given that a container is rendered with a bigger content element (for scrollbars)", {
		beforeEach : function() {
			this.oContent = jQuery("

");
			this.oContainer = jQuery("

");
			this.oContainer.append(this.oContent).appendTo("#qunit-fixture");
		},
		afterEach : function() {
			this.oContainer.remove();
		}
	}, function(){
		QUnit.test("when getOffsetFromParent is called for the content without scrolling", function(assert) {
			var oContentGeometry = DOMUtil.getGeometry(this.oContent.get(0));
			var mOffset = DOMUtil.getOffsetFromParent(oContentGeometry, this.oContainer.get(0));
			//TODO: Remove when bug in Chrome and Safari is fixed
			var iExpectedOffsetLeft = (Device.browser.webkit || Device.browser.blink) ? -47 : -35;
			// in some cases (special physical devices) the offset is returend as decimal value
			// actually we need to round the offset for chrome browser on mac
			assert.strictEqual(Math.round(mOffset.left), iExpectedOffsetLeft, "the left offset is correct - result: " +
				Math.round(mOffset.left) + " / expected value: " + iExpectedOffsetLeft);
			assert.strictEqual(mOffset.top, 40, "the top offset is correct");
		});

		QUnit.test("when getOffsetFromParent is called for the content after scrolling on the container", function(assert) {
			var oContainerDomRef = this.oContainer.get(0);
			var oContentGeometry = DOMUtil.getGeometry(this.oContent.get(0));
			var iScrollValue = -50;
			//TODO: Remove when bug in Chrome and Safari is fixed
			var iExpectedOffsetLeft = (Device.browser.webkit || Device.browser.blink) ? -97 : -85;
			// IE and Edge use positive leftScroll
			if (Device.browser.msie || Device.browser.edge) {
				iScrollValue = -iScrollValue;
			}
			// Blink (Chrome) uses positive leftScroll but starts on the extreme left
			if (Device.browser.blink){
				var iMaxScrollWidth = oContainerDomRef.scrollWidth - oContainerDomRef.clientWidth;
				iScrollValue = iMaxScrollWidth + iScrollValue;
			}
			this.oContainer.scrollLeft(iScrollValue);
			this.oContainer.scrollTop(60);
			var mOffset = DOMUtil.getOffsetFromParent(oContentGeometry, oContainerDomRef);
			// round for offset value is actually nedded for chrome browser on mac
			assert.strictEqual(Math.round(mOffset.left), iExpectedOffsetLeft, "the left offset is correct - result: " +
				Math.round(mOffset.left) + " / expected value: " + iExpectedOffsetLeft);
			assert.strictEqual(mOffset.top, 100, "the top offset is correct");
		});
	});

	QUnit.module("getScrollLeft()", {
		beforeEach: function() {
			this.$Panel = jQuery('
').css({
				'width': '100px',
				'height': '100px',
				'overflow': 'auto'
			}).appendTo("#qunit-fixture");

			jQuery('
').css({
				'width': '200px',
				'height': '200px'
			}).appendTo(this.$Panel);
		},
		afterEach: function() {
			this.$Panel.remove();
		}
	}, function () {
		QUnit.test("initial position", function (assert) {
			assert.strictEqual(DOMUtil.getScrollLeft(this.$Panel.get(0)), 0);
		});
		QUnit.test("scrolled to the most left position", function (assert) {
			var iMaxScrollLeftValue = this.$Panel.get(0).scrollWidth - this.$Panel.get(0).clientWidth;
			var iScrollValue;

			if (Device.browser.blink) {
				iScrollValue = 0;
			} else if (Device.browser.msie || Device.browser.edge) {
				iScrollValue = iMaxScrollLeftValue;
			} else {
				iScrollValue = -iMaxScrollLeftValue;
			}

			this.$Panel.scrollLeft(iScrollValue);
			assert.strictEqual(DOMUtil.getScrollLeft(this.$Panel.get(0)), -iMaxScrollLeftValue);
		});
	});

	QUnit.done(function() {
		jQuery("#qunit-fixture").hide();
	});
});<|endoftext|>


<commit_before>/**
 * This file contains some re-usable parts for websocket audio communication.
 *
 * @module api/utils/audio-over-socket
 */

import autobahn from 'autobahn';
import {
  getWebsocketConnection,
  makeWebsocketCall,
} from '../communication/websocket';
import broadcaster from '../broadcaster';
import { dataToBase64, asyncBlobToArrayBuffer } from './index';

/**
 * This class allows us to stream audio from the recorder to the backend.
 * @private
 */
class StreamRecorderAudio {
  /**
   * @param {MediaRecorder} recorder - Recorder to use to capture data from.
   * @param {string} rpcName - Name of the registered RPC function.
   */
  constructor(recorder, rpcName, websocketConnection) {
    /**
     * MediaRecorder to process the stream from.
     * @type {MediaRecorder}
     */
    this.recorder = recorder;

    /**
     * Name of the RPC registered.
     * This name will be prepended with 'nl.itslanguage' for better consistency.
     * @type {string}
     */
    this.rpcName = `nl.itslanguage.${rpcName}`;

    /**
     * Store a reference to the websocket connection.
     * @type {autobahn.Connection}
     */
    this.websocketConnection = websocketConnection;

    /**
     * The autobahn.Registration object. This is returned when you register
     * a function through Session.register.
     * @type {null|autobahn.Registration}
     */
    this.registration = null;

    this.sendAudioChunks = this.sendAudioChunks.bind(this);
    this.register = this.register.bind(this);
    this.unregister = this.unregister.bind(this);
  }

  /**
   * This is the function that will be registered to the autobahn realm that the backend will call
   * to receive audio on.
   *
   * Once called, it will prepare the recorder to allow data transmission trough the progressive
   * results meganism.
   *
   * @see https://github.com/crossbario/autobahn-js/blob/master/doc/reference.md#register
   * @see https://github.com/crossbario/autobahn-js/blob/master/doc/reference.md#progressive-results
   *
   * @private
   * @param {Array} args - Argument list.
   * @param {Object} kwargs - Key-valued argument list.
   * @param {Object} details - Details, just as the progress function.
   * @returns {Promise} - A promise that can be resolved to end the asynchronous behaviour of this
   * registered RCP.
   */
  sendAudioChunks(args, kwargs, details) {
    const defer = new autobahn.when.defer(); // eslint-disable-line new-cap
    let lastChunk = false;

    const processData = ({ data }) => {
      asyncBlobToArrayBuffer(data).then(audioData => {
        if (details.progress) {
          const dataToSend = Array.from(new Uint8Array(audioData));
          details.progress([dataToSend]);

          // If the last one ends, closing time!
          if (lastChunk) {
            defer.resolve();
            this.unregister();
          }
        } else {
          defer.reject('no progress function registered');
        }
      });
    };

    const recorderStopped = () => {
      // When stopped, the dataavailableevent will be triggered
      // one final time, so make sure it will cleanup afterwards
      lastChunk = true;
    };

    // Before adding the events, let's make sure they have not been added
    // on a previous session;
    this.recorder.removeEventListener('dataavailable', processData);
    this.recorder.removeEventListener('stop', recorderStopped);

    // Now add the event listeners!
    this.recorder.addEventListener('dataavailable', processData);
    this.recorder.addEventListener('stop', recorderStopped);

    // Notify listeners that we are ready to process audio;
    this.recorder.dispatchEvent(new Event('recorderready'));

    return defer.promise;
  }

  /**
   * register the RPC to the autobahn realm.
   * @returns {Promise}
   */
  register() {
    return new Promise((resolve, reject) => {
      this.websocketConnection.session
        .register(this.rpcName, this.sendAudioChunks)
        .then(registration => {
          this.registration = registration;
          resolve(registration);
        })
        .catch(reject);
    });
  }

  /**
   * unregister the RPC from the autobahn realm.
   */
  unregister() {
    return new Promise((resolve, reject) => {
      this.websocketConnection.session
        .unregister(this.registration)
        .then(() => {
          this.registration = null;
          resolve();
        })
        .catch(reject);
    });
  }
}

/**
 * Register a RPC call to the current websocket connection. The backend will call this registered
 * function once, an then we can send progressive results (the details.progress call) to send audio
 * chunks to the backend. We will send those chunks as soon as we got audio from the recorder.
 *
 * When the recording ends we un-register the rpc.
 *
 * @param {MediaRecorder} recorder - Audio recorder instance.
 * @param {string} rpcName - Name of the RPC to register. This name will be prepended with
 * nl.itslanguage for better consistency.
 * @fires broadcaster#websocketserverreadyforaudio
 * @returns {Promise} - It returns a promise with the service registration as result.
 */
export function registerStreamForRecorder(recorder, rpcName) {
  // Start registering a RPC call. As a result, this function will return a promise with the
  // registration of the RPC as result.
  return new Promise((resolve, reject) => {
    getWebsocketConnection().then(websocketConnection => {
      const streamingSession = new StreamRecorderAudio(
        recorder,
        rpcName,
        websocketConnection,
      );
      streamingSession
        .register()
        .then(registration => {
          /**
           * Notify that we are ready to process audio.
           * @event broadcaster#websocketserverreadyforaudio
           * @deprecated will be removed in a future version
           */
          broadcaster.emit('websocketserverreadyforaudio');
          recorder.dispatchEvent(new Event('websocketserverreadyforaudio'));
          resolve(registration);
        })
        .catch(reject);
    });
  });
}

/**
 * Encode the audio as base64 and send it to the websocket server.
 *
 * @param {string} id - The reserved ID for the audio.
 * @param {MediaRecorder} recorder - The recorder to use to get the recording.
 * @param {string} rpc - The RPC to use to store the data.
 *
 * @returns {Promise<*>} - The response of the given RPC.
 */
export function encodeAndSendAudioOnDataAvailable(id, recorder, rpc) {
  return new Promise((resolve, reject) => {
    let lastChunk = false;

    // When data is received from the recorder, it will be in Blob format.
    // When we read the data from the Blob element, base64 it and send it to
    // the websocket server and continue with the chain.
    const processData = ({ data }) => {
      asyncBlobToArrayBuffer(data).then(audioData => {
        const encoded = dataToBase64(audioData);
        // Send the audio
        makeWebsocketCall(rpc, { args: [id, encoded, 'base64'] })
          .then(result => {
            if (lastChunk) {
              resolve(result);
            }
          })
          .catch(error => {
            reject(error);
          });
      });
    };

    const recorderStopped = () => {
      // When stopped, the dataavailable event will be triggered
      // one final time, so make sure it will cleanup afterwards
      lastChunk = true;
    };

    // Before adding the events, let's make sure they have not been added
    // on a previous session;
    recorder.removeEventListener('dataavailable', processData);
    recorder.removeEventListener('stop', recorderStopped);

    // Now add the event listeners!
    recorder.addEventListener('dataavailable', processData);
    recorder.addEventListener('stop', recorderStopped);

    // Notify listeners that we are ready to process audio;
    recorder.dispatchEvent(new Event('recorderready'));
  });
}

/**
 * Send the recorder settings to the websocket server to initialize it.
 *
 * The reserved ID (passed in the parameters) is returned once the promise is resolved.
 *
 * @param {string} id - The reserved ID for the audio.
 * @param {MediaRecorder} recorder - The recorder which has been set up to record.
 * @param {string} rpc - The RPC to use to initialize the websocket server.
 *
 * @emits {websocketserverreadyforaudio} - When the websocket server has been prepared for and is
 * ready to receive the audio.
 *
 * @returns {Promise} - The promise which resolves when the websocket server is ready for the audio.
 */
export function prepareServerForAudio(id, recorder, rpc) {
  const { audioFormat, audioParameters } = recorder.getAudioSpecs();
  return makeWebsocketCall(rpc, {
    args: [id, audioFormat],
    kwargs: audioParameters,
  }).then(() => {
    // We've prepped the websocket server, now it can receive audio. Broadcast
    // that it is allowed to record.
    // This call is deprecated and will be removed in a future version, the
    // event on the recorder will stay.
    broadcaster.emit('websocketserverreadyforaudio');
    recorder.dispatchEvent(new Event('websocketserverreadyforaudio'));
    return id;
  });
}
<commit_msg>refactor: cleanup rpc registrations<commit_after>/**
 * This file contains some re-usable parts for websocket audio communication.
 *
 * @module api/utils/audio-over-socket
 */

import autobahn from 'autobahn';
import {
  getWebsocketConnection,
  makeWebsocketCall,
} from '../communication/websocket';
import broadcaster from '../broadcaster';
import { dataToBase64, asyncBlobToArrayBuffer } from './index';

/**
 * This class allows us to stream audio from the recorder to the backend.
 * @private
 */
class StreamRecorderAudio {
  /**
   * @param {MediaRecorder} recorder - Recorder to use to capture data from.
   * @param {string} rpcName - Name of the registered RPC function.
   */
  constructor(recorder, rpcName, websocketConnection) {
    /**
     * MediaRecorder to process the stream from.
     * @type {MediaRecorder}
     */
    this.recorder = recorder;

    /**
     * Name of the RPC registered.
     * This name will be prepended with 'nl.itslanguage' for better consistency.
     * @type {string}
     */
    this.rpcName = `nl.itslanguage.${rpcName}`;

    /**
     * Store a reference to the websocket connection.
     * @type {autobahn.Connection}
     */
    this.websocketConnection = websocketConnection;

    /**
     * The autobahn.Registration object. This is returned when you register
     * a function through Session.register.
     * @type {null|autobahn.Registration}
     */
    this.registration = null;

    this.sendAudioChunks = this.sendAudioChunks.bind(this);
    this.register = this.register.bind(this);
    this.unregister = this.unregister.bind(this);
  }

  /**
   * This is the function that will be registered to the autobahn realm that the backend will call
   * to receive audio on.
   *
   * Once called, it will prepare the recorder to allow data transmission trough the progressive
   * results meganism.
   *
   * @see https://github.com/crossbario/autobahn-js/blob/master/doc/reference.md#register
   * @see https://github.com/crossbario/autobahn-js/blob/master/doc/reference.md#progressive-results
   *
   * @private
   * @param {Array} args - Argument list.
   * @param {Object} kwargs - Key-valued argument list.
   * @param {Object} details - Details, just as the progress function.
   * @returns {Promise} - A promise that can be resolved to end the asynchronous behaviour of this
   * registered RCP.
   */
  sendAudioChunks(args, kwargs, details) {
    const defer = new autobahn.when.defer(); // eslint-disable-line new-cap
    let lastChunk = false;

    const processData = ({ data }) => {
      asyncBlobToArrayBuffer(data).then(audioData => {
        if (details.progress) {
          const dataToSend = Array.from(new Uint8Array(audioData));
          details.progress([dataToSend]);

          // If the last one ends, closing time!
          if (lastChunk) {
            defer.resolve();
            this.unregister();
          }
        } else {
          defer.reject('no progress function registered');
        }
      });
    };

    const recorderStopped = () => {
      // When stopped, the dataavailableevent will be triggered
      // one final time, so make sure it will cleanup afterwards
      lastChunk = true;
    };

    // Before adding the events, let's make sure they have not been added
    // on a previous session;
    this.recorder.removeEventListener('dataavailable', processData);
    this.recorder.removeEventListener('stop', recorderStopped);

    // Now add the event listeners!
    this.recorder.addEventListener('dataavailable', processData);
    this.recorder.addEventListener('stop', recorderStopped);

    // Notify listeners that we are ready to process audio;
    this.recorder.dispatchEvent(new Event('recorderready'));

    return defer.promise;
  }

  /**
   * register the RPC to the autobahn realm.
   * @returns {Promise}
   */
  register() {
    return new Promise((resolve, reject) => {
      const { session } = this.websocketConnection;

      // First cleanup previously created registrations on this session;
      Promise.all(
        session.registrations.map(reg => session.unregister(reg)),
      ).then(() => {
        session
          .register(this.rpcName, this.sendAudioChunks)
          .then(registration => {
            this.registration = registration;
            resolve(registration);
          })
          .catch(reject);
      });
    });
  }

  /**
   * unregister the RPC from the autobahn realm.
   */
  unregister() {
    return new Promise((resolve, reject) => {
      this.websocketConnection.session
        .unregister(this.registration)
        .then(() => {
          this.registration = null;
          resolve();
        })
        .catch(reject);
    });
  }
}

/**
 * Register a RPC call to the current websocket connection. The backend will call this registered
 * function once, an then we can send progressive results (the details.progress call) to send audio
 * chunks to the backend. We will send those chunks as soon as we got audio from the recorder.
 *
 * When the recording ends we un-register the rpc.
 *
 * @param {MediaRecorder} recorder - Audio recorder instance.
 * @param {string} rpcName - Name of the RPC to register. This name will be prepended with
 * nl.itslanguage for better consistency.
 * @fires broadcaster#websocketserverreadyforaudio
 * @returns {Promise} - It returns a promise with the service registration as result.
 */
export function registerStreamForRecorder(recorder, rpcName) {
  // Start registering a RPC call. As a result, this function will return a promise with the
  // registration of the RPC as result.
  return new Promise((resolve, reject) => {
    getWebsocketConnection().then(websocketConnection => {
      const streamingSession = new StreamRecorderAudio(
        recorder,
        rpcName,
        websocketConnection,
      );
      streamingSession
        .register()
        .then(registration => {
          /**
           * Notify that we are ready to process audio.
           * @event broadcaster#websocketserverreadyforaudio
           * @deprecated will be removed in a future version
           */
          broadcaster.emit('websocketserverreadyforaudio');
          recorder.dispatchEvent(new Event('websocketserverreadyforaudio'));
          resolve(registration);
        })
        .catch(reject);
    });
  });
}

/**
 * Encode the audio as base64 and send it to the websocket server.
 *
 * @param {string} id - The reserved ID for the audio.
 * @param {MediaRecorder} recorder - The recorder to use to get the recording.
 * @param {string} rpc - The RPC to use to store the data.
 *
 * @returns {Promise<*>} - The response of the given RPC.
 */
export function encodeAndSendAudioOnDataAvailable(id, recorder, rpc) {
  return new Promise((resolve, reject) => {
    let lastChunk = false;

    // When data is received from the recorder, it will be in Blob format.
    // When we read the data from the Blob element, base64 it and send it to
    // the websocket server and continue with the chain.
    const processData = ({ data }) => {
      asyncBlobToArrayBuffer(data).then(audioData => {
        const encoded = dataToBase64(audioData);
        // Send the audio
        makeWebsocketCall(rpc, { args: [id, encoded, 'base64'] })
          .then(result => {
            if (lastChunk) {
              resolve(result);
            }
          })
          .catch(error => {
            reject(error);
          });
      });
    };

    const recorderStopped = () => {
      // When stopped, the dataavailable event will be triggered
      // one final time, so make sure it will cleanup afterwards
      lastChunk = true;
    };

    // Before adding the events, let's make sure they have not been added
    // on a previous session;
    recorder.removeEventListener('dataavailable', processData);
    recorder.removeEventListener('stop', recorderStopped);

    // Now add the event listeners!
    recorder.addEventListener('dataavailable', processData);
    recorder.addEventListener('stop', recorderStopped);

    // Notify listeners that we are ready to process audio;
    recorder.dispatchEvent(new Event('recorderready'));
  });
}

/**
 * Send the recorder settings to the websocket server to initialize it.
 *
 * The reserved ID (passed in the parameters) is returned once the promise is resolved.
 *
 * @param {string} id - The reserved ID for the audio.
 * @param {MediaRecorder} recorder - The recorder which has been set up to record.
 * @param {string} rpc - The RPC to use to initialize the websocket server.
 *
 * @emits {websocketserverreadyforaudio} - When the websocket server has been prepared for and is
 * ready to receive the audio.
 *
 * @returns {Promise} - The promise which resolves when the websocket server is ready for the audio.
 */
export function prepareServerForAudio(id, recorder, rpc) {
  const { audioFormat, audioParameters } = recorder.getAudioSpecs();
  return makeWebsocketCall(rpc, {
    args: [id, audioFormat],
    kwargs: audioParameters,
  }).then(() => {
    // We've prepped the websocket server, now it can receive audio. Broadcast
    // that it is allowed to record.
    // This call is deprecated and will be removed in a future version, the
    // event on the recorder will stay.
    broadcaster.emit('websocketserverreadyforaudio');
    recorder.dispatchEvent(new Event('websocketserverreadyforaudio'));
    return id;
  });
}
<|endoftext|>


<commit_before>const prisma = require('.prisma/client')
const path = require('path')

module.exports = prisma

/**
 * Annotation for ncc/zeit
 */
path.join(__dirname, '../../.prisma/client/schema.prisma')
path.join(__dirname, '../../../.prisma/client/schema.prisma')
path.join(__dirname, '../../../../.prisma/client/schema.prisma')
<commit_msg>fix(client): point backup index to default runtime<commit_after>const prisma = require('.prisma/client/index')
const path = require('path')

module.exports = prisma

/**
 * Annotation for ncc/zeit
 */
path.join(__dirname, '../../.prisma/client/schema.prisma')
path.join(__dirname, '../../../.prisma/client/schema.prisma')
path.join(__dirname, '../../../../.prisma/client/schema.prisma')
<|endoftext|>


<commit_before>import rebind  from '../src/rebind';

describe('rebind', function() {

    var source, target, value;

    beforeEach(function() {
        value = {};
        source = {
            fn: function(arg) {
                if (!arguments.length) {
                    return value;
                }
                value = arg;
                return source;
            }
        };
        target = {};
    });

    it('should have the same behaviour as d3.rebind', function() {
        var targetObject = rebind(target, source, 'fn');
        expect(targetObject).toBe(target);

        expect(target.fn())
            .toEqual(value);

        var newValue = {};
        expect(target.fn(newValue))
            .toEqual(target);
        expect(target.fn())
            .toEqual(newValue);
    });
});
<commit_msg>chore: update to es2015<commit_after>import rebind  from '../src/rebind';

describe('rebind', () => {

    let source, target, value;

    beforeEach(() => {
        value = {};
        source = {
            fn: (...args) => {
                if (!args.length) {
                    return value;
                }
                value = args[0];
                return source;
            }
        };
        target = {};
    });

    it('should have the same behaviour as d3.rebind', () => {
        const targetObject = rebind(target, source, 'fn');
        expect(targetObject).toBe(target);

        expect(target.fn())
            .toEqual(value);

        const newValue = {};
        expect(target.fn(newValue))
            .toEqual(target);
        expect(target.fn())
            .toEqual(newValue);
    });
});
<|endoftext|>


<commit_before>JSONEditor.defaults.editors.number = JSONEditor.defaults.editors.string.extend({
  sanitize: function(value) {
    return (value+"").replace(/[^0-9\.\-eE]/g,'');
  },
  getNumColumns: function() {
    return 2;
  },
  getValue: function() {
    return this.value*1;
  }
});
<commit_msg>Respect "minimum"/"maximum" and "exclusiveMinimum/Maximum" (#7)<commit_after>JSONEditor.defaults.editors.number = JSONEditor.defaults.editors.string.extend({
  build: function() {
    this._super();

    if (typeof this.schema.minimum !== "undefined") {
      var minimum = this.schema.minimum;

      if (typeof this.schema.exclusiveMinimum !== "undefined") {
        minimum += 1;
      }

      this.input.setAttribute("min", minimum);
    }

    if (typeof this.schema.maximum !== "undefined") {
      var maximum = this.schema.maximum;

      if (typeof this.schema.exclusiveMaximum !== "undefined") {
        maximum -= 1;
      }

      this.input.setAttribute("max", maximum);
    }
  },
  sanitize: function(value) {
    return (value+"").replace(/[^0-9\.\-eE]/g,'');
  },
  getNumColumns: function() {
    return 2;
  },
  getValue: function() {
    return this.value*1;
  }
});
<|endoftext|>


<commit_before>import { AbstractEditor } from '../editor'
import { $extend, $each } from '../utilities'

export var UploadEditor = AbstractEditor.extend({

  getNumColumns: function () {
    return 4
  },
  build: function () {
    var self = this
    this.title = this.header = this.label = this.theme.getFormInputLabel(this.getTitle(), this.isRequired())

    // Editor options
    this.options = this.expandCallbacks('upload', $extend({}, {
      'title': 'Browse',
      'icon': '',
      'auto_upload': false, // Trigger file upload button automatically
      'hide_input': false, // Hide the Browse button and name display (Only works if 'enable_drag_drop' is true)
      'enable_drag_drop': false, // Enable Drag&Drop uploading
      'drop_zone_text': 'Drag & Drop file here', // Text displayed in dropzone box
      'drop_zone_top': false, // Position of dropzone. true=before button input, false=after button input
      'alt_drop_zone_id': '', // Alternate DropZone ID (Can be created inside another property)
      'mime_type': '', // If set, restricts to mime type(s). Can be either a string or an array
      'max_upload_size': 0, // Maximum file size allowed. 0 = no limit
      'allow_reupload': false, // Allow reupload of file (prevents property from being readonly)
      'upload_handler': function (jseditor, type, file, cbs) {
        // Default dummy test upload handler
        window.alert('No upload_handler defined for "' + jseditor.path + '". You must create your own handler to enable upload to server')
      }.bind(null, this)
    }, this.defaults.options.upload || {}, this.options.upload || {}))

    this.options.mime_type = this.options.mime_type ? [].concat(this.options.mime_type) : []

    // Input that holds the base64 string
    this.input = this.theme.getFormInputField('hidden')
    this.container.appendChild(this.input)

    // Don't show uploader if this is readonly
    if ((!this.schema.readOnly && !this.schema.readonly) || this.options.allow_reupload === true) {
      if (typeof this.options.upload_handler !== 'function') throw new Error('Upload handler required for upload editor')

      // File uploader
      this.uploader = this.theme.getFormInputField('file')
      this.uploader.style.display = 'none'
      if (this.options.mime_type.length) this.uploader.setAttribute('accept', this.options.mime_type)

      if (!(this.options.enable_drag_drop === true && this.options.hide_input === true)) {
        // Pass click to this.uploader element
        this.clickHandler = function (e) {
          self.uploader.dispatchEvent(new window.MouseEvent('click', {
            'view': window,
            'bubbles': true,
            'cancelable': false
          }))
        }

        // Browse button
        this.browseButton = this.getButton(this.options.title, this.options.icon, this.options.title)
        this.browseButton.addEventListener('click', this.clickHandler)

        // Display field
        this.fileDisplay = this.theme.getFormInputField('input')
        this.fileDisplay.setAttribute('readonly', true)
        this.fileDisplay.value = 'No file selected.'
        this.fileDisplay.addEventListener('dblclick', this.clickHandler)

        this.fileUploadGroup = this.theme.getInputGroup(this.fileDisplay, [this.browseButton])
      }

      // Drag&Drop upload enabled
      if (this.options.enable_drag_drop === true) {
        // Alternate DropZone defined
        if (this.options.alt_drop_zone_id !== '') {
          if (this.options.alt_drop_zone_id.substr(0, 1) !== '#') this.options.alt_drop_zone_id = '#' + this.options.alt_drop_zone_id
          this.dropZone = document.querySelector(this.options.alt_drop_zone_id)
        } else {
          this.dropZone = document.createElement('div')
          this.dropZone.classList.add('je-dropzone')
          this.dropZone.setAttribute('data-text', this.options.drop_zone_text)
          this.container.appendChild(this.dropZone)

          // The Style Rules should be placed in theme once we have theme functions to render the dropzone
          this.jsoneditor.addNewStyleRules(this.jsoneditor.options.theme || window.JSONEditor.defaults.theme, {
            '.je-dropzone': 'position:relative;margin:0.5rem 0;border 2px dashed black;width:100%;height:60px;background:teal;transition: all 0.5s',
            '.je-dropzone:before': 'position:absolute;content:attr(data-text);left:50%;top:50%;transform: translate(-50%,-50%)',
            '.je-dropzone.active-dropzone': 'background:green'
          })
        }
        if (this.dropZone) this.dropZone.classList.add('upload-dropzone')
      }

      // Triggered after file have been selected
      this.uploadHandler = function (e) {
        e.preventDefault()
        e.stopPropagation()
        var files = e.target.files || e.dataTransfer.files
        if (files && files.length) {
          var errors = []
          // size of uploaded file is too big
          if (self.options.max_upload_size !== 0 && files[0].size > self.options.max_upload_size) {
            errors.push({
              path: self.path,
              property: 'size',
              message: 'Filesize too large. Max size is ' + self.options.max_upload_size
            })
          }
          // wrong file/mime type
          if (self.options.mime_type.length !== 0 && !self.isValidMimeType(files[0].type, self.options.mime_type)) {
            errors.push({
              path: self.path,
              property: 'format',
              message: 'Wrong file format. Allowed format(s): ' + self.options.mime_type.toString()
            })
          }
          if (errors.length > 0) {
            self.is_dirty = true
            self.showValidationErrors(errors)
          } else {
            if (self.fileDisplay) self.fileDisplay.value = files[0].name
            var fr = new window.FileReader()
            fr.onload = function (evt) {
              self.preview_value = evt.target.result
              self.refreshPreview(e)
              self.onChange(true)
              fr = null
            }
            fr.readAsDataURL(files[0])
          }
        }
      }

      this.uploader.addEventListener('change', this.uploadHandler)

      // Drag&Drop Event Handler
      this.dragHandler = function (e) {
        var files = e.dataTransfer.items || e.dataTransfer.files
        var validType = files && files.length && (self.options.mime_type.length === 0 || self.isValidMimeType(files[0].type, self.options.mime_type))
        var validZone = e.currentTarget.classList && e.currentTarget.classList.contains('upload-dropzone') && validType
        switch ((this === window ? 'w_' : 'e_') + e.type) {
          case 'w_drop':
          case 'w_dragover':
            if (!validZone) e.dataTransfer.dropEffect = 'none'
            break
          case 'e_dragenter': {
            if (validZone) {
              self.dropZone.classList.add('active-dropzone')
              e.dataTransfer.dropEffect = 'copy'
            }
            break
          }
          case 'e_dragleave':
            if (validZone) self.dropZone.classList.remove('active-dropzone')
            break
          case 'e_dragover': {
            if (validZone) {
              e.dataTransfer.dropEffect = 'copy'
              self.dropZone.classList.add('active-dropzone')
            }
            break
          }
          case 'e_drop': {
            if (validZone) self.uploadHandler(e)
            self.dropZone.classList.remove('active-dropzone')
            break
          }
        }
        if (!validZone) e.preventDefault()
      }

      // Set Drag'n'Drop handlers
      if (this.options.enable_drag_drop === true) {
        ['dragover', 'drop'].forEach(function (ev) {
          window.addEventListener(ev, self.dragHandler, true)
        });
        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(function (ev) {
          self.dropZone.addEventListener(ev, self.dragHandler, true)
        })
      }
    }

    var description = this.schema.description || ''

    this.preview = this.theme.getFormInputDescription(description)

    this.control = this.theme.getFormControl(this.label, this.uploader || this.input, this.preview)
    this.input.controlgroup = this.control
    if (this.uploader) this.uploader.controlgroup = this.control

    this.container.appendChild(this.control)
    if (this.dropZone && this.options.alt_drop_zone_id === '' && this.options.drop_zone_top === true) this.container.appendChild(this.dropZone)
    if (this.fileUploadGroup) this.container.appendChild(this.fileUploadGroup)
    if (this.dropZone && this.options.alt_drop_zone_id === '' && this.options.drop_zone_top !== true) this.container.appendChild(this.dropZone)
    this.container.appendChild(this.preview)

    // Any special formatting that needs to happen after the input is added to the dom
    window.requestAnimationFrame(function () {
      self.afterInputReady()
    })
  },
  afterInputReady: function () {
    var self = this
    if (self.value) {
      var img = document.createElement('img')
      img.style.maxWidth = '100%'
      img.style.maxHeight = '100px'
      img.onload = function (event) {
        self.preview.appendChild(img)
      }
      img.onerror = function (error) {
        console.error('upload error', error, this)
      }
      img.src = self.container.querySelector('a').href
    }
    self.theme.afterInputReady(self.input)
  },
  refreshPreview: function (e) {
    if (this.last_preview === this.preview_value) return
    this.last_preview = this.preview_value

    this.preview.innerHTML = ''

    if (!this.preview_value) return

    var self = this

    var mime = this.preview_value.match(/^data:([^;,]+)[;,]/)
    if (mime) mime = mime[1]
    if (!mime) mime = 'unknown'

    var files = e.target.files || e.dataTransfer.files
    var file = files[0]

    this.preview.innerHTML = 'Type: ' + mime + ', Size: ' + file.size + ' bytes'
    if (mime.substr(0, 5) === 'image') {
      this.preview.innerHTML += '
'
      var img = document.createElement('img')
      img.style.maxWidth = '100%'
      img.style.maxHeight = '100px'
      img.src = this.preview_value
      this.preview.appendChild(img)
    }

    this.preview.innerHTML += '
'
    var uploadButton = this.getButton('Upload', 'upload', 'Upload')
    this.preview.appendChild(uploadButton)
    uploadButton.addEventListener('click', function (event) {
      event.preventDefault()

      uploadButton.setAttribute('disabled', 'disabled')
      self.theme.removeInputError(self.uploader)

      if (self.theme.getProgressBar) {
        self.progressBar = self.theme.getProgressBar()
        self.preview.appendChild(self.progressBar)
      }

      self.options.upload_handler(self.path, file, {
        success: function (url) {
          self.setValue(url)

          if (self.parent) self.parent.onChildEditorChange(self)
          else self.jsoneditor.onChange()

          if (self.progressBar) self.preview.removeChild(self.progressBar)
          uploadButton.removeAttribute('disabled')
        },
        failure: function (error) {
          self.theme.addInputError(self.uploader, error)
          if (self.progressBar) self.preview.removeChild(self.progressBar)
          uploadButton.removeAttribute('disabled')
        },
        updateProgress: function (progress) {
          if (self.progressBar) {
            if (progress) self.theme.updateProgressBar(self.progressBar, progress)
            else self.theme.updateProgressBarUnknown(self.progressBar)
          }
        }
      })
    })

    if (this.options.auto_upload) {
      uploadButton.dispatchEvent(new window.MouseEvent('click'))
      this.preview.removeChild(uploadButton)
    }
  },
  enable: function () {
    if (!this.always_disabled) {
      if (this.uploader) this.uploader.disabled = false
      this._super()
    }
  },
  disable: function (alwaysDisabled) {
    if (alwaysDisabled) this.always_disabled = true
    if (this.uploader) this.uploader.disabled = true
    this._super()
  },
  setValue: function (val) {
    if (this.value !== val) {
      this.value = val
      this.input.value = this.value
      this.onChange()
    }
  },
  destroy: function () {
    var self = this
    if (this.uploader && this.uploader.parentNode) {
      this.uploader.removeEventListener('change', this.uploadHandler)
      this.uploader.parentNode.removeChild(this.uploader)
    }
    if (this.browseButton && this.browseButton.parentNode) {
      this.browseButton.removeEventListener('click', this.clickHandler)
      this.browseButton.parentNode.removeChild(this.browseButton)
    }
    if (this.fileDisplay && this.fileDisplay.parentNode) {
      this.fileDisplay.removeEventListener('dblclick', this.clickHandler)
      this.fileDisplay.parentNode.removeChild(this.fileDisplay)
    }
    if (this.fileUploadGroup && this.fileUploadGroup.parentNode) this.fileUploadGroup.parentNode.removeChild(this.fileUploadGroup)

    // Remove Drag'n'Drop handlers
    if (this.options.enable_drag_drop === true) {
      ['dragover', 'drop'].forEach(function (ev) {
        window.removeEventListener(ev, self.dragHandler, true)
      });
      ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(function (ev) {
        self.dropZone.removeEventListener(ev, self.dragHandler, true)
      })
    }

    if (this.preview && this.preview.parentNode) this.preview.parentNode.removeChild(this.preview)
    if (this.title && this.title.parentNode) this.title.parentNode.removeChild(this.title)
    if (this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input)

    this._super()
  },
  isValidMimeType: function (mimeType, mimeTypesList) {
    return mimeTypesList.reduce(function (a, v) {
      return a || new RegExp(v.replace(/\*/g, '.*'), 'gi').test(mimeType)
    }, false)
  },
  showValidationErrors: function (errors) {
    var self = this
    if (this.jsoneditor.options.show_errors === 'always') {
    } else if (!this.is_dirty && this.previous_error_setting === this.jsoneditor.options.show_errors) {
      return
    }

    this.previous_error_setting = this.jsoneditor.options.show_errors

    var messages = []
    $each(errors, function (i, error) {
      if (error.path === self.path) {
        messages.push(error.message)
      }
    })

    if (messages.length) {
      this.theme.addInputError(this.input, messages.join('. ') + '.')
    } else {
      this.theme.removeInputError(this.input)
    }
  }
})
<commit_msg>Update upload.js<commit_after>import { AbstractEditor } from '../editor'
import { $extend, $each } from '../utilities'

export var UploadEditor = AbstractEditor.extend({

  getNumColumns: function () {
    return 4
  },
  build: function () {
    var self = this
    if (!this.options.compact) this.header = this.label = this.theme.getFormInputLabel(this.getTitle(), this.isRequired())
    if (this.schema.description) this.description = this.theme.getFormInputDescription(this.schema.description)
    if (this.options.infoText) this.infoButton = this.theme.getInfoButton(this.options.infoText)

    // Editor options
    this.options = this.expandCallbacks('upload', $extend({}, {
      'title': 'Browse',
      'icon': '',
      'auto_upload': false, // Trigger file upload button automatically
      'hide_input': false, // Hide the Browse button and name display (Only works if 'enable_drag_drop' is true)
      'enable_drag_drop': false, // Enable Drag&Drop uploading
      'drop_zone_text': 'Drag & Drop file here', // Text displayed in dropzone box
      'drop_zone_top': false, // Position of dropzone. true=before button input, false=after button input
      'alt_drop_zone': '', // Alternate DropZone DOM selector (Can be created inside another property)
      'mime_type': '', // If set, restricts to mime type(s). Can be either a string or an array
      'max_upload_size': 0, // Maximum file size allowed. 0 = no limit
      'allow_reupload': false, // Allow reupload of file (prevents property from being readonly)
      'upload_handler': function (jseditor, type, file, cbs) {
        // Default dummy test upload handler
        window.alert('No upload_handler defined for "' + jseditor.path + '". You must create your own handler to enable upload to server')
      }.bind(null, this)
    }, this.defaults.options.upload || {}, this.options.upload || {}))

    this.options.mime_type = this.options.mime_type ? [].concat(this.options.mime_type) : []

    // Input that holds the base64 string
    this.input = this.theme.getFormInputField('hidden')
    this.container.appendChild(this.input)

    // Don't show uploader if this is readonly
    if ((!this.schema.readOnly && !this.schema.readonly) || this.options.allow_reupload === true) {
      if (typeof this.options.upload_handler !== 'function') throw new Error('Upload handler required for upload editor')

      // File uploader
      this.uploader = this.theme.getFormInputField('file')
      this.uploader.style.display = 'none'
      if (this.options.mime_type.length) this.uploader.setAttribute('accept', this.options.mime_type)

      if (!(this.options.enable_drag_drop === true && this.options.hide_input === true)) {
        // Pass click to this.uploader element
        this.clickHandler = function (e) {
          self.uploader.dispatchEvent(new window.MouseEvent('click', {
            'view': window,
            'bubbles': true,
            'cancelable': false
          }))
        }

        // Browse button
        this.browseButton = this.getButton(this.options.title, this.options.icon, this.options.title)
        this.browseButton.addEventListener('click', this.clickHandler)

        // Display field
        this.fileDisplay = this.theme.getFormInputField('input')
        this.fileDisplay.setAttribute('readonly', true)
        this.fileDisplay.value = 'No file selected.'
        this.fileDisplay.addEventListener('dblclick', this.clickHandler)

        this.fileUploadGroup = this.theme.getInputGroup(this.fileDisplay, [this.browseButton])
      }

      // Drag&Drop upload enabled
      if (this.options.enable_drag_drop === true) {
        // Alternate DropZone defined
        if (this.options.alt_drop_zone !== '') {
          this.altDropZone = document.querySelector(this.options.alt_drop_zone)
          if (this.altDropZone) this.dropZone = this.altDropZone
        } else {
          this.dropZone = document.createElement('div')
          this.dropZone.classList.add('je-dropzone')
          this.dropZone.setAttribute('data-text', this.options.drop_zone_text)
          // this.container.appendChild(this.dropZone)

          // The Style Rules should be placed in theme once we have theme functions to render the dropzone
          this.jsoneditor.addNewStyleRules(this.jsoneditor.options.theme || window.JSONEditor.defaults.theme, {
            '.je-dropzone': 'position:relative;margin:0.5rem 0;border 2px dashed black;width:100%;height:60px;background:teal;transition: all 0.5s',
            '.je-dropzone:before': 'position:absolute;content:attr(data-text);left:50%;top:50%;transform: translate(-50%,-50%)',
            '.je-dropzone.active-dropzone': 'background:green'
          })
        }
        if (this.dropZone) {
          this.dropZone.classList.add('upload-dropzone')
          this.dropZone.addEventListener('dblclick', this.clickHandler)
        }
      }

      // Triggered after file have been selected
      this.uploadHandler = function (e) {
        e.preventDefault()
        e.stopPropagation()
        var files = e.target.files || e.dataTransfer.files
        if (files && files.length) {
          var errors = []
          // size of uploaded file is too big
          if (self.options.max_upload_size !== 0 && files[0].size > self.options.max_upload_size) {
            errors.push({
              path: self.path,
              property: 'size',
              message: 'Filesize too large. Max size is ' + self.options.max_upload_size
            })
          }
          // wrong file/mime type
          if (self.options.mime_type.length !== 0 && !self.isValidMimeType(files[0].type, self.options.mime_type)) {
            errors.push({
              path: self.path,
              property: 'format',
              message: 'Wrong file format. Allowed format(s): ' + self.options.mime_type.toString()
            })
          }
          if (errors.length > 0) {
            self.is_dirty = true
            self.showValidationErrors(errors)
          } else {
            if (self.fileDisplay) self.fileDisplay.value = files[0].name
            var fr = new window.FileReader()
            fr.onload = function (evt) {
              self.preview_value = evt.target.result
              self.refreshPreview(e)
              self.onChange(true)
              fr = null
            }
            fr.readAsDataURL(files[0])
          }
        }
      }

      this.uploader.addEventListener('change', this.uploadHandler)

      // Drag&Drop Event Handler
      this.dragHandler = function (e) {
        var files = e.dataTransfer.items || e.dataTransfer.files
        var validType = files && files.length && (self.options.mime_type.length === 0 || self.isValidMimeType(files[0].type, self.options.mime_type))
        var validZone = e.currentTarget.classList && e.currentTarget.classList.contains('upload-dropzone') && validType
        switch ((this === window ? 'w_' : 'e_') + e.type) {
          case 'w_drop':
          case 'w_dragover':
            if (!validZone) e.dataTransfer.dropEffect = 'none'
            break
          case 'e_dragenter': {
            if (validZone) {
              self.dropZone.classList.add('active-dropzone')
              e.dataTransfer.dropEffect = 'copy'
            }
            break
          }
          case 'e_dragleave':
            if (validZone) self.dropZone.classList.remove('active-dropzone')
            break
          case 'e_dragover': {
            if (validZone) {
              e.dataTransfer.dropEffect = 'copy'
              self.dropZone.classList.add('active-dropzone')
            }
            break
          }
          case 'e_drop': {
            if (validZone) self.uploadHandler(e)
            self.dropZone.classList.remove('active-dropzone')
            break
          }
        }
        if (!validZone) e.preventDefault()
      }

      // Set Drag'n'Drop handlers
      if (this.options.enable_drag_drop === true) {
        ['dragover', 'drop'].forEach(function (ev) {
          window.addEventListener(ev, self.dragHandler, true)
        });
        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(function (ev) {
          self.dropZone.addEventListener(ev, self.dragHandler, true)
        })
      }
    }

    this.preview = document.createElement('div')

    this.control = this.input.controlgroup = this.theme.getFormControl(this.label, this.uploader || this.input, this.description, this.infoButton)
    if (this.uploader) this.uploader.controlgroup = this.control
    var inputNode = this.uploader || this.input
    var elements = document.createElement('div')

    if (this.dropZone && !this.altDropZone && this.options.drop_zone_top === true) elements.appendChild(this.dropZone)
    if (this.fileUploadGroup) elements.appendChild(this.fileUploadGroup)
    if (this.dropZone && !this.altDropZone && this.options.drop_zone_top !== true) elements.appendChild(this.dropZone)
    elements.appendChild(this.preview)
    inputNode.parentNode.insertBefore(elements, inputNode.nextSibling)

    this.container.appendChild(this.control)

    // Any special formatting that needs to happen after the input is added to the dom
    window.requestAnimationFrame(function () {
      self.afterInputReady()
    })
  },
  afterInputReady: function () {
    var self = this
    if (self.value) {
      var img = document.createElement('img')
      img.style.maxWidth = '100%'
      img.style.maxHeight = '100px'
      img.onload = function (event) {
        self.preview.appendChild(img)
      }
      img.onerror = function (error) {
        console.error('upload error', error, this)
      }
      img.src = self.container.querySelector('a').href
    }
    self.theme.afterInputReady(self.input)
  },
  refreshPreview: function (e) {
    if (this.last_preview === this.preview_value) return
    this.last_preview = this.preview_value

    this.preview.innerHTML = ''

    if (!this.preview_value) return

    var self = this

    var mime = this.preview_value.match(/^data:([^;,]+)[;,]/)
    if (mime) mime = mime[1]
    if (!mime) mime = 'unknown'

    var files = e.target.files || e.dataTransfer.files
    var file = files[0]

    this.preview.innerHTML = 'Type: ' + mime + ', Size: ' + file.size + ' bytes'
    if (mime.substr(0, 5) === 'image') {
      this.preview.innerHTML += '
'
      var img = document.createElement('img')
      img.style.maxWidth = '100%'
      img.style.maxHeight = '100px'
      img.src = this.preview_value
      this.preview.appendChild(img)
    }

    this.preview.innerHTML += '
'
    var uploadButton = this.getButton('Upload', 'upload', 'Upload')
    this.preview.appendChild(uploadButton)
    uploadButton.addEventListener('click', function (event) {
      event.preventDefault()

      uploadButton.setAttribute('disabled', 'disabled')
      self.theme.removeInputError(self.uploader)

      if (self.theme.getProgressBar) {
        self.progressBar = self.theme.getProgressBar()
        self.preview.appendChild(self.progressBar)
      }

      self.options.upload_handler(self.path, file, {
        success: function (url) {
          self.setValue(url)

          if (self.parent) self.parent.onChildEditorChange(self)
          else self.jsoneditor.onChange()

          if (self.progressBar) self.preview.removeChild(self.progressBar)
          uploadButton.removeAttribute('disabled')
        },
        failure: function (error) {
          self.theme.addInputError(self.uploader, error)
          if (self.progressBar) self.preview.removeChild(self.progressBar)
          uploadButton.removeAttribute('disabled')
        },
        updateProgress: function (progress) {
          if (self.progressBar) {
            if (progress) self.theme.updateProgressBar(self.progressBar, progress)
            else self.theme.updateProgressBarUnknown(self.progressBar)
          }
        }
      })
    })

    if (this.options.auto_upload) {
      uploadButton.dispatchEvent(new window.MouseEvent('click'))
      this.preview.removeChild(uploadButton)
    }
  },
  enable: function () {
    if (!this.always_disabled) {
      if (this.uploader) this.uploader.disabled = false
      this._super()
    }
  },
  disable: function (alwaysDisabled) {
    if (alwaysDisabled) this.always_disabled = true
    if (this.uploader) this.uploader.disabled = true
    this._super()
  },
  setValue: function (val) {
    if (this.value !== val) {
      this.value = val
      this.input.value = this.value
      this.onChange()
    }
  },
  destroy: function () {
    var self = this
    // Remove Drag'n'Drop handlers
    if (this.options.enable_drag_drop === true) {
      ['dragover', 'drop'].forEach(function (ev) {
        window.removeEventListener(ev, self.dragHandler, true)
      });
      ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(function (ev) {
        self.dropZone.removeEventListener(ev, self.dragHandler, true)
      })
      this.dropZone.removeEventListener('dblclick', this.clickHandler)
      if (this.dropZone && this.dropZone.parentNode) this.dropZone.parentNode.removeChild(this.dropZone)
    }

    if (this.uploader && this.uploader.parentNode) {
      this.uploader.removeEventListener('change', this.uploadHandler)
      this.uploader.parentNode.removeChild(this.uploader)
    }
    if (this.browseButton && this.browseButton.parentNode) {
      this.browseButton.removeEventListener('click', this.clickHandler)
      this.browseButton.parentNode.removeChild(this.browseButton)
    }
    if (this.fileDisplay && this.fileDisplay.parentNode) {
      this.fileDisplay.removeEventListener('dblclick', this.clickHandler)
      this.fileDisplay.parentNode.removeChild(this.fileDisplay)
    }
    if (this.fileUploadGroup && this.fileUploadGroup.parentNode) this.fileUploadGroup.parentNode.removeChild(this.fileUploadGroup)
    if (this.preview && this.preview.parentNode) this.preview.parentNode.removeChild(this.preview)
    if (this.header && this.header.parentNode) this.header.parentNode.removeChild(this.header)
    if (this.input && this.input.parentNode) this.input.parentNode.removeChild(this.input)

    this._super()
  },
  isValidMimeType: function (mimeType, mimeTypesList) {
    return mimeTypesList.reduce(function (a, v) {
      return a || new RegExp(v.replace(/\*/g, '.*'), 'gi').test(mimeType)
    }, false)
  },
  showValidationErrors: function (errors) {
    var self = this
    if (this.jsoneditor.options.show_errors === 'always') {
    } else if (!this.is_dirty && this.previous_error_setting === this.jsoneditor.options.show_errors) {
      return
    }

    this.previous_error_setting = this.jsoneditor.options.show_errors

    var messages = []
    $each(errors, function (i, error) {
      if (error.path === self.path) {
        messages.push(error.message)
      }
    })

    if (messages.length) {
      this.theme.addInputError(this.input, messages.join('. ') + '.')
    } else {
      this.theme.removeInputError(this.input)
    }
  }
})
<|endoftext|>


<commit_before>var socket = io.connect(window.location.host);
var emoticons = [
	[":)","Veryhappy.gif"],
	[":s","dizzy.gif"],
	[":o","outraged.gif"],
	[":(","sad.gif"],
	[";)","wink.gif"]
]

var getMessage = function(message) {
	var messageToAppend = isEncHTML(message) ? decHTMLifEnc(message) : message;
	$("#listOfMessages").html("
" + messageToAppend);
};

function sendImage() {
	var list = document.getElementById("listOfMessages");
	var imgWidth = parseInt($("#imgWidth").val()) > 0 ? $("#imgWidth").val() : "200";
	var imgHeight = parseInt($("#imgHeight").val()) > 0 ? $("#imgHeight").val() : "300";
	var url = $("#valueImg").val();
	socket.emit("image", $("#valueImg").val(), imgHeight, imgWidth);
	list.appendChild(createImgElement(url, imgHeight, imgWidth));
	list.appendChild(createBrElement());
}

function createImgElement(url, height, width) {
	var imgElement = document.createElement("img");
	imgElement.setAttribute("src", url);
	imgElement.setAttribute("height", height + "px");
	imgElement.setAttribute("width", width + "px");
	return imgElement;
}
function createBrElement() {
	return document.createElement("br");
}

function getImage(url, height, width) {
	var list = document.getElementById("listOfMessages");
	list.appendChild(createImgElement(url, height, width));
	list.appendChild(createBrElement());
}

function sendMessage() {
	var message = $("#message").html();
	console.log(message);
	socket.emit("message", message);
	var list = document.getElementById("listOfMessages");
	list.innerHTML = list.innerHTML + "
" + message;
	$("#message").html("");
}

function showAliasForm (request) {
	if(!request.isFirstTime) {
		$('.alias #errorMessage').text = request.message;
		console.log(request.message);
	}
	$('#showAliasForm').click();;

};

function sendAlias() {
	var alias = $('#txtAlias').val();
	if('' != alias) {
		socket.emit('alias', alias);
		$('.fancybox-close').click();
	}
}
socket.on('message', getMessage);
socket.on('image', getImage);
socket.on("alias", showAliasForm);
/*socket.on("alias", sendAlias);*/
document.getElementById("sendMessage").addEventListener("click", sendMessage);

/** Initialisation des div éditables et gestion des émoticones dans l'input associé. **/
function initTextDivWithSmileys(){
	$('.editable').each(function(){
		this.contentEditable = true;
	});
	$("#message").keyup(function(){
		for (i = 0; i < emoticons.length; ++i) {
			if($(this).html().indexOf(emoticons[i][0]) >= 0){
				$("#message").append('');
				$('#message').html($('#message').html().replace(emoticons[i][0], ''));

				// Déplace le curseur juste après l'insertion de l'emoticone dans la div editable
				var range = window.getSelection().getRangeAt($("#message").children()[$("#message").children().length-1]);
				range.setStartAfter($("#message").children()[$("#message").children().length-1]);
				window.getSelection().removeAllRanges();
				window.getSelection().addRange(range);
			}
		}
	});
}

/** Génération du tableau contenant la liste des emoticons et raccourcis disponibles **/
function generateTable(){
	var html = "

Raccourci	Smiley
";
	for (i = 0; i < emoticons.length; ++i) {
		html += "
";
		for (j = 0; j < 2; ++j) {
			html += "";
			if( j == 0 ){
				//Nous sommes sur la premiere colonne (raccourci)
				html += emoticons[i][j];
			}
			else{
				//Nous sommes sur la seconde colonne (image de l'émoticone)
				html += "";
			}
			html += "	";
		}
		html += "
";
	}
	html += "
";
	return html;
}
/** Initialisation des popins du chat **/
function initChatPopins(){
	// Popin d'insertion d'image
	$('.sendImage').fancybox({
			minWidth	: 520,
			minHeight	: 25,
			width	: 520,
			height	: 25,
			fitToView	: false,
			autoSize	: false,
			closeClick	: false,
			openEffect	: 'none',
			closeEffect	: 'none',
			beforeShow:function(){
				$('#sendImg').click(sendImage);
			}
	});

	//Popin de saisie d'alias
	$('#showAliasForm').fancybox({
		minWidth	: 520,
		minHeight	: 25,
		width	: 520,
		height	: 25,
		fitToView	: false,
		autoSize	: false,
		closeClick	: false,
		openEffect	: 'none',
		closeEffect	: 'none',
		beforeShow:function(){
			$('#sendAlias').click(sendAlias);
		}
	});

	$('.showEmoticons').fancybox({
			minWidth	: 140,
			minHeight	: 200,
			width	: 140,
			height	: 200,
			fitToView	: false,
			autoSize	: false,
			closeClick	: false,
			openEffect	: 'none',
			closeEffect	: 'none',
			beforeShow:function(){
				$('#showEmoticons').append(
				"
" + generateTable() +"
"
				);
			}
	});
}

$( document ).ready(function() {
	initChatPopins();
	initTextDivWithSmileys();
});<commit_msg>Modif encodage message lors de l'envoi<commit_after>var socket = io.connect(window.location.host);
var emoticons = [
	[":)","Veryhappy.gif"],
	[":s","dizzy.gif"],
	[":o","outraged.gif"],
	[":(","sad.gif"],
	[";)","wink.gif"]
]

var getMessage = function(message) {
	var messageToAppend = isEncHTML(message) ? decHTMLifEnc(message) : message;
	$("#listOfMessages").html("
" + messageToAppend);
};

function sendImage() {
	var list = document.getElementById("listOfMessages");
	var imgWidth = parseInt($("#imgWidth").val()) > 0 ? $("#imgWidth").val() : "200";
	var imgHeight = parseInt($("#imgHeight").val()) > 0 ? $("#imgHeight").val() : "300";
	var url = $("#valueImg").val();
	socket.emit("image", $("#valueImg").val(), imgHeight, imgWidth);
	list.appendChild(createImgElement(url, imgHeight, imgWidth));
	list.appendChild(createBrElement());
}

function createImgElement(url, height, width) {
	var imgElement = document.createElement("img");
	imgElement.setAttribute("src", url);
	imgElement.setAttribute("height", height + "px");
	imgElement.setAttribute("width", width + "px");
	return imgElement;
}
function createBrElement() {
	return document.createElement("br");
}

function getImage(url, height, width) {
	var list = document.getElementById("listOfMessages");
	list.appendChild(createImgElement(url, height, width));
	list.appendChild(createBrElement());
}

function sendMessage() {
	var message = $("#message").html();
	var messageToAppend = isEncHTML(message) ? decHTMLifEnc(message) : message;
	socket.emit("message", messageToAppend);
	$("#listOfMessages").html("
" + messageToAppend);
	$("#message").html("");
}

function showAliasForm (request) {
	if(!request.isFirstTime) {
		$('.alias #errorMessage').text = request.message;
		console.log(request.message);
	}
	$('#showAliasForm').click();;

};

function sendAlias() {
	var alias = $('#txtAlias').val();
	if('' != alias) {
		socket.emit('alias', alias);
		$('.fancybox-close').click();
	}
}
socket.on('message', getMessage);
socket.on('image', getImage);
socket.on("alias", showAliasForm);
/*socket.on("alias", sendAlias);*/
document.getElementById("sendMessage").addEventListener("click", sendMessage);

/** Initialisation des div éditables et gestion des émoticones dans l'input associé. **/
function initTextDivWithSmileys(){
	$('.editable').each(function(){
		this.contentEditable = true;
	});
	$("#message").keyup(function(){
		for (i = 0; i < emoticons.length; ++i) {
			if($(this).html().indexOf(emoticons[i][0]) >= 0){
				$("#message").append('');
				$('#message').html($('#message').html().replace(emoticons[i][0], ''));

				// Déplace le curseur juste après l'insertion de l'emoticone dans la div editable
				var range = window.getSelection().getRangeAt($("#message").children()[$("#message").children().length-1]);
				range.setStartAfter($("#message").children()[$("#message").children().length-1]);
				window.getSelection().removeAllRanges();
				window.getSelection().addRange(range);
			}
		}
	});
}

/** Génération du tableau contenant la liste des emoticons et raccourcis disponibles **/
function generateTable(){
	var html = "

Raccourci	Smiley
";
	for (i = 0; i < emoticons.length; ++i) {
		html += "
";
		for (j = 0; j < 2; ++j) {
			html += "";
			if( j == 0 ){
				//Nous sommes sur la premiere colonne (raccourci)
				html += emoticons[i][j];
			}
			else{
				//Nous sommes sur la seconde colonne (image de l'émoticone)
				html += "";
			}
			html += "	";
		}
		html += "
";
	}
	html += "
";
	return html;
}
/** Initialisation des popins du chat **/
function initChatPopins(){
	// Popin d'insertion d'image
	$('.sendImage').fancybox({
			minWidth	: 520,
			minHeight	: 25,
			width	: 520,
			height	: 25,
			fitToView	: false,
			autoSize	: false,
			closeClick	: false,
			openEffect	: 'none',
			closeEffect	: 'none',
			beforeShow:function(){
				$('#sendImg').click(sendImage);
			}
	});

	//Popin de saisie d'alias
	$('#showAliasForm').fancybox({
		minWidth	: 520,
		minHeight	: 25,
		width	: 520,
		height	: 25,
		fitToView	: false,
		autoSize	: false,
		closeClick	: false,
		openEffect	: 'none',
		closeEffect	: 'none',
		beforeShow:function(){
			$('#sendAlias').click(sendAlias);
		}
	});

	$('.showEmoticons').fancybox({
			minWidth	: 140,
			minHeight	: 200,
			width	: 140,
			height	: 200,
			fitToView	: false,
			autoSize	: false,
			closeClick	: false,
			openEffect	: 'none',
			closeEffect	: 'none',
			beforeShow:function(){
				$('#showEmoticons').append(
				"
" + generateTable() +"
"
				);
			}
	});
}

$( document ).ready(function() {
	initChatPopins();
	initTextDivWithSmileys();
});<|endoftext|>


<commit_before>import { Condition } from 'selenium-webdriver';
import getWebElement from './getWebElement';

export const checkElementValueIsFactory = getWebElementImpl => (elementOrSelector, value, waitTimeout) =>
    async (driver) => {
        const element = await getWebElementImpl(elementOrSelector, driver, waitTimeout);
        return element.getAttribute('value').then(t => t === value);
    };

export const elementValueIsFactory = getWebElementImpl => (elementOrSelector, value, waitTimeout) => {
    const checkElementValueIs = checkElementValueIsFactory(getWebElementImpl);
    return new Condition('until element value is', checkElementValueIs(elementOrSelector, value, waitTimeout));
};

export default elementValueIsFactory(getWebElement);

<commit_msg>review<commit_after>import { Condition } from 'selenium-webdriver';
import getWebElement from './getWebElement';

export const checkElementValueIsFactory = getWebElementImpl =>
    (elementOrLocator, value, waitTimeout) =>
        async (driver) => {
            const element = await getWebElementImpl(elementOrLocator, driver, waitTimeout);
            return element.getAttribute('value').then(t => t === value);
        };

export const elementValueIsFactory = checkElementValueIs =>
    (elementOrLocator, value, waitTimeout) =>
        new Condition('until element value is', checkElementValueIs(elementOrLocator, value, waitTimeout));

export default elementValueIsFactory(checkElementValueIsFactory(getWebElement));

<|endoftext|>


<commit_before>var DiceRoll = (function() {

  var dice_src = [];
  dice_src[4] = [];
  for (var i = 1; i <= 4; i++) {
    dice_src[4][i] = '/dice/4_dice/4_dice[' + i + '].png';
  }

  dice_src[6] = [];
  for (var i = 1; i <= 6; i++) {
    dice_src[6][i] = '/dice/6_dice/6_dice[' + i + '].png';
  }

  dice_src[8] = [];
  for (var i = 1; i <= 8; i++) {
    dice_src[8][i] = '/dice/8_dice/8_dice[' + i + '].png';
  }

  dice_src[10] = [];
  dice_src[10][0] = '/dice/100_dice/100_dice[10].png';
  for (var i = 1; i <= 10; i++) {
    dice_src[10][i] = '/dice/10_dice/10_dice[' + i + '].png';
  }

  dice_src[20] = [];
  for (var i = 1; i <= 20; i++) {
    dice_src[20][i] = '/dice/20_dice/20_dice[' + i + '].png';
  }

  dice_src[100] = [];
  dice_src[100][0] = '/dice/100_dice/100_dice[10].png';
  for (var i = 1; i <= 10; i++) {
    dice_src[100][i] = '/dice/100_dice/100_dice[' + i + '].png';
  }

  var drawing_dice = [4, 6, 8, 10, 20, 100];

  var que = [];
  var timer;
  var state = 'stop'; //'rolling' or 'stop'

  var window_width, window_height;

  var DiceRoll = function(option) {
    this.d       = option.d;
    this.total   = option.total;
    this.numbers = option.numbers;
    this.comp    = option.comp;
    this.success = option.success;
    this.name    = option.name;
    this.dice    = [];
    this.count   = 0;

    que.push(this);

    if (que.length == 1) {
      this.begin();
    }
    else if (que.length == 2 && state == 'stop') {
      erase();
      que.shift();
      this.begin();
    }
  };

  DiceRoll.prototype.begin = function() {
    if (drawing_dice.indexOf(this.d) == -1) {
      this.showResultToLog();
      return;
    }

    window_width  = $(window).width();
    window_height = $(window).height();

    var num = this.numbers.length;
    for (var i = 0; i < num; i++) {
      var obj = genDiceObj(i, this.numbers[i], this.d);
      document.body.appendChild(obj);
      this.dice.push(obj);
    }

    timer = setInterval(this.updateDice, 50, this);
    state = 'rolling';
  };

  DiceRoll.prototype.updateDice = function(instans) {
    if (state == 'rolling') {
      instans.count++;
      for (var i = 0; i < instans.dice.length; i++) {
        var obj = instans.dice[i];

        if (instans.d == 100) {
          obj.img.src  = dice_src[100][instans.count % 10 + 1];
          obj.img2.src = dice_src[10][instans.count % 10 + 1];
        }
        else {
          obj.img.src = dice_src[instans.d][instans.count % instans.d + 1];
        }

        obj.vy = obj.vy - 9.8;
        obj.y -= obj.vy;
        obj.x -= obj.vx;

        if (obj.x < 0) {
          obj.x = 0
          obj.vx = -obj.vx * 0.9;
        }

        if (obj.vy < 0 && obj.base_of_dounding < obj.y) {
          obj.vy = -obj.vy * 0.94;
          obj.vx *= 0.86;
          obj.y = obj.base_of_dounding - (obj.y - obj.base_of_dounding);
          obj.base_of_dounding = obj.base_of_dounding * 0.75;
        }

        if (obj.base_of_dounding < obj.epsilon_y || state == 'stop') {
          state = 'stop';
          if (instans.d == 100) {
            obj.img.src  = dice_src[100][Math.floor(obj.number / 10)];
            obj.img2.src = dice_src[10][obj.number % 10];
          }
          else{
            obj.img.src = dice_src[instans.d][obj.number];
          }
          obj.onclick = erase;
          continue;
        }
        else {
          obj.style.top  = obj.y + "px";
          obj.style.left = obj.x + "px";
        }
      }
    }
    else if (state == 'stop') {
      clearInterval(timer);
      if (que.length > 1) {
        window.setTimeout(function() {
          erase();
          que.shift();
          que[0].begin();
        }, 500);
      }
      instans.showResultToLog();
      showAmount(instans.total, instans.success, (instans.dice[0].y - 50) + 'px', instans.dice[0].style.left);
    }
  };

  DiceRoll.prototype.showResultToLog = function() {
    var roll   = this.numbers.length + 'D' + this.d;
    var amount = this.total + ' ー> [' + this.numbers + ']';
    if (this.success != null) {
      roll   += this.comp;
      amount += ' ー> ' + (this.success ? '成功' : '失敗');
    }
    addMessage(this.name + ' ( ' + roll + ' ) ー> ' + amount);
  };

  var erase = function() {
    var objs = document.getElementsByClassName("dice");
    for (i = objs.length - 1; i >= 0; i--) {
      document.body.removeChild(objs[i]);
    }

    var total = document.getElementById('amount');
    if (total) {
      document.body.removeChild(total);
    }
  };

  var genDiceObj = function(id, number, d) {
    var obj = document.createElement("div");
    obj.number = number;
    obj.className = "dice";

    obj.x = window_width - 100 - 150 * (id % 5);
    obj.y = window_height - 100 * Math.floor(id / 5 + 1);

    obj.epsilon_y = 110 * 1.8;
    obj.style.left = obj.x + "px";
    obj.style.top = obj.y + "px";

    obj.vy = 100 * (window_height / 800);
    if (obj.vy < 100) {
      obj.vy = 100;
    }
    obj.vx = 25 * (window_width / 1000);
    obj.base_of_dounding = obj.epsilon_y + (window_height - obj.epsilon_y) * 0.2;

    obj.img = document.createElement("img");
    obj.img.src = dice_src[d][1];
    obj.appendChild(obj.img);

    if (d == 100) {
      obj.img2 = document.createElement("img");
      obj.img2.src = dice_src[10][1];
      obj.appendChild(obj.img2);
    }
    return obj;
  };

  var showAmount = function (number, success, top, left) {
    var obj = document.createElement("div");
    obj.id = 'amount'
    if (success == null) {
      obj.textContent = number;
    }
    else {
      obj.textContent = success ? '成功' : '失敗';
    }
    obj.style.top = top;
    obj.style.left = left;
    document.body.appendChild(obj);
  };

  return DiceRoll;
})();
<commit_msg>10面ダイス画像のパスを修正<commit_after>var DiceRoll = (function() {

  var dice_src = [];
  dice_src[4] = [];
  for (var i = 1; i <= 4; i++) {
    dice_src[4][i] = '/dice/4_dice/4_dice[' + i + '].png';
  }

  dice_src[6] = [];
  for (var i = 1; i <= 6; i++) {
    dice_src[6][i] = '/dice/6_dice/6_dice[' + i + '].png';
  }

  dice_src[8] = [];
  for (var i = 1; i <= 8; i++) {
    dice_src[8][i] = '/dice/8_dice/8_dice[' + i + '].png';
  }

  dice_src[10] = [];
  dice_src[10][0] = '/dice/10_dice/10_dice[10].png';
  for (var i = 1; i <= 10; i++) {
    dice_src[10][i] = '/dice/10_dice/10_dice[' + i + '].png';
  }

  dice_src[20] = [];
  for (var i = 1; i <= 20; i++) {
    dice_src[20][i] = '/dice/20_dice/20_dice[' + i + '].png';
  }

  dice_src[100] = [];
  dice_src[100][0] = '/dice/100_dice/100_dice[10].png';
  for (var i = 1; i <= 10; i++) {
    dice_src[100][i] = '/dice/100_dice/100_dice[' + i + '].png';
  }

  var drawing_dice = [4, 6, 8, 10, 20, 100];

  var que = [];
  var timer;
  var state = 'stop'; //'rolling' or 'stop'

  var window_width, window_height;

  var DiceRoll = function(option) {
    this.d       = option.d;
    this.total   = option.total;
    this.numbers = option.numbers;
    this.comp    = option.comp;
    this.success = option.success;
    this.name    = option.name;
    this.dice    = [];
    this.count   = 0;

    que.push(this);

    if (que.length == 1) {
      this.begin();
    }
    else if (que.length == 2 && state == 'stop') {
      erase();
      que.shift();
      this.begin();
    }
  };

  DiceRoll.prototype.begin = function() {
    if (drawing_dice.indexOf(this.d) == -1) {
      this.showResultToLog();
      return;
    }

    window_width  = $(window).width();
    window_height = $(window).height();

    var num = this.numbers.length;
    for (var i = 0; i < num; i++) {
      var obj = genDiceObj(i, this.numbers[i], this.d);
      document.body.appendChild(obj);
      this.dice.push(obj);
    }

    timer = setInterval(this.updateDice, 50, this);
    state = 'rolling';
  };

  DiceRoll.prototype.updateDice = function(instans) {
    if (state == 'rolling') {
      instans.count++;
      for (var i = 0; i < instans.dice.length; i++) {
        var obj = instans.dice[i];

        if (instans.d == 100) {
          obj.img.src  = dice_src[100][instans.count % 10 + 1];
          obj.img2.src = dice_src[10][instans.count % 10 + 1];
        }
        else {
          obj.img.src = dice_src[instans.d][instans.count % instans.d + 1];
        }

        obj.vy = obj.vy - 9.8;
        obj.y -= obj.vy;
        obj.x -= obj.vx;

        if (obj.x < 0) {
          obj.x = 0
          obj.vx = -obj.vx * 0.9;
        }

        if (obj.vy < 0 && obj.base_of_dounding < obj.y) {
          obj.vy = -obj.vy * 0.94;
          obj.vx *= 0.86;
          obj.y = obj.base_of_dounding - (obj.y - obj.base_of_dounding);
          obj.base_of_dounding = obj.base_of_dounding * 0.75;
        }

        if (obj.base_of_dounding < obj.epsilon_y || state == 'stop') {
          state = 'stop';
          if (instans.d == 100) {
            obj.img.src  = dice_src[100][Math.floor(obj.number / 10)];
            obj.img2.src = dice_src[10][obj.number % 10];
          }
          else{
            obj.img.src = dice_src[instans.d][obj.number];
          }
          obj.onclick = erase;
          continue;
        }
        else {
          obj.style.top  = obj.y + "px";
          obj.style.left = obj.x + "px";
        }
      }
    }
    else if (state == 'stop') {
      clearInterval(timer);
      if (que.length > 1) {
        window.setTimeout(function() {
          erase();
          que.shift();
          que[0].begin();
        }, 500);
      }
      instans.showResultToLog();
      showAmount(instans.total, instans.success, (instans.dice[0].y - 50) + 'px', instans.dice[0].style.left);
    }
  };

  DiceRoll.prototype.showResultToLog = function() {
    var roll   = this.numbers.length + 'D' + this.d;
    var amount = this.total + ' ー> [' + this.numbers + ']';
    if (this.success != null) {
      roll   += this.comp;
      amount += ' ー> ' + (this.success ? '成功' : '失敗');
    }
    addMessage(this.name + ' ( ' + roll + ' ) ー> ' + amount);
  };

  var erase = function() {
    var objs = document.getElementsByClassName("dice");
    for (i = objs.length - 1; i >= 0; i--) {
      document.body.removeChild(objs[i]);
    }

    var total = document.getElementById('amount');
    if (total) {
      document.body.removeChild(total);
    }
  };

  var genDiceObj = function(id, number, d) {
    var obj = document.createElement("div");
    obj.number = number;
    obj.className = "dice";

    obj.x = window_width - 100 - 150 * (id % 5);
    obj.y = window_height - 100 * Math.floor(id / 5 + 1);

    obj.epsilon_y = 110 * 1.8;
    obj.style.left = obj.x + "px";
    obj.style.top = obj.y + "px";

    obj.vy = 100 * (window_height / 800);
    if (obj.vy < 100) {
      obj.vy = 100;
    }
    obj.vx = 25 * (window_width / 1000);
    obj.base_of_dounding = obj.epsilon_y + (window_height - obj.epsilon_y) * 0.2;

    obj.img = document.createElement("img");
    obj.img.src = dice_src[d][1];
    obj.appendChild(obj.img);

    if (d == 100) {
      obj.img2 = document.createElement("img");
      obj.img2.src = dice_src[10][1];
      obj.appendChild(obj.img2);
    }
    return obj;
  };

  var showAmount = function (number, success, top, left) {
    var obj = document.createElement("div");
    obj.id = 'amount'
    if (success == null) {
      obj.textContent = number;
    }
    else {
      obj.textContent = success ? '成功' : '失敗';
    }
    obj.style.top = top;
    obj.style.left = left;
    document.body.appendChild(obj);
  };

  return DiceRoll;
})();
<|endoftext|>


<commit_before>import h from '../hyperscript.js';
import SiimpleComponent from '../index.js';
import SiimpleClose from './close.js';

//Alert component
export default class SiimpleAlert extends SiimpleComponent
{
  //Constructor
  constructor(props)
  {
    //Call super
    super(props);

    //Bind the handle close method
    this.handleClose = this.handleClose.bind(this);
  }

  //Handle close button event
  handleClose(e)
  {
    //Check if the close button handler is defined
    if(typeof this.props.onClose === 'function')
    {
      //Call the close handler method
      return this.props.onClose.call(null, e);
    }
  }

  //Render the alert component
  render()
  {
    //Initialize the list with the element classes
    var class_list = [ 'siimple-alert' ];

    //Check the color
    if(typeof this.props.color === 'string')
    {
      //Add the alert color
      class_list.push('siimple-alert--'  + this.props.color.toLowerCase().trim());
    }

    //Initialize the child elements list
    var children = [ h.span({}, this.props.children) ];

    //Check if the close button is enabled
    if(this.props.showCloseButton === true)
    {
      //Add the close button element
      children.push(h(SiimpleClose, { onClick: this.handleClose }));
    }

    //Create the alert element
    return h.div({ className: class_list.join(' ') }, children);
  }
}

//Alert default props
SiimpleAlert.defaultProps = { color: 'blue', showCloseButton: false, onClose: null };
<commit_msg>src/elements/alert.js: minor changes<commit_after>import h from '../hyperscript.js';
import SiimpleComponent from '../index.js';
import SiimpleClose from './close.js';

//Alert component
export default class SiimpleAlert extends SiimpleComponent
{
  //Constructor
  constructor(props)
  {
    //Call super
    super(props);

    //Bind the handle close method
    this.handleClose = this.handleClose.bind(this);
  }

  //Handle close button event
  handleClose(e)
  {
    //Check if the close button handler is defined
    if(typeof this.props.onClose === 'function')
    {
      //Call the close handler method
      return this.props.onClose.call(null, e);
    }
  }

  //Render the alert component
  render()
  {
    //Initialize the list with the element classes
    var class_list = [ 'siimple-alert' ];

    //Check the color
    if(typeof this.props.color === 'string')
    {
      //Add the alert color
      class_list.push('siimple-alert--'  + this.props.color.toLowerCase().trim());
    }

    //Initialize the child elements list
    var children = [ h.span({}, this.props.children) ];

    //Check if the close button is enabled
    if(this.props.showCloseButton === true)
    {
      //Add the close button element
      children.push(h(SiimpleClose, { onClick: this.handleClose }));
    }

    //Create the alert element
    return h.div({ className: class_list }, children);
  }
}

//Alert default props
SiimpleAlert.defaultProps = { color: 'blue', showCloseButton: false, onClose: null };
<|endoftext|>


<commit_before>import Util from '../../../client/util'
import {CAPABILITY_MANAGE_CMS_CONTENT} from '../constants'
import {NO_SESSION_KEY_VALUES_SERVER} from "../../../client/constants";
import gql from "graphql-tag";

//map with slugs that are url sensitive
export const urlSensitivMap = {}

// the key prefix to store the settings in the keyvalue store
export const settingKeyPrefix = 'CmsViewContainerSettings'

// the graphql query is also need to access and update the cache when data arrive from a subscription
let _gqlQuery
export const gqlQuery = ()=>{
    if(!_gqlQuery) {
        _gqlQuery = gql`query cmsPage($slug:String!,$query:String,$props:String,$nosession:String,$editmode:Boolean,$_version:String){cmsPage(slug:$slug,query:$query,props:$props,nosession:$nosession,editmode:$editmode,_version:$_version){cacheKey slug name{${_app_.lang}} urlSensitiv template script serverScript resources dataResolver ssr public online resolvedData parseResolvedData alwaysLoadAssets html subscriptions _id modifiedAt createdBy{_id username} status}}`
    }
    return _gqlQuery
}

// query to get a keyvalue pair
export const gqlQueryKeyValue = gql`query keyValue($key:String!){keyValue(key:$key){key value createdBy{_id}}}`

export const isPreview = () => {
    const params = new URLSearchParams(window.location.search)
    return params.get('preview')
}

export const isEditMode = (props) => {
    const {user} = props
    return (user.isAuthenticated && Util.hasCapability(user, CAPABILITY_MANAGE_CMS_CONTENT) && !isPreview())
}

export const getSlugVersion = (slug) => {
    const ret = {}
    if (slug.indexOf('@') === 0) {
        const pos = slug.indexOf('/')
        ret.slug = pos >= 0 ? slug.substring(pos + 1) : ''
        ret._version = pos >= 0 ? slug.substring(1, pos) : slug.substring(1)

    } else {
        ret.slug = slug
    }

    return ret
}

export const getGqlVariables = props => {
    const {slug, urlSensitiv, dynamic, user, _props} = props,
        variables = {
            ...getSlugVersion(slug)
        }

    if (_props && _props.$) {
        variables.props = JSON.stringify(_props.$)
    }

    if (!dynamic && isEditMode(props)) {
        variables.editmode = true
    }

    // add settings from local storage if user is not logged in
    if (!user.isAuthenticated) {
        const kv = localStorage.getItem(NO_SESSION_KEY_VALUES_SERVER)
        if (kv) {
            variables.nosession = kv
        }
    }

    // add query if page is url sensitiv
    if (urlSensitiv === true || (!dynamic && urlSensitiv === undefined && (urlSensitivMap[slug] || urlSensitivMap[slug] === undefined))) {
        const q = window.location.search.substring(1)
        if (q)
            variables.query = q
    }

    return variables
}
<commit_msg>Small improvements<commit_after>import Util from '../../../client/util'
import {CAPABILITY_MANAGE_CMS_CONTENT} from '../constants'
import {NO_SESSION_KEY_VALUES_SERVER} from "../../../client/constants";
import gql from "graphql-tag";

//map with slugs that are url sensitive
export const urlSensitivMap = {}

// the key prefix to store the settings in the keyvalue store
export const settingKeyPrefix = 'CmsViewContainerSettings'

// the graphql query is also need to access and update the cache when data arrive from a subscription
let _gqlQuery
export const gqlQuery = ()=>{
    if(!_gqlQuery) {
        _gqlQuery = gql`query cmsPage($slug:String!,$query:String,$props:String,$nosession:String,$editmode:Boolean,$_version:String){cmsPage(slug:$slug,query:$query,props:$props,nosession:$nosession,editmode:$editmode,_version:$_version){cacheKey slug name{en de} urlSensitiv template script serverScript resources dataResolver ssr public online resolvedData parseResolvedData alwaysLoadAssets html subscriptions _id modifiedAt createdBy{_id username} status}}`
    }
    return _gqlQuery
}

// query to get a keyvalue pair
export const gqlQueryKeyValue = gql`query keyValue($key:String!){keyValue(key:$key){key value createdBy{_id}}}`

export const isPreview = () => {
    const params = new URLSearchParams(window.location.search)
    return params.get('preview')
}

export const isEditMode = (props) => {
    const {user} = props
    return (user.isAuthenticated && Util.hasCapability(user, CAPABILITY_MANAGE_CMS_CONTENT) && !isPreview())
}

export const getSlugVersion = (slug) => {
    const ret = {}
    if (slug.indexOf('@') === 0) {
        const pos = slug.indexOf('/')
        ret.slug = pos >= 0 ? slug.substring(pos + 1) : ''
        ret._version = pos >= 0 ? slug.substring(1, pos) : slug.substring(1)

    } else {
        ret.slug = slug
    }

    return ret
}

export const getGqlVariables = props => {
    const {slug, urlSensitiv, dynamic, user, _props} = props,
        variables = {
            ...getSlugVersion(slug)
        }

    if (_props && _props.$) {
        variables.props = JSON.stringify(_props.$)
    }

    if (!dynamic && isEditMode(props)) {
        variables.editmode = true
    }

    // add settings from local storage if user is not logged in
    if (!user.isAuthenticated) {
        const kv = localStorage.getItem(NO_SESSION_KEY_VALUES_SERVER)
        if (kv) {
            variables.nosession = kv
        }
    }

    // add query if page is url sensitiv
    if (urlSensitiv === true || (!dynamic && urlSensitiv === undefined && (urlSensitivMap[slug] || urlSensitivMap[slug] === undefined))) {
        const q = window.location.search.substring(1)
        if (q)
            variables.query = q
    }

    return variables
}
<|endoftext|>


<commit_before>$(document).ready(function() {
    console.log("touchscreen is", VirtualJoystick.touchScreenAvailable() ? "available" : "not available");
    var canvas = document.getElementById("overlay"),
    context     = canvas.getContext('2d');
      var centerX = canvas.width / 2;
      var centerY = canvas.height / 2;
      var radius = 70;

      context.beginPath();
      context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
      context.fillStyle = 'green';
      context.fill();
      context.lineWidth = 5;
      context.strokeStyle = '#003300';
      context.stroke();    //
    var joystick_a    = new VirtualJoystick({
        container   : document.body,
        strokeStyle : 'cyan',
        limitStickTravel: true,
        stickRadius : 120,
    });
    joystick_a.addEventListener('touchStartValidation', function(event){
        var touch   = event.changedTouches[0];
        return touch.pageX < window.innerWidth/2;
    });

    // one on the right of the screen
    var joystick_b    = new VirtualJoystick({
        container   : document.body,
        strokeStyle : 'orange',
        limitStickTravel: true,
        stickRadius : 120
    });
    joystick_b.addEventListener('touchStartValidation', function(event){
        var touch   = event.changedTouches[0];
        return touch.pageX >= window.innerWidth/2;
    });

    var parser = document.createElement('a');
    parser.href = document.URL

    var ws = new WebSocket("ws://" + parser.hostname + ":3001");
    ws.binaryType = "arraybuffer";

    var elem;
    ws.onopen = function(){
        ws.onmessage = function(e) {
            if (e.data[0] == 0) {
                document.getElementById('video').src = URL.createObjectURL(new Blob([e.data.slice(5)]));
            } else {

            }
        }
        ws.onerror = function(e) {
            console.error(e);
        }
        ws.onclose = function() {
            console.log("Socket closed");
        }
        setInterval(function(){
        ws.send(JSON.stringify({
            a: {
                dx: joystick_a.deltaX(),
                dy: joystick_a.deltaY()
            },
            b: {
                dx: joystick_b.deltaY(),
                dy: joystick_b.deltaY()
            }
        }));
        }, 1/30 * 1000);
    }
    $(window).on('beforeunload', function(){
        ws.close();
    });
    function check_landscape() {
        if (window.innerHeight > window.innerWidth) {
            $("#landscape-alert").fadeIn();
        } else {
            $("#landscape-alert").fadeOut();
        }
    }
    check_landscape();
    $(window).resize(function() {
        check_landscape();
    });
    function toggleFullScreen() {
  var doc = window.document;
  var docEl = doc.documentElement;

  var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
  var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen;

  if(!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement && !doc.msFullscreenElement) {
    requestFullScreen.call(docEl);
  }
  else {
    //cancelFullScreen.call(doc);
  }
}
document.documentElement.addEventListener("mousedown", function(){
    toggleFullScreen();
});
document.documentElement.addEventListener("touchstart", function(){
    toggleFullScreen();
});
});<commit_msg>Small fix<commit_after>$(document).ready(function() {
    console.log("touchscreen is", VirtualJoystick.touchScreenAvailable() ? "available" : "not available");
    var canvas = document.getElementById("overlay"),
    context     = canvas.getContext('2d');
      /*var centerX = canvas.width / 2;
      var centerY = canvas.height / 2;
      var radius = 70;

      context.beginPath();
      context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
      context.fillStyle = 'green';
      context.fill();
      context.lineWidth = 5;
      context.strokeStyle = '#003300';
      context.stroke();    // */
    var joystick_a    = new VirtualJoystick({
        container   : document.body,
        strokeStyle : 'cyan',
        limitStickTravel: true,
        stickRadius : 120,
    });
    joystick_a.addEventListener('touchStartValidation', function(event){
        var touch   = event.changedTouches[0];
        return touch.pageX < window.innerWidth/2;
    });

    // one on the right of the screen
    var joystick_b    = new VirtualJoystick({
        container   : document.body,
        strokeStyle : 'orange',
        limitStickTravel: true,
        stickRadius : 120
    });
    joystick_b.addEventListener('touchStartValidation', function(event){
        var touch   = event.changedTouches[0];
        return touch.pageX >= window.innerWidth/2;
    });

    var parser = document.createElement('a');
    parser.href = document.URL

    var ws = new WebSocket("ws://" + parser.hostname + ":3001");
    ws.binaryType = "arraybuffer";

    var elem;
    ws.onopen = function(){
        ws.onmessage = function(e) {
            if (e.data[0] == 0) {
                document.getElementById('video').src = URL.createObjectURL(new Blob([e.data.slice(5)]));
            } else {

            }
        }
        ws.onerror = function(e) {
            console.error(e);
        }
        ws.onclose = function() {
            console.log("Socket closed");
        }
        setInterval(function(){
        ws.send(JSON.stringify({
            a: {
                dx: joystick_a.deltaX(),
                dy: joystick_a.deltaY()
            },
            b: {
                dx: joystick_b.deltaY(),
                dy: joystick_b.deltaY()
            }
        }));
        }, 1/30 * 1000);
    }
    $(window).on('beforeunload', function(){
        ws.close();
    });
    function check_landscape() {
        if (window.innerHeight > window.innerWidth) {
            $("#landscape-alert").fadeIn();
        } else {
            $("#landscape-alert").fadeOut();
        }
    }
    check_landscape();
    $(window).resize(function() {
        check_landscape();
    });
    function toggleFullScreen() {
  var doc = window.document;
  var docEl = doc.documentElement;

  var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
  var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen;

  if(!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement && !doc.msFullscreenElement) {
    requestFullScreen.call(docEl);
  }
  else {
    //cancelFullScreen.call(doc);
  }
}
document.documentElement.addEventListener("mousedown", function(){
    toggleFullScreen();
});
document.documentElement.addEventListener("touchstart", function(){
    toggleFullScreen();
});
});<|endoftext|>


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

  $('#about')
    .hide()
    .removeClass('hidden');

  $('#faq').on("click", () => {
    $('#about').slideToggle();

    $('#nav-back')
    .hide()
    .removeClass('hidden');
  });

  $('#nav-forward').on("click", () => {
    let progress = Number($('.progress-bar').attr('aria-valuenow'));
    progress += 25;
    showPage(progress);
  });

    $('#nav-back').on("click", () => {
    let progress = Number($('.progress-bar').attr('aria-valuenow'));
    progress -= 25;
    showPage(progress);
  });

  function showPage(progress) {
    $('.progress-bar span').text(`${progress} Complete`);
    $('.progress-bar').attr('aria-valuenow', progress);
    $('.progress-bar').attr('style', `width: ${progress}%`);
    switch (progress) {
      case 25:
        $('#nav-back').hide();
        $('.about-img').attr('src', "images/about-1.png");
        break;
      case 50:
        $('#nav-back').show();
        $('.about-img').attr('src', "images/about-2.png");
        break;
      case 75:
        $('.about-img').attr('src', "images/about-3.png");
        break;
      case 100:
        $('.about-img').attr('src', "images/about-4.png");
        break;
      case 125:
        $('#about').slideToggle(() => {
          showPage(25);
        });
        break;
    }
  }
});<commit_msg>fixing broken faq images on nested pages<commit_after>$(document).ready(function() {

  $('#about')
    .hide()
    .removeClass('hidden');

  $('#faq').on("click", () => {
    $('#about').slideToggle();

    $('#nav-back')
    .hide()
    .removeClass('hidden');
  });

  $('#nav-forward').on("click", () => {
    let progress = Number($('.progress-bar').attr('aria-valuenow'));
    progress += 25;
    showPage(progress);
  });

    $('#nav-back').on("click", () => {
    let progress = Number($('.progress-bar').attr('aria-valuenow'));
    progress -= 25;
    showPage(progress);
  });

  function showPage(progress) {
    $('.progress-bar span').text(`${progress} Complete`);
    $('.progress-bar').attr('aria-valuenow', progress);
    $('.progress-bar').attr('style', `width: ${progress}%`);
    switch (progress) {
      case 25:
        $('#nav-back').hide();
        $('.about-img').attr('src', "http://binnerpickup.org/images/about-1.png");
        break;
      case 50:
        $('#nav-back').show();
        $('.about-img').attr('src', "http://binnerpickup.org/images/about-2.png");
        break;
      case 75:
        $('.about-img').attr('src', "http://binnerpickup.org/images/about-3.png");
        break;
      case 100:
        $('.about-img').attr('src', "http://binnerpickup.org/images/about-4.png");
        break;
      case 125:
        $('#about').slideToggle(() => {
          showPage(25);
        });
        break;
    }
  }
});<|endoftext|>