text:
// Unit test for TFLite Layer Norm LSTM op.

#include <memory>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "flatbuffers/flexbuffers.h"  // TF:flatbuffers
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/kernels/test_util.h"
#include "tensorflow/lite/model.h"

namespace tflite {
namespace ops {
namespace custom {

TfLiteRegistration* Register_LAYER_NORM_LSTM();

namespace {

using ::testing::ElementsAreArray;

class LayerNormLSTMOpModel : public SingleOpModel {
 public:
  LayerNormLSTMOpModel(int n_batch, int n_input, int n_cell, int n_output,
                       bool use_cifg, bool use_peephole,
                       bool use_projection_weights, bool use_projection_bias,
                       float cell_clip, float proj_clip,
                       const std::vector<std::vector<int>>& input_shapes,
                       const TensorType& weight_type = TensorType_FLOAT32)
      : n_batch_(n_batch),
        n_input_(n_input),
        n_cell_(n_cell),
        n_output_(n_output) {
    input_ = AddInput(TensorType_FLOAT32);

    if (use_cifg) {
      input_to_input_weights_ = AddNullInput();
    } else {
      input_to_input_weights_ = AddInput(weight_type);
    }

    input_to_forget_weights_ = AddInput(weight_type);
    input_to_cell_weights_ = AddInput(weight_type);
    input_to_output_weights_ = AddInput(weight_type);

    if (use_cifg) {
      recurrent_to_input_weights_ = AddNullInput();
    } else {
      recurrent_to_input_weights_ = AddInput(weight_type);
    }

    recurrent_to_forget_weights_ = AddInput(weight_type);
    recurrent_to_cell_weights_ = AddInput(weight_type);
    recurrent_to_output_weights_ = AddInput(weight_type);

    if (use_peephole) {
      if (use_cifg) {
        cell_to_input_weights_ = AddNullInput();
      } else {
        cell_to_input_weights_ = AddInput(weight_type);
      }
      cell_to_forget_weights_ = AddInput(weight_type);
      cell_to_output_weights_ = AddInput(weight_type);
    } else {
      cell_to_input_weights_ = AddNullInput();
      cell_to_forget_weights_ = AddNullInput();
      cell_to_output_weights_ = AddNullInput();
    }

    if (use_cifg) {
      input_layer_norm_weights_ = AddNullInput();
    } else {
      input_layer_norm_weights_ = AddInput(TensorType_FLOAT32);
    }
    forget_layer_norm_weights_ = AddInput(TensorType_FLOAT32);
    cell_layer_norm_weights_ = AddInput(TensorType_FLOAT32);
    output_layer_norm_weights_ = AddInput(TensorType_FLOAT32);

    if (use_cifg) {
      input_gate_bias_ = AddNullInput();
    } else {
      input_gate_bias_ = AddInput(TensorType_FLOAT32);
    }
    forget_gate_bias_ = AddInput(TensorType_FLOAT32);
    cell_bias_ = AddInput(TensorType_FLOAT32);
    output_gate_bias_ = AddInput(TensorType_FLOAT32);

    if (use_projection_weights) {
      projection_weights_ = AddInput(weight_type);
      if (use_projection_bias) {
        projection_bias_ = AddInput(TensorType_FLOAT32);
      } else {
        projection_bias_ = AddNullInput();
      }
    } else {
      projection_weights_ = AddNullInput();
      projection_bias_ = AddNullInput();
    }

    // Adding the 2 state tensors.
    output_state_ =
        AddInput(TensorData{TensorType_FLOAT32, {n_output_ * n_batch_}}, true);
    cell_state_ =
        AddInput(TensorData{TensorType_FLOAT32, {n_cell_ * n_batch_}}, true);

    output_ = AddOutput(TensorType_FLOAT32);

    // Set up and pass in custom options using flexbuffer.
    flexbuffers::Builder fbb;
    fbb.Map([&]() {
      fbb.Int("cell_clip", cell_clip);
      fbb.Int("proj_clip", proj_clip);
      fbb.String("fused_activation_function", "TANH");
    });
    fbb.Finish();
    SetCustomOp("LAYER_NORM_LSTM", fbb.GetBuffer(), Register_LAYER_NORM_LSTM);
    BuildInterpreter(input_shapes);
  }

  void SetInputToInputWeights(const std::vector<float>& f) {
    PopulateTensor(input_to_input_weights_, f);
  }

  void SetInputToForgetWeights(const std::vector<float>& f) {
    PopulateTensor(input_to_forget_weights_, f);
  }

  void SetInputToCellWeights(const std::vector<float>& f) {
    PopulateTensor(input_to_cell_weights_, f);
  }

  void SetInputToOutputWeights(const std::vector<float>& f) {
    PopulateTensor(input_to_output_weights_, f);
  }

  void SetRecurrentToInputWeights(const std::vector<float>& f) {
    PopulateTensor(recurrent_to_input_weights_, f);
  }

  void SetRecurrentToForgetWeights(const std::vector<float>& f) {
    PopulateTensor(recurrent_to_forget_weights_, f);
  }

  void SetRecurrentToCellWeights(const std::vector<float>& f) {
    PopulateTensor(recurrent_to_cell_weights_, f);
  }

  void SetRecurrentToOutputWeights(const std::vector<float>& f) {
    PopulateTensor(recurrent_to_output_weights_, f);
  }

  void SetCellToInputWeights(const std::vector<float>& f) {
    PopulateTensor(cell_to_input_weights_, f);
  }

  void SetCellToForgetWeights(const std::vector<float>& f) {
    PopulateTensor(cell_to_forget_weights_, f);
  }

  void SetCellToOutputWeights(const std::vector<float>& f) {
    PopulateTensor(cell_to_output_weights_, f);
  }

  void SetInputLayerNormWeights(const std::vector<float>& f) {
    PopulateTensor(input_layer_norm_weights_, f);
  }

  void SetForgetLayerNormWeights(const std::vector<float>& f) {
    PopulateTensor(forget_layer_norm_weights_, f);
  }

  void SetCellLayerNormWeights(const std::vector<float>& f) {
    PopulateTensor(cell_layer_norm_weights_, f);
  }

  void SetOutputLayerNormWeights(const std::vector<float>& f) {
    PopulateTensor(output_layer_norm_weights_, f);
  }

  void SetInputGateBias(const std::vector<float>& f) {
    PopulateTensor(input_gate_bias_, f);
  }

  void SetForgetGateBias(const std::vector<float>& f) {
    PopulateTensor(forget_gate_bias_, f);
  }

  void SetCellBias(const std::vector<float>& f) {
    PopulateTensor(cell_bias_, f);
  }

  void SetOutputGateBias(const std::vector<float>& f) {
    PopulateTensor(output_gate_bias_, f);
  }

  void SetProjectionWeights(const std::vector<float>& f) {
    PopulateTensor(projection_weights_, f);
  }

  void SetProjectionBias(const std::vector<float>& f) {
    PopulateTensor(projection_bias_, f);
  }

  void SetInput(int offset, const float* begin, const float* end) {
    PopulateTensor(input_, offset, const_cast<float*>(begin),
                   const_cast<float*>(end));
  }

  std::vector<float> GetOutput() { return ExtractVector<float>(output_); }

  int num_inputs() { return n_input_; }
  int num_outputs() { return n_output_; }
  int num_cells() { return n_cell_; }
  int num_batches() { return n_batch_; }

 protected:
  int input_;
  int input_to_input_weights_;
  int input_to_forget_weights_;
  int input_to_cell_weights_;
  int input_to_output_weights_;

  int recurrent_to_input_weights_;
  int recurrent_to_forget_weights_;
  int recurrent_to_cell_weights_;
  int recurrent_to_output_weights_;

  int cell_to_input_weights_;
  int cell_to_forget_weights_;
  int cell_to_output_weights_;

  int input_layer_norm_weights_;
  int forget_layer_norm_weights_;
  int cell_layer_norm_weights_;
  int output_layer_norm_weights_;

  int input_gate_bias_;
  int forget_gate_bias_;
  int cell_bias_;
  int output_gate_bias_;

  int projection_weights_;
  int projection_bias_;

  int output_state_;
  int cell_state_;

  int output_;

  int n_batch_;
  int n_input_;
  int n_cell_;
  int n_output_;
};

class HybridLayerNormLSTMOpModel : public LayerNormLSTMOpModel {
 public:
  HybridLayerNormLSTMOpModel(int n_batch, int n_input, int n_cell, int n_output,
                             bool use_cifg, bool use_peephole,
                             bool use_projection_weights,
                             bool use_projection_bias, float cell_clip,
                             float proj_clip,
                             const std::vector<std::vector<int>>& input_shapes)
      : LayerNormLSTMOpModel(n_batch, n_input, n_cell, n_output, use_cifg,
                             use_peephole, use_projection_weights,
                             use_projection_bias, cell_clip, proj_clip,
                             input_shapes, TensorType_UINT8) {}

  void SetInputToInputWeights(const std::vector<float>& f) {
    SymmetricQuantizeAndPopulate(input_to_input_weights_, f);
  }

  void SetInputToForgetWeights(const std::vector<float>& f) {
    SymmetricQuantizeAndPopulate(input_to_forget_weights_, f);
  }

  void SetInputToCellWeights(const std::vector<float>& f) {
    SymmetricQuantizeAndPopulate(input_to_cell_weights_, f);
  }

  void SetInputToOutputWeights(const std::vector<float>& f) {
    SymmetricQuantizeAndPopulate(input_to_output_weights_, f);
  }

  void SetRecurrentToInputWeights(const std::vector<float>& f) {
    SymmetricQuantizeAndPopulate(recurrent_to_input_weights_, f);
  }

  void SetRecurrentToForgetWeights(const std::vector<float>& f) {
    SymmetricQuantizeAndPopulate(recurrent_to_forget_weights_, f);
  }

  void SetRecurrentToCellWeights(const std::vector<float>& f) {
    SymmetricQuantizeAndPopulate(recurrent_to_cell_weights_, f);
  }

  void SetRecurrentToOutputWeights(const std::vector<float>& f) {
    SymmetricQuantizeAndPopulate(recurrent_to_output_weights_, f);
  }

  void SetCellToInputWeights(const std::vector<float>& f) {
    SymmetricQuantizeAndPopulate(cell_to_input_weights_, f);
  }

  void SetCellToForgetWeights(const std::vector<float>& f) {
    SymmetricQuantizeAndPopulate(cell_to_forget_weights_, f);
  }

  void SetCellToOutputWeights(const std::vector<float>& f) {
    SymmetricQuantizeAndPopulate(cell_to_output_weights_, f);
  }

  void SetInputLayerNormWeights(const std::vector<float>& f) {
    PopulateTensor(input_layer_norm_weights_, f);
  }

  void SetForgetLayerNormWeights(const std::vector<float>& f) {
    PopulateTensor(forget_layer_norm_weights_, f);
  }

  void SetCellLayerNormWeights(const std::vector<float>& f) {
    PopulateTensor(cell_layer_norm_weights_, f);
  }

  void SetOutputLayerNormWeights(const std::vector<float>& f) {
    PopulateTensor(output_layer_norm_weights_, f);
  }

  void SetProjectionWeights(const std::vector<float>& f) {
    SymmetricQuantizeAndPopulate(projection_weights_, f);
  }
};

class BaseLayerNormLstmTest : public ::testing::Test {
 protected:
  // Weights of the Layer Norm LSTM model. Some are optional.
  std::vector<float> input_to_input_weights_;
  std::vector<float> input_to_cell_weights_;
  std::vector<float> input_to_forget_weights_;
  std::vector<float> input_to_output_weights_;
  std::vector<float> input_gate_bias_;
  std::vector<float> cell_gate_bias_;
  std::vector<float> forget_gate_bias_;
  std::vector<float> output_gate_bias_;
  std::vector<float> recurrent_to_input_weights_;
  std::vector<float> recurrent_to_cell_weights_;
  std::vector<float> recurrent_to_forget_weights_;
  std::vector<float> recurrent_to_output_weights_;
  std::vector<float> cell_to_input_weights_;
  std::vector<float> cell_to_forget_weights_;
  std::vector<float> cell_to_output_weights_;
  std::vector<float> input_layer_norm_weights_;
  std::vector<float> forget_layer_norm_weights_;
  std::vector<float> cell_layer_norm_weights_;
  std::vector<float> output_layer_norm_weights_;
  std::vector<float> projection_weights_;

  // Layer Norm LSTM input is stored as num_batch x num_inputs vector.
  std::vector<std::vector<float>> layer_norm_lstm_input_;

  // Compares output up to tolerance to the result of the layer_norm_lstm given
  // the input.
  void VerifyGoldens(const std::vector<std::vector<float>>& input,
                     const std::vector<std::vector<float>>& output,
                     LayerNormLSTMOpModel* layer_norm_lstm,
                     float tolerance = 1e-5) {
    const int num_batches = input.size();
    EXPECT_GT(num_batches, 0);
    const int num_inputs = layer_norm_lstm->num_inputs();
    EXPECT_GT(num_inputs, 0);
    const int input_sequence_size = input[0].size() / num_inputs;
    EXPECT_GT(input_sequence_size, 0);
    for (int i = 0; i < input_sequence_size; ++i) {
      for (int b = 0; b < num_batches; ++b) {
        const float* batch_start = input[b].data() + i * num_inputs;
        const float* batch_end = batch_start + num_inputs;

        layer_norm_lstm->SetInput(b * layer_norm_lstm->num_inputs(),
                                  batch_start, batch_end);
      }

      layer_norm_lstm->Invoke();

      const int num_outputs = layer_norm_lstm->num_outputs();
      std::vector<float> expected;
      for (int b = 0; b < num_batches; ++b) {
        const float* golden_start_batch = output[b].data() + i * num_outputs;
        const float* golden_end_batch = golden_start_batch + num_outputs;
        expected.insert(expected.end(), golden_start_batch, golden_end_batch);
      }
      EXPECT_THAT(layer_norm_lstm->GetOutput(),
                  ElementsAreArray(ArrayFloatNear(expected, tolerance)));
    }
  }
};

class NoCifgPeepholeProjectionNoClippingLayerNormLstmTest
    : public BaseLayerNormLstmTest {
  void SetUp() override {
    input_to_input_weights_ = {0.5,  0.6,  0.7,  -0.8, -0.9, 0.1,  0.2,
                               0.3,  -0.4, 0.5,  -0.8, 0.7,  -0.6, 0.5,
                               -0.4, -0.5, -0.4, -0.3, -0.2, -0.1};

    input_to_forget_weights_ = {-0.6, -0.1, 0.3,  0.2,  0.9,  -0.5, -0.2,
                                -0.4, 0.3,  -0.8, -0.4, 0.3,  -0.5, -0.4,
                                -0.6, 0.3,  -0.4, -0.6, -0.5, -0.5};

    input_to_cell_weights_ = {-0.4, -0.3, -0.2, -0.1, -0.5, 0.5,  -0.2,
                              -0.3, -0.2, -0.6, 0.6,  -0.1, -0.4, -0.3,
                              -0.7, 0.7,  -0.9, -0.5, 0.8,  0.6};

    input_to_output_weights_ = {-0.8, -0.4, -0.2, -0.9, -0.1, -0.7, 0.3,
                                -0.3, -0.8, -0.2, 0.6,  -0.2, 0.4,  -0.7,
                                -0.3, -0.5, 0.1,  0.5,  -0.6, -0.4};

    input_gate_bias_ = {0.03, 0.15, 0.22, 0.38};

    forget_gate_bias_ = {0.1, -0.3, -0.2, 0.1};

    cell_gate_bias_ = {-0.05, 0.72, 0.25, 0.08};

    output_gate_bias_ = {0.05, -0.01, 0.2, 0.1};

    recurrent_to_input_weights_ = {-0.2, -0.3, 0.4,  0.1,  -0.5, 0.9,
                                   -0.2, -0.3, -0.7, 0.05, -0.2, -0.6};

    recurrent_to_cell_weights_ = {-0.3, 0.2, 0.1, -0.3, 0.8,  -0.08,
                                  -0.2, 0.3, 0.8, -0.6, -0.1, 0.2};

    recurrent_to_forget_weights_ = {-0.5, -0.3, -0.5, -0.2, 0.6, 0.4,
                                    0.9,  0.3,  -0.1, 0.2,  0.5, 0.2};

    recurrent_to_output_weights_ = {0.3,  -0.1, 0.1,  -0.2, -0.5, -0.7,
                                    -0.2, -0.6, -0.1, -0.4, -0.7, -0.2};

    cell_to_input_weights_ = {0.05, 0.1, 0.25, 0.15};

    cell_to_forget_weights_ = {-0.02, -0.15, -0.25, -0.03};

    cell_to_output_weights_ = {0.1, -0.1, -0.5, 0.05};

    input_layer_norm_weights_ = {0.1, 0.2, 0.3, 0.5};
    forget_layer_norm_weights_ = {0.2, 0.2, 0.4, 0.3};
    cell_layer_norm_weights_ = {0.7, 0.2, 0.3, 0.8};
    output_layer_norm_weights_ = {0.6, 0.2, 0.2, 0.5};

    projection_weights_ = {-0.1, 0.2,  0.01, -0.2, 0.1,  0.5,
                           0.3,  0.08, 0.07, 0.2,  -0.4, 0.2};

    layer_norm_lstm_input_ = {
        {// Batch0: 3 (input_sequence_size) * 5 (n_input)
         0.7, 0.8, 0.1, 0.2, 0.3,   // seq 0
         0.8, 0.1, 0.2, 0.4, 0.5,   // seq 1
         0.2, 0.7, 0.7, 0.1, 0.7},  // seq 2

        {// Batch1: 3 (input_sequence_size) * 5 (n_input)
         0.3, 0.2, 0.9, 0.8, 0.1,   // seq 0
         0.1, 0.5, 0.2, 0.4, 0.2,   // seq 1
         0.6, 0.9, 0.2, 0.5, 0.7},  // seq 2
    };
  }
};

TEST_F(NoCifgPeepholeProjectionNoClippingLayerNormLstmTest,
       LayerNormLstmBlackBoxTest) {
  const int n_batch = 2;
  const int n_input = 5;
  const int n_cell = 4;
  const int n_output = 3;
  const float ceil_clip = 0.0;
  const float proj_clip = 0.0;

  LayerNormLSTMOpModel layer_norm_lstm(
      n_batch, n_input, n_cell, n_output,
      /*use_cifg=*/false, /*use_peephole=*/true,
      /*use_projection_weights=*/true,
      /*use_projection_bias=*/false, ceil_clip, proj_clip,
      {
          {n_batch, n_input},  // input tensor

          {n_cell, n_input},  // input_to_input_weight tensor
          {n_cell, n_input},  // input_to_forget_weight tensor
          {n_cell, n_input},  // input_to_cell_weight tensor
          {n_cell, n_input},  // input_to_output_weight tensor

          {n_cell, n_output},  // recurrent_to_input_weight tensor
          {n_cell, n_output},  // recurrent_to_forget_weight tensor
          {n_cell, n_output},  // recurrent_to_cell_weight tensor
          {n_cell, n_output},  // recurrent_to_output_weight tensor

          {n_cell},  // cell_to_input_weight tensor
          {n_cell},  // cell_to_forget_weight tensor
          {n_cell},  // cell_to_output_weight tensor

          {n_cell},  // input_layer_norm_weight tensor
          {n_cell},  // forget_layer_norm_weight tensor
          {n_cell},  // cell_layer_norm_weight tensor
          {n_cell},  // output_layer_norm_weight tensor

          {n_cell},  // input_gate_bias tensor
          {n_cell},  // forget_gate_bias tensor
          {n_cell},  // cell_bias tensor
          {n_cell},  // output_gate_bias tensor

          {n_output, n_cell},  // projection_weight tensor
          {0},                 // projection_bias tensor
      });

  layer_norm_lstm.SetInputToInputWeights(input_to_input_weights_);
  layer_norm_lstm.SetInputToCellWeights(input_to_cell_weights_);
  layer_norm_lstm.SetInputToForgetWeights(input_to_forget_weights_);
  layer_norm_lstm.SetInputToOutputWeights(input_to_output_weights_);

  layer_norm_lstm.SetInputGateBias(input_gate_bias_);
  layer_norm_lstm.SetCellBias(cell_gate_bias_);
  layer_norm_lstm.SetForgetGateBias(forget_gate_bias_);
  layer_norm_lstm.SetOutputGateBias(output_gate_bias_);

  layer_norm_lstm.SetRecurrentToInputWeights(recurrent_to_input_weights_);
  layer_norm_lstm.SetRecurrentToCellWeights(recurrent_to_cell_weights_);
  layer_norm_lstm.SetRecurrentToForgetWeights(recurrent_to_forget_weights_);
  layer_norm_lstm.SetRecurrentToOutputWeights(recurrent_to_output_weights_);

  layer_norm_lstm.SetCellToInputWeights(cell_to_input_weights_);
  layer_norm_lstm.SetCellToForgetWeights(cell_to_forget_weights_);
  layer_norm_lstm.SetCellToOutputWeights(cell_to_output_weights_);

  layer_norm_lstm.SetInputLayerNormWeights(input_layer_norm_weights_);
  layer_norm_lstm.SetForgetLayerNormWeights(forget_layer_norm_weights_);
  layer_norm_lstm.SetCellLayerNormWeights(cell_layer_norm_weights_);
  layer_norm_lstm.SetOutputLayerNormWeights(output_layer_norm_weights_);

  layer_norm_lstm.SetProjectionWeights(projection_weights_);

  // Verify the final output.
  const std::vector<std::vector<float>> layer_norm_lstm_golden_output = {
      {
          // Batch0: 3 (input_sequence_size) * 3 (n_output)
          0.0244077, 0.128027, -0.00170918,  // seq 0
          0.0137642, 0.140751, 0.0395835,    // seq 1
          -0.00459231, 0.155278, 0.0837377,  // seq 2
      },
      {
          // Batch1: 3 (input_sequence_size) * 3 (n_output)
          -0.00692428, 0.0848741, 0.063445,  // seq 0
          -0.00403912, 0.139963, 0.072681,   // seq 1
          0.00752706, 0.161903, 0.0561371,   // seq 2
      }};

  VerifyGoldens(layer_norm_lstm_input_, layer_norm_lstm_golden_output,
                &layer_norm_lstm);
}

TEST_F(NoCifgPeepholeProjectionNoClippingLayerNormLstmTest,
       HybridLayerNormLstmBlackBoxTest) {
  const int n_batch = 2;
  const int n_input = 5;
  const int n_cell = 4;
  const int n_output = 3;
  const float ceil_clip = 0.0;
  const float proj_clip = 0.0;

  HybridLayerNormLSTMOpModel layer_norm_lstm(
      n_batch, n_input, n_cell, n_output,
      /*use_cifg=*/false, /*use_peephole=*/true,
      /*use_projection_weights=*/true,
      /*use_projection_bias=*/false, ceil_clip, proj_clip,
      {
          {n_batch, n_input},  // input tensor

          {n_cell, n_input},  // input_to_input_weight tensor
          {n_cell, n_input},  // input_to_forget_weight tensor
          {n_cell, n_input},  // input_to_cell_weight tensor
          {n_cell, n_input},  // input_to_output_weight tensor

          {n_cell, n_output},  // recurrent_to_input_weight tensor
          {n_cell, n_output},  // recurrent_to_forget_weight tensor
          {n_cell, n_output},  // recurrent_to_cell_weight tensor
          {n_cell, n_output},  // recurrent_to_output_weight tensor

          {n_cell},  // cell_to_input_weight tensor
          {n_cell},  // cell_to_forget_weight tensor
          {n_cell},  // cell_to_output_weight tensor

          {n_cell},  // input_layer_norm_weight tensor
          {n_cell},  // forget_layer_norm_weight tensor
          {n_cell},  // cell_layer_norm_weight tensor
          {n_cell},  // output_layer_norm_weight tensor

          {n_cell},  // input_gate_bias tensor
          {n_cell},  // forget_gate_bias tensor
          {n_cell},  // cell_bias tensor
          {n_cell},  // output_gate_bias tensor

          {n_output, n_cell},  // projection_weight tensor
          {0},                 // projection_bias tensor
      });

  layer_norm_lstm.SetInputToInputWeights(input_to_input_weights_);
  layer_norm_lstm.SetInputToCellWeights(input_to_cell_weights_);
  layer_norm_lstm.SetInputToForgetWeights(input_to_forget_weights_);
  layer_norm_lstm.SetInputToOutputWeights(input_to_output_weights_);

  layer_norm_lstm.SetInputGateBias(input_gate_bias_);
  layer_norm_lstm.SetCellBias(cell_gate_bias_);
  layer_norm_lstm.SetForgetGateBias(forget_gate_bias_);
  layer_norm_lstm.SetOutputGateBias(output_gate_bias_);

  layer_norm_lstm.SetRecurrentToInputWeights(recurrent_to_input_weights_);
  layer_norm_lstm.SetRecurrentToCellWeights(recurrent_to_cell_weights_);
  layer_norm_lstm.SetRecurrentToForgetWeights(recurrent_to_forget_weights_);
  layer_norm_lstm.SetRecurrentToOutputWeights(recurrent_to_output_weights_);

  layer_norm_lstm.SetCellToInputWeights(cell_to_input_weights_);
  layer_norm_lstm.SetCellToForgetWeights(cell_to_forget_weights_);
  layer_norm_lstm.SetCellToOutputWeights(cell_to_output_weights_);

  layer_norm_lstm.SetInputLayerNormWeights(input_layer_norm_weights_);
  layer_norm_lstm.SetForgetLayerNormWeights(forget_layer_norm_weights_);
  layer_norm_lstm.SetCellLayerNormWeights(cell_layer_norm_weights_);
  layer_norm_lstm.SetOutputLayerNormWeights(output_layer_norm_weights_);

  layer_norm_lstm.SetProjectionWeights(projection_weights_);

  const std::vector<std::vector<float>> layer_norm_lstm_golden_output = {
      {
          // Batch0: 3 (input_sequence_size) * 3 (n_output)
          0.0244576, 0.127847, -0.00181765,  // seq 0
          0.0137518, 0.140892, 0.0402234,    // seq 1
          -0.0048839, 0.155096, 0.0840309,   // seq 2
      },
      {
          // Batch1: 3 (input_sequence_size) * 3 (n_output)
          -0.00728636, 0.0843957, 0.0634786,  // seq 0
          -0.00448382, 0.139278, 0.0737372,   // seq 1
          0.00734616, 0.161793, 0.0560238,    // seq 2
      }};

  VerifyGoldens(layer_norm_lstm_input_, layer_norm_lstm_golden_output,
                &layer_norm_lstm);
}

class CifgPeepholeProjectionNoClippingLayerNormLstmTest
    : public BaseLayerNormLstmTest {
  void SetUp() override {
    input_to_forget_weights_ = {-0.6, -0.1, 0.3,  0.2,  0.9,  -0.5, -0.2,
                                -0.4, 0.3,  -0.8, -0.4, 0.3,  -0.5, -0.4,
                                -0.6, 0.3,  -0.4, -0.6, -0.5, -0.5};
    input_to_cell_weights_ = {-0.4, -0.3, -0.2, -0.1, -0.5, 0.5,  -0.2,
                              -0.3, -0.2, -0.6, 0.6,  -0.1, -0.4, -0.3,
                              -0.7, 0.7,  -0.9, -0.5, 0.8,  0.6};
    input_to_output_weights_ = {-0.8, -0.4, -0.2, -0.9, -0.1, -0.7, 0.3,
                                -0.3, -0.8, -0.2, 0.6,  -0.2, 0.4,  -0.7,
                                -0.3, -0.5, 0.1,  0.5,  -0.6, -0.4};

    forget_gate_bias_ = {0.1, -0.3, -0.2, 0.1};
    cell_gate_bias_ = {-0.05, 0.72, 0.25, 0.08};
    output_gate_bias_ = {0.05, -0.01, 0.2, 0.1};

    recurrent_to_cell_weights_ = {-0.3, 0.2, 0.1, -0.3, 0.8,  -0.08,
                                  -0.2, 0.3, 0.8, -0.6, -0.1, 0.2};
    recurrent_to_forget_weights_ = {-0.5, -0.3, -0.5, -0.2, 0.6, 0.4,
                                    0.9,  0.3,  -0.1, 0.2,  0.5, 0.2};
    recurrent_to_output_weights_ = {0.3,  -0.1, 0.1,  -0.2, -0.5, -0.7,
                                    -0.2, -0.6, -0.1, -0.4, -0.7, -0.2};

    cell_to_forget_weights_ = {-0.02, -0.15, -0.25, -0.03};
    cell_to_output_weights_ = {0.1, -0.1, -0.5, 0.05};

    forget_layer_norm_weights_ = {0.2, 0.2, 0.4, 0.3};
    cell_layer_norm_weights_ = {0.7, 0.2, 0.3, 0.8};
    output_layer_norm_weights_ = {0.6, 0.2, 0.2, 0.5};
    projection_weights_ = {-0.1, 0.2,  0.01, -0.2, 0.1,  0.5,
                           0.3,  0.08, 0.07, 0.2,  -0.4, 0.2};

    layer_norm_lstm_input_ = {
        {// Batch0: 3 (input_sequence_size) * 5 (n_input)
         0.7, 0.8, 0.1, 0.2, 0.3,   // seq 0
         0.8, 0.1, 0.2, 0.4, 0.5,   // seq 1
         0.2, 0.7, 0.7, 0.1, 0.7},  // seq 2

        {// Batch1: 3 (input_sequence_size) * 5 (n_input)
         0.3, 0.2, 0.9, 0.8, 0.1,   // seq 0
         0.1, 0.5, 0.2, 0.4, 0.2,   // seq 1
         0.6, 0.9, 0.2, 0.5, 0.7},  // seq 2
    };
  }
};

TEST_F(CifgPeepholeProjectionNoClippingLayerNormLstmTest,
       LayerNormLstmBlackBoxTest) {
  const int n_batch = 2;
  const int n_input = 5;
  const int n_cell = 4;
  const int n_output = 3;
  const float ceil_clip = 0.0;
  const float proj_clip = 0.0;

  LayerNormLSTMOpModel layer_norm_lstm(
      n_batch, n_input, n_cell, n_output,
      /*use_cifg=*/true, /*use_peephole=*/true,
      /*use_projection_weights=*/true,
      /*use_projection_bias=*/false, ceil_clip, proj_clip,
      {
          {n_batch, n_input},  // input tensor

          {0, 0},             // input_to_input_weight tensor
          {n_cell, n_input},  // input_to_forget_weight tensor
          {n_cell, n_input},  // input_to_cell_weight tensor
          {n_cell, n_input},  // input_to_output_weight tensor

          {0, 0},              // recurrent_to_input_weight tensor
          {n_cell, n_output},  // recurrent_to_forget_weight tensor
          {n_cell, n_output},  // recurrent_to_cell_weight tensor
          {n_cell, n_output},  // recurrent_to_output_weight tensor

          {0},       // cell_to_input_weight tensor
          {n_cell},  // cell_to_forget_weight tensor
          {n_cell},  // cell_to_output_weight tensor

          {0},       // input_layer_norm_weight tensor
          {n_cell},  // forget_layer_norm_weight tensor
          {n_cell},  // cell_layer_norm_weight tensor
          {n_cell},  // output_layer_norm_weight tensor

          {0},       // input_gate_bias tensor
          {n_cell},  // forget_gate_bias tensor
          {n_cell},  // cell_bias tensor
          {n_cell},  // output_gate_bias tensor

          {n_output, n_cell},  // projection_weight tensor
          {0},                 // projection_bias tensor
      });

  layer_norm_lstm.SetInputToCellWeights(input_to_cell_weights_);
  layer_norm_lstm.SetInputToForgetWeights(input_to_forget_weights_);
  layer_norm_lstm.SetInputToOutputWeights(input_to_output_weights_);

  layer_norm_lstm.SetCellBias(cell_gate_bias_);
  layer_norm_lstm.SetForgetGateBias(forget_gate_bias_);
  layer_norm_lstm.SetOutputGateBias(output_gate_bias_);

  layer_norm_lstm.SetRecurrentToCellWeights(recurrent_to_cell_weights_);
  layer_norm_lstm.SetRecurrentToForgetWeights(recurrent_to_forget_weights_);
  layer_norm_lstm.SetRecurrentToOutputWeights(recurrent_to_output_weights_);

  layer_norm_lstm.SetCellToForgetWeights(cell_to_forget_weights_);
  layer_norm_lstm.SetCellToOutputWeights(cell_to_output_weights_);

  layer_norm_lstm.SetForgetLayerNormWeights(forget_layer_norm_weights_);
  layer_norm_lstm.SetCellLayerNormWeights(cell_layer_norm_weights_);
  layer_norm_lstm.SetOutputLayerNormWeights(output_layer_norm_weights_);

  layer_norm_lstm.SetProjectionWeights(projection_weights_);

  // Verify the final output.
  const std::vector<std::vector<float>> layer_norm_lstm_golden_output = {
      {
          // Batch0: 3 (input_sequence_size) * 3 (n_output)
          0.02129706, 0.140816242, 0.0112733059,     // seq 0
          0.0132302344, 0.152308047, 0.0346313119,   // seq 1
          -0.0123688057, 0.165790111, 0.0893077999,  // seq 2
      },
      {
          // Batch1: 3 (input_sequence_size) * 3 (n_output)
          -0.0226350538, 0.0916948169, 0.0769175813,  // seq 0
          -0.0269966982, 0.149707705, 0.094149217,    // seq 1
          -0.0103429332, 0.173016444, 0.0720508844,   // seq 2
      }};

  VerifyGoldens(layer_norm_lstm_input_, layer_norm_lstm_golden_output,
                &layer_norm_lstm);
}

TEST_F(CifgPeepholeProjectionNoClippingLayerNormLstmTest,
       HybridLayerNormLstmBlackBoxTest) {
  const int n_batch = 2;
  const int n_input = 5;
  const int n_cell = 4;
  const int n_output = 3;
  const float ceil_clip = 0.0;
  const float proj_clip = 0.0;

  HybridLayerNormLSTMOpModel layer_norm_lstm(
      n_batch, n_input, n_cell, n_output,
      /*use_cifg=*/true, /*use_peephole=*/true,
      /*use_projection_weights=*/true,
      /*use_projection_bias=*/false, ceil_clip, proj_clip,
      {
          {n_batch, n_input},  // input tensor

          {0, 0},             // input_to_input_weight tensor
          {n_cell, n_input},  // input_to_forget_weight tensor
          {n_cell, n_input},  // input_to_cell_weight tensor
          {n_cell, n_input},  // input_to_output_weight tensor

          {0, 0},              // recurrent_to_input_weight tensor
          {n_cell, n_output},  // recurrent_to_forget_weight tensor
          {n_cell, n_output},  // recurrent_to_cell_weight tensor
          {n_cell, n_output},  // recurrent_to_output_weight tensor

          {0},       // cell_to_input_weight tensor
          {n_cell},  // cell_to_forget_weight tensor
          {n_cell},  // cell_to_output_weight tensor

          {0},       // input_layer_norm_weight tensor
          {n_cell},  // forget_layer_norm_weight tensor
          {n_cell},  // cell_layer_norm_weight tensor
          {n_cell},  // output_layer_norm_weight tensor

          {0},       // input_gate_bias tensor
          {n_cell},  // forget_gate_bias tensor
          {n_cell},  // cell_bias tensor
          {n_cell},  // output_gate_bias tensor

          {n_output, n_cell},  // projection_weight tensor
          {0},                 // projection_bias tensor
      });

  layer_norm_lstm.SetInputToCellWeights(input_to_cell_weights_);
  layer_norm_lstm.SetInputToForgetWeights(input_to_forget_weights_);
  layer_norm_lstm.SetInputToOutputWeights(input_to_output_weights_);

  layer_norm_lstm.SetCellBias(cell_gate_bias_);
  layer_norm_lstm.SetForgetGateBias(forget_gate_bias_);
  layer_norm_lstm.SetOutputGateBias(output_gate_bias_);

  layer_norm_lstm.SetRecurrentToCellWeights(recurrent_to_cell_weights_);
  layer_norm_lstm.SetRecurrentToForgetWeights(recurrent_to_forget_weights_);
  layer_norm_lstm.SetRecurrentToOutputWeights(recurrent_to_output_weights_);

  layer_norm_lstm.SetCellToForgetWeights(cell_to_forget_weights_);
  layer_norm_lstm.SetCellToOutputWeights(cell_to_output_weights_);

  layer_norm_lstm.SetForgetLayerNormWeights(forget_layer_norm_weights_);
  layer_norm_lstm.SetCellLayerNormWeights(cell_layer_norm_weights_);
  layer_norm_lstm.SetOutputLayerNormWeights(output_layer_norm_weights_);

  layer_norm_lstm.SetProjectionWeights(projection_weights_);

  // Verify the final output.
  const std::vector<std::vector<float>> layer_norm_lstm_golden_output = {
      {
          // Batch0: 3 (input_sequence_size) * 3 (n_output)
          0.0212250091, 0.140474007, 0.0115012666,   // seq 0
          0.0130806509, 0.152660668, 0.0347516984,   // seq 1
          -0.0124010444, 0.166042402, 0.0898982584,  // seq 2
      },
      {
          // Batch1: 3 (input_sequence_size) * 3 (n_output)
          -0.0228835996, 0.0917588323, 0.0778886303,  // seq 0
          -0.0275101066, 0.148769245, 0.0938384682,   // seq 1
          -0.0103605557, 0.172605693, 0.0728750974,   // seq 2
      }};

  VerifyGoldens(layer_norm_lstm_input_, layer_norm_lstm_golden_output,
                &layer_norm_lstm);
}

}  // namespace
}  // namespace custom
}  // namespace ops
}  // namespace tflite

int main(int argc, char** argv) {
  ::tflite::LogToStderr();
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

redpajama_set_name: RedPajamaGithub


text:
//  Created by Dmitry Markushevich (dmitrym@evidentpoint.com)
//
//  Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without modification,
//  are permitted provided that the following conditions are met:
//  1. Redistributions of source code must retain the above copyright notice, this
//  list of conditions and the following disclaimer.
//  2. Redistributions in binary form must reproduce the above copyright notice,
//  this list of conditions and the following disclaimer in the documentation and/or
//  other materials provided with the distribution.
//  3. Neither the name of the organization nor the names of its contributors may be
//  used to endorse or promote products derived from this software without specific
//  prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
//  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
//  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
//  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
//  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
//  OF THE POSSIBILITY OF SUCH DAMAGE.

/*

# Highlighting in Readium - A primer

Please note:

- only simple text highlighting is currently supported
- it's the job of the reading system to keep track of annotations. readium-js simply displays your annotations.
- full CFIs for annotations are not currently available. We use so called "partial CFI"s, a tuple containing idref of the spine item and the CFI definition relative to the root of the spine item.

Currently, the API exposed via `ReaderView` exposes 4 functions and 1 even which should be sufficient for a simple highlighting workflow.

# API

For the purposes of the examples below, `RReader` is a previously instantiated `ReaderView` instance.

## Is anything selected (getCurrentSelectionCfi())

Before proceeding with the highlighting workflow it is sometimes necessary to determine whether the user has in fact selected anything. This can be accomplished with the following:

    > RReader.getCurrentSelectionCfi()
    Object {idref: "id-id2604743", cfi: "/4/2/6,/1:74,/1:129"}

The response contains a partial CFI that is sufficient to create a highlight based on selection. If nothing is selected *undefined* is returned.

You can also use partial Cfi with `openSpineItemElementCfi()` to navigate to where this selection is later.

## Highlighting (addHighlight and addSelectionHighlight)

Once we've determined what needs to be highlighted (by generating a partial CFI from a selection, or having an existing partial CFI stored externally) we can add it to the reader by calling `addHighlight()`:

    > RReader.addHighlight('id-id2604743', "/4/2/6,/1:74,/1:129", 123, "highlight")
    Object {CFI: "/4/2/6,/1:74,/1:129", selectedElements: Array[1], idref: "id-id2604743"}

*addHighligh*t takes the following parameters:

- *id-id2604743* - `idref` is the idref value from `getCurrentSelectionCfi()
- * /4/2/6,/1:74,/1:129* - `cfi` is the cfi value from `getCurrentSelectionCfi()
- *123* - `id` is the unique id that defines this annotation
- *highlight* - 'type' of annotation. only 'highlight' is currently supported.

### addSelectioHighlight

Alternatively, you can call addSelectionHighlight(). It combines both getCurrentSelectionCfi() and addHighlight into one call:

    > RReader.addSelectionHighlight(124, "highlight")
    Object {CFI: "/4/2/4,/1:437,/1:503", selectedElements: Array[1], idref: "id-id2604743"}

Note that it provides no validation. If nothing is selected, `undefined` is returned.

## Removing highlights

To remove the highlight, call `removeHighlight`:

    > RReader.removeHighlight(123)
    undefined

# Handling annotation click events

When a user clicks on a highlight `annotationClicked` event is dispatched with the following arguments:

- type of annotation
- idref of the spine item
- partial Cfi of the annotation
- annotationdId

    > RReader.on('annotationClicked', function(type, idref, cfi, annotationId) { console.log (type, idref, cfi, annotationId)});
    Views.ReaderView {on: function, once: function, off: function, trigger: function, listenTo: function???}

Then when the user clicks on the highlight the following will show up in the console:

    highlight id-id2604743 /4/2/6,/1:74,/1:129 123

*/
define(['jquery', 'underscore', 'eventEmitter', './annotations_module'], function($, _, EventEmitter, EpubAnnotationsModule) {
/**
 *
 * @param proxyObj
 * @param options
 * @constructor
 */
var AnnotationsManager = function (proxyObj, options) {

    var self = this;
    var liveAnnotations = {};
    var spines = {};
    var proxy = proxyObj;
    var annotationCSSUrl = options.annotationCSSUrl;

    if (!annotationCSSUrl) {
        console.warn("WARNING! Annotations CSS not supplied. Highlighting is not going to work.");
    }

    $.extend(this, new EventEmitter());

    // we want to bubble up all of the events that annotations module may trigger up.
    // this.on("all", function() {
    // });
    //TODO: EventEmitter3 does not support "all" or "*" (catch-all event sink)
    //https://github.com/primus/eventemitter3/blob/master/index.js#L61
    //...so instead we patch trigger() and emit() (which are synonymous, see Bootstrapper.js EventEmitter.prototype.trigger = EventEmitter.prototype.emit;)

    var originalEmit = self['emit'];

    var triggerEmitPatch = function() {
        var args = Array.prototype.slice.call(arguments);
console.debug(args);

        // mangle annotationClicked event. What really needs to happen is, the annotation_module needs to return a
        // bare Cfi, and this class should append the idref.
        var annotationClickedEvent = 'annotationClicked';
        if (args.length && args[0] === annotationClickedEvent) {
            for (var spineIndex in liveAnnotations)
            {
                var jQueryEvent = args[4];
                var annotationId = args[3];
                var fullFakeCfi = args[2];
                var type = args[1];
                if (liveAnnotations[spineIndex].getHighlight(annotationId)) {
                    var idref = spines[spineIndex].idref;
                    var partialCfi = getPartialCfi(fullFakeCfi);
                    args = [annotationClickedEvent, type, idref, partialCfi, annotationId, jQueryEvent];

console.debug("Corrected CFI:");
console.debug(args);
                }
            }
        }

        originalEmit.apply(this, args);
        originalEmit.apply(proxy, args);
    };

    this.trigger = triggerEmitPatch;
    this.emit = triggerEmitPatch;

    this.attachAnnotations = function($iframe, spineItem) {
        var epubDocument = $iframe[0].contentDocument;
        liveAnnotations[spineItem.index] = new EpubAnnotationsModule(epubDocument, self, annotationCSSUrl);
        spines[spineItem.index] = spineItem;

        // check to see which spine indecies can be culled depending on the distance from current spine item
        for(var spineIndex in liveAnnotations) {
            if (Math.abs(spineIndex - spineIndex.index) > 3) {
                delete liveAnnotations[spineIndex];
            }
        }
    };

    this.getCurrentSelectionCfi = function() {
        for(var spine in liveAnnotations) {
            var annotationsForView = liveAnnotations[spine];
            var partialCfi = annotationsForView.getCurrentSelectionCFI();
            if (partialCfi) {
                return {"idref":spines[spine].idref, "cfi":partialCfi};
            }
        }
        return undefined;
    };

    this.addSelectionHighlight = function(id, type) {
        for(spine in liveAnnotations) {
            var annotationsForView = liveAnnotations[spine];
            if (annotationsForView.getCurrentSelectionCFI()) {
                var annotation = annotationsForView.addSelectionHighlight(id, type);
                annotation.idref = spines[spine].idref;
                return annotation;
            }
        }
        return undefined;
    };

    this.addHighlight = function(spineIdRef, partialCfi, id, type, styles) {
        for(var spine in liveAnnotations) {
            if (spines[spine].idref === spineIdRef) {
                var fakeCfi = "epubcfi(/99!" + partialCfi + ")";
                var annotationsForView = liveAnnotations[spine];
                var annotation = annotationsForView.addHighlight(fakeCfi, id, type, styles);
                annotation.idref = spineIdRef;
                annotation.CFI = getPartialCfi(annotation.CFI);
                return annotation;
            }
        }
        return undefined;
    };

    this.removeHighlight = function(id) {
        var result = undefined;
        for(var spine in liveAnnotations) {
            var annotationsForView = liveAnnotations[spine];
            result  = annotationsForView.removeHighlight(id);
        }
        return result;
    };

    function getPartialCfi(CFI) {
        var cfiWrapperPattern = new RegExp("^.*!")
        // remove epubcfi( and indirection step
        var partiallyNakedCfi = CFI.replace(cfiWrapperPattern, "");
        // remove last paren
        var nakedCfi = partiallyNakedCfi.substring(0, partiallyNakedCfi.length -1);
        return nakedCfi;
    }

};

return AnnotationsManager;
});


This summer we are one of the lucky food trucks that get to visit the patio at Parkside Brewery!
Parkside is Port Moody's newest craft brewery, and if you've been in that area recently you've surely noticed their vibrant branding and jam packed family friendly patio!
To find out when you can find us at Parkside Brewery and other public sales events around the lower mainland or to sign up for our location based updates, visit our homepage.
To see the full Food Truck schedule at the Parkside Brewery visit their new site.
If you would like to book our Taco Truck for your special event, you can send us a contact form with your event details.
We are great at keeping secrets! Don't believe us? Ask the birthday guy who had his surprise birthday party last weekend in White Rock and wasn't aware of anything! We love being the catering service in birthday parties, and we enjoy them, even more, when everything's a surprise and the birthday boy or girl hasn't got a clue of what's going to happen!


text:
» News And Events 4
KRING & CHUNG LAWYERS NAMED TO 2015 SOUTHERN CALIFORNIA SUPER LAWYERS LIST
Kring & Chung, LLP is please to announce that Kenneth W. Chung and Laura C. Hess have once again been named to the Southern California Super Lawyers list. This is the fifth consecutive year Kenneth Chung has received this honor, and the second consecutive year for Laura Hess. Super Lawyers is a rating service of outstanding lawyers from various practice areas who have attained a high-degree of peer recognition and professional achievement.
A patented multiphased selection process includes independent research, peer nominations and peer evaluations. Each candidate is evaluated on 12 indicators of peer recognition and professional achievement. Selections are made on an annual, state-by-state basis with no more than 5% of the attorneys in California being selected as Super Lawyers.
INLAND EMPIRE MANUFACTURERS' SUMMIT
Kring & Chung, LLP, is a bronze sponsor at the Manufacturers' Summit taking place on February 19, 2015 at the Riverside Convention Center. Partners' Laura C. Hess of our Irvine, CA office will be on hand highlighting some of our key offerings for manufacturers in the areas of employment and business law. The Manufacturers' Counsel of the Inland Empire supports and provides education on manufacturing topics to manufacturers, employees and the community. The summit gives attendees the opportunity to discuss solutions to many issues facing the manufacturing community. If you are attending this very informative summit, please stop by the Kring & Chung booth.
MICHELLE PHILO ELECTED AS OCBA YOUNG LAWYER'S DIVISION CHAIR-ELECT
Michelle Philo has been elected as the Orange County Bar Association Young Lawyer's Division Chair-Elect. The Young Lawyer's Division represents over 800 of Orange County's young lawyers with up to 5 years' experience in the profession. When Philo rises to the position of Chair in 2016, she will serve as the voice of the Young Lawyer's Division to the Orange County Bar Association's Board of Directors.
Ms. Philo is an attorney in our Irvine, CA office. Her practice includes general civil litigation; business transactions, including formations, maintenance, mergers, dissolutions; estate planning and probate. Philo's litigation cases have included partnership disputes, contract disputes, employment disputes, and personal injury cases. To view Philo's full profile, click here.
MELISSA BRIGHT JOINS KRING & CHUNG'S LAS VEGAS OFFICE
Kring & Chung, LLP would like to welcome Melissa Bright to its Las Vegas, Nevada office. Bright graduated from the University of Nevada, Las Vegas where she majored in criminal justice and minored in sociology. She received her Juris Doctorate degree in 2011 from University of Nevada, Las Vegas, William S. Boyd School of Law. Bright's practice consists of employment law, personal injury and business litigation.
KRING & CHUNG 6TH ANNUAL THANKSGIVING FOOD DRIVE
In collaborative efforts with Families Forward, Kring & Chung will be preparing 20 food baskets for families to celebrate Thanksgiving. Each year, Families Forward holds a Thanksgiving-themed grocery distribution for local families in need. The weekend before Thanksgiving, local families come to Families Forward to receive all of the traditional Thanksgiving fixings to cook a warm, holiday meal. While parents pick up their baskets, their children participate in fun-filled activities such as arts and crafts, and face painting.
Families Forward relies on the generous support from the local community to fill the needs of the families they serve during this busy time of year. Last year they provided 700 families with food needed to celebrate Thanksgiving. Click here (http://www.families-forward.org) for more information about Families Forward.
Items needed include: 20-$20 gift cards for turkey or produce; 40 boxes of stuffing; 40 jars of gravy; 40 cans of cranberry sauce; 40 boxes of muffin or corn bread mix; 40 cans of sweet potatoes or yams; 40 cans of soup (1 broth & 1 cream); 80 cans of vegetables; 60 cans of fruit; 40 cans of evaporated milk; 40 cans of pumpkin or other pie filling; and 20 boxed pie crust.
Items can be dropped off at our Irvine office located at 38 Corporate Park, Irvine, CA 92606.
Please contact Michelle Bennett at [email protected] if you have any questions. Thank you for your support.

redpajama_set_name: RedPajamaCommonCrawl


Mövenpick Hotel & Residences Nairobi is situated in the popular Westlands District, approximately 20 kilometres from Jomo Kenyatta International Airport. It is the perfect base to explore Kenya's capital while staying for business or leisure in 276 spacious rooms, suites and residences.
The rates quoted are subject to availability at the time of booking and will be allocated on a first-come, first-served basis.


Written by Dr. Marvin Anderson, a physician with over 10 year's experience caring for children with this calamity – summarizes the problem and solution to the epidemic of autism that is spreading throughout the world.
Chapter One describes each person's biochemical individuality and stresses how attention to this must shape medical management strategies.
Chapter Two decries the "one-size-fits-all" approach to childhood vaccinations and provides sensible alternatives to the immunization problem.
Chapter Three investigates intestinal health in children with autism and covers relevant testing and care measures.
Chapter Four identifies toxic agents in our air, water, food, and environment that lurk behind the high autism rate and advises parents how to keep themselves and their children healthy in our contaminated world.
Chapter Five discusses the benefits keeping domestic animals can have on autistic children and discloses other advantages animals confer to families.
Chapter Six provides a novel approach to autism's prevention by showing that the liver can become congested from contaminants, chemicals and drugs rendering it unable to tolerate a vaccination load.The chapter refers to proven methods and techniques developed by a well-known Australian physician to help persons of all ages regain liver health, thereby enabling our vulnerable children to avoid what this author considers to be the cause of this horrible epidemic raging worldwide.


text:
1 Table of contents 2 84
Baker Academic Fall 2021 Catalog
A C A D E M I C C ATA L O G Fall 2021
PRACTICAL THEOLOGY, SPIRITUALITY, and FORMATION ....... 54
THEOLOGY, HISTORY, and ETHICS . .................. 1
ALSO OF INTEREST to PROFESSORS from BRAZOS PRESS . ....... 70
BIBLE and INTERPRETATION . ... 22
If you are a professor seriously considering a textbook for a class, request a free exam copy at bit.ly/examcopy2021 .
INTERCULTURAL STUDIES ...................... 50
*See page 77 for exam copy terms and conditions
BAKER ACADEMIC & BRAZOS PRESS CONTACTS
Jim Kinney Executive Vice President, Academic Publishing jkinney@bakerpublishinggroup.com Robert N. Hosack Executive Editor rhosack@bakerpublishinggroup.com R. David Nelson Senior Acquisitions Editor dnelson@bakerpublishinggroup.com Bryan R. Dyer Senior Acquisitions Editor bdyer@bakerpublishinggroup.com Katelyn Beaty
Mason Slater Academic Sales Manager mslater@bakerpublishinggroup.com Jeremy Wells Senior Director of Marketing jwells@bakerpublishinggroup.com Sarah Gombis
bakeracademic.com brazospress.com
View our complete list and indexes online at bit.ly/BAfall21catalog
Marketing Manager, Baker Academic sgombis@bakerpublishinggroup.com Shelly MacNaughton Senior Publicist smacnaughton@bakerpublishinggroup.com
Cover image: Clickalps SRLs/age fotostock/Superstock
Acquisitions Editor, Brazos Press kbeaty@bakerpublishinggroup.com
THEOLOGY, HISTORY, and ETHICS
TRADITION AND APOCALYPSE An Essay on the Future of Christian Belief David Bentley Hart
In this carefully argued essay, David Bentley Hart critiques the concept of "tradition" that has become dominant in Christian thought as fundamentally incoherent. He puts forth a convincing new explanation of Christian tradition, one that is obedient to the nature of Christianity not only as a "revealed" creed embodied in historical events but as the "apocalyptic" revelation of a history that is largely identical with the eternal truth it supposedly dis- closes. Hart shows that Christian tradition is sustained not simply by its preservation of the past, but more essentially by its antici- pation of the future. He offers a compelling portrayal of a living tradition held together by apocalyptic expectation—the promised transformation of all things in God. DAVID BENTLEY HART (DPhil, University of Virginia) has taught at the University of Virginia, the University of St. Thomas, Loyola College in Maryland, Providence College, and Saint Louis University. In 2015, he was granted a Templeton Fellowship at the University of Notre Dame Institute for Advanced Study. Hart has written numerous books, including The Beauty of the Infinite , The New Testament: A Translation , Atheist Delusions (winner of the Michael Ramsey Prize in Theology), Theological Territories: A David Bentley Hart Digest , and That All Shall Be Saved . FROM THE BOOK It seems clear to me that the concept of "tradition" in the theolog- ical sense, however lucid and cogent it might appear to the eyes of faith, is incorrigibly obscure and incoherent. This, I would argue, is true not only of the vague, popular version of that con- cept that a good many believers harbor but rarely think about. It is true also of the version that many (perhaps most) Christian theologians have tended consciously to adopt since the publica- tion in 1845 of the first edition of John Henry Newman's Essay on the Development of Christian Doctrine , which more or less set the agenda for discussion of the topic, and to which no alternative account of any very great significance has yet been proposed. . . .
FEBRUARY 2022 • 208 pp. • cloth • $24.99 • 9780801039386
The general neglect of the topic leaves a fairly enormous unre- solved question in Christian thought lying quite conspicuously and troublingly open. When we speak of "Christian tradition," what are we really talking about? Can we really prove the exis- tence of—and then in fact identify—a particular living, contin- uous, and internally coherent phenomenon that corresponds to that phrase, or will any attempt to do so find evidence only of a product of pure historical fortuity, consisting in a mere mechan- ically determined series of consecutive viable forms united more by evolutionary imperatives than by internal rationality?
Request your free exam copies at bit.ly/examcopy2021
A THEOLOGY OF THE CHRISTIAN LIFE Imitating and Participating in God Christopher R. J. Holmes What does Scripture say about the manner of God's being? And what kind of life resembles the one God? In this book, theologian Christopher Holmes encourages readers to be more deeply captivated by the Bible's witness to God. He gets at the heart of the Christian life by considering some of the great truths of God's existence. Holmes engages with the church fathers along with Augustine and Aquinas to offer a rich, accessible account of the triune God and the divine perfections. He unfolds a program of spiritual renewal founded on the essential attributes of God, showing how we share in the life of God through imitation and participation and how the doctrines of the triune God and the divine attributes shape our understanding of the Christian life. Throughout, Holmes demon- strates the importance of theology for Christian faith and practice. A Theology of the Christian Life will appeal to professors and stu- dents of Christian theology as well as pastors and church leaders.
CHRISTOPHER R. J. HOLMES (ThD, Wycliffe College, University of Toronto) is associate professor in systematic theology and head of the theology program at the University of Otago in New Zealand. He is the author of a number of books, including The Holy Spirit and The Lord Is Good .
SEPTEMBER 2021 • 192 pp. • paper • $24.99 • 9781540964694
"It would not have occurred to the theologians of Christian antiquity or even those of the High Middle Ages that metaphysics, doctrine, and the spiritual life were discrete disciplines. Today, alas, we can scarcely imagine them as anything else. The great liberating force of Holmes's book is its relentless dedication to restoring a unity that believers should never have put asunder." —DAVID BENTLEY HART, author of Roland in Moonlight and Tradition and Apocalypse "This book undertakes the counterintuitive task of show- ing how those attributes of God that distinguish Creator from creature are at the same time to be imitated by us. In doing so, it brings austere aspects of the doctrine of God alive in their spiritually transformative implications." —SUSANNAH TICCIATI, King's College London "A magnificently theological reflection on Christian existence. Dogmatic and spiritual theology are wedded here in an incomparable contemporary fashion that calls
PART 1 1.	The Existence of God and the Christian Life 2.	The Manner of God's Existence and the Christian Life 3.	Perfection and the Christian Life 4.	Infinity and the Christian Life 5.	Immutability and the Christian Life PART 2 6.	The Hypostatic Union and the Christian Life
7.	Virtue and the Christian Life 8.	Church and the Christian Life Conclusion Indexes
for the urgent attention of every Christian." —EPHRAIM RADNER, Wycliffe College
Faculty can use code BAFA21 to receive a 40% discount at BakerBookHouse.com. Offer expires December 31, 2021.
WHY GOD MAKES SENSE IN A WORLD THAT DOESN'T The Beauty of Christian Theism Gavin Ortlund
This winsome apologetics book for a new generation makes the case that Christianity offers a compelling explanatory framework for making sense of our world. Gavin Ortlund believes it is essen- tial to appeal not only to the mind but also to the heart and the imagination as we articulate the beauty of the gospel. Why God Makes Sense in a World That Doesn't reimagines four classical theistic arguments—cosmological, teleological, moral, and Christological—making a cumulative case for God as the best framework for understanding the storied nature of reality. The book suggests that Christian theism can explain such things as the elegance of math, the beauty of music, and the value of love. It is suitable for use in classes yet accessibly written, making it a perfect resource for churches and small groups.
GAVIN ORTLUND (PhD, Fuller Theological Seminary) is a scholar, pastor, and writer. He serves as senior pastor of First Baptist Church of Ojai in Ojai, California, and is the author of a number of books, including Retrieving Augustine's Doctrine of Creation , Theological Retrieval for Evangelicals , and Finding the Right Hills to Die On: The Case for Theological Triage . He blogs at gavinortlund.com.
OCTOBER 2021 • 240 pp. • paper • $22.99 • 9781540964090
FROM THE BOOK This book is about the knowledge of God, who, if he exists, is to us something like what Shakespeare is to Hamlet. For instance, if God is real, he will be both infinitely close and infinitely far. He is infinitely close because reality itself abides within him; each breath we breathe is a gift from him. As Augustine put it, God is closer to us than we are to ourselves. He is infinitely far because he is qualitatively different than anything we have ever known; he surpasses us constantly at every level; for all eternity we could search him out and still always have infinitely more to discover. As Job observed, "How faint the whisper we hear of him!" (Job 26:14 NIV).
"An approach to apologetics that is much needed today. Ortlund makes an argument for God that is as rigorous as it is beautiful and is as convincing as it is compelling." —KAREN SWALLOW PRIOR, Southeastern Baptist Theological Seminary; author of On Reading Well "In a few short years, Ortlund has become one of the world's leading Christian scholars. This book delivers on its pledge to be both scholarly and inspiring." —MATTHEW LEVERING, Mundelein Seminary "Ortlund argues that belief in God and the Christian story is more rational and desirable than believing in atheism and the story that naturalism tells about the world. This book will help you consider how wagering on God and Jesus might surprisingly make sense to you after all." —JOSH CHATRAW, executive director, Center for Public Christianity
A FIELD GUIDE TO CHRISTIAN NONVIOLENCE Key Thinkers, Activists, and Movements
for the Gospel of Peace David C. Cramer and Myles Werntz
Christian nonviolence is not a settled position but a vibrant and living tradition that includes mystics, feminists, liberation theologians, civil rights activists, Niebuhrian realists, and more. This book offers a concise introduction to the variety of recent movements within the broad stream of Christian nonviolence. Since the 1980s, there has been an explosion of writings on Christian nonviolence, yet no work exists to make sense of this plurality or to orient newcomers to the resources available to think faithfully and critically through what it means to be a proponent of Christian nonviolence. This book provides such an introduction for professors, students, scholars, and lay readers. The authors explore the myriad biblical, theological, and practical dimensions of Christian nonviolence as represented by a variety of twentieth- and twenty-first-century thinkers and movements, including pre- viously underrepresented voices. They invite readers to explore the tradition and to discover how they might live out the gospel in our modern world.
DAVID C. CRAMER (PhD, Baylor University) is managing editor at the Institute of Mennonite Studies, sessional lecturer at Anabaptist Mennonite Biblical Seminary, and teaching pastor at Keller Park Church in South Bend, Indiana. MYLES WERNTZ (PhD, Baylor University) is director of Baptist studies and associate professor of theology at Abilene Christian University.
FEBRUARY 2022 • 208 pp. • paper • $21.99 • 9781540960122
Introduction 1.	Nonviolence of Christian Discipleship: Following Jesus in a World at War 2.	Nonviolence as Christian Virtue: Becoming a Peaceable People 3.	Nonviolence of Christian Mysticism: Uniting with the God of Peace 4.	Apocalyptic Nonviolence: Exposing the Power of Death 5.	Realist Nonviolence: Creating Just Peace in a Fallen World 6.	Nonviolence as Political Practice: Bringing Nonviolence into the Public Square 7.	Liberationist Nonviolence: Disrupting the Spiral of Violence 8.	Christian Antiviolence: Resisting Sexual and Gender-Based Violence Conclusion Index
ALSO BY THE AUTHOR
FROM ISOLATION TO COMMUNITY 9781540965059 • $22.99p COMING APRIL 2022
COMMON CALLINGS AND ORDINARY VIRTUES Christian Ethics for Everyday Life Brent Waters
Every day, we do commonplace things and interact with ordinary people without giving them much thought. This volume offers a theological guide to thinking Christianly about the ordinary nature of everyday life. Ethicist Brent Waters shows that the activities and relationships we think of as mundane are actually expressions of love of neighbor that are vitally important to our wellbeing. We live out the Christian gospel in the contexts that define us and in the routine chores, practices, activities, and social settings that give ordinary life meaning. It is in those contexts that we discover what we were created for, to be, and to become.
BRENT WATERS (DPhil, University of Oxford) is the Jerre and Mary Joy Stead Professor of Christian Social Ethics at Garrett-Evangelical Theological Seminary, where he also directs the Jerre L. and Mary Joy Stead Center for Ethics and Values. He has written, edited, or contributed to many books and has lectured extensively on the relationship between theology, ethics, and technology. He received the Paul Ramsey Award for Excellence in Bioethics in 2016.
APRIL 2022 • 288 pp. • paper • $27.99 • 9780801099427
CONTENTS PART 1: THEOLOGICAL AND MORAL THEMES 1.	Creation, Incarnation, and Resurrection 2.	Calling and Vocation 3.	Virtue and Vice 4.	Ritual and the Ordering of Time and Place: On Belonging PART 2: EVERYDAY RELATIONSHIPS 5.	Neighbors
6.	Friends 7.	Spouses 8.	Parents and Children
9.	Strangers 10.	Citizens PART 3: EVERYDAY ACTIVITIES 11.	Work 12.	Housework and Homework 13.	Manners 14.	Appearance
15.	Eating 16.	Leisure
Postscript: On the Good of Being Boring Indexes
RELIGIOUS EXPERIENCE AND THE KNOWLEDGE OF GOD The Evidential Force of Divine Encounters Harold A. Netland
For many Christians, personal experiences of God provide an important ground or justification for accepting the truth of the gospel. But we are sometimes mistaken about our experiences, and followers of other religions also provide impressive testimo- nies to support their religious beliefs. Religious Experience and the Knowledge of God offers an introduc- tion to the complex topic of religious experience and its viability as support for Christian belief, lending credibility to the Christian claim that experiences support our beliefs and actions. Harold Netland explores from a philosophical and theological perspective the viability of divine encounters as support for belief in God, arguing that some religious experiences can be accepted as gen- uine experiences of God and can provide evidence for Christian beliefs. The book also draws out the implications of religious experience for Christian witness, missiology, and apologetics in today's globalizing and religiously diverse world. HAROLD A. NETLAND (PhD, Claremont Graduate University) is professor of philosophy of religion and intercultural studies at Trinity Evangelical Divinity School, where he has taught for more than twenty-five years. He previously served as a missionary in Japan and taught at Tokyo Christian University. He is the author or coauthor of numerous books, including Christianity and Religious Diversity , Encountering Religious Pluralism , and Buddhism: A Christian Explora- tion and Appraisal . He is also the coeditor of Globalizing Theology and Handbook of Religion .
Introduction 1.	Religious Experience: Mapping the Conceptual Territory 2.	Religious Experience and Interpretation 3.	The Critical-Trust Approach 4.	Edwards and Wesley on Experiencing God 5.	Experiencing God, Basic Beliefs, and the Holy Spirit 6.	Mysticism 7.	Theistic Experiences and Religious Diversity Conclusion Index
CHRISTIANITY AND RELIGIOUS DIVERSITY 9780801038570 • $28.00p
THE RESURRECTION OF JESUS CHRIST Exploring Its Theological Significance and Ongoing Relevance W. Ross Hastings The resurrection of Jesus Christ is one of the best-attested facts of history. But believing in the resurrection is one thing. Knowing what it means is another. Although much has been written about the apologetics of the resurrection, little has been written about its theological meaning. This book reveals the hidden depths of the theological signifi- cance and ongoing relevance of the resurrection of Jesus Christ for our being, our salvation, Christian life, ethics, and our future hope. W. Ross Hastings explains that the resurrection has profound consequences for who we are. Jesus as the last Adam formed a new humanity when he rose again. This has significance for our regeneration, our future resurrection, the reaffirmation of creation and the moral order, and ethics. Precisely because Jesus is the representative man for humanity, the resurrection also has profound consequences for our human salvation. By his resur- rection, who we are changes, but who we are before God changes too. The resurrection is atoning in itself, but it is also the seal of the atonement. It is the gateway to Christ's ascension and high priesthood. The resurrection therefore brings about our justifica- tion, sanctification, vocation, and glorification.
W. ROSS HASTINGS (PhD, Queens University, Ontario, and University of St. Andrews) is the Sangwoo Youtong Chee Professor of Theology at Regent College in Vancouver. He is the author of a number of books, including Total Atonement, Theological Ethics, Pastoral Ethics, and Missional God, Missional Church. He has also served as a senior pastor in several churches.
Introduction 1.	The Resurrection as Good History PART 1: CHRIST'S RESURRECTION HAS SAVING EFFICACY 2.	The Resurrection as the Seal of the Atonement 3.	The Resurrection as the Substance of the Atonement 4.	The Resurrection as the Ground of Participation in the Life of God 5.	The Resurrection as the Ground of Vocation and Mission 6.	The Resurrection as the Ground of the Bodily Resurrection PART 2: CHRIST'S RESURRECTION HAS ONTOLOGICAL SIGNIFICANCE 7.	The Resurrection Declares Jesus's Unrivaled Supremacy 8.	The Resurrection Signals Christ's Entry into His Office as Great High Priest and King 9.	The Resurrection as the Reaffirmation of Creation 10.	The Resurrection and the Nature of the Second Coming Conclusion Indexes
BIBLE and INTERPRETATION THEOLOGY, HISTORY, and ETHICS
BAVINCK A Critical Biography James Eglinton
James Eglinton brings to light a wealth of new insights and previously un- published documents to offer a definitive biography of renowned Reformed theologian Herman Bavinck. This book received a 2020 Book Award from The Gospel Coalition (History & Biography) and a 2020 Book Award from For the Church. "If you want to understand the life and world of the man behind Reformed Dogmatics , this book is for you." —THE GOSPEL COALITION "Impeccably researched and thoroughly readable, Eglinton's biography of Herman Bavinck deserves a wide readership." —KRISTEN DEEDE JOHNSON, Western Theological Seminary
JAMES EGLINTON (PhD, University of Edinburgh) is Meldrum Senior Lecturer in Reformed Theology at the University of Edinburgh. He is the author or editor of several books, including Herman Bavinck on Preaching and Preachers .
NOW AVAILABLE • 480 pp. • cloth • $44.99 • 9781540961358
THE FATHER OF LIGHTS A Theology of Beauty Junius Johnson THEOLOGY FOR THE LIFE OF THE WORLD
Junius Johnson offers a full-orbed theology of beauty, showing how it has functioned as a theological concept from biblical times to the present day.
"'The beauty of holiness' has long been a familiar phrase with a somewhat elusive meaning. With a combination of scholarly preci- sion and infectious relish for the theological task, Johnson gives a new clarity to this phrase." —BEN QUASH, Centre for Arts and the Sacred, King's College London "An illuminating meditation on the experience of beauty and that experience's implications for the world of theology." —ANNE M. CARPENTER, St. Mary's College of California
JUNIUS JOHNSON (PhD, Yale University) is a scholar and writer whose work focuses on historical and philosophical theology. He offers direct teaching over Zoom to adults and younger students through Junius Johnson Academics and is the author of several books.
NOW AVAILABLE • 224 pp. • paper • $32.00 • 9781540964892
REFORMED ETHICS, VOL. 2 The Duties of the Christian Life Herman Bavinck; John Bolt, editor
Herman Bavinck's four-volume Reformed Dogmatics is one of the most important theological works of the twentieth century. The English translation was edited by leading Bavinck expert John Bolt, who now brings forth a recently discovered manuscript from Bavinck that is being published for the first time. Serving as a companion to Reformed Dogmatics , Reformed Ethics offers readers Bavinck's mature reflections on ethical issues. This book, the sec- ond of three planned volumes, covers the duties of the Christian life and includes Bavinck's exposition of the Ten Commandments. HERMAN BAVINCK (1854–1921) succeeded Abraham Kuyper as professor of systematic theology at the Free University of Amsterdam in 1902. JOHN BOLT (PhD, University of St. Michael's College) is professor emeritus of systematic theology at Calvin Theological Seminary, where he taught for more than twenty-five years. He is the editor of Bavinck's four-volume Reformed Dogmatics . "In Reformed Ethics , we are invited to think with Bavinck about the concreteness of human life in the light and strength of God's deeds for us. For that, we owe the editor and translators a great deal." —JAMES EGLINTON, New College, University of Edinburgh "John Bolt and his accomplished team of translators and editors have added amazing value to Bavinck's recently rediscovered manuscripts in the field of moral theology. An invaluable background study on the history of theological ethics." —JAMES A. DE JONG, Calvin Theological Seminary "John Bolt and his colleagues have provided us with a fresh resource for theological and ethical reflection." —CRAIG G. BARTHOLOMEW, Kirby Laing Institute for Christian Ethics, Cambridge
NOVEMBER 2021 • 560 pp. • cloth • $59.99 • 9780801098222
CONTENTS Continued from Volume 1
BOOK III HUMANITY AFTER CONVERSION 13.	Duties, Precepts and Counsels, Adiaphora 14.	Collision and Classification of Duties PART A. OUR DUTIES TOWARD GOD 15.	No Other Gods; No Images 16.	The Honor of God's Name 17.	The Sabbath PART B. OUR DUTIES TOWARD OURSELVES
18.	General Bodily Duties to Self 19.	Basic Necessities of Bodily Life 20.	Bodily Duties to Our Souls PART C. DUTIES TOWARD OUR NEIGHBOR 21.	Loving Our Neighbor Indexes
ALSO BY THE AUTHOR AND EDITOR
REFORMED ETHICS, VOL. 1 9780801098024 • $59.99c
FOR THE LIFE OF THE WORLD Theology That Makes a Difference Miroslav Volf and Matthew Croasmun
For the Life of the World shows that a recovery of theology is vital to help us evaluate contested questions of value, articulate compelling visions of the good life, and answer the fundamental question of what makes life worth living. It won a Christianity Today Book Award and was named an Outreach Recommended Resource of the Year.
"This is a theology of life that concerns every person who loves life and that is fit for academia in connection to the human sciences." —JÜRGEN MOLTMANN, University of Tübingen
"A timely work with which theologians across the spectrum need to contend." —KRISTEN JOHNSON, Western Theological Seminary
NOW IN PAPER
MIROSLAV VOLF (DrTheol, University of Tübingen) is the Henry B. Wright Professor of Theology at Yale Divinity School and founding director of the Yale Center for Faith and Culture. MATTHEW CROASMUN (PhD, Yale University) is associate research scholar and director of the Life Worth Living Program at the Yale Center for Faith and Culture. He is also staff pastor at the Elm City Vineyard Church.
THE PRIORITY OF CHRIST Toward a Postliberal Catholicism Robert Barron
Bishop Robert Barron transcends liberal/conservative and Protestant/Catholic divides to explore the possibilities of postliberal theology for Catholicism.
"This stunning summa for a 'postliberal Catholicism' will at once subvert any tendency among the faithful to demand a facile 'fix,' as well as offer lucid direction for anyone daring to undertake a pilgrimage of understanding—in and with the Christ." —DAVID B. BURRELL, CSC, University of Notre Dame (emeritus) "A downright lovely book, written with a kind of winsome literary flair that exhibits the inviting clarity of a master teacher. Highly recommended for sharp undergraduates;
required reading for graduate students and scholars." —JAMES K. A. SMITH, Religious Studies Review
ROBERT BARRON (STD, Institut Catholique de Paris) is auxiliary bishop of the Archdiocese of Los Angeles. He founded Word on Fire and has written numerous books, including Catholi- cism , Exploring Catholic Theology , and The Strangest Way: Walking the Christian Path .
YOU'RE ONLY HUMAN How Your Limits Reflect God's Design and Why That's Good News Kelly M. Kapic Work. Family. Church. Exercise. Sleep. The list of demands on our time seems to be never ending. It can leave us feeling a little guilty—like we should always be doing one more thing. Rather than sharing better time-management tips to squeeze more hours out of the day, theologian Kelly Kapic takes a different approach in You're Only Human . He offers a better way to make peace with the fact that God didn't create us to do it all. Kapic explores the theology behind seeing our human limitations as a gift rather than a deficiency. He lays out a path to holistic living with healthy self-understanding, life-giving relationships, and meaningful contributions to the world. He frees us from confusing our limitations with sin and instead invites us to rest in the joy and relief of knowing that God can use our limitations to foster freedom, joy, growth, and community. Readers will emerge better equipped to cultivate a life that fosters gratitude, rest, and faithful service to God.
KELLY M. KAPIC (PhD, King's College, University of London) is professor of theological studies at Covenant College, where he has taught for twenty years. He is an award-winning author or editor of more than fifteen books, including Embodied Hope: A Theological Meditation on Pain and Suffering , winner of a Christianity Today Book Award, and Mapping Modern Theology . He is also a contributor to various journals and a popular speaker.
JANUARY 2022 • 272 pp. • cloth • $24.99 • 9781587435102
"As this book helped me to see the manifold ways in which we live in denial about the goodness of limits, I made fresh commitments to seek new, healthier habits. I cannot value and recommend a book more highly than that." —DANIEL J. TREIER, Wheaton College "A mature, winsome, theologically steady, and pastorally gentle invitation to receive with gratitude and rejoice once again in the triune God's good gift of finite creatureliness." —LEOPOLDO A. SÁNCHEZ M., Center for Hispanic Studies, Concordia Seminary
CONTENTS PART 1: PARTICULARITY AND LIMITS 1.	Have I Done Enough? Facing Our Finitude
2.	Does God Love . . . Me? Crucified . . . but I Still Live 3.	Are the Limits of My Body Bad? Praise God for Mary 4.	Why Does Physical Touch Matter? Images, Trauma, and Embodied Worship 5.	Is Identity Purely Self-Generated? Understanding the Self in Context PART 2: HEALTHY DEPENDENCE 6.	Have We Misunderstood Humility? Joyful Realism 7.	Do I Have Enough Time? Clocks, Anxiety, and Presence 8.	Why Doesn't God Just Instantly Change Me? Process, Humanity, and the Spirit's Work 9.	Do I Need to Be Part of the Church? Loving the Whole Body 10.	How Do We Faithfully Live within Our Finitude? Rhythm, Vulnerability, Gratitude, and Rest Indexes
MAPPING MODERN THEOLOGY 9780801035357 • $38.00p
THE ESSENTIAL SUMMA THEOLOGIAE A Reader and Commentary, 2nd ed. Frederick Christian Bauerschmidt
This volume offers an ideal introduction to Saint Thomas Aquinas's master- work, the Summa theologiae . It presents key selections from the Summa along with accessible commentary designed to provide background, explain key concepts, and walk readers through Aquinas's arguments. Previously pub- lished as Holy Teaching , this new edition has been fully revised and includes a substantial amount of new material. "This is it: the ideal set of Summa selections for most classrooms as well as for readers who wish they could take a class on Thomas Aquinas with a professor capable of paraphrasing the angelic doc- tor, explaining and illustrating his thought while pointing to further readings both medieval and modern." —FRED SANDERS, Torrey Honors College, Biola University
FREDERICK CHRISTIAN BAUERSCHMIDT (PhD, Duke University) is professor of theology at Loyola University Maryland and is a deacon of the Archdiocese of Baltimore. He is the author or coauthor of numerous books.
NOVEMBER 2021 • 464 pp. • paper • $36.99 • 9781540960061
CHURCH CONFLICTS The Cross, Apocalyptic, and Political Resistance Ernst Käsemann; Ry O. Siggelkow, editor; Roy A. Harrisville, translator Foreword by James H. Cone
This important work by one of the most significant New Testament scholars of the modern period explores the significance of Christian apocalyptic for the church in times of conflict and crisis.
"This fine collection of Käsemann's essays shows him at his provoc- ative best. Siggelkow and Harrisville are to be thanked for exposing an English-language readership afresh to the voice of this fierce disciple of Christ." —PHILIP G. ZIEGLER, University of Aberdeen; author of Militant Grace "An important addition to our libraries." —BEVERLY ROBERTS GAVENTA, Princeton Theological Seminary (emerita) ERNST KÄSEMANN (1906–98) was professor of New Testament at the Universities of Mainz, Göttingen, and Tübingen. RY O. SIGGELKOW (PhD, Princeton Theological Seminary) is director of initiatives in faith and praxis in the theology department at the University of St. Thomas. ROY A. HARRISVILLE (PhD, Princeton Theological Seminary) was for many years professor of New Testament at Luther Seminary.
A BASIC GUIDE TO EASTERN ORTHODOX THEOLOGY Introducing Beliefs and Practices Eve Tibbs Foreword by His All Holiness Ecumenical Patriarch Bartholomew
Eve Tibbs offers a comprehensive yet accessible introduction to the theology, spirituality, and life of the Eastern Orthodox Church for Western readers. Tibbs has devoted her career to translating the Orthodox faith to an evangelical audience and has over twenty years of experience teaching this material to students. Assuming no prior knowledge of Orthodox theology, this survey covers the basic ideas of Eastern Orthodox Christianity from its origins at Pentecost to the present day.
EVE TIBBS (PhD, Fuller Theological Seminary) is affiliate assistant professor of theology at Fuller Theological Seminary. For more than twenty years, she has taught Western systematic theology and Eastern Orthodox theology and has been the ministry lead for Christian education in the Greek Orthodox Metropolis of San Francisco, California.
" A Basic Guide to Eastern Orthodox Theolog y is an invita- tion into the mysteries and beauty of this ancient yet ever- renewing and living tradition. An indispensable guide for all students, ministers, and instructors." —VELI-MATTI KÄRKKÄINEN, Fuller Theological Semi- nary and University of Helsinki "Tibbs's experience dealing with common questions and misconceptions that evangelicals often have makes this book a valuable text for students and teachers alike." —BRADLEY NASSIF, North Park University "An Orthodox Christian with years of experience teaching evangelical students—Tibbs is an ideal person to explain the fundamentals about the life, ethos, and faith of the Orthodox Church." —PETER C. BOUTENEFF, St. Vladimir's Orthodox Theological Seminary
Introduction 1.	The Orthodox Christian Worldview 2.	The Church 3.	Communion and Revelation 4.	Ministry and Leadership 5.	Christology 6.	Who Are We? What Are We to Do? 7.	The Holy Trinity 8.	Orthodox Worship Epilogue Appendix: Excerpts from Selected Apostolic and Patristic Writings Excerpts from the Epistle of St. Ignatius to the Philadelphians Excerpts from the Epistle of St. Ignatius to the Smyrnaeans Excerpts from Against Heresies 3.3 by St. Irenaeus, Bishop of Lyons Full Text of The Didache: The Lord's Teaching through the Twelve Apostles to the Nations Glossary of Orthodox Terms Index
EARLY NORTH AFRICAN CHRISTIANITY Turning Points in the Development of the Church David L. Eastman Zeroing in on five key moments in history, this book explores how the North African church significantly shaped Christian theology, identity, and practice in ways that still directly impact the church today. "This book skillfully weaves history and reflection into a highly accessible account of North African Christianity. This title is indis- pensable for any reader, whether beginner or seasoned scholar, who wants to understand North Africa's early contributions to fundamen- tal issues of the Christian faith." —KYAMA MUGAMBI, Pan Africa Christian University; Centre for World Christianity, Africa International University "A compelling and insightful introduction to the faith, context, and practices of early African Christianity that will enrich readers' grasp of its decisive influence on the legacy of the Western church." —ROBIN JENSEN, University of Notre Dame
DAVID L. EASTMAN (PhD, Yale University) is the Joseph Glenn Sherrill Chair of Bible at the McCallie School. He is also an adjunct fellow at the University of Regensburg (Germany), a fellow with the Center for Early African Christianity, and the author of several books.
WHEN DID SIN BEGIN? Human Evolution and the Doctrine of Original Sin Loren Haarsma
A science-and-theology scholar argues that there are several possible ways to harmonize the doctrine of original sin and human evolution, taking seriously both Scripture and science.
"I wholeheartedly recommend this book to the church as we think through the question of the relationship between the Bible and science." —TREMPER LONGMAN III, Westmont College
"My own work as a sociologist shows that Christians need rigorous examples of deep theological debate that takes science and Chris- tian doctrine seriously. When Did Sin Begin? is an accessible, lively, rich volume that is an excellent example of this kind of debate." —ELAINE HOWARD ECKLUND, Rice University; author of Why Science and Faith Need Each Other
LOREN HAARSMA (PhD, Harvard University) is associate professor of physics at Calvin Uni- versity, a fellow of the American Scientific Affiliation, and a member of the BioLogos Voices network of scholars.
A CALL TO CHRISTIAN FORMATION How Theology Makes Sense of Our World John C. Clark and Marcus Peter Johnson
This book demonstrates that theology is integrally related to formation in Jesus Christ and shapes our understanding of the world.
"This presentation of the foundational role of orthodox, biblical theology in daily life and work will be of great encouragement to students and pastors, as well as lay persons." —FLEMING RUTLEDGE, author of The Crucifixion: Understanding the Death of Jesus Christ "This wonderful book offers a clarion call to recover the significance of theology once again in an age when most Christians pay
lip service to God without knowing much about him." —DOUGLAS A. SWEENEY, Beeson Divinity School, Samford University
JOHN C. CLARK (PhD, St. Michael's College, University of Toronto) is professor of theology at Moody Bible Institute and a deacon at Church of the Resurrection in Wheaton, Illinois. MARCUS PETER JOHNSON (PhD, St. Michael's College, University of Toronto) is professor of theology at Moody Bible Institute and associate rector at St. Mark's Church in Geneva, Illinois.
REFORMED PUBLIC THEOLOGY A Global Vision for Life in the World Matthew Kaemingk, editor
Leading Reformed thinkers introduce the depth, diversity, and global impact of the Reformed tradition.
"In this volume public theology in the Reformed tradition is cat- apulted into the twenty-first century. Anyone with an interest in Reformed theology should read this book. Those who are not Re- formed will still find intellectual riches with which to engage." —OLIVER D. CRISP, Logos Institute, University of St. Andrews "This book offers a real contribution to the wider landscape of pub- lic theology. It is also a page-turner! I hope it is read far and wide." —KRISTEN DEEDE JOHNSON, Western Seminary MATTHEW KAEMINGK (PhD, Vrije Universiteit and Fuller Theological Seminary) is the Richard John Mouw Assistant Professor of Faith and Public Life at Fuller Theological Seminary where he also serves as the director of the Richard John Mouw Institute of Faith and Public Life. He also serves as a research fellow for the Center for Public Justice.
AN INTRODUCTION TO CHRISTIAN MYSTICISM Recovering the Wildness of Spiritual Life Jason M. Baxter This accessibly written volume introduces key figures, texts, and themes of the mystical tradition, showing that the mystics have much to say to contem- porary Christians searching for authentic modes of spirituality. "Any undergraduate or general reader who wishes to take his or her first steps in learning about Christian mysticism can do no better than to read Baxter's remarkable, clear, and thorough Introduction to Christian Mysticism ." —KEVIN HART, University of Virginia "Tracing the mystic experiences of God from the pagans to Julian of Norwich and Nicholas of Cusa, Baxter reorients us to the tradi- tion that we lost after the Reformation and the Enlightenment. To read this book is to be lit up again by our bright, burning, wild, and unfathomable God." —JESSICA HOOTEN WILSON, University of Dallas
JASON M. BAXTER (PhD, University of Notre Dame) is associate professor of fine arts and humanities at Wyoming Catholic College. He is the author of A Beginner's Guide to Dante's "Divine Comedy."
MARRIAGE, SCRIPTURE, AND THE CHURCH Theological Discernment on the Question of Same-Sex Union
Darrin W. Snyder Belousek Afterword by Wesley Hill
Darrin Synder Belousek takes a distinctive approach to the same-sex-union debate by framing the issue as a matter of marriage and articulates a biblical-traditional theology of marriage for the contemporary church.
"A theologically robust, exegetically responsible, and pastorally compassionate tour de force. Anyone who wants to engage this topic must read this book." —PRESTON SPRINKLE, president of the Center for Faith, Sexuality & Gender "By placing the question of same-sex union within the larger con- text of a theology of marriage, Snyder Belousek reminds us that marriage and sex are not primarily for our own pleasure or purposes but were designed by God to orient our lives toward him and toward his great work of salvation." —CHRISTINA S. HITCHCOCK, University of Sioux Falls; author of The Significance of Singleness
DARRIN W. SNYDER BELOUSEK (PhD, University of Notre Dame) teaches philosophy and religion at Ohio Northern University and has taught at various church-related colleges.
CONTEMPLATING GOD WITH THE GREAT TRADITION Recovering Trinitarian Classical Theism Craig A. Carter Foreword by Carl R. Trueman
This book presents the biblical and theological foundations of trinitarian classical theism.
"Here evangelical and Reformed theological practice receives a needed recalibration." —MICHAEL ALLEN, Reformed Theological Seminary, Orlando, Florida "Carter makes another important contribution to the theological interpretation of Scripture, upholding Nicene trinitarian classical theism against modern metaphysical assumptions." —AIMEE BYRD, author of Recovering from Biblical Manhood and Womanhood and Theological Fitness
CRAIG A. CARTER (PhD, University of St. Michael's College) is professor of theology at Tyndale University and theologian in residence at Westney Heights Baptist Church in Ajax, Ontario.
DIVINE ATTRIBUTES Knowing the Covenantal God of Scripture John C. Peckham
John Peckham offers a clear and constructive account of the nature and attributes of God, bringing the biblical portrayal of God in relationship to the world into dialogue with prominent philosophical and theological questions.
"Divine attribution is often overlooked in its importance for Chris- tian reflection, but it is critical to reckon with the identity and character of the One Christians worship. Peckham's book provides an accessible framework for this topic, all the while demonstrating a resounding attentiveness to the biblical witness as contemporary discussions are judiciously elaborated." —DANIEL CASTELO, Seattle Pacific University and Seminary "A rich and careful depiction of the canonical God. This is com- pulsory reading for any theologian who seeks to make necessary connections with the biblical texts." —DRU JOHNSON, Center for Hebraic Thought, The King's College, New York City; host of the OnScript podcast
JOHN C. PECKHAM (PhD, Andrews University) is professor of theology and Christian phi- losophy at Andrews University. He is the author of several books, including Theodicy of Love .
Explore the History of Women in Christianity
9781587434709 • 256 pp. • $19.99p USA Today Bestseller
9781540963086 • 240 pp. • $24.99p
9780801039553 • 336 pp. • $35.00p A Jesus Creed 2017 Book of the Year (Honorable Mention) A Top Ten Book for Parish Ministry in 2017, Academy of Parish Clergy
9781540960726 • 256 pp. • $24.99p See page 53
Help Your Students Understand Evangelical Theology
9780801039461• 976 pp. • $59.99c
9780801097690 • 464 pp. • $32.99p 2020 Christian Book Award ® Winner (Bible Reference Works)
course help for professors and study aids for students
Essential Barth Resources
9780801098178 • 272 pp. • $48.00c
THEOLOGY, HISTORY , and ETHICS TEXTBOOKS
9780801049750 • 200 pp. • $22.00p Outreach 2019 Resource of the Year (Theology/Biblical Studies)
9780801098284 • 368 pp. • $44.99c See page 61
BIBLE and INTERPRETATION
YOU NEED A BETTER GOSPEL Reclaiming the Good News of Participation with Christ Klyne R. Snodgrass Too often, the church hasn't done justice to its own gospel be- cause it has neglected how much the New Testament message is about deep involvement in life with God. New Testament scholar Klyne Snodgrass offers a corrective, explaining that the church will never be what it is supposed to be without a recovery of the gospel. This brief, accessibly written, and timely book shows that the biblical message is about attachment to Christ, participation in his death and resurrection, and engagement in his purposes. Snodgrass demonstrates that understanding and appropriating the gospel of participation conforms with what the church's great thinkers have emphasized throughout history and enables the church to recover its true identity. This book brings the notion of participation in the gospel to a wider church audience, including professors and students of the Bible, pastors, and ministry workers. While other studies on this topic focus mostly on Paul's writings, You Need a Better Gospel shows that participation is the emphasis of the entire Bible, in- cluding the Old Testament. The real gospel, which offers partici- pation in life with God, is astounding in its beauty and its power for life. KLYNE R. SNODGRASS (PhD, University of St. Andrews) is professor emer- itus of New Testament studies at North Park Theological Seminary, where he taught for more than forty years. He is the author of several books, including the influential Christianity Today Book Award Winner Stories with Intent: A Compre- hensive Guide to the Parables of Jesus . Snodgrass has served as the editor of Ex Auditu: An International Journal of Theological Interpretation of Scripture for twenty-five years.
JANUARY 2022 • 208 pp. • paper • $22.99 • 9781540965042
Introduction 1.	Participation in Christ 2.	Is Faith as Participation a New Idea?
3.	What Is Participation, and Why Is It Important? 4.	Is the Gospel of Participation in the Old Testament?
5.	The Gospels in the Synoptic Gospels 6.	Deep Participation in John and 1 John 7.	The Gospel in the Book of Acts
8.	Paul's Letters: How Does Salvation Work and for What Purpose? 9.	Paul's Letters: How Does Salvation Work and for What Purpose ? 10.	Striking Assertions of Participation 11.	So What? Appendix: The Relation of the Gospels of Jesus and Paul
ABRAHAM'S SILENCE The Binding of Isaac, the Suffering of Job, and How to Talk Back to God J. Richard Middleton
It is traditional to think we should praise Abraham for his will- ingness to sacrifice his son as proof of his love for God. But have we misread the point of the story? Is it possible that a careful reading of Genesis 22 could reveal that God was not pleased with Abraham's silent obedience? J. Richard Middleton suggests we have misread and misapplied the story of the binding of Isaac and shows that God desires something other than silent obedience in difficult times. Middle- ton focuses on the ethical and theological problem of Abraham's silence and explores the rich biblical tradition of vigorous prayer, including the lament psalms, as a resource for faith. Middleton also examines the book of Job in terms of God validating Job's lament as "right speech," showing how the vocal Job provides an alternative to the silent Abraham. Abraham's Silence provides a fresh interpretation of Genesis 22 and reinforces the church's resurgent interest in lament as an ap- propriate response to God. Professors and students of the Bible, theology, and spirituality; pastors and church leaders; biblical scholars and theologians; and Jewish Rabbis, scholars, and lay- people will all value this work.
J. RICHARD MIDDLETON (PhD, Free University of Amsterdam) is professor of biblical worldview and exegesis at Northeastern Seminary. He is the author of The Liberating Image and the award-winning A New Heaven and a New Earth . He is also the coauthor of Truth Is Stranger Than It Used to Be and The Transforming Vision . Middleton has served as president of the Canadian Society of Biblical Studies and as president of the Canadian-American Theological Association.
"A groundbreaking work. The pastoral implications of this book make it a must-read for pastors and biblical scholars alike." —CARMEN JOY IMES, Biola University "I consider this to be a masterpiece of once-in-a-generation quality." —RABBI YITZ GREENBERG, president, J. J. Greenberg Institute for the Advancement of Jewish Life
CONTENTS Introduction: Does Abraham's Silence Matter? PART 1: MODELS OF VIGOROUS PRAYER IN THE BIBLE 1.	Voices from the Ragged Edge 2.	God's Loyal Opposition PART 2: MAKING SENSE OF THE BOOK OF JOB 3.	The Question of Appropriate Speech 4.	Does God Come to Bury Job or to Praise Him? PART 3: UNBINDING THE AQEDAH FROM THE STRAITJACKET OF TRADITION 5.	Is It Permissible to Criticize Abraham or God? 6.	Reading Rhetorical Signals in the Aqedah and Job 7.	Did Abraham Pass the Test? Conclusion: The Gritty Spirituality of Lament Indexes
A NEW HEAVEN AND A NEW EARTH 9780801048685 • $29.99p
Page 1 Page 2 Page 3 Page 4 Page 5 Page 6 Page 7 Page 8 Page 9 Page 10 Page 11 Page 12 Page 13 Page 14 Page 15 Page 16 Page 17 Page 18 Page 19 Page 20 Page 21 Page 22 Page 23 Page 24 Page 25 Page 26 Page 27 Page 28 Page 29 Page 30 Page 31 Page 32 Page 33 Page 34 Page 35 Page 36 Page 37 Page 38 Page 39 Page 40 Page 41 Page 42 Page 43 Page 44 Page 45 Page 46 Page 47 Page 48 Page 49 Page 50 Page 51 Page 52 Page 53 Page 54 Page 55 Page 56 Page 57 Page 58 Page 59 Page 60 Page 61 Page 62 Page 63 Page 64 Page 65 Page 66 Page 67 Page 68 Page 69 Page 70 Page 71 Page 72 Page 73 Page 74 Page 75 Page 76 Page 77 Page 78 Page 79 Page 80 Page 81 Page 82 Page 83 Page 84
bakerpublishinggroup.com
Made with FlippingBook - professional solution for displaying marketing and sales documents online


Carousel Bar (New Orleans); Florida Room (Miami); La Floridita (Cuba); Merchant Hotel bar (Belfast); Quaich Bar — 1,000 single malts (Speyside, Scotland ); Bramble — built for just £16,000 (Edinburgh ); Bar 50 — home to the world-famous Peter Sellers lookalike and Breakfast Martini inventor Salvatore Calabrese, Dukes Hotel, Quo Vadis, Milk & Honey, the LAB (London); Blackfriars Distillery Bar — shameless plug from brand ambassador Simon Ford (Plymouth, England); Apoteke (Tromso, Norway); Ruby (Copenhagen); Hemingway Bar, Harry's New York Bar (Paris); Widder Bar (Zurich); Barfly's Club — 60 different ryes! (Vienna); Dry Martini — over 1 million served, Boadas — here they "throw" drinks between giant shakers like in Jerry Thomas' day (Barcelona); Paparazzi, UFO (Bratislava, Slovakia); Le Lion de Paris (Hamburg); Schumann's (Munich); Becketskoff (Berlin); Nottingham Forest — molecular mixology pioneer (Milan); Door 74 (Amsterdam); Burj al Arab — world's priciest cocktail (Dubai); Sky Bar (Moscow); Felix, Captain's Bar, China Club (Hong Kong); Olives (Mumbai); Rick's (Delhi); Raffles — originator of Singapore Sling but a depressing tourist trap, Tippling Club (Singapore); Constellation (Shanghai); High Five — jaw-dropping technique, Tender Bar — six different shaking techniques, carved ice cubes (Tokyo); Bayswater Brasserie (Sydney); Der Raum, Tiki Bar, 1806 (Melbourne); Motel, Matterhorn (Wellington, NZ); Cafe Tortoni (Buenos Aires); Andres Carne de Res — filled with junk (Bogota, Colombia); Westin Hotel bar — home of the Caesar (Calgary); Zig Zag, Vessel (Seattle); Bel Ami (Portland); Bix, Tommy's, Bourbon & Branch (San Francisco); Doheny, the Edison (L.A.); Downtown Hotel (Dawson City, Yukon Territory); Churchill Downs (Kentucky); Pegu Club, King Cole bar in the St. Regis Hotel, P.J. Clarke's, PDT, Death & Co., Randall (NYC); Drink (Boston); the Gibson, Bourbon (Washington D.C.); Absinthe House, Alibi (New Orleans). Extra credit: Vodka & Shotguns (Lithuania).
I have only been to a handful of these places. Got some travelin' to do.
I guess it would have been a lot easier to link to the New York Times' version of this list, complete with links. D'oh.