text:
LISY Protocol
=============

The LISY protocol is a generic serial protocol to control pinball machines.
It was developed for the :doc:`LISY platform <index>` but is also used in other
custom pinball platforms such as :doc:`APC </hardware/apc/index>`.

Theory of operations
--------------------

All communication is initiated from the host PC.
Commands are binary and generally have a fixed length.
They may contain a length byte to indicate how many entries are to
expect (i.e. three color values).
Strings are zero terminated in both command and response.

At startup MPF resets the hardware and queries the count of all peripherals
(i.e. switches, coils, lamps).
Afterwards, it will query the state of switches and configure coils/lamps.

During the runtime MPF periodically polls changed switches and sends a
watchdog every 500ms.
The platform is expected to disable all outputs after 1s without watchdog.

Limitations
-----------

Let us know if you hit any of those and we can develop a plan forward.

 - Max 127 switches are supported (because polling uses the upper bit as state)
 - Max 256 hardware sounds (alternatively, you can use the MPF sound system)
 - Max 256 simple lamps (on/off only)
 - Max 256 lights (with fading and brightness)
 - Max 256 coils (MPF currently only supports 100 of them; let us know if you need more)
 - Max 7 alphanumeric displays (BCD, 7-segment or 14-segment displays)
 - No error correction on the wire (your serial should be reliable)

Protocol reference (v0.08)
--------------------------

.. csv-table:: General command format
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "Command Byte (see table below"
   "1 - n", "n - 1", "Payload (n-1 bytes)"

.. csv-table:: String format (in both payload and response)
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0 to (n-1)", "n - 1", "String"
   "n", "1", "Null byte"

Get Connected Hardware (0x00)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get the name of the connected hardware.
Does not have any payload.

Example:

.. csv-table:: Command 0x00 - Get Connected Hardware
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "0", "Command 0 - Get Connected Hardware"

Returns a null terminated string.

Example: ``LISY80``.

MPF uses this string to identify the platform and might perform certain
quirks based on this info if necessary.
Currently, there is quirk ``coils_start_at_one`` for ``LISY1``, ``LISY35``
and ``APC`` to index coils starting at one instead of zero.

Get Firmware Version (0x01)
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get firmware version of the hardware board.
Does not have any payload.

Example:

.. csv-table:: Example Command 0x01 - Get Firmware Version
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "1", "Command 1 - Get Firmware Version"

Returns a null terminated string.

Example: ``4.01``.

MPF parses this string as semantic version.
It exposes the version as variable and in the logs.
This might be used to perform quirks around known bugs.

Get API Version (0x02)
^^^^^^^^^^^^^^^^^^^^^^

Get the API version.
Does not have any payload.

Example:

.. csv-table:: Example Command 0x02 - Get API Version
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "2", "Command 2 - Get API Version"

Returns a null terminated string.

Example: ``0.08``.

MPF parses this string as semantic version.
This is expected to be ``0.08`` for this version.
MPF might refuse old API versions at some point.

Get Simple Lamp Count (0x03)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get count of lamps connected to the hardware platform.
Does not have any payload.

Example:

.. csv-table:: Example Command 0x03 - Get Simple Lamp Count
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "3", "Command 3 - Get Simple Lamp Count"

Returns one byte:

.. csv-table:: Response to 0x03 - Get Simple Lamp Count
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "Simple Lamp count ``l`` (0 to 255). 0 if no simple lamps exist."

Example:

.. csv-table:: Example Response to 0x03 - Get Simple Lamp Count
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "64", "Platform supports 64 simple lamps with numbers 0 to 63."

MPF uses this number to refuse any lights with a number larger or equal than
``l`` and subtype ``lamp``.
Lamps in LISY are expected to be ``on/off`` type devices and do not support
fading or dimming.
Use this for older style lamps and GIs.

Get Solenoid Count (0x04)
^^^^^^^^^^^^^^^^^^^^^^^^^

Get count of solenoids connected to the hardware platform.
Does not have any payload.

Example:

.. csv-table:: Example Command 0x04 - Get Solenoid Count
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "4", "Command 4 - Get Solenoid Count"

Returns one byte:

.. csv-table:: Response to 0x04 - Get Solenoid Count
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "Solenoid count ``c`` (0 to 127). 0 if no solenoids exist."

Example:

.. csv-table:: Example Response to 0x04 - Get Solenoid Count
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "64", "Platform supports 64 solenoids with numbers 0 to 63."

MPF uses this number to refuse any solenoids with a number larger or equal than
``c``.

Get Sound Count (0x05)
^^^^^^^^^^^^^^^^^^^^^^

Get count of sounds available.
Does not have any payload.

Example:

.. csv-table:: Example Command 0x05 - Get Sound Count
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "5", "Command 5 - Get Sound Count"

Returns one byte:

.. csv-table:: Response to 0x05 - Get Sound Count
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "Sound count ``o`` (0 to 255). 0 if no sounds exist."

Example:

.. csv-table:: Example Response to 0x05 - Get Sound Count
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "128", "Platform supports 128 sounds with numbers 0 to 127."

MPF uses this number to refuse any sounds with a number larger or equal than
``o``.
This is used for older machines with a hardware soundcard.
In :doc:`LISY <index>` it can be used to play sounds from the ROM of the
original game.
Return ``0`` if you do not support sounds in your platform.

Get Segment Display Count (0x06)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get count of segment displays available.
Does not have any payload.

Example:

.. csv-table:: Example Command 0x06 - Get Segment Display Count
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "6", "Command 6 - Get Segment Display Count"

Returns one byte:

.. csv-table:: Response to 0x06 - Get Segment Display Count
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "Segment display count ``sd`` (0 to 255). 0 if no sounds exist."

Example:

.. csv-table:: Example Response to 0x06 - Get Segment Display Count
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "6", "Platform supports 6 segment displays with numbers 0 to 5."

MPF uses this number to refuse any segment display with a number larger or
equal than ``sd``.
Return ``0`` if you do not support displays in your platform.

Get Segment Display Details (0x07)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get type of segment displays.

.. csv-table:: Payload of Command 0x07 - Get Segment Display Details
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``sd`` of the segment display to query"

Example:

.. csv-table:: Example Command 0x07 - Get Segment Display Details
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "7", "Command 7 - Get Segment Display Details"
   "1", "1", "0", "Query the first display"

Returns two bytes:

.. csv-table:: Response to 0x07 - Get Segment Display Details
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "Type of segment display (see list below)"
   "1", "1", "Number of segments ``sw(sd)`` (0-255)"

``sw(sd)`` is the segment width for display index ``sd``.

Example:

.. csv-table:: Example Response to 0x07 - Get Segment Display Details
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "1", "Segment display is a BCD7 display"
   "1", "1", "12", "Segment display is 12 segments wide"

Options are:

.. csv-table:: Types in Response of 0x07 - Get Segment Display Details
   :header: "Byte of segment type ``st``", "Name", "Description", "Bytes per Segment ``bs(st)``"
   :widths: 10, 10, 10, 30

   "0", "Invalid", "Display index is invalid or does not exist in machine.", "-"
   "1", "BCD7", "BCD Code for 7 Segment Displays without comma", "1 byte (4 bit BCD in the first four byte)"
   "2", "BCD8", "BCD Code for 8 Segment Displays (same as BCD7 but with comma)", "1 byte (4 bit BCD in the first four byte, 7th byte is the comma)"
   "3", "SEG7", "Fully addressable 7 Segment Display (with comma)", "1 byte (a-g encoded as bit 0 to 6 and bit 7 as comma)"
   "4", "SEG14", "Fully addressable 14 Segment Display (with comma)", "2 bytes (a-g encoded as bit 0 to 6 in first byte. h to r encoded as bit 0 to 6 in second byte. comma as bit 7 in second byte)"
   "5", "ASCII", "ASCII Code", "1 ascii byte per segment"
   "6", "ASCII_DOT", "ASCII Code with comma (every segment has an additional comma)", "1 ascii byte per segment. Additionally bit 7 encodes the comma."

Not yet used in MPF but will be added soon.

Get Game Info (0x08)
^^^^^^^^^^^^^^^^^^^^

Get the game number.
Does not have any payload.

Example:

.. csv-table:: Example Command 0x08 - Get Game Info
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "8", "Command 8 - Get Game Info"

Returns null terminated string.
This is the internal Gottlieb number in LISY.
MPF does not use the command at all (and we are not planning to).
It is used in PinMAME on LISY.

Get Switch Count (0x09)
^^^^^^^^^^^^^^^^^^^^^^^

Get count of switches available.
Does not have any payload.

Example:

.. csv-table:: Example Command 0x09 - Get Switch Count
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "9", "Command 9 - Get Switch Count"

Returns one byte:

.. csv-table:: Response to 0x09 - Get Switch Count
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "Switch count ``s`` (0 to 127)"

Example:

.. csv-table:: Example Response to 0x09 - Get Switch Count
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "70", "Platform supports 70 switches with numbers 0 to 69."

MPF uses this number to refuse any switches with a number larger or
equal than ``s``.
Please note that the procotol is currently limited to 127 switches since the
upper byte is used to indicate inverted switches in commands.

Get Status of Simple Lamp (0x0A)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get the status of a simple lamp.
Payload is the lamp index:

.. csv-table:: Payload of Command 0x0A - Get Status of Simple Lamp
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``l`` of the lamp to query"

Example:

.. csv-table:: Example Command 0x0A - Get Status of Simple Lamp
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "10", "Command 10 - Get Status of Simple Lamp"
   "1", "1", "25", "Query status of lamp 25"

Returns one byte:

.. csv-table:: Response to 0x0A - Get Status of Simple Lamp
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "0=Off, 1=On, 2=Lamp not existing"

Example:

.. csv-table:: Example Response to 0x0A - Get Status of Simple Lamp
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "0", "Status of lamp is off"

MPF will not use this.
After init/reset MPF assumes all lights to be in state off.

Set Status of Simple Lamp to On (0x0B)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Set simple lamp to on.
Payload is the lamp index:

.. csv-table:: Payload of Command 0x0B - Set Status of Simple Lamp to On
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``l`` of the lamp to set to on"

Example:

.. csv-table:: Example Command 0x0B - Set Status of Simple Lamp to On
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "11", "Command 11 - Set Status of Simple Lamp to On"
   "1", "1", "25", "Set lamp 25 to on"

No response is expected.

Set Status of Simple Lamp to Off (0x0C)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Set simple lamp to off.
Payload is the lamp index:

.. csv-table:: Payload of Command 0x0C - Set Status of Simple Lamp to Off
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``l`` of the lamp to set to off"

Example:

.. csv-table:: Example Command 0x0C - Set Status of Simple Lamp to Off
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "12", "Command 12 - Set Status of Simple Lamp to Off"
   "1", "1", "25", "Set lamp 25 to off"

No response is expected.

Get Status of Solenoid (0x14)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get the status of a solenoid.
Payload is the solenoid index:

.. csv-table:: Payload of Command 0x14 - Get Status of Solenoid
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``c`` of the solenoid to query"

Example:

.. csv-table:: Example Command 0x14 - Get Status of Solenoid
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "20", "Command 20 - Get Status of Solenoid"
   "1", "1", "25", "Query status of solenoid 25"

Returns one byte:

.. csv-table:: Response to 0x14 - Get Status of Solenoid
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "0=Off, 1=On, 2=Solenoid not existing"

Example:

.. csv-table:: Example Response to 0x14 - Get Status of Solenoid
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "0", "Status of solenoid is off"

MPF will not use this.
After init/reset MPF assumes all solenoids to be in state disabled.

Enable Solenoid at Full Power (0x15)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Enable solenoid at full power.
Payload is the solenoid index:

.. csv-table:: Payload of Command 0x15 - Enable Solenoid at Full Power
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``c`` of the solenoid to enable"

Example:

.. csv-table:: Example Command 0x15 - Enable Solenoid at Full Power
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "21", "Command 21 - Enable Solenoid at Full Power"
   "1", "1", "25", "Enable solenoid 25 at full power"

No response is expected.
This is mostly used in older machines where solenoids could be enabled without PWM.

Disable Solenoid (0x16)
^^^^^^^^^^^^^^^^^^^^^^^

Disable solenoid.
Payload is the solenoid index:

.. csv-table:: Payload of Command 0x16 - Disable Solenoid
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``c`` of the solenoid to disable"

Example:

.. csv-table:: Example Command 0x16 - Disable Solenoid
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "22", "Command 22 - Disable Solenoid"
   "1", "1", "25", "Disable solenoid 25"

No response is expected.

Pulse Solenoid (0x17)
^^^^^^^^^^^^^^^^^^^^^

Pulse solenoid with it's configured pulse time.
Payload is the solenoid index:

.. csv-table:: Payload of Command 0x17 - Pulse Solenoid
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``c`` of the solenoid to pulse"

Example:

.. csv-table:: Example Command 0x17 - Pulse Solenoid
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "23", "Command 23 - Pulse Solenoid"
   "1", "1", "25", "Pulse solenoid 25"

No response is expected.
Use command 0x18 to configure the pulse time.

Set Solenoid Pulse Time (0x18)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Configure the pulse time of a solenoid in milliseconds.
Payload is the solenoid index and pulse time.

.. csv-table:: Payload of Command 0x18 - Set Solenoid Pulse Time
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``c`` of the solenoid to configure"
   "2", "1", "Pulse time in ms (0-255)"

Example:

.. csv-table:: Example Command 0x18 - Set Solenoid Pulse Time
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "21", "Command 24 - Set Solenoid Pulse Time"
   "1", "1", "25", "Configure solenoid 25"
   "2", "1", "50", "Set pulse time to 50ms"

No response is expected.
This will affect pulses in command 0x17.

Set Segment Display 0-6 (0x1E - 0x24)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Set content of segment display ``d`` 0-6.
Payload is a null terminated string.
Content encoding depends on the type of the display (from command 0x7).

.. csv-table:: Command 0x1E - 0x24 - Set Segment Display ``d``
   :header: "Byte", "Length", "Value", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "30 + d", "Command byte for set segment depending on segment number ``d``"
   "1", "1", "``sw(sd) * bs(st)``", "Bytes which will follow. Number of segments (0-127) multiplied by bytes per segment for this display (1 or 2 bytes)."
   "2", "``sw(sd) * bs(st)``", "Number of segments (0-127) multiplied by bytes per segment for this display (1 or 2 bytes)", "One or two bytes per segment for all segments. Encoding depends on segment type (see command 0x7)."

Example:

.. csv-table:: Example Command 0x1E - 0x24 - Set Segment Display ``d``
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "31", "Command 31 - Set Segment display 1"
   "1", "1", "12", "12 Bytes will follow"
   "2", "12", "Hello World!", "Set display1 to hello world (ASCII type display)"

No response is expected.

Get Status of Switch (0x28)
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get the status of a switch.
Payload is the switch index:

.. csv-table:: Payload of Command 0x28 - Get Status of Switch
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``s`` of the switch to query"

Example:

.. csv-table:: Example Command 0x28 - Get Status of Switch
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "40", "Command 40 - Get Status of Switch"
   "1", "1", "25", "Query status of switch 25"

Returns one byte:

.. csv-table:: Response to 0x28 - Get Status of Switch
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "0=Off, 1=On, 2=Switch not existing"

Example:

.. csv-table:: Example Response to 0x28 - Get Status of Switch
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "0", "Status of switch is off"

MPF will read all switches at startup using this command.

Get Changed Switches (0x29)
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Check is switches changed.
Does not have any payload.

Example:

.. csv-table:: Example Command 0x29 - Get Changed Switches
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "41", "Command 41 - Get Changed Switches"

Returns one byte:

.. csv-table:: Response to 0x29 - Get Changed Switches
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "127=No change. Otherwise: The numer of changed switch. Bit 7 is the status of that switch."

Example:

.. csv-table:: Example Response to 0x29 - Get Changed Switches
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "10", "Switch 10 turned off"

MPF will poll this at 100 Hz by default.

Play Sound (0x32)
^^^^^^^^^^^^^^^^^

Play a sound on a hardware sound card.
This is used to trigger sounds on existing sound interfaces on older machines.
The behavior of sounds usually differs per sound number (looping/not looping/stop other sounds etc) and cannot be
influenced by the CPU.

Payload is the sound number.

.. csv-table:: Payload of Command 0x32 - Play Sound
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Track to play (default track is 1)"
   "2", "1", "Index of sound to play"

Example:

.. csv-table:: Example Command 0x32 - Play Sound
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "50", "Command 50 - Play Sound"
   "1", "1", "1", "Play on track 1"
   "2", "1", "42", "Play sound 42"

No response is expected.

Stop Sound (0x33)
^^^^^^^^^^^^^^^^^

Stop the current playing sound.

Payload is the sound number.

.. csv-table:: Payload of Command 0x33 - Stop Sound
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Track to stop (default track is 1)"

Example:

.. csv-table:: Example Command 0x33 - Stop Sound
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "51", "Command 51 - Stop Sound"
   "1", "1", "1", "Stop all sounds on track 1"

No response is expected.

Play Sound File (0x34)
^^^^^^^^^^^^^^^^^^^^^^

Play a sound file on external hardware.
This is used to extend sound capabilities on older machines in LISY.
Alternatively, you can use the MPF sound system.

Payload is a null terminated string containing track, flags and the filename of the sound.

.. csv-table:: Payload of Command 0x34 - Play Sound File
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Track to play (default track is 1)"
   "2", "1", "Flags (bit 0=loop, 1=no cache)"
   "3", "``n``", "Filename (length ``n``)"
   "3 + ``n``", "1", "Null terminator"

Example:

.. csv-table:: Example Command 0x34 - Play Sound File
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "52", "Command 52 - Play Sound File"
   "1", "1", "1", "Use Track 1"
   "2", "1", "1", "Loop file"
   "3", "9", "test.mp3 ", "Play sound test.mp3. Last character is null byte."

No response is expected.

Text to speech (0x35)
^^^^^^^^^^^^^^^^^^^^^

This is used to extend sound capabilities on older machines in LISY.

Payload is a null terminated string containing track, flags and the text to play.

.. csv-table:: Payload of Command 0x35 - Text to speech
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Track to play (default track is 1)"
   "2", "1", "Flags (bit 0=loop, 1=no cache)"
   "3", "``n``", "Text to play (length ``n``)"
   "3 + ``n``", "1", "Null terminator"

Example:

.. csv-table:: Example Command 0x35 - Text to speech
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "53", "Command 53 - Text to speech"
   "1", "1", "Track to play (default track is 1)"
   "2", "1", "1", "No loop. Use Cache."
   "3", "6", "Hello ", "Play text 'hello'. Last character is null byte."

No response is expected.

Set Sound Volume (0x36)
^^^^^^^^^^^^^^^^^^^^^^^

Set volume of amplifier.
This may be connected either to a hardware soundcard or to the output of the MPF sound system.

Payload is the sound number.

.. csv-table:: Payload of Command 0x36 - Set Sound Volume
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Volume in percent (0-100)"
   "2", "1", "Track to change (default track is 1)"

Example:

.. csv-table:: Example Command 0x36 - Set Sound Volume
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "54", "Command 54 - Set Sound Volume"
   "1", "1", "Change track 1"
   "2", "1", "50", "Set volume to 50%"

No response is expected.

Init/Reset (0x64)
^^^^^^^^^^^^^^^^^

Reset and initialize the platform.
MPF will expect this command to reset all coil configs and to disable all coils and lights.
Does not have any payload.

Example:

.. csv-table:: Example Command 0x64 - Init/Reset
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "100", "Command 100 - Init/Reset"

Returns one byte:

.. csv-table:: Response to 0x64 - Init/Reset
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "0=OK. Otherwise an error code. MPF will retry on error."

Example:

.. csv-table:: Example Response to 0x64 - Init/Reset
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "0", "Reset ok."

This will be the first command send by MPF.

Watchdog (0x65)
^^^^^^^^^^^^^^^

Will be send every 500ms.
The hardware is expected to disable all solenoids and light if it did not get a watchdog for 1s.
Does not have any payload.

Example:

.. csv-table:: Example Command 0x65 - Watchdog
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "101", "Command 101 - Watchdog"

Returns one byte:

.. csv-table:: Response to 0x65 - Watchdog
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "0=OK. Otherwise an error code"

Example:

.. csv-table:: Example Response to 0x65 - Watchdog
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "0", "Watchdog ok."

This be send periodically at 2 Hz in MPF.

Protocol reference (v0.09) - RFC
--------------------------------

This section contains a proposal for new methods.
This is still in development.
Requests and commends are welcome.
All commands are considered in "Request for Comments (RFC)" state.
They will likely end up in v0.09 in some way.

Get Count of Modern Lights (0x13)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get count of modern lights available.
Does not have any payload.

Example:

.. csv-table:: Example Command 0x13 - Get Count of Modern Lights
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "19", "Command 19 - Get Count of Modern Lights"

Returns one byte:

.. csv-table:: Response to 0x13 - Get Count of Modern Lights
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "0", "1", "Light count ``m`` (0 to 255). 0 if no modern lights exist."

Example:

.. csv-table:: Example Response to 0x13 - Get Count of Modern Lights
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "128", "Platform supports 128 modern lights with numbers 0 to 127."

MPF uses this number to refuse any lights with a number larger or equal than
``m`` and subtype ``light``.
Return ``0`` if you do not support modern lights in your platform.

Fade Modern Light (0x0d)
^^^^^^^^^^^^^^^^^^^^^^^^

Fade a group of modern lights.

.. csv-table:: Payload of Command 0x0d - Fade Modern Light
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``m`` of the first light"
   "2", "2", "Fade time in ms (0-65535). Can be 0 to set the brightness instantly."
   "4", "1", "Number ``n`` of lights to fade. Can be 1 to set or fade a single light."
   "5", "``n``", "One byte of brightness per light (0-255). ``n`` bytes in total"

Example:

.. csv-table:: Example Command 0x0d - Fade Modern Light
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "19", "Command 13 - Fade Modern Light"
   "1", "1", "42", "First light is 42"
   "2", "2", "50", "Fade to color in 50ms."
   "4", "1", "3", "Fade three lights (i.e. RGB in sync)"
   "5", "1", "127", "Fade light 42 to 50% brightness"
   "6", "1", "0", "Fade light 43 to 0% brightness"
   "7", "1", "255", "Fade light 44 to 100% brightness"

No response is expected.

Set Solenoid Recycle Time (0x19)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Configure the recycle time of a solenoid in milliseconds.
The platform will prevent any new pulse/enable until recycle time has passed after a pulse end or disable.
This prevents overheating through "machine gunning" on pops, flaky switches or repeated pulses through bad code.
By default MPF will set recycle to two times the pulse time but it can be changed.

Payload is the solenoid index and recycle time.

.. csv-table:: Payload of Command 0x19 - Set Solenoid Recycle Time
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``c`` of the solenoid to configure"
   "2", "1", "Recycle time in ms (0-255)"

Example:

.. csv-table:: Example Command 0x19 - Set Solenoid Recycle Time
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "25", "Command 25 - Set Solenoid Recycle Time"
   "1", "1", "25", "Configure solenoid 25"
   "2", "1", "50", "Set recycle time to 100ms"

No response is expected.
This will affect pulses, enables and all hardware rules.

Pulse and Enable Solenoid with PWM (0x1A)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pulse solenoid and then enable solenoid with PWM.
Payload is the solenoid index, pulse time, pulse power and hold power:

.. csv-table:: Payload of Command 0x1A - Pulse and Enable Solenoid with PWM
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``c`` of the solenoid to enable"
   "2", "1", "Pulse time in ms (0-255)"
   "3", "1", "Pulse PWM power (0-255). 0=0% power. 255=100% power"
   "4", "1", "Hold PWM power (0-255). 0=0% power. 255=100% power"

Example:

.. csv-table:: Example Command 0x15 - Pulse and Enable Solenoid with PWM
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "26", "Command 26 - Enable Solenoid with PWM and Pulse"
   "1", "1", "25", "Enable solenoid 25"
   "2", "1", "30", "30ms initial pulse"
   "3", "1", "191", "191/255 = 75% pulse power"
   "4", "1", "64", "25% hold power"

No response is expected.
This command can also be used to just pulse a coil with PWM if "Hold PWM power" is set to 0.

Configure Hardware Rule for Solenoid (0x3C)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Program a hardware rule into the controller to control a solenoid based on one to three switches.
This is used in modern machines to implement low latency responses (because responding to switch hits in software
causes too much latency and jitter).
There can be only one hardware rule per solenoid.
A new rule will always overwrite an old one for the solenoid.

Flags decide what the three switches do:

.. csv-table:: Flags for Command 0x3C - Configure Hardware Rule for Solenoid
   :header: "Bit", "Description"
   :widths: 10, 30

   "0", "When switch becomes active trigger the rule. Usually set on the first switch to trigger the rule.
   Sometimes a second switch is used just to disable a rule (such as on EOS of a flipper)."
   "1", "When switch becomes inactive disable the rule. This is what you want on flipper fingers but not on slings/pops."
   "2", "reserved"
   "3", "reserved"
   "4", "reserved"
   "5", "reserved"
   "6", "reserved"
   "7", "reserved"

Payload is the solenoid index, one to three switches, pulse time, pulse power, hold power and some flags:

.. csv-table:: Payload of Command 0x3C - Configure Hardware Rule for Solenoid
   :header: "Byte", "Length", "Description"
   :widths: 10, 10, 30

   "1", "1", "Index ``c`` of the solenoid to configure"
   "2", "1", "Switch ``sw1``. Set bit 7 to invert the switch."
   "3", "1", "Switch ``sw2``. Set bit 7 to invert the switch."
   "4", "1", "Switch ``sw3``. Set bit 7 to invert the switch."
   "5", "1", "Pulse time in ms (0-255)"
   "6", "1", "Pulse PWM power (0-255). 0=0% power. 255=100% power"
   "7", "1", "Hold PWM power (0-255). 0=0% power. 255=100% power"
   "8", "1", "Flag for ``sw1``"
   "9", "1", "Flag for ``sw2``"
   "10", "1", "Flag for ``sw3``"

Example:

.. csv-table:: Example Command 0x3C - Configure Hardware Rule for Solenoid
   :header: "Byte", "Length", "Example", "Comment"
   :widths: 10, 10, 10, 30

   "0", "1", "60", "Command 60 - Configure Hardware Rule for Solenoid"
   "1", "1", "25", "Configure rule for solenoid 25"
   "2", "1", "5", "Use Switch 5 as ``sw1``"
   "3", "1", "134", "Use inverted Switch 6 as ``sw2``"
   "4", "1", "127", "No switch as ``sw3``"
   "5", "1", "30", "30ms initial pulse"
   "6", "1", "191", "191/255 = 75% pulse power"
   "7", "1", "64", "25% hold power"
   "8", "1", "3", "``sw1`` will enable the rule and disable it when released."
   "9", "1", "2", "``sw2`` will disable the rule if it closes (because it is inverted)."
   "10", "1", "0", "Do not use ``sw3``"

No response is expected.
To disable a rule just set all flags to 0.


text:
The main rest view
==================

The main view of the api is the RestApiView, with mixins combined this view is very powerful,
there are 3 main optional parameters to initialize:

* function_field_name, default "action", this is the api function in the class see example below

* api_allowed_post_methods, default ["__all__"], this field is for security reasons and defines the avilable methods for post in the class

* api_allowed_get_methods, default ["__all__"], this field is for security reasons and defines the avilable methods for get in the class

Example of the api
^^^^^^^^^^^^^^^^^^

python:

.. code-block:: python

    from easy_rest.views import RestApiView

    class UsersApi(RestApiView):
        api_allowed_post_methods = [
            "authenticate",
        ]

        def authenticate(self, api_data):
            """
            Some authentication code here
            """

            return {
                "data": "user authenticated successfully"
            }

Sync request demo

.. code-block:: javascript

    let api = new RequestHandler("/<url_to_api>/");

    // now lets create a sync post to authenticate a user

    let api_data = api.PostSync({"action": "authenticate"});

    console.log(api_data.data);

Async request demo

.. code-block:: javascript

    let api = new RequestHandler("/<url_to_api>/");

    // now lets create a sync post to authenticate a user

    api.PostASync({"action": "authenticate"}, function(api_data) {
        console.log(api_data.data);
    });

The function field name
^^^^^^^^^^^^^^^^^^^^^^^
this field controls the name of the function field

.. code-block:: javascript

    let api = new RequestHandler("/<url_to_api>/");

    // if function_field_name = "action", the request is
    api.PostSync({"action": "authenticate"});

    // if function_field_name = "something_else", the request is
    api.PostSync({"something_else": "authenticate"});

redpajama_set_name: RedPajamaGithub


text:
package org.datasays.wes.actions;

import okhttp3.HttpUrl;
import org.datasays.wes.core.RequestInfo;
import org.datasays.wes.types.*;
// documentation: https://www.elastic.co/guide/en/elasticsearch/reference/5.x/indices-aliases.html
public class IndicesGetAlias extends RequestInfo{

	public IndicesGetAlias(String baseUrl){
		super(baseUrl);
	}
	public IndicesGetAlias(HttpUrl baseUrl){
		super(baseUrl);
	}

	// param: boolean ignoreUnavailable: Whether specified concrete indices should be ignored when unavailable (missing or closed)
	public IndicesGetAlias ignoreUnavailable(boolean ignoreUnavailable){
		addParams("ignoreUnavailable", ignoreUnavailable);
		return this;
	}
	// param: boolean allowNoIndices: Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)
	public IndicesGetAlias allowNoIndices(boolean allowNoIndices){
		addParams("allowNoIndices", allowNoIndices);
		return this;
	}
	// param: enum expandWildcards: Whether to expand wildcard expression to concrete indices that are open, closed or both.
	public IndicesGetAlias expandWildcards(EnumExpandWildcards expandWildcards){
		addParams("expandWildcards", expandWildcards);
		return this;
	}
	// param: boolean local: Return local information, do not retrieve the state from master node (default: false)
	public IndicesGetAlias local(boolean local){
		addParams("local", local);
		return this;
	}
	// body:null
	@Override
	public void setBody(Object body) {
		super.setBody(body);
	}

	//A comma-separated list of index names to filter aliases
	private String index;
	//A comma-separated list of alias names to return
	private String name;
	public IndicesGetAlias setParts(String index,String name){
		this.index=index;
		this.name=name;

		return this;
	}

	@Override
	public String parseUrl(String method) {
		if(!"GET".equalsIgnoreCase(method)){
			throw new IllegalArgumentException("Unsupported method:"+method);
		}
		//=>/{index}/_alias/{name}
		if(index != null && name != null ){
			setUrl(index, "_alias", name);
			return super.parseUrl(method);
		}
		//=>/_alias/{name}
		if(name != null ){
			setUrl("_alias", name);
			return super.parseUrl(method);
		}
		//=>/{index}/_alias
		if(index != null ){
			setUrl(index, "_alias");
			return super.parseUrl(method);
		}
		//=>/_alias
		setUrl("_alias");
		return super.parseUrl(method);

	}
}


text:
/// <reference path="base.d.ts" />
/// <reference path="tools.d.ts" />
declare module Shumway.SWF.Parser.LowLevel {
    function parseRgb(stream: any): number;
    function parseDefineImageTag(stream: Stream, swfVersion: number, tagCode: number, tagEnd: number, jpegTables: Uint8Array): ImageTag;
    function parseDefineFontTag(stream: Stream, swfVersion: number, tagCode: number): FontTag;
    function parseSoundStreamHeadTag(stream: Stream, tagEnd: number): SoundStreamHeadTag;
    function parseDefineBitmapTag(stream: Stream, swfVersion: number, tagCode: number, tagEnd: number): BitmapTag;
    function parseDefineFont2Tag(stream: Stream, swfVersion: number, tagCode: number, tagEnd: number): FontTag;
    function parseDefineFont4Tag(stream: Stream, swfVersion: number, tagCode: number, tagEnd: number): FontTag;
    function parseDefineSceneTag(stream: Stream, tagCode: number): SceneTag;
    var tagHandlers: any;
    function parseHeader(stream: Stream): {
        frameRate: number;
        frameCount: number;
        bounds: Bounds;
    };
}

declare module Shumway.SWF.Parser {
    const enum BitmapFormat {
        /**
         * 8-bit color mapped image.
         */
        FORMAT_COLORMAPPED = 3,
        /**
         * 15-bit RGB image.
         */
        FORMAT_15BPP = 4,
        /**
         * 24-bit RGB image, however stored as 4 byte value 0x00RRGGBB.
         */
        FORMAT_24BPP = 5,
    }
    function defineBitmap(tag: BitmapTag): {
        definition: ImageDefinition;
        type: string;
    };
}
/**
 * Copyright 2014 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
declare module Shumway.SWF.Parser {
    function defineButton(tag: ButtonTag, dictionary: any): any;
}
/**
 * Copyright 2014 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
declare module Shumway.SWF.Parser {
    function defineFont(tag: FontTag): {
        type: string;
        id: number;
        name: string;
        bold: boolean;
        italic: boolean;
        codes: any;
        metrics: any;
        data: Uint8Array;
        originalSize: boolean;
    };
}
declare module Shumway.SWF.Parser {
    /**
     * Parses JPEG chunks and reads image width and height information. JPEG data
     * in SWFs is encoded in chunks and not directly decodable by the JPEG parser.
     */
    function parseJpegChunks(bytes: Uint8Array, chunks: Uint8Array[]): void;
    /**
     * Extracts PNG width and height information.
     */
    function parsePngHeaders(image: any, bytes: Uint8Array): void;
    interface ImageDefinition {
        type: string;
        id: number;
        width: number;
        height: number;
        mimeType: string;
        data: Uint8Array;
        dataType?: ImageType;
        image: any;
    }
    interface JPEGTablesState {
        data: Uint8Array;
        parsedChunks?: Uint8Array[];
    }
    function defineImage(tag: ImageTag): ImageDefinition;
}
/**
 * Copyright 2014 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
declare module Shumway.SWF.Parser {
    function defineLabel(tag: StaticTextTag): {
        type: string;
        id: number;
        fillBounds: Bbox;
        matrix: Matrix;
        tag: {
            hasText: boolean;
            initialText: string;
            html: boolean;
            readonly: boolean;
        };
        records: TextRecord[];
        coords: any;
        static: boolean;
        require: any;
    };
}
/**
 * Copyright 2014 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
declare module Shumway.SWF.Parser {
    function defineShape(tag: ShapeTag): {
        type: string;
        id: number;
        fillBounds: Bbox;
        lineBounds: Bbox;
        morphFillBounds: Bbox;
        morphLineBounds: Bbox;
        shape: PlainObjectShapeData;
        transferables: ArrayBuffer[];
        require: any[];
    };
}
/**
 * Copyright 2014 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
declare module Shumway.SWF.Parser {
    function defineSound(tag: SoundTag): {
        type: string;
        id: number;
        sampleRate: number;
        channels: number;
        pcm: any;
        packaged: any;
    };
    interface DecodedSound {
        streamId: number;
        samplesCount: number;
        pcm?: Float32Array;
        data?: Uint8Array;
        seek?: number;
    }
    class SoundStream {
        streamId: number;
        samplesCount: number;
        sampleRate: number;
        channels: number;
        format: any;
        currentSample: number;
        decode: (block: Uint8Array) => DecodedSound;
        constructor(samplesCount: any, sampleRate: any, channels: any);
        static FromTag(tag: any): SoundStream;
    }
}
/**
 * Copyright 2014 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
declare module Shumway.SWF.Parser {
    function defineText(tag: TextTag): {
        type: string;
        id: number;
        fillBounds: Bbox;
        variableName: string;
        tag: TextTag;
        bold: boolean;
        italic: boolean;
    };
}
declare module Shumway.SWF {
    var timelineBuffer: Tools.Profiler.TimelineBuffer;
    function enterTimeline(name: string, data?: any): void;
    function leaveTimeline(data?: any): void;
}
declare module Shumway.SWF {
    var parserOptions: any;
    var traceLevel: any;
}
declare module Shumway.SWF {
    var StreamNoDataError: {};
    class Stream {
        bytes: Uint8Array;
        view: DataView;
        pos: number;
        end: number;
        bitBuffer: number;
        bitLength: number;
        constructor(buffer: any, offset?: number, length?: number, maxLength?: number);
        align(): void;
        ensure(size: number): void;
        remaining(): number;
        substream(begin: number, end: number): Stream;
        push(data: any): void;
        readSi8(): number;
        readSi16(): number;
        readSi32(): number;
        readUi8(): number;
        readUi16(): number;
        readUi32(): number;
        readFixed(): number;
        readFixed8(): number;
        readFloat16(): number;
        readFloat(): number;
        readDouble(): number;
        readEncodedU32(): number;
        readBool(): boolean;
        readSb(size: number): number;
        readUb(size: number): number;
        readFb(size: number): number;
        readString(length: number): string;
    }
}
declare module Shumway.SWF {
    var MP3WORKER_PATH: string;
    class MP3DecoderSession {
        private _sessionId;
        private _onworkermessageBound;
        private _worker;
        onframedata: (frameData: Uint8Array, channels: number, sampleRate: number, bitRate: number) => void;
        onid3tag: (tagData: any) => void;
        onclosed: () => void;
        onerror: (error: string) => void;
        constructor();
        private onworkermessage(e);
        pushAsync(data: any): void;
        close(): void;
        static processAll(data: Uint8Array): Promise<{
            data: Uint8Array;
            id3Tags: any;
        }>;
    }
}
/**
 * Copyright 2014 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
declare module Shumway.SWF {
    import Parser = Shumway.SWF.Parser;
    const enum CompressionMethod {
        None = 0,
        Deflate = 1,
        LZMA = 2,
    }
    class SWFFile {
        compression: CompressionMethod;
        swfVersion: number;
        useAVM1: boolean;
        backgroundColor: number;
        bounds: Bounds;
        frameRate: number;
        frameCount: number;
        attributes: any;
        sceneAndFrameLabelData: any;
        bytesLoaded: number;
        bytesTotal: number;
        pendingUpdateDelays: number;
        framesLoaded: number;
        frames: SWFFrame[];
        abcBlocks: ABCBlock[];
        dictionary: DictionaryEntry[];
        fonts: {
            name: string;
            style: string;
            id: number;
        }[];
        data: Uint8Array;
        env: any;
        symbolClassesMap: string[];
        symbolClassesList: {
            id: number;
            className: string;
        }[];
        eagerlyParsedSymbolsMap: EagerlyParsedDictionaryEntry[];
        eagerlyParsedSymbolsList: EagerlyParsedDictionaryEntry[];
        private _uncompressedLength;
        private _uncompressedLoadedLength;
        private _dataView;
        private _dataStream;
        private _decompressor;
        private _jpegTables;
        private _endTagEncountered;
        private _loadStarted;
        private _lastScanPosition;
        private _currentFrameLabel;
        private _currentSoundStreamHead;
        private _currentSoundStreamBlock;
        private _currentControlTags;
        private _currentActionBlocks;
        private _currentInitActionBlocks;
        private _currentExports;
        constructor(initialBytes: Uint8Array, length: number, env: any);
        appendLoadedData(bytes: Uint8Array): void;
        finishLoading(): void;
        getSymbol(id: number): any;
        getParsedTag(unparsed: UnparsedTag): any;
        private readHeaderAndInitialize(initialBytes);
        private parseHeaderContents();
        private processFirstBatchOfDecompressedData(data);
        private processDecompressedData(data);
        private scanLoadedData();
        private scanTagsToOffset(endOffset, rootTimelineMode);
        /**
         * Parses tag header information at the current seek offset and stores it in the given object.
         *
         * Public so it can be used by tools to parse through entire SWFs.
         */
        parseNextTagHeader(target: UnparsedTag): boolean;
        private scanTag(tag, rootTimelineMode);
        parseSpriteTimeline(spriteTag: DictionaryEntry): any;
        private jumpToNextTag(currentTagLength);
        private emitTagSlopWarning(tag, tagEnd);
        private finishFrame();
        private setFileAttributes(tagLength);
        private setSceneAndFrameLabelData(tagLength);
        private addControlTag(tagCode, byteOffset, tagLength);
        private addLazySymbol(tagCode, byteOffset, tagLength);
        private decodeEmbeddedFont(unparsed);
        private registerEmbeddedFont(unparsed);
        private decodeEmbeddedImage(unparsed);
    }
    class SWFFrame {
        controlTags: UnparsedTag[];
        labelName: string;
        soundStreamHead: Parser.SoundStream;
        soundStreamBlock: Uint8Array;
        actionBlocks: ActionBlock[];
        initActionBlocks: InitActionBlock[];
        exports: SymbolExport[];
        constructor(controlTags?: UnparsedTag[], labelName?: string, soundStreamHead?: Parser.SoundStream, soundStreamBlock?: Uint8Array, actionBlocks?: ActionBlock[], initActionBlocks?: InitActionBlock[], exports?: SymbolExport[]);
    }
    class ABCBlock {
        name: string;
        flags: number;
        data: Uint8Array;
    }
    class ActionBlock {
        actionsData: Uint8Array;
        precedence: number;
    }
    class InitActionBlock {
        spriteId: number;
        actionsData: Uint8Array;
    }
    class SymbolExport {
        symbolId: number;
        className: string;
        constructor(symbolId: number, className: string);
    }
    class UnparsedTag {
        tagCode: number;
        byteOffset: number;
        byteLength: number;
        constructor(tagCode: number, byteOffset: number, byteLength: number);
    }
    class DictionaryEntry extends UnparsedTag {
        id: number;
        constructor(id: number, tagCode: number, byteOffset: number, byteLength: number);
    }
    class EagerlyParsedDictionaryEntry extends DictionaryEntry {
        type: string;
        definition: Object;
        env: any;
        ready: boolean;
        constructor(id: number, unparsed: UnparsedTag, type: string, definition: any, env: any);
    }
}
/**
 * Copyright 2014 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
declare module Shumway {
    class ImageFile {
        env: any;
        data: Uint8Array;
        bytesLoaded: number;
        image: any;
        mimeType: string;
        type: number;
        width: number;
        height: number;
        constructor(header: Uint8Array, fileLength: number, env: any);
        bytesTotal: number;
        appendLoadedData(data: Uint8Array): void;
        private setMimetype();
    }
}
/**
 * Copyright 2014 Mozilla Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * Encapsulates as much of the external file loading process as possible. This means all of it
 * except for (stand-alone or embedded) images and fonts embedded in SWFs. As these have to be
 * decoded before being usable by content, we stall reporting loading progress until the decoding
 * has finished. The following is a description of the ridiculously complicated contortions we
 * have to go through for this to work:

  ### Life-cycle of embedded images and fonts from being encountered in the SWF to being ready for
     use:
  1.
    1. An image tag is encountered, `SWFFile#decodeEmbeddedImage` is called.
    2. A font tag is encountered, `SWFFile#registerEmbeddedFont` is called. For Firefox, things end
       here for now: fonts can be decoded synchronously, so we don't need to do it eagerly.
  2. Embedded asset's contents are extracted from SWF and stored in an
     `EagerlyParsedDictionaryEntry`.
  3. Once scanning of the currently loaded SWF bytes is complete, `Loader#onNewEagerlyParsedSymbols`
     is called with a list of all newly encountered fonts and images.
     Note: `Loader` does *not* receive updates about any other newly loaded data; not even how many
           bytes were loaded.
  4. `Loader#onNewEagerlyParsedSymbols` iterates over list of fonts and images and retrieves their
     symbols.
  5. `LoaderInfo#getSymbolById` creates a `{Font,Bitmap}Symbol` instance, which gets a `syncID` and
     a `resolveAssetPromise` and a `ready` flag set to `false`.
  6. `LoaderInfo#getSymbolById` invokes `Timeline.IAssetResolver#registerFont` or
     `Timeline.IAssetResolver#registerImage`. The singleton implementation of `IAssetResolver` is
     the active instance of `Player`.
  7. `Player#registerFont` or `Player#registerImage` send sync message to GFX side requesting
     decoding of asset.
  8. `GFXChannelDeserializerContext#register{Font,Image}` is called, which triggers the actual
     decoding and, in the image case, registration of the asset.
  9.
    1. A `CSSFont` is created and a 400ms timeout triggered.
    2.
      1. A `HTMLImageElement` is created and a load triggered from the blob containing the image
         bytes.
      2. A `RenderableBitmap` is created with the `HTMLImageElement` as its `renderSource` and
         `-1,-1` dimensions.
  10. `Loader#onNewEagerlyParsedSymbols` creates a `Promise.all` promise for all assets'
      `resolveAssetPromise`s and returns that to the `FileLoader`.
  11. For all assets:
    1. Loading finishes for images / timeout happens for fonts, resolving their
       `resolveAssetPromise`.
    2. Symbols get marked as `ready`, fonts get their metrics filled in.
  12. The combined promise is resolved, causing `FileLoader` to deliver the queued load update,
      informing content about newly loaded bytes, assets, scripts, etc.

  Note: loading and scanning of the SWF has continued in the meantime, so there can be multiple
        updates queued for the same promise.

  ### Usage of an image in GFX-land:
  Images are guaranteed to be ready for rendering when content is told about them, so there can
  never be a need to asynchronously decode them. If an image is never used for anything but
  rendering, it's never expanded into a Canvas. If, see below, content accesses the image's bytes,
  it's expanded and the original `HTMLImageElement` discarded.

  ### Usage of an image in Player-land:
  If content accesses an image's pixels for the first time, e.g. using `BitmapData#getPixel`, the
  `BitmapData` instance requests the pixel data from GFX-land. That causes the above-mentioned
  expansion into a Canvas and discarding of the `HTMLImageElement`, followed by a `getImageData`
  call.
 */
declare module Shumway {
    class LoadProgressUpdate {
        bytesLoaded: number;
        framesLoaded: number;
        constructor(bytesLoaded: number, framesLoaded: number);
    }
    interface ILoadListener {
        onLoadOpen: (any) => void;
        onLoadProgress: (update: LoadProgressUpdate) => void;
        onNewEagerlyParsedSymbols: (symbols: SWF.EagerlyParsedDictionaryEntry[], delta: number) => Promise<any>;
        onImageBytesLoaded: () => void;
        onLoadComplete: () => void;
        onLoadError: () => void;
    }
    class FileLoader {
        _url: string;
        _file: any;
        private _listener;
        private _env;
        private _loadingServiceSession;
        private _delayedUpdatesPromise;
        private _lastDelayedUpdate;
        private _bytesLoaded;
        private _queuedInitialData;
        constructor(listener: ILoadListener, env: any);
        loadFile(request: any): void;
        abortLoad(): void;
        loadBytes(bytes: Uint8Array): void;
        processLoadOpen(): void;
        processNewData(data: Uint8Array, progressInfo: {
            bytesLoaded: number;
            bytesTotal: number;
        }): void;
        processError(error: any): void;
        processLoadClose(): void;
        private processSWFFileUpdate(file, previousEagerlyParsedSymbolsCount, previousFramesLoaded);
    }
}


text:
<?php

namespace backend\controllers;

use Yii;
use backend\models\InvoiceItem;
use yii\data\ActiveDataProvider;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use backend\components\AdminController as BackendAdminController;

/**
 * InvoiceItemController implements the CRUD actions for InvoiceItem model.
 */
class InvoiceItemController extends BackendAdminController
{
    /**
     * Lists all InvoiceItem models.
     * @return mixed
     */
    public function actionIndex()
    {
        $dataProvider = new ActiveDataProvider([
            'query' => InvoiceItem::find(),
        ]);

        return $this->render('index', [
            'dataProvider' => $dataProvider,
        ]);
    }

    /**
     * Displays a single InvoiceItem model.
     * @param integer $id
     * @return mixed
     */
    public function actionView($id)
    {
        return $this->render('view', [
            'model' => $this->findModel($id),
        ]);
    }

    /**
     * Creates a new InvoiceItem model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     * @return mixed
     */
    public function actionCreate()
    {
        $model = new InvoiceItem();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('create', [
                'model' => $model,
            ]);
        }
    }

    /**
     * Updates an existing InvoiceItem model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    }

    /**
     * Deletes an existing InvoiceItem model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     */
    public function actionDelete($id)
    {
        $this->findModel($id)->delete();

        return $this->redirect(['index']);
    }

    /**
     * Finds the InvoiceItem model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param integer $id
     * @return InvoiceItem the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id)
    {
        if (($model = InvoiceItem::findOne($id)) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }
}


text:
Inspired by: https://dribbble.com/shots/3380672-Sketch-Gradients-Freebie

## Example

```js
import { AreaClosed } from '@visx/shape';
import { GradientPinkBlue } from '@visx/gradient';

const GradientArea = () => {
  return (
    <svg>
      <GradientPinkBlue id="gradient" />
      <AreaClosed fill="url('#gradient')" />
    </svg>
  );
};
```

## The Definition Caveat

Like patterns, gradients are "defined." When you render `<GradientPinkBlue />`, it's rendering a
[`<linearGradient/>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/linearGradient)
element inside a `<def>` in the SVG.

It's often better to think of these as variable definitions rather than true DOM elements. When you
use `fill="url('#gradient')"` you're referencing the gradient's id: `gradient`.

## Make your own!

In addition to the preset linear gradients, you can make any linear or radial gradient like so:

```js
import { LinearGradient, RadialGradient } from '@visx/gradient';

<LinearGradient from="#a18cd1" to="#fbc2eb" />;
<RadialGradient from="#a18cd1" to="#fbc2eb" />;
```

## Installation

```
npm install --save @visx/gradient
```


text:
package mvcc

import (
	"github.com/coreos/etcd/lease"
	"github.com/coreos/etcd/mvcc/backend"
	"github.com/coreos/etcd/mvcc/mvccpb"
)

type KV interface {
	// Rev returns the current revision of the KV.
	Rev() int64

	// FirstRev returns the first revision of the KV.
	// After a compaction, the first revision increases to the compaction
	// revision.
	FirstRev() int64

	// Range gets the keys in the range at rangeRev.
	// The returned rev is the current revision of the KV when the operation is executed.
	// If rangeRev <=0, range gets the keys at currentRev.
	// If `end` is nil, the request returns the key.
	// If `end` is not nil and not empty, it gets the keys in range [key, range_end).
	// If `end` is not nil and empty, it gets the keys greater than or equal to key.
	// Limit limits the number of keys returned.
	// If the required rev is compacted, ErrCompacted will be returned.
	Range(key, end []byte, limit, rangeRev int64) (kvs []mvccpb.KeyValue, rev int64, err error)

	// Put puts the given key, value into the store. Put also takes additional argument lease to
	// attach a lease to a key-value pair as meta-data. KV implementation does not validate the lease
	// id.
	// A put also increases the rev of the store, and generates one event in the event history.
	// The returned rev is the current revision of the KV when the operation is executed.
	Put(key, value []byte, lease lease.LeaseID) (rev int64)

	// DeleteRange deletes the given range from the store.
	// A deleteRange increases the rev of the store if any key in the range exists.
	// The number of key deleted will be returned.
	// The returned rev is the current revision of the KV when the operation is executed.
	// It also generates one event for each key delete in the event history.
	// if the `end` is nil, deleteRange deletes the key.
	// if the `end` is not nil, deleteRange deletes the keys in range [key, range_end).
	DeleteRange(key, end []byte) (n, rev int64)

	// TxnBegin begins a txn. Only Txn prefixed operation can be executed, others will be blocked
	// until txn ends. Only one on-going txn is allowed.
	// TxnBegin returns an int64 txn ID.
	// All txn prefixed operations with same txn ID will be done with the same rev.
	TxnBegin() int64
	// TxnEnd ends the on-going txn with txn ID. If the on-going txn ID is not matched, error is returned.
	TxnEnd(txnID int64) error
	// TxnRange returns the current revision of the KV when the operation is executed.
	TxnRange(txnID int64, key, end []byte, limit, rangeRev int64) (kvs []mvccpb.KeyValue, rev int64, err error)
	TxnPut(txnID int64, key, value []byte, lease lease.LeaseID) (rev int64, err error)
	TxnDeleteRange(txnID int64, key, end []byte) (n, rev int64, err error)

	// Compact frees all superseded keys with revisions less than rev.
	Compact(rev int64) (<-chan struct{}, error)

	// Hash retrieves the hash of KV state and revision.
	// This method is designed for consistency checking purpose.
	Hash() (hash uint32, revision int64, err error)

	// Commit commits txns into the underlying backend.
	Commit()

	// Restore restores the KV store from a backend.
	Restore(b backend.Backend) error
	Close() error
}

// WatchableKV is a KV that can be watched.
type WatchableKV interface {
	KV
	Watchable
}

// Watchable is the interface that wraps the NewWatchStream function.
type Watchable interface {
	// NewWatchStream returns a WatchStream that can be used to
	// watch events happened or happening on the KV.
	NewWatchStream() WatchStream
}

// ConsistentWatchableKV is a WatchableKV that understands the consistency
// algorithm and consistent index.
// If the consistent index of executing entry is not larger than the
// consistent index of ConsistentWatchableKV, all operations in
// this entry are skipped and return empty response.
type ConsistentWatchableKV interface {
	WatchableKV
	// ConsistentIndex returns the current consistent index of the KV.
	ConsistentIndex() uint64
}


text:
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Mycologia 84(5): 750 (1992)

#### Original name
Hypsostroma saxicola Huhndorf, 1992

### Remarks
null


text:
<?php

namespace LeMike\PhpSpec\WpExtension\Locator\WordPress;

use PhpSpec\Locator\ResourceLocatorInterface;
use PhpSpec\Util\Filesystem;

abstract class AbstractResourceLocator
{
    protected $classType;
    protected $validator;
    protected $srcPath;
    protected $specPath;
    protected $srcNamespace;
    protected $specNamespace;
    protected $fullSrcPath;
    protected $fullSpecPath;
    protected $filesystem;
    protected $codePool;

    public function getFullSrcPath()
    {
        return $this->fullSrcPath;
    }

    public function getFullSpecPath()
    {
        return $this->fullSpecPath;
    }

    public function getSrcNamespace()
    {
        return $this->srcNamespace;
    }

    public function getSpecNamespace()
    {
        return $this->specNamespace;
    }

    public function getAllResources()
    {
        return $this->findSpecResources($this->fullSpecPath);
    }

    public function supportsQuery($query)
    {
        $isSupported = (bool) preg_match($this->validator, $query) || $this->isSupported($query);;

        return $isSupported;
    }

    public function findResources($query)
    {
        $path = rtrim(realpath(str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $query)), DIRECTORY_SEPARATOR);

        if ('.php' !== substr($path, -4)) {
            $path .= DIRECTORY_SEPARATOR;
        }

        if ($path && 0 === strpos($path, $this->fullSrcPath)) {
            $path = $this->fullSpecPath.substr($path, strlen($this->fullSrcPath));
            $path = preg_replace('/\.php/', 'Spec.php', $path);

            return $this->findSpecResources($path);
        }

        if ($path && 0 === strpos($path, $this->srcPath)) {
            $path = $this->fullSpecPath.substr($path, strlen($this->srcPath));
            $path = preg_replace('/\.php/', 'Spec.php', $path);

            return $this->findSpecResources($path);
        }

        if ($path && 0 === strpos($path, $this->specPath)) {
            return $this->findSpecResources($path);
        }

        return array();
    }

    public function supportsClass($classname)
    {
	    return true;
        $parts = explode('_', $classname);

        if (count($parts) < 2) {
            return false;
        }

        return (
            $this->supportsQuery($classname) ||
            $classname === implode('_', array($parts[0], $parts[1], $this->classType, $parts[count($parts)-1]))
        );
    }

    public function createResource($classname)
    {
        return $this->getResource(explode('\\', $classname), $this);
    }

    abstract public function getPriority();

    /**
     * @param string $path
     */
    protected function findSpecResources($path)
    {
        if (!$this->filesystem->pathExists($path)) {
            return array();
        }

        if ('.php' === substr($path, -4)) {
            if (!$this->isSupported($path)) {
                return array();
            }

            return array($this->createResourceFromSpecFile(realpath($path)));
        }

        $resources = array();
        foreach ($this->filesystem->findSpecFilesIn($path) as $file) {
            $specFile = $file->getRealPath();
            if ($this->isSupported($specFile)) {
                $resources[] = $this->createResourceFromSpecFile($specFile);
            }
        }

        return $resources;
    }

    private function createResourceFromSpecFile($path)
    {
        // cut "Spec.php" from the end
        $relative = $this->getRelative($path);

        return $this->getResource(explode(DIRECTORY_SEPARATOR, $relative), $this);
    }

    private function checkInitialData()
    {
        if (null === $this->classType) {
            throw new \UnexpectedValueException('Concrete resource locators mist specify a class type');
        }

        if (null === $this->validator) {
            throw new \UnexpectedValueException('Concrete resource locators mist specify a validation rule');
        }
    }

    protected function getClassnameFromMatches(array $matches)
    {
        $vendor = ucfirst(array_shift($matches));
        $module = ucfirst(array_shift($matches));

        $objectName = implode('_', array_map('ucfirst', explode('_', implode('', $matches))));
        return implode('_', array($vendor, $module, $this->classType, $objectName));
    }

    protected function getRelative($path)
    {
        // cut "Spec.php" from the end
        $relative = substr($path, strlen($this->fullSpecPath), -4);
        return preg_replace('/Spec$/', '', $relative);
    }

    abstract protected function isSupported($file);

    abstract protected function getResource(array $parts, ResourceLocatorInterface $locator);
}


text:
'use strict';

const React = require('react');
const PropTypes = React.PropTypes;

const ResumePropTypes = require('../prop_types/resume');

function mapIcon(socialMedia) {
    const media = socialMedia.replace(/ /g, '-');
    switch (socialMedia) {
        case 'email':
            return (

            );
        case 'quora':
            return (

                    Q

            );
        default:
            return (

            );
    }
}

const SocialMedia = React.createClass({
    propTypes: {
        ulClass: PropTypes.string.isRequired,
        profiles: ResumePropTypes.profiles
    },

    render: function () {
        return (

                {this.props.profiles.map(function (profile, index) {
                    const icon = mapIcon(profile.network.toLowerCase());
                    return (

                                {icon}

                    );
                })}

        );
    }
});

module.exports = SocialMedia;


text:
require 'spec_helper'

describe 'shared_context region' do
  before do
    Aws.config[:region] = 'ap-northeast-1'
  end

  context 'use default region' do
    it 'used ap-northeast-1' do
      expect(Aws.config[:region]).to eq 'ap-northeast-1'
    end
  end

  context 'use custom region', region: 'us-east-1' do
    it 'used us-east-1' do
      expect(Aws.config[:region]).to eq 'us-east-1'
    end
  end
end