text:
#include "config.h"

#include <stdlib.h>
#include "alMain.h"
#include "AL/alc.h"
#include "AL/al.h"
#include "AL/alext.h"
#include "alError.h"
#include "alSource.h"
#include "alAuxEffectSlot.h"
#include "alMidi.h"

#include "midi/base.h"

static const ALchar alVendor[] = "OpenAL Community";
static const ALchar alVersion[] = "1.1 ALSOFT "ALSOFT_VERSION;
static const ALchar alRenderer[] = "OpenAL Soft";

// Error Messages
static const ALchar alNoError[] = "No Error";
static const ALchar alErrInvalidName[] = "Invalid Name";
static const ALchar alErrInvalidEnum[] = "Invalid Enum";
static const ALchar alErrInvalidValue[] = "Invalid Value";
static const ALchar alErrInvalidOp[] = "Invalid Operation";
static const ALchar alErrOutOfMemory[] = "Out of Memory";

AL_API ALvoid AL_APIENTRY alEnable(ALenum capability)
{
    ALCcontext *context;

    context = GetContextRef();
    if(!context) return;

    switch(capability)
    {
    case AL_SOURCE_DISTANCE_MODEL:
        context->SourceDistanceModel = AL_TRUE;
        ATOMIC_STORE(&context->UpdateSources, AL_TRUE);
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);
}

AL_API ALvoid AL_APIENTRY alDisable(ALenum capability)
{
    ALCcontext *context;

    context = GetContextRef();
    if(!context) return;

    switch(capability)
    {
    case AL_SOURCE_DISTANCE_MODEL:
        context->SourceDistanceModel = AL_FALSE;
        ATOMIC_STORE(&context->UpdateSources, AL_TRUE);
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);
}

AL_API ALboolean AL_APIENTRY alIsEnabled(ALenum capability)
{
    ALCcontext *context;
    ALboolean value=AL_FALSE;

    context = GetContextRef();
    if(!context) return AL_FALSE;

    switch(capability)
    {
    case AL_SOURCE_DISTANCE_MODEL:
        value = context->SourceDistanceModel;
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);

    return value;
}

AL_API ALboolean AL_APIENTRY alGetBoolean(ALenum pname)
{
    ALCcontext *context;
    ALboolean value=AL_FALSE;

    context = GetContextRef();
    if(!context) return AL_FALSE;

    switch(pname)
    {
    case AL_DOPPLER_FACTOR:
        if(context->DopplerFactor != 0.0f)
            value = AL_TRUE;
        break;

    case AL_DOPPLER_VELOCITY:
        if(context->DopplerVelocity != 0.0f)
            value = AL_TRUE;
        break;

    case AL_DISTANCE_MODEL:
        if(context->DistanceModel == AL_INVERSE_DISTANCE_CLAMPED)
            value = AL_TRUE;
        break;

    case AL_SPEED_OF_SOUND:
        if(context->SpeedOfSound != 0.0f)
            value = AL_TRUE;
        break;

    case AL_DEFERRED_UPDATES_SOFT:
        value = context->DeferUpdates;
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);

    return value;
}

AL_API ALdouble AL_APIENTRY alGetDouble(ALenum pname)
{
    ALCdevice *device;
    ALCcontext *context;
    ALdouble value = 0.0;

    context = GetContextRef();
    if(!context) return 0.0;

    switch(pname)
    {
    case AL_DOPPLER_FACTOR:
        value = (ALdouble)context->DopplerFactor;
        break;

    case AL_DOPPLER_VELOCITY:
        value = (ALdouble)context->DopplerVelocity;
        break;

    case AL_DISTANCE_MODEL:
        value = (ALdouble)context->DistanceModel;
        break;

    case AL_SPEED_OF_SOUND:
        value = (ALdouble)context->SpeedOfSound;
        break;

    case AL_DEFERRED_UPDATES_SOFT:
        value = (ALdouble)context->DeferUpdates;
        break;

    case AL_MIDI_GAIN_SOFT:
        device = context->Device;
        value = (ALdouble)MidiSynth_getGain(device->Synth);
        break;

    case AL_MIDI_STATE_SOFT:
        device = context->Device;
        value = (ALdouble)MidiSynth_getState(device->Synth);
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);

    return value;
}

AL_API ALfloat AL_APIENTRY alGetFloat(ALenum pname)
{
    ALCdevice *device;
    ALCcontext *context;
    ALfloat value = 0.0f;

    context = GetContextRef();
    if(!context) return 0.0f;

    switch(pname)
    {
    case AL_DOPPLER_FACTOR:
        value = context->DopplerFactor;
        break;

    case AL_DOPPLER_VELOCITY:
        value = context->DopplerVelocity;
        break;

    case AL_DISTANCE_MODEL:
        value = (ALfloat)context->DistanceModel;
        break;

    case AL_SPEED_OF_SOUND:
        value = context->SpeedOfSound;
        break;

    case AL_DEFERRED_UPDATES_SOFT:
        value = (ALfloat)context->DeferUpdates;
        break;

    case AL_MIDI_GAIN_SOFT:
        device = context->Device;
        value = MidiSynth_getGain(device->Synth);
        break;

    case AL_MIDI_STATE_SOFT:
        device = context->Device;
        value = (ALfloat)MidiSynth_getState(device->Synth);
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);

    return value;
}

AL_API ALint AL_APIENTRY alGetInteger(ALenum pname)
{
    ALCcontext *context;
    ALCdevice *device;
    MidiSynth *synth;
    ALint value = 0;

    context = GetContextRef();
    if(!context) return 0;

    switch(pname)
    {
    case AL_DOPPLER_FACTOR:
        value = (ALint)context->DopplerFactor;
        break;

    case AL_DOPPLER_VELOCITY:
        value = (ALint)context->DopplerVelocity;
        break;

    case AL_DISTANCE_MODEL:
        value = (ALint)context->DistanceModel;
        break;

    case AL_SPEED_OF_SOUND:
        value = (ALint)context->SpeedOfSound;
        break;

    case AL_DEFERRED_UPDATES_SOFT:
        value = (ALint)context->DeferUpdates;
        break;

    case AL_SOUNDFONTS_SIZE_SOFT:
        device = context->Device;
        synth = device->Synth;
        value = synth->NumSoundfonts;
        break;

    case AL_MIDI_STATE_SOFT:
        device = context->Device;
        value = MidiSynth_getState(device->Synth);
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);

    return value;
}

AL_API ALint64SOFT AL_APIENTRY alGetInteger64SOFT(ALenum pname)
{
    ALCcontext *context;
    ALCdevice *device;
    MidiSynth *synth;
    ALint64SOFT value = 0;

    context = GetContextRef();
    if(!context) return 0;

    switch(pname)
    {
    case AL_DOPPLER_FACTOR:
        value = (ALint64SOFT)context->DopplerFactor;
        break;

    case AL_DOPPLER_VELOCITY:
        value = (ALint64SOFT)context->DopplerVelocity;
        break;

    case AL_DISTANCE_MODEL:
        value = (ALint64SOFT)context->DistanceModel;
        break;

    case AL_SPEED_OF_SOUND:
        value = (ALint64SOFT)context->SpeedOfSound;
        break;

    case AL_DEFERRED_UPDATES_SOFT:
        value = (ALint64SOFT)context->DeferUpdates;
        break;

    case AL_MIDI_CLOCK_SOFT:
        device = context->Device;
        ALCdevice_Lock(device);
        value = MidiSynth_getTime(device->Synth);
        ALCdevice_Unlock(device);
        break;

    case AL_SOUNDFONTS_SIZE_SOFT:
        device = context->Device;
        synth = device->Synth;
        value = (ALint64SOFT)synth->NumSoundfonts;
        break;

    case AL_MIDI_STATE_SOFT:
        device = context->Device;
        value = (ALint64SOFT)MidiSynth_getState(device->Synth);
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);

    return value;
}

AL_API ALvoid AL_APIENTRY alGetBooleanv(ALenum pname, ALboolean *values)
{
    ALCcontext *context;

    if(values)
    {
        switch(pname)
        {
            case AL_DOPPLER_FACTOR:
            case AL_DOPPLER_VELOCITY:
            case AL_DISTANCE_MODEL:
            case AL_SPEED_OF_SOUND:
            case AL_DEFERRED_UPDATES_SOFT:
                values[0] = alGetBoolean(pname);
                return;
        }
    }

    context = GetContextRef();
    if(!context) return;

    if(!(values))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
    switch(pname)
    {
    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);
}

AL_API ALvoid AL_APIENTRY alGetDoublev(ALenum pname, ALdouble *values)
{
    ALCcontext *context;

    if(values)
    {
        switch(pname)
        {
            case AL_DOPPLER_FACTOR:
            case AL_DOPPLER_VELOCITY:
            case AL_DISTANCE_MODEL:
            case AL_SPEED_OF_SOUND:
            case AL_DEFERRED_UPDATES_SOFT:
            case AL_MIDI_GAIN_SOFT:
            case AL_MIDI_STATE_SOFT:
                values[0] = alGetDouble(pname);
                return;
        }
    }

    context = GetContextRef();
    if(!context) return;

    if(!(values))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
    switch(pname)
    {
    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);
}

AL_API ALvoid AL_APIENTRY alGetFloatv(ALenum pname, ALfloat *values)
{
    ALCcontext *context;

    if(values)
    {
        switch(pname)
        {
            case AL_DOPPLER_FACTOR:
            case AL_DOPPLER_VELOCITY:
            case AL_DISTANCE_MODEL:
            case AL_SPEED_OF_SOUND:
            case AL_DEFERRED_UPDATES_SOFT:
            case AL_MIDI_GAIN_SOFT:
            case AL_MIDI_STATE_SOFT:
                values[0] = alGetFloat(pname);
                return;
        }
    }

    context = GetContextRef();
    if(!context) return;

    if(!(values))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
    switch(pname)
    {
    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);
}

AL_API ALvoid AL_APIENTRY alGetIntegerv(ALenum pname, ALint *values)
{
    ALCcontext *context;
    ALCdevice *device;
    MidiSynth *synth;
    ALsizei i;

    if(values)
    {
        switch(pname)
        {
            case AL_DOPPLER_FACTOR:
            case AL_DOPPLER_VELOCITY:
            case AL_DISTANCE_MODEL:
            case AL_SPEED_OF_SOUND:
            case AL_DEFERRED_UPDATES_SOFT:
            case AL_SOUNDFONTS_SIZE_SOFT:
            case AL_MIDI_STATE_SOFT:
                values[0] = alGetInteger(pname);
                return;
        }
    }

    context = GetContextRef();
    if(!context) return;

    switch(pname)
    {
    case AL_SOUNDFONTS_SOFT:
        device = context->Device;
        synth = device->Synth;
        if(synth->NumSoundfonts > 0)
        {
            if(!(values))
                SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
            for(i = 0;i < synth->NumSoundfonts;i++)
                values[i] = synth->Soundfonts[i]->id;
        }
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);
}

AL_API void AL_APIENTRY alGetInteger64vSOFT(ALenum pname, ALint64SOFT *values)
{
    ALCcontext *context;
    ALCdevice *device;
    MidiSynth *synth;
    ALsizei i;

    if(values)
    {
        switch(pname)
        {
            case AL_DOPPLER_FACTOR:
            case AL_DOPPLER_VELOCITY:
            case AL_DISTANCE_MODEL:
            case AL_SPEED_OF_SOUND:
            case AL_DEFERRED_UPDATES_SOFT:
            case AL_MIDI_CLOCK_SOFT:
            case AL_SOUNDFONTS_SIZE_SOFT:
            case AL_MIDI_STATE_SOFT:
                values[0] = alGetInteger64SOFT(pname);
                return;
        }
    }

    context = GetContextRef();
    if(!context) return;

    switch(pname)
    {
    case AL_SOUNDFONTS_SOFT:
        device = context->Device;
        synth = device->Synth;
        if(synth->NumSoundfonts > 0)
        {
            if(!(values))
                SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
            for(i = 0;i < synth->NumSoundfonts;i++)
                values[i] = (ALint64SOFT)synth->Soundfonts[i]->id;
        }
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);
}

AL_API const ALchar* AL_APIENTRY alGetString(ALenum pname)
{
    const ALchar *value = NULL;
    ALCcontext *context;

    context = GetContextRef();
    if(!context) return NULL;

    switch(pname)
    {
    case AL_VENDOR:
        value = alVendor;
        break;

    case AL_VERSION:
        value = alVersion;
        break;

    case AL_RENDERER:
        value = alRenderer;
        break;

    case AL_EXTENSIONS:
        value = context->ExtensionList;
        break;

    case AL_NO_ERROR:
        value = alNoError;
        break;

    case AL_INVALID_NAME:
        value = alErrInvalidName;
        break;

    case AL_INVALID_ENUM:
        value = alErrInvalidEnum;
        break;

    case AL_INVALID_VALUE:
        value = alErrInvalidValue;
        break;

    case AL_INVALID_OPERATION:
        value = alErrInvalidOp;
        break;

    case AL_OUT_OF_MEMORY:
        value = alErrOutOfMemory;
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    ALCcontext_DecRef(context);

    return value;
}

AL_API ALvoid AL_APIENTRY alDopplerFactor(ALfloat value)
{
    ALCcontext *context;

    context = GetContextRef();
    if(!context) return;

    if(!(value >= 0.0f && isfinite(value)))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);

    context->DopplerFactor = value;
    ATOMIC_STORE(&context->UpdateSources, AL_TRUE);

done:
    ALCcontext_DecRef(context);
}

AL_API ALvoid AL_APIENTRY alDopplerVelocity(ALfloat value)
{
    ALCcontext *context;

    context = GetContextRef();
    if(!context) return;

    if(!(value >= 0.0f && isfinite(value)))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);

    context->DopplerVelocity = value;
    ATOMIC_STORE(&context->UpdateSources, AL_TRUE);

done:
    ALCcontext_DecRef(context);
}

AL_API ALvoid AL_APIENTRY alSpeedOfSound(ALfloat value)
{
    ALCcontext *context;

    context = GetContextRef();
    if(!context) return;

    if(!(value > 0.0f && isfinite(value)))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);

    context->SpeedOfSound = value;
    ATOMIC_STORE(&context->UpdateSources, AL_TRUE);

done:
    ALCcontext_DecRef(context);
}

AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
{
    ALCcontext *context;

    context = GetContextRef();
    if(!context) return;

    if(!(value == AL_INVERSE_DISTANCE || value == AL_INVERSE_DISTANCE_CLAMPED ||
         value == AL_LINEAR_DISTANCE || value == AL_LINEAR_DISTANCE_CLAMPED ||
         value == AL_EXPONENT_DISTANCE || value == AL_EXPONENT_DISTANCE_CLAMPED ||
         value == AL_NONE))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);

    context->DistanceModel = value;
    if(!context->SourceDistanceModel)
        ATOMIC_STORE(&context->UpdateSources, AL_TRUE);

done:
    ALCcontext_DecRef(context);
}

AL_API ALvoid AL_APIENTRY alDeferUpdatesSOFT(void)
{
    ALCcontext *context;

    context = GetContextRef();
    if(!context) return;

    if(!context->DeferUpdates)
    {
        ALboolean UpdateSources;
        ALactivesource **src, **src_end;
        ALeffectslot **slot, **slot_end;
        FPUCtl oldMode;

        SetMixerFPUMode(&oldMode);

        LockContext(context);
        context->DeferUpdates = AL_TRUE;

        /* Make sure all pending updates are performed */
        UpdateSources = ATOMIC_EXCHANGE(ALenum, &context->UpdateSources, AL_FALSE);

        src = context->ActiveSources;
        src_end = src + context->ActiveSourceCount;
        while(src != src_end)
        {
            ALsource *source = (*src)->Source;

            if(source->state != AL_PLAYING && source->state != AL_PAUSED)
            {
                ALactivesource *temp = *(--src_end);
                *src_end = *src;
                *src = temp;
                --(context->ActiveSourceCount);
                continue;
            }

            if(ATOMIC_EXCHANGE(ALenum, &source->NeedsUpdate, AL_FALSE) || UpdateSources)
                (*src)->Update(*src, context);

            src++;
        }

        slot = VECTOR_ITER_BEGIN(context->ActiveAuxSlots);
        slot_end = VECTOR_ITER_END(context->ActiveAuxSlots);
        while(slot != slot_end)
        {
            if(ATOMIC_EXCHANGE(ALenum, &(*slot)->NeedsUpdate, AL_FALSE))
                V((*slot)->EffectState,update)(context->Device, *slot);
            slot++;
        }

        UnlockContext(context);
        RestoreFPUMode(&oldMode);
    }

    ALCcontext_DecRef(context);
}

AL_API ALvoid AL_APIENTRY alProcessUpdatesSOFT(void)
{
    ALCcontext *context;

    context = GetContextRef();
    if(!context) return;

    if(ExchangeInt(&context->DeferUpdates, AL_FALSE))
    {
        ALsizei pos;

        LockContext(context);
        LockUIntMapRead(&context->SourceMap);
        for(pos = 0;pos < context->SourceMap.size;pos++)
        {
            ALsource *Source = context->SourceMap.array[pos].value;
            ALenum new_state;

            if((Source->state == AL_PLAYING || Source->state == AL_PAUSED) &&
               Source->Offset >= 0.0)
            {
                ReadLock(&Source->queue_lock);
                ApplyOffset(Source);
                ReadUnlock(&Source->queue_lock);
            }

            new_state = ExchangeInt(&Source->new_state, AL_NONE);
            if(new_state)
                SetSourceState(Source, context, new_state);
        }
        UnlockUIntMapRead(&context->SourceMap);
        UnlockContext(context);
    }

    ALCcontext_DecRef(context);
}


text:
require "googleauth"

module Google
  module Cloud
    module Kms
      module V1
        class Credentials < Google::Auth::Credentials
          SCOPE = [
            "https://www.googleapis.com/auth/cloud-platform",
            "https://www.googleapis.com/auth/cloudkms"
          ].freeze
          PATH_ENV_VARS = %w(KMS_CREDENTIALS
                             KMS_KEYFILE
                             GOOGLE_CLOUD_CREDENTIALS
                             GOOGLE_CLOUD_KEYFILE
                             GCLOUD_KEYFILE)
          JSON_ENV_VARS = %w(KMS_CREDENTIALS_JSON
                             KMS_KEYFILE_JSON
                             GOOGLE_CLOUD_CREDENTIALS_JSON
                             GOOGLE_CLOUD_KEYFILE_JSON
                             GCLOUD_KEYFILE_JSON)
          DEFAULT_PATHS = ["~/.config/gcloud/application_default_credentials.json"]
        end
      end
    end
  end
end

redpajama_set_name: RedPajamaGithub


text:
1. [组合模式](https://github.com/worthed/OriginBlog/blob/master/articles/CompositePattern.md)
2. [外观模式](https://github.com/worthed/OriginBlog/blob/master/articles/FacadePattern.md)
3. [桥接模式](https://github.com/worthed/OriginBlog/blob/master/articles/BridgePattern.md)
4. [代理模式](https://github.com/worthed/OriginBlog/blob/master/articles/ProxyPattern.md)
5. [享元模式](https://github.com/worthed/OriginBlog/blob/master/articles/FlyweightPattern.md)
6. [适配器模式](https://github.com/worthed/OriginBlog/blob/master/articles/AdapterPattern.md)
7. [装饰模式](https://github.com/worthed/OriginBlog/blob/master/articles/DecoratorPattern.md)


text:
(function() {
    'use strict';

    var express = require('express');
    var router = express.Router();
    var path = require('path');
    var userAuth = require('./helpers/authentication');

    /* GET home page. */
    router.get('/', function(req, res) {
        if (userAuth.userValidated(req, res, false)) {
            res.sendFile(path.join(__dirname, '../views', 'index.html'));
        }
    });

    module.exports = router;
})();


text:
using System;
using NUnit.Framework;

public class Test14
{
    [TestCase]
    public void ChangeCardType_OnMultipleBattlecards_ShouldWorkCorrectly()
    {
        //Arrange
        IArena RA = new RoyaleArena();
        Battlecard cd1 = new Battlecard(5, CardType.SPELL, "joro", 5, 5);
        Battlecard cd2 = new Battlecard(6, CardType.SPELL, "joro", 6, 5);
        Battlecard cd3 = new Battlecard(7, CardType.SPELL, "joro", 7, 5);
        //Act
        RA.Add(cd1);
        RA.Add(cd2);
        RA.Add(cd3);
        RA.ChangeCardType(7, CardType.BUILDING);
        RA.ChangeCardType(5, CardType.MELEE);
        RA.ChangeCardType(6, CardType.SPELL);
        //Assert
        Assert.AreEqual(3, RA.Count);
        Assert.AreEqual(cd1.Type, CardType.MELEE);
        Assert.AreEqual(cd3.Type, CardType.BUILDING);
        Assert.AreEqual(cd2.Type, CardType.SPELL);
    }

}


text:
layout: docwithnav
title: Temperature upload over MQTT using ESP8266 and DHT22 sensor
description: ThingsBoard IoT Platform sample for temperature data upload over MQTT using ESP8266 and DHT22 sensor.

---

* TOC
{:toc}

## Introduction
{% include templates/what-is-thingsboard.md %}

This sample application performs collection of temperature and humidity values produced by [DHT22 sensor](https://www.adafruit.com/product/385) and further visualization on the real-time web dashboard.
Collected data is pushed via MQTT to ThingsBoard server for storage and visualization.
The purpose of this application is to demonstrate ThingsBoard [data collection API](/docs/user-guide/telemetry/) and [visualization capabilities](/docs/user-guide/visualization/).

The DHT22 sensor is connected to [ESP8266](https://en.wikipedia.org/wiki/ESP8266).
ESP8266 offers a complete and self-contained Wi-Fi networking solution.
ESP8266 push data to ThingsBoard server via MQTT protocol by using [PubSubClient](https://github.com/knolleary/pubsubclient) library for Arduino.
Data is visualized using built-in customizable dashboard.
The application that is running on ESP8266 is written using Arduino SDK which is quite simple and easy to understand.

The video below demonstrates the final result of this tutorial.

Once you complete this sample/tutorial, you will see your sensor data on the following dashboard.

![image](/images/samples/esp8266/temperature/dashboard.gif)

{% include templates/prerequisites.md %}

## List of hardware and pinouts

 - [ESP8266 module](https://www.aliexpress.com/item/2PCS-ESP8266-Serial-Esp-01-WIFI-Wireless-Transceiver-Module-Send-Receive-LWIP-AP-STA/32302638695.html?spm=2114.03010208.3.163.FPBlcc&ws_ab_test=searchweb0_0,searchweb201602_2_10065_10068_10084_10083_10080_10082_10081_10060_10061_10062_10056_10055_10054_10059_10099_10078_10079_10093_427_10073_10103_10102_10096_10052_10050_10051,searchweb201603_3&btsid=1494d8a7-6202-4a69-a0e7-877ffa333243)

  ![image](/images/samples/arduino/temperature/esp8266-pinout.png)

 - [DHT22 sensor](https://www.aliexpress.com/item/1pcs-DHT22-digital-temperature-and-humidity-sensor-Temperature-and-humidity-module-AM2302-replace-SHT11-SHT15/32316036161.html?spm=2114.03010208.3.49.aZvfaG&ws_ab_test=searchweb0_0,searchweb201602_2_10065_10068_10084_10083_10080_10082_10081_10060_10061_10062_10056_10055_10054_10059_10099_10078_10079_10093_426_10073_10103_10102_10096_10052_10050_10051,searchweb201603_6&btsid=28d9ee9a-283a-4e97-af7b-a7e530490916)

  ![image](/images/samples/arduino/temperature/dht22-pinout.png)

 - USB to TTL

    - [With DTR & RTS](https://www.aliexpress.com/item/Free-shipping-1pcs-FT232RL-FTDI-USB-3-3V-5-5V-to-TTL-Serial-Adapter-Module-for/32256920717.html?spm=2114.03010208.3.11.qSXSby&ws_ab_test=searchweb0_0,searchweb201602_2_10065_10068_10084_10083_10080_10082_10081_10060_10061_10062_10056_10055_10054_10059_10099_10078_10079_10093_427_10073_10103_10102_10096_10052_10050_10051,searchweb201603_3&btsid=54ef4b72-5ab0-4ce6-aa89-74726d95c099)

    ![image](/images/samples/esp8266/temperature/usb-ttl-ft232rl-pinout.png)

    - Or [Without DTR & RTS](https://www.aliexpress.com/item/1pcs-lot-PL2303-USB-To-RS232-TTL-Converter-Adapter-Module-with-Dust-proof-Cover-PL2303HX/32642301991.html?spm=2114.03010208.3.50.WdAM18&ws_ab_test=searchweb0_0,searchweb201602_2_10065_10068_10084_10083_10080_10082_10081_10060_10061_10062_10056_10055_10054_10059_10099_10078_10079_10093_427_10073_10103_10102_10096_10052_10050_10051,searchweb201603_3&btsid=9ac20e48-da8c-4a0f-8f33-d40c241fe5a3)

    ![image](/images/samples/esp8266/temperature/usb-ttl-pl2303hx.png)

 - Resistor (between 4.7K and 10K)

 - Breadboard

 - 2 female-to-female jumper wires

 - 10 female-to-male jumper wires

 - 3 male-to-male jumper wire

 - 3.3V power source (for example 2 AA batteries)

## Wiring schemes

### Programming/flashing schema

ESP8266 Pin|USB-TTL Pin
-----------|-----------
ESP8266 VCC|USB-TTL VCC +3.3V
ESP8266 CH_PD|USB-TTL VCC +3.3V
ESP8266 GND (-)|USB-TTL GND
ESP8266 GPIO 0|USB-TTL GND
ESP8266 RX|USB-TTL TX
ESP8266 TX|USB-TTL RX

DHT-22 Pin|ESP8266 Pin
-----------|-----------
DHT-22 Data|ESP8266 GPIO 2

DHT-22 Pin|USB-TTL Pin
-----------|-----------
DHT-22 VCC|USB-TTL VCC +3.3V
DHT-22 GND (-)|USB-TTL GND

Finally, place a resistor (between 4.7K and 10K) between pin number 1 and 2 of the DHT sensor.

The following picture summarizes the connections for this project in programming/debug mode:

![image](/images/samples/esp8266/temperature/schema-flash.png)

### Final schema (Battery Powered)

ESP8266 Pin|3.3V power source
-----------|-----------
ESP8266 VCC|VCC+
ESP8266 CH_PD|VCC+
ESP8266 GND (-)|VCC-

DHT-22 Pin|ESP8266 Pin
-----------|-----------
DHT-22 Data|ESP8266 GPIO 2

DHT-22 Pin|3.3V power source
-----------|-----------
DHT-22 VCC|VCC+
DHT-22 GND (-)|VCC-

The final picture:

![image](/images/samples/esp8266/temperature/schema.png)

{% include templates/thingsboard-configuration.md %}

### Provision your device

This step contains instructions that are necessary to connect your device to ThingsBoard.

Open ThingsBoard Web UI (http://localhost:8080) in browser and login as tenant administrator

 - login: tenant@thingsboard.org
 - password: tenant

Go to "Devices" section. Click "+" button and create a device with the name "ESP8266 Demo Device".

![image](/images/samples/esp8266/temperature/device.png)

Once device created, open its details and click "Manage credentials".
Copy auto-generated access token from the "Access token" field. Please save this device token. It will be referred to later as **$ACCESS_TOKEN**.

![image](/images/samples/esp8266/temperature/credentials.png)

Click "Copy Device ID" in device details to copy your device id to the clipboard.
Paste your device id to some place, this value will be used in further steps.

### Provision your dashboard

Download the dashboard file using this [**link**](/docs/samples/esp8266/resources/esp8266_dht_temp_dashboard_v2.json).
Use import/export [**instructions**](/docs/user-guide/ui/dashboards/#dashboard-importexport) to import the dashboard to your ThingsBoard instance.

## Programming the ESP8266

### Step 1. ESP8266 and Arduino IDE setup.

In order to start programming ESP8266 device, you will need Arduino IDE installed and all related software.

Download and install [Arduino IDE](https://www.arduino.cc/en/Main/Software).

After starting Arduino IDE, open the preferences from the 'file' menu.

![image](/images/samples/esp8266/temperature/arduino-preferences.png)

Paste the following URL to the "Additional board managers URL":  http://arduino.esp8266.com/stable/package_esp8266com_index.json

Close the screen by clicking the OK button.

Now we can add the board ESP8266 using the board manager.

In the menu tools, click on the menu option Board: "*Most likely Arduino UNO*".
There you will find the first option "Board Manager".

Type in the search bar the 3 letters ESP. Locate and click on "*esp8266 by ESP8266 Community*".
Click on install and wait for a minute to download the board.

![image](/images/samples/esp8266/temperature/arduino-board-manager.png)

**Note** that this tutorial was tested with the "*esp8266 by ESP8266 Community*" version 2.3.0.

In the menu Tools "Board "*Most likely Arduino UNO*" three new boards are added.

Select "Generic ESP8266 Module".

Prepare your hardware according to the [Programming/flashing schema](#programmingflashing-schema).
Connect USB-TTL adapter with PC.

In the menu Tools, select the corresponding port of the USB-TTL adapter.
Open the serial monitor (by pressing CTRL-Shift-M or from the menu Tools).
Set the key emulation to "Both NL & CR" and the speed to 115200 baud. This can be set in the bottom of terminal screen.

### Step 2. Install Arduino libraries.

Open Arduino IDE and go to **Sketch -> Include Library -> Manage Libraries**.
Find and install the following libraries:

- [PubSubClient by Nick O'Leary](http://pubsubclient.knolleary.net/).
- [Adafruit Unified Sensor by Adafruit](https://github.com/adafruit/Adafruit_Sensor)
- [DHT sensor library by Adafruit](https://github.com/adafruit/DHT-sensor-library)
- [Arduino ThingsBoard SDK by ThingsBoard](https://github.com/thingsboard/ThingsBoard-Arduino-MQTT-SDK)
- [ArduinoJSON by bblanchon](https://github.com/bblanchon/ArduinoJson)
- [Arduino Http Client](https://github.com/arduino-libraries/ArduinoHttpClient)

**Note** that this tutorial was tested with the following versions of the libraries:

- PubSubClient 2.6
- Adafruit Unified Sensor 1.0.2
- DHT sensor library 1.3.0
- Arduino ThingsBoard SDK 0.4
- ArduinoJSON 6.10.1
- Arduino Http Client 0.4.0

### Step 3. Prepare and upload a sketch.

Download and open **esp8266-dht-mqtt.ino** sketch.

**Note** You need to edit following constants and variables in the sketch:

- WIFI_AP - name of your access point
- WIFI_PASSWORD - access point password
- TOKEN - the **$ACCESS_TOKEN** from ThingsBoard configuration step.
- thingsboardServer - ThingsBoard HOST/IP address that is accessible within your wifi network. Specify "demo.thingsboard.io" if you are using [live demo](https://demo.thingsboard.io/) server.

{% capture tabspec %}arduino-sketch
esp8266-dht-mqtt,esp8266-dht-mqtt.ino,c,resources/esp8266-dht-mqtt.ino,/docs/samples/esp8266/resources/esp8266-dht-mqtt.ino{% endcapture %}
{% include tabs.html %}

Connect USB-TTL adapter to PC and select the corresponding port in Arduino IDE. Compile and Upload your sketch to the device using "Upload" button.

After application will be uploaded and started it will try to connect to ThingsBoard node using mqtt client and upload "temperature" and "humidity" timeseries data once per second.

## Autonomous operation

When you have uploaded the sketch, you may remove all the wires required for uploading including USB-TTL adapter and connect your ESP8266 and DHT sensor directly to the power source according to the [Final wiring schema](#final-schema-battery-powered).

## Troubleshooting

In order to perform troubleshooting, you should assemble your hardware according to the [Programming/flashing schema](#programmingflashing-schema).
Then connect USB-TTL adapter with PC and select port of the USB-TTL adapter in Arduino IDE. Finally, open "Serial Monitor" in order to view debug information produced by serial output.

## Data visualization

Finally, open ThingsBoard Web UI. You can access this dashboard by logging in as a tenant administrator. Use:

 - login: tenant@thingsboard.org
 - password: tenant

in case of local ThingsBoard installation.

Go to **"Devices"** section and locate **"ESP8266 Demo Device"**, open device details and switch to **"Latest telemetry"** tab.
If all is configured correctly you should be able to see latest values of *"temperature"* and *"humidity"* in the table.

![image](/images/samples/esp8266/temperature/attributes.png)

After, open **"Dashboards"** section then locate and open **"ESP8266 DHT22: Temperature & Humidity Demo Dashboard"**.
As a result, you will see two digital gauges and two time-series charts displaying temperature and humidity level (similar to dashboard image in the introduction).

## See also

Browse other [samples](/docs/samples) or explore guides related to main ThingsBoard features:

 - [Device attributes](/docs/user-guide/attributes/) - how to use device attributes.
 - [Telemetry data collection](/docs/user-guide/telemetry/) - how to collect telemetry data.
 - [Using RPC capabilities](/docs/user-guide/rpc/) - how to send commands to/from devices.
 - [Rule Engine](/docs/user-guide/rule-engine/) - how to use rule engine to analyze data from devices.
 - [Data Visualization](/docs/user-guide/visualization/) - how to visualize collected data.

{% include templates/feedback.md %}

{% include socials.html %}

## Next steps

{% assign currentGuide = "HardwareSamples" %}{% include templates/guides-banner.md %}


text:
title: Zero to One - Peter Thiel
author: sanjiv sahayam
description: Ideas from the book: Zero to One - Notes on startups or How to build the future - Peter Thiel with Blake Masters
tags: book, ideas
---

Ideas from the book [Zero to one by Peter Thiel](http://zerotoonebook.com/)

Progress
--------
1. Horizontal - Copying things that work. Going from 1 to x.  Eg. You take one typewriter and then build another hundred copies.
1. Vertical - Doing new things. Going from 0 to 1. Eg. You take a typewriter and build a word processor.

Startup Thinking
----------------
* A new company's most important strength is new thinking.
* A startup has to question received ideas and rethink business from scratch.
* A lone genius might create a classic work of art or literature but he will never create an entire industry on his own.
* Startups operate on the principle that you need to work with other people to get things done. You also need to stay small enough so you actually can.
* A startup is the largest group of people you can convince of a plan to build a different future.

Monopolies
----------
* Competition and Capitalism are opposites.
* Monopolies exaggerate the power of their (nonexistent) competition to avoid scrutiny.
* Entrepreneur's exaggerate how powerful they are and understate the competition. "We are in a league of our own".
* The value of a business today is the sum of all the money it will make in the future. You also have to discount future cash flow to its present worth due to depreciation.
* Ask yourself "will this business be around a decade from now?"

How to Build a Monopoly
-----------------------

### 1. Proprietary Technology

* A proprietary technology must be at least 10 times better than its closest substitute in some important dimension.
* The easiest way to be 10 times better is to invent something new. Where there was nothing before, the increase in value is theoretically infinite.

### 2. Network Effects

* Network effects make a product more useful as more people use it. Eg. Twitter.
* To reap the benefits of network effects, your product must be useful to its very first users, when the network is naturally small.
* You must start will specially small markets.

### 3. Economies of Scale

* The cost of creating another copy of your software should be close to zero.
* A good startup should have the potential for great scale built into its first design.

### 4. Branding

* A technology company can't be built on brand alone.
* Begin with substance then build your brand.

How to Choose A Market
-----------------------

* Start with a very small market. Always err on the side of starting too small.
* It's easier to dominate a small market than a large one.
* Choose a small group of particular people, concentrated together and served by few or no competition.
* It's a red flag to talk about 1% of a very large market. You'll have to fight too many competitors to get that 1%.
* Once you create and dominate a niche market, gradually expand into related and slightly broader markets. Eg. Amazon wanted to dominate all online retail but started with books.
* Don't disrupt. Avoid competition as much as possible
* "You must study the endgame before anything else" - Grandmaster José Raúl Capablanca

The Power Law
-------------

* A small handful of companies radically outperform all others.
* The differences between companies dwarf differences in roles within companies.
* Before you focus relentlessly on something you're good at, think hard about whether it will be valuable in the future.
* For startups this means you should not necessarily start your own company, even if you are extraordinarily talented. It might be better to join a successful company when it's growing fast.
* You could have 100% equity if you fully fund your own company. If it fails you will have a 100% of nothing. Owning just 0.01% of Google will give you millions.

Secrets
-------
* There are two kinds of secrets:
    1. Secrets about nature - Undiscovered aspects of the physical world.
    1. Secrets about people - Things people don't know about themselves or things people want to hide from you.
* What secrets is nature not telling you?
* What secrets are people not telling you?
* You can't find secrets without looking for them.
* The best place to look for secrets is where no one else is looking for them.
* A great company is a conspiracy to change the world.

Selling
-------

Your company needs to sell more than its product. You must sell your company to employees and investors.

Computers are a Tool
--------------------

"How can computers help humans solve hard problems?"

Planning
-------

* Jobs saw that you can change the world through planning; not by listening to focus group feedback or copying others' success.
* Long-term planning is often undervalued in our indefinite short-term world - If you see the future as random why plan?

7 Questions Every Business must Answer
--------------------------------------

1. Can you create breakthrough technology instead of incremental improvements?
2. Is now the right time to start your particular business?
3. Are you starting with a big share of a small market?
4. Do you have the right team?
5. Do you have a way to create and deliver your product?
6. Will your market position be defensible 10 to 20 years into the future?
7. Have you identified a unique opportunity others don't see?

The Future
----------

* Focus on making new things.
* Make the future not just different but better.
* Think for yourself.
* Look at the world with fresh perspective similar to the ancients.


text:
#pragma once
#include <aws/appsync/AppSync_EXPORTS.h>
#include <aws/appsync/AppSyncRequest.h>
#include <aws/core/utils/memory/stl/AWSString.h>
#include <aws/appsync/model/LogConfig.h>
#include <aws/appsync/model/AuthenticationType.h>
#include <aws/appsync/model/UserPoolConfig.h>
#include <aws/appsync/model/OpenIDConnectConfig.h>
#include <utility>

namespace Aws
{
namespace AppSync
{
namespace Model
{

  /**
   */
  class AWS_APPSYNC_API UpdateGraphqlApiRequest : public AppSyncRequest
  {
  public:
    UpdateGraphqlApiRequest();

    // Service request name is the Operation name which will send this request out,
    // each operation should has unique request name, so that we can get operation's name from this request.
    // Note: this is not true for response, multiple operations may have the same response name,
    // so we can not get operation's name from response.
    inline virtual const char* GetServiceRequestName() const override { return "UpdateGraphqlApi"; }

    Aws::String SerializePayload() const override;

    /**
     *
The API ID.

     */
    inline const Aws::String& GetApiId() const{ return m_apiId; }

    /**
     *
The API ID.

     */
    inline void SetApiId(const Aws::String& value) { m_apiIdHasBeenSet = true; m_apiId = value; }

    /**
     *
The API ID.

     */
    inline void SetApiId(Aws::String&& value) { m_apiIdHasBeenSet = true; m_apiId = std::move(value); }

    /**
     *
The API ID.

     */
    inline void SetApiId(const char* value) { m_apiIdHasBeenSet = true; m_apiId.assign(value); }

    /**
     *
The API ID.

     */
    inline UpdateGraphqlApiRequest& WithApiId(const Aws::String& value) { SetApiId(value); return *this;}

    /**
     *
The API ID.

     */
    inline UpdateGraphqlApiRequest& WithApiId(Aws::String&& value) { SetApiId(std::move(value)); return *this;}

    /**
     *
The API ID.

     */
    inline UpdateGraphqlApiRequest& WithApiId(const char* value) { SetApiId(value); return *this;}

    /**
     *
The new name for the GraphqlApi object.

     */
    inline const Aws::String& GetName() const{ return m_name; }

    /**
     *
The new name for the GraphqlApi object.

     */
    inline void SetName(const Aws::String& value) { m_nameHasBeenSet = true; m_name = value; }

    /**
     *
The new name for the GraphqlApi object.

     */
    inline void SetName(Aws::String&& value) { m_nameHasBeenSet = true; m_name = std::move(value); }

    /**
     *
The new name for the GraphqlApi object.

     */
    inline void SetName(const char* value) { m_nameHasBeenSet = true; m_name.assign(value); }

    /**
     *
The new name for the GraphqlApi object.

     */
    inline UpdateGraphqlApiRequest& WithName(const Aws::String& value) { SetName(value); return *this;}

    /**
     *
The new name for the GraphqlApi object.

     */
    inline UpdateGraphqlApiRequest& WithName(Aws::String&& value) { SetName(std::move(value)); return *this;}

    /**
     *
The new name for the GraphqlApi object.

     */
    inline UpdateGraphqlApiRequest& WithName(const char* value) { SetName(value); return *this;}

    /**
     *
The Amazon CloudWatch logs configuration for the GraphqlApi
     * object.

     */
    inline const LogConfig& GetLogConfig() const{ return m_logConfig; }

    /**
     *
The Amazon CloudWatch logs configuration for the GraphqlApi
     * object.

     */
    inline void SetLogConfig(const LogConfig& value) { m_logConfigHasBeenSet = true; m_logConfig = value; }

    /**
     *
The Amazon CloudWatch logs configuration for the GraphqlApi
     * object.

     */
    inline void SetLogConfig(LogConfig&& value) { m_logConfigHasBeenSet = true; m_logConfig = std::move(value); }

    /**
     *
The Amazon CloudWatch logs configuration for the GraphqlApi
     * object.

     */
    inline UpdateGraphqlApiRequest& WithLogConfig(const LogConfig& value) { SetLogConfig(value); return *this;}

    /**
     *
The Amazon CloudWatch logs configuration for the GraphqlApi
     * object.

     */
    inline UpdateGraphqlApiRequest& WithLogConfig(LogConfig&& value) { SetLogConfig(std::move(value)); return *this;}

    /**
     *
The new authentication type for the GraphqlApi object.

     */
    inline const AuthenticationType& GetAuthenticationType() const{ return m_authenticationType; }

    /**
     *
The new authentication type for the GraphqlApi object.

     */
    inline void SetAuthenticationType(const AuthenticationType& value) { m_authenticationTypeHasBeenSet = true; m_authenticationType = value; }

    /**
     *
The new authentication type for the GraphqlApi object.

     */
    inline void SetAuthenticationType(AuthenticationType&& value) { m_authenticationTypeHasBeenSet = true; m_authenticationType = std::move(value); }

    /**
     *
The new authentication type for the GraphqlApi object.

     */
    inline UpdateGraphqlApiRequest& WithAuthenticationType(const AuthenticationType& value) { SetAuthenticationType(value); return *this;}

    /**
     *
The new authentication type for the GraphqlApi object.

     */
    inline UpdateGraphqlApiRequest& WithAuthenticationType(AuthenticationType&& value) { SetAuthenticationType(std::move(value)); return *this;}

    /**
     *
The new Amazon Cognito User Pool configuration for the
     * GraphqlApi object.

     */
    inline const UserPoolConfig& GetUserPoolConfig() const{ return m_userPoolConfig; }

    /**
     *
The new Amazon Cognito User Pool configuration for the
     * GraphqlApi object.

     */
    inline void SetUserPoolConfig(const UserPoolConfig& value) { m_userPoolConfigHasBeenSet = true; m_userPoolConfig = value; }

    /**
     *
The new Amazon Cognito User Pool configuration for the
     * GraphqlApi object.

     */
    inline void SetUserPoolConfig(UserPoolConfig&& value) { m_userPoolConfigHasBeenSet = true; m_userPoolConfig = std::move(value); }

    /**
     *
The new Amazon Cognito User Pool configuration for the
     * GraphqlApi object.

     */
    inline UpdateGraphqlApiRequest& WithUserPoolConfig(const UserPoolConfig& value) { SetUserPoolConfig(value); return *this;}

    /**
     *
The new Amazon Cognito User Pool configuration for the
     * GraphqlApi object.

     */
    inline UpdateGraphqlApiRequest& WithUserPoolConfig(UserPoolConfig&& value) { SetUserPoolConfig(std::move(value)); return *this;}

    /**
     *
The Open Id Connect configuration configuration for the
     * GraphqlApi object.

     */
    inline const OpenIDConnectConfig& GetOpenIDConnectConfig() const{ return m_openIDConnectConfig; }

    /**
     *
The Open Id Connect configuration configuration for the
     * GraphqlApi object.

     */
    inline void SetOpenIDConnectConfig(const OpenIDConnectConfig& value) { m_openIDConnectConfigHasBeenSet = true; m_openIDConnectConfig = value; }

    /**
     *
The Open Id Connect configuration configuration for the
     * GraphqlApi object.

     */
    inline void SetOpenIDConnectConfig(OpenIDConnectConfig&& value) { m_openIDConnectConfigHasBeenSet = true; m_openIDConnectConfig = std::move(value); }

    /**
     *
The Open Id Connect configuration configuration for the
     * GraphqlApi object.

     */
    inline UpdateGraphqlApiRequest& WithOpenIDConnectConfig(const OpenIDConnectConfig& value) { SetOpenIDConnectConfig(value); return *this;}

    /**
     *
The Open Id Connect configuration configuration for the
     * GraphqlApi object.

     */
    inline UpdateGraphqlApiRequest& WithOpenIDConnectConfig(OpenIDConnectConfig&& value) { SetOpenIDConnectConfig(std::move(value)); return *this;}

  private:

    Aws::String m_apiId;
    bool m_apiIdHasBeenSet;

    Aws::String m_name;
    bool m_nameHasBeenSet;

    LogConfig m_logConfig;
    bool m_logConfigHasBeenSet;

    AuthenticationType m_authenticationType;
    bool m_authenticationTypeHasBeenSet;

    UserPoolConfig m_userPoolConfig;
    bool m_userPoolConfigHasBeenSet;

    OpenIDConnectConfig m_openIDConnectConfig;
    bool m_openIDConnectConfigHasBeenSet;
  };

} // namespace Model
} // namespace AppSync
} // namespace Aws


text:
FOUNDATION_EXPORT NSString* const ANEExceptionErrorObjectKey;
FOUNDATION_EXPORT NSString* const ANEException;


text:
var ec2_PermissionDetails = {
    init : function() {
        var perm = window.arguments[0];
        document.getElementById("ec2ui.permission.protocol").value = perm.protocol;
        document.getElementById("ec2ui.permission.fromport").value = perm.fromPort;
        document.getElementById("ec2ui.permission.toport").value = perm.toPort;
        if (perm.ipRanges.length > 0) {
            document.getElementById("ec2ui.permission.sourcecidr").value = perm.ipRanges[0];
        }
        if (perm.groupTuples.length > 0) {
            document.getElementById("ec2ui.permission.sourceusergroup").value = '('+perm.groupTuples[0].join(',')+')';
        }
    }
}


text:
class SeedsController < ApplicationController
  # GET /seeds
  # GET /seeds.json
  def index
    @seeds = Seed.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @seeds }
    end
  end

  # GET /seeds/1
  # GET /seeds/1.json
  def show
    @seed = Seed.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @seed }
    end
  end

  # GET /seeds/new
  # GET /seeds/new.json
  def new
    @seed = Seed.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @seed }
    end
  end

  # GET /seeds/1/edit
  def edit
    @seed = Seed.find(params[:id])
  end

  # POST /seeds
  # POST /seeds.json
  def create
    @seed = Seed.new(params[:seed])

    respond_to do |format|
      if @seed.save
        format.html { redirect_to @seed, notice: 'Seed was successfully created.' }
        format.json { render json: @seed, status: :created, location: @seed }
      else
        format.html { render action: "new" }
        format.json { render json: @seed.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /seeds/1
  # PUT /seeds/1.json
  def update
    @seed = Seed.find(params[:id])

    respond_to do |format|
      if @seed.update_attributes(params[:seed])
        format.html { redirect_to @seed, notice: 'Seed was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @seed.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /seeds/1
  # DELETE /seeds/1.json
  def destroy
    @seed = Seed.find(params[:id])
    @seed.destroy

    respond_to do |format|
      format.html { redirect_to seeds_url }
      format.json { head :no_content }
    end
  end
end


text:
import {IPlayerMap} from '../../types'
import {ActionTypes} from '../../action-types'

export interface IBidAction {
  type: ActionTypes.BID,
  payload?: IPlayerMap<number>
}

/**
 * End bidding process in bridge game
 * @param payload - A map that maps player ID to their bid choice.
 * If undefined, bid property in currentGame state will be used
 */
export function bidAction(payload?: IPlayerMap<number>): IBidAction {
  return {type: ActionTypes.BID, payload}
}