text:
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/quic/quic_connection.h"

#include <algorithm>

#include "base/logging.h"
#include "base/stl_util.h"
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
#include "net/quic/quic_utils.h"

using base::hash_map;
using base::hash_set;
using base::StringPiece;
using std::list;
using std::make_pair;
using std::min;
using std::max;
using std::vector;
using std::set;
using std::string;

namespace net {

// TODO(pwestin): kDefaultTimeoutUs is in int64.
int32 kNegotiatedTimeoutUs = kDefaultTimeoutUs;

namespace {

// The largest gap in packets we'll accept without closing the connection.
// This will likely have to be tuned.
const QuicPacketSequenceNumber kMaxPacketGap = 5000;

// The maximum number of nacks which can be transmitted in a single ack packet
// without exceeding kMaxPacketSize.
// TODO(satyamshekhar): Get rid of magic numbers and move this to protocol.h
// 16 - Min ack frame size.
// 16 - Crypto hash for integrity. Not a static value. Use
// QuicEncrypter::GetMaxPlaintextSize.
size_t GetMaxUnackedPackets(bool include_version)  {
  return (kMaxPacketSize - GetPacketHeaderSize(include_version) - 16 - 16) /
      kSequenceNumberSize;
}

// We want to make sure if we get a large nack packet, we don't queue up too
// many packets at once.  10 is arbitrary.
const int kMaxRetransmissionsPerAck = 10;

// TCP retransmits after 2 nacks.  We allow for a third in case of out-of-order
// delivery.
// TODO(ianswett): Change to match TCP's rule of retransmitting once an ack
// at least 3 sequence numbers larger arrives.
const size_t kNumberOfNacksBeforeRetransmission = 3;

// The maxiumum number of packets we'd like to queue.  We may end up queueing
// more in the case of many control frames.
// 6 is arbitrary.
const int kMaxPacketsToSerializeAtOnce = 6;

// Limit the number of packets we send per retransmission-alarm so we
// eventually cede.  10 is arbitrary.
const int kMaxPacketsPerRetransmissionAlarm = 10;

bool Near(QuicPacketSequenceNumber a, QuicPacketSequenceNumber b) {
  QuicPacketSequenceNumber delta = (a > b) ? a - b : b - a;
  return delta <= kMaxPacketGap;
}

}  // namespace

#define ENDPOINT (is_server_ ? "Server: " : " Client: ")

QuicConnection::QuicConnection(QuicGuid guid,
                               IPEndPoint address,
                               QuicConnectionHelperInterface* helper,
                               bool is_server)
    : helper_(helper),
      framer_(kQuicVersion1,
              QuicDecrypter::Create(kNULL),
              QuicEncrypter::Create(kNULL),
              helper->GetClock()->ApproximateNow(),
              is_server),
      clock_(helper->GetClock()),
      random_generator_(helper->GetRandomGenerator()),
      guid_(guid),
      peer_address_(address),
      largest_seen_packet_with_ack_(0),
      peer_largest_observed_packet_(0),
      least_packet_awaited_by_peer_(1),
      peer_least_packet_awaiting_ack_(0),
      handling_retransmission_timeout_(false),
      write_blocked_(false),
      debug_visitor_(NULL),
      packet_creator_(guid_, &framer_, random_generator_, is_server),
      packet_generator_(this, &packet_creator_),
      timeout_(QuicTime::Delta::FromMicroseconds(kDefaultTimeoutUs)),
      time_of_last_received_packet_(clock_->ApproximateNow()),
      time_of_last_sent_packet_(clock_->ApproximateNow()),
      time_largest_observed_(QuicTime::Zero()),
      congestion_manager_(clock_, kTCP),
      version_negotiation_state_(START_NEGOTIATION),
      quic_version_(kQuicVersion1),
      is_server_(is_server),
      connected_(true),
      received_truncated_ack_(false),
      send_ack_in_response_to_packet_(false) {
  helper_->SetConnection(this);
  // TODO(satyamshekhar): Have a smaller timeout till version is negotiated and
  // connection is established (CHLO fully processed).
  helper_->SetTimeoutAlarm(timeout_);
  framer_.set_visitor(this);
  framer_.set_entropy_calculator(&entropy_manager_);
  outgoing_ack_.sent_info.least_unacked = 0;
  outgoing_ack_.sent_info.entropy_hash = 0;
  outgoing_ack_.received_info.largest_observed = 0;
  outgoing_ack_.received_info.entropy_hash = 0;

  /*
  if (FLAGS_fake_packet_loss_percentage > 0) {
    int32 seed = RandomBase::WeakSeed32();
    LOG(INFO) << ENDPOINT << "Seeding packet loss with " << seed;
    random_.reset(new MTRandom(seed));
  }
  */
}

QuicConnection::~QuicConnection() {
  STLDeleteValues(&unacked_packets_);
  STLDeleteValues(&group_map_);
  for (QueuedPacketList::iterator it = queued_packets_.begin();
       it != queued_packets_.end(); ++it) {
    delete it->packet;
  }
}

bool QuicConnection::SelectMutualVersion(
    const QuicVersionTagList& available_versions) {
  // TODO(satyamshekhar): Make this generic.
  if (std::find(available_versions.begin(), available_versions.end(),
                kQuicVersion1) == available_versions.end()) {
    return false;
  }

  // Right now we only support kQuicVersion1 so it's okay not to
  // update the framer and quic_version_. When start supporting more
  // versions please update both.
  return true;
}

void QuicConnection::OnError(QuicFramer* framer) {
  if (!connected_) {
    return;
  }
  SendConnectionClose(framer->error());
}

void QuicConnection::OnPacket() {
  // TODO(satyamshekhar): Validate packet before updating the time
  // since it affects the timeout of the connection.
  time_of_last_received_packet_ = clock_->Now();
  DVLOG(1) << "time of last received packet: "
           << time_of_last_received_packet_.ToDebuggingValue();

  // TODO(alyssar, rch) handle migration!
  self_address_ = last_self_address_;
  peer_address_ = last_peer_address_;
}

void QuicConnection::OnPublicResetPacket(
    const QuicPublicResetPacket& packet) {
  if (debug_visitor_) {
    debug_visitor_->OnPublicResetPacket(packet);
  }
  CloseConnection(QUIC_PUBLIC_RESET, true);
}

bool QuicConnection::OnProtocolVersionMismatch(
    QuicVersionTag received_version) {
  // TODO(satyamshekhar): Implement no server state in this mode.
  if (!is_server_) {
    LOG(DFATAL) << "Framer called OnProtocolVersionMismatch for server. "
                << "Closing connection.";
    CloseConnection(QUIC_INTERNAL_ERROR, false);
    return false;
  }
  DCHECK_NE(quic_version_, received_version);

  if (debug_visitor_) {
    debug_visitor_->OnProtocolVersionMismatch(received_version);
  }

  switch (version_negotiation_state_) {
    case START_NEGOTIATION:
      if (!framer_.IsSupportedVersion(received_version)) {
        SendVersionNegotiationPacket();
        version_negotiation_state_ = SENT_NEGOTIATION_PACKET;
        return false;
      }
      break;

    case SENT_NEGOTIATION_PACKET:
      if (!framer_.IsSupportedVersion(received_version)) {
        // Drop packets which can't be parsed due to version mismatch.
        return false;
      }
      break;

    case NEGOTIATED_VERSION:
      // Might be old packets that were sent by the client before the version
      // was negotiated. Drop these.
      return false;

    default:
      DCHECK(false);
  }

  // Right now we only support kQuicVersion1 so it's okay not to
  // update the framer and quic_version_. When start supporting more
  // versions please update both.
  version_negotiation_state_ = NEGOTIATED_VERSION;
  // TODO(satyamshekhar): Store the sequence number of this packet and close the
  // connection if we ever received a packet with incorrect version and whose
  // sequence number is greater.
  return true;
}

// Handles version negotiation for client connection.
void QuicConnection::OnVersionNegotiationPacket(
    const QuicVersionNegotiationPacket& packet) {
  if (is_server_) {
    LOG(DFATAL) << "Framer parsed VersionNegotiationPacket for server."
                << "Closing connection.";
    CloseConnection(QUIC_INTERNAL_ERROR, false);
    return;
  }
  if (debug_visitor_) {
    debug_visitor_->OnVersionNegotiationPacket(packet);
  }

  if (version_negotiation_state_ == NEGOTIATED_VERSION) {
    // Possibly a duplicate version negotiation packet.
    return;
  }

  if (std::find(packet.versions.begin(),
                packet.versions.end(), quic_version_) !=
      packet.versions.end()) {
    DLOG(WARNING) << "The server already supports our version. It should have "
                  << "accepted our connection.";
    // Just drop the connection.
    CloseConnection(QUIC_INVALID_VERSION_NEGOTIATION_PACKET, false);
    return;
  }

  if (!SelectMutualVersion(packet.versions)) {
    SendConnectionCloseWithDetails(QUIC_INVALID_VERSION,
                                   "no common version found");
  }

  version_negotiation_state_ = NEGOTIATED_VERSION;
  RetransmitAllUnackedPackets();
}

void QuicConnection::OnRevivedPacket() {
}

bool QuicConnection::OnPacketHeader(const QuicPacketHeader& header) {
  if (debug_visitor_) {
    debug_visitor_->OnPacketHeader(header);
  }

  // Will be decrement below if we fall through to return true;
  ++stats_.packets_dropped;

  if (header.public_header.guid != guid_) {
    DLOG(INFO) << ENDPOINT << "Ignoring packet from unexpected GUID: "
               << header.public_header.guid << " instead of " << guid_;
    return false;
  }

  if (!Near(header.packet_sequence_number,
            last_header_.packet_sequence_number)) {
    DLOG(INFO) << ENDPOINT << "Packet " << header.packet_sequence_number
               << " out of bounds.  Discarding";
    // TODO(alyssar) close the connection entirely.
    return false;
  }

  // If this packet has already been seen, or that the sender
  // has told us will not be retransmitted, then stop processing the packet.
  if (!IsAwaitingPacket(outgoing_ack_.received_info,
                        header.packet_sequence_number)) {
    return false;
  }

  if (version_negotiation_state_ != NEGOTIATED_VERSION) {
    if (is_server_) {
      if (!header.public_header.version_flag) {
        DLOG(WARNING) << ENDPOINT << "Got packet without version flag before "
                      << "version negotiated.";
        // Packets should have the version flag till version negotiation is
        // done.
        CloseConnection(QUIC_INVALID_VERSION, false);
        return false;
      } else {
        DCHECK_EQ(1u, header.public_header.versions.size());
        DCHECK_EQ(header.public_header.versions[0], quic_version_);
        version_negotiation_state_ = NEGOTIATED_VERSION;
      }
    } else {
      DCHECK(!header.public_header.version_flag);
      // If the client gets a packet without the version flag from the server
      // it should stop sending version since the version negotiation is done.
      packet_creator_.StopSendingVersion();
      version_negotiation_state_ = NEGOTIATED_VERSION;
    }
  }

  DCHECK_EQ(NEGOTIATED_VERSION, version_negotiation_state_);

  --stats_.packets_dropped;
  DVLOG(1) << "Received packet header: " << header;
  last_header_ = header;
  return true;
}

void QuicConnection::OnFecProtectedPayload(StringPiece payload) {
  DCHECK_NE(0u, last_header_.fec_group);
  QuicFecGroup* group = GetFecGroup();
  group->Update(last_header_, payload);
}

bool QuicConnection::OnStreamFrame(const QuicStreamFrame& frame) {
  DCHECK(connected_);
  if (debug_visitor_) {
    debug_visitor_->OnStreamFrame(frame);
  }
  last_stream_frames_.push_back(frame);
  return true;
}

bool QuicConnection::OnAckFrame(const QuicAckFrame& incoming_ack) {
  DCHECK(connected_);
  if (debug_visitor_) {
    debug_visitor_->OnAckFrame(incoming_ack);
  }
  DVLOG(1) << "OnAckFrame: " << incoming_ack;

  if (last_header_.packet_sequence_number <= largest_seen_packet_with_ack_) {
    DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
    return true;
  }
  largest_seen_packet_with_ack_ = last_header_.packet_sequence_number;

  if (!ValidateAckFrame(incoming_ack)) {
    SendConnectionClose(QUIC_INVALID_ACK_DATA);
    return false;
  }

  // TODO(satyamshekhar): Not true if missing_packets.size() was actually
  // kMaxUnackedPackets. This can result in a dead connection if all the
  // missing packets get lost during retransmission. Now the new packets(or the
  // older packets) will not be retransmitted due to RTO
  // since received_truncated_ack_ is true and their sequence_number is >
  // peer_largest_observed_packet. Fix either by resetting it in
  // MaybeRetransmitPacketForRTO or keeping an explicit flag for ack truncation.
  received_truncated_ack_ =
      incoming_ack.received_info.missing_packets.size() >=
      GetMaxUnackedPackets(last_header_.public_header.version_flag);

  UpdatePacketInformationReceivedByPeer(incoming_ack);
  UpdatePacketInformationSentByPeer(incoming_ack);
  congestion_manager_.OnIncomingAckFrame(incoming_ack,
                                         time_of_last_received_packet_);

  // Now the we have received an ack, we might be able to send queued packets.
  if (!queued_packets_.empty()) {
    QuicTime::Delta delay = congestion_manager_.TimeUntilSend(
        time_of_last_received_packet_, NOT_RETRANSMISSION,
        HAS_RETRANSMITTABLE_DATA);
    if (delay.IsZero()) {
      helper_->UnregisterSendAlarmIfRegistered();
      if (!write_blocked_) {
        OnCanWrite();
      }
    } else if (!delay.IsInfinite()) {
      helper_->SetSendAlarm(time_of_last_received_packet_.Add(delay));
    }
  }
  return connected_;
}

bool QuicConnection::OnCongestionFeedbackFrame(
    const QuicCongestionFeedbackFrame& feedback) {
  DCHECK(connected_);
  if (debug_visitor_) {
    debug_visitor_->OnCongestionFeedbackFrame(feedback);
  }
  congestion_manager_.OnIncomingQuicCongestionFeedbackFrame(
      feedback, time_of_last_received_packet_);
  return connected_;
}

bool QuicConnection::ValidateAckFrame(const QuicAckFrame& incoming_ack) {
  if (incoming_ack.received_info.largest_observed >
      packet_creator_.sequence_number()) {
    DLOG(ERROR) << ENDPOINT << "Peer's observed unsent packet:"
                << incoming_ack.received_info.largest_observed << " vs "
                << packet_creator_.sequence_number();
    // We got an error for data we have not sent.  Error out.
    return false;
  }

  if (incoming_ack.received_info.largest_observed <
      peer_largest_observed_packet_) {
    DLOG(ERROR) << ENDPOINT << "Peer's largest_observed packet decreased:"
                << incoming_ack.received_info.largest_observed << " vs "
                << peer_largest_observed_packet_;
    // We got an error for data we have not sent.  Error out.
    return false;
  }

  // We can't have too many unacked packets, or our ack frames go over
  // kMaxPacketSize.
  DCHECK_LE(incoming_ack.received_info.missing_packets.size(),
            GetMaxUnackedPackets(last_header_.public_header.version_flag));

  if (incoming_ack.sent_info.least_unacked < peer_least_packet_awaiting_ack_) {
    DLOG(ERROR) << ENDPOINT << "Peer's sent low least_unacked: "
                << incoming_ack.sent_info.least_unacked
                << " vs " << peer_least_packet_awaiting_ack_;
    // We never process old ack frames, so this number should only increase.
    return false;
  }

  if (incoming_ack.sent_info.least_unacked >
      last_header_.packet_sequence_number) {
    DLOG(ERROR) << ENDPOINT << "Peer sent least_unacked:"
                << incoming_ack.sent_info.least_unacked
                << " greater than the enclosing packet sequence number:"
                << last_header_.packet_sequence_number;
    return false;
  }

  if (!incoming_ack.received_info.missing_packets.empty() &&
      *incoming_ack.received_info.missing_packets.rbegin() >
      incoming_ack.received_info.largest_observed) {
    DLOG(ERROR) << ENDPOINT << "Peer sent missing packet: "
                << *incoming_ack.received_info.missing_packets.rbegin()
                << " greater than largest observed: "
                << incoming_ack.received_info.largest_observed;
    return false;
  }

  if (!incoming_ack.received_info.missing_packets.empty() &&
      *incoming_ack.received_info.missing_packets.begin() <
      least_packet_awaited_by_peer_) {
    DLOG(ERROR) << ENDPOINT << "Peer sent missing packet: "
                << *incoming_ack.received_info.missing_packets.begin()
                << "smaller than least_packet_awaited_by_peer_: "
                << least_packet_awaited_by_peer_;
    return false;
  }

  if (!entropy_manager_.IsValidEntropy(
          incoming_ack.received_info.largest_observed,
          incoming_ack.received_info.missing_packets,
          incoming_ack.received_info.entropy_hash)) {
    DLOG(ERROR) << ENDPOINT << "Peer sent invalid entropy.";
    return false;
  }

  return true;
}

void QuicConnection::UpdatePacketInformationReceivedByPeer(
    const QuicAckFrame& incoming_ack) {
  SequenceNumberSet acked_packets;

  // ValidateAck should fail if largest_observed ever shrinks.
  DCHECK_LE(peer_largest_observed_packet_,
            incoming_ack.received_info.largest_observed);
  peer_largest_observed_packet_ = incoming_ack.received_info.largest_observed;

  if (incoming_ack.received_info.missing_packets.empty()) {
    least_packet_awaited_by_peer_ = peer_largest_observed_packet_ + 1;
  } else {
    least_packet_awaited_by_peer_ =
        *(incoming_ack.received_info.missing_packets.begin());
  }

  entropy_manager_.ClearSentEntropyBefore(least_packet_awaited_by_peer_ - 1);

  int retransmitted_packets = 0;
  // Go through the packets we have not received an ack for and see if this
  // incoming_ack shows they've been seen by the peer.
  UnackedPacketMap::iterator it = unacked_packets_.begin();
  while (it != unacked_packets_.end()) {
    QuicPacketSequenceNumber sequence_number = it->first;
    if (sequence_number > peer_largest_observed_packet_) {
      break;
    }
    RetransmittableFrames* unacked = it->second;
    if (!IsAwaitingPacket(incoming_ack.received_info, sequence_number)) {
      // Packet was acked, so remove it from our unacked packet list.
      DVLOG(1) << "Got an ack for " << sequence_number;
      acked_packets.insert(sequence_number);
      delete unacked;
      UnackedPacketMap::iterator it_tmp = it;
      ++it;
      unacked_packets_.erase(it_tmp);
      retransmission_map_.erase(sequence_number);
    } else {
      // This is a packet which we planned on retransmitting and has not been
      // seen at the time of this ack being sent out.  See if it's our new
      // lowest unacked packet.
      DVLOG(1) << "still missing " << sequence_number;
      ++it;
      // The peer got packets after this sequence number.  This is an explicit
      // nack.
      RetransmissionMap::iterator retransmission_it =
          retransmission_map_.find(sequence_number);
      ++(retransmission_it->second.number_nacks);
      if (retransmission_it->second.number_nacks >=
             kNumberOfNacksBeforeRetransmission &&
          retransmitted_packets < kMaxRetransmissionsPerAck) {
        ++retransmitted_packets;
        DVLOG(1) << "Trying to retransmit packet " << sequence_number
                 << " as it has been nacked 3 or more times.";
        // TODO(satyamshekhar): save in a vector and retransmit after the
        // loop.
        RetransmitPacket(sequence_number);
      }
    }
  }
  if (acked_packets.size() > 0) {
    visitor_->OnAck(acked_packets);
  }
}

bool QuicConnection::DontWaitForPacketsBefore(
    QuicPacketSequenceNumber least_unacked) {
  size_t missing_packets_count =
      outgoing_ack_.received_info.missing_packets.size();
  outgoing_ack_.received_info.missing_packets.erase(
      outgoing_ack_.received_info.missing_packets.begin(),
      outgoing_ack_.received_info.missing_packets.lower_bound(least_unacked));
  return missing_packets_count !=
      outgoing_ack_.received_info.missing_packets.size();
}

void QuicConnection::UpdatePacketInformationSentByPeer(
    const QuicAckFrame& incoming_ack) {
  // ValidateAck() should fail if peer_least_packet_awaiting_ack_ shrinks.
  DCHECK_LE(peer_least_packet_awaiting_ack_,
            incoming_ack.sent_info.least_unacked);
  if (incoming_ack.sent_info.least_unacked > peer_least_packet_awaiting_ack_) {
    bool missed_packets =
        DontWaitForPacketsBefore(incoming_ack.sent_info.least_unacked);
    if (missed_packets || incoming_ack.sent_info.least_unacked >
        outgoing_ack_.received_info.largest_observed + 1) {
      DVLOG(1) << "Updating entropy hashed since we missed packets";
      // There were some missing packets that we won't ever get now. Recalculate
      // the received entropy hash.
      entropy_manager_.RecalculateReceivedEntropyHash(
          incoming_ack.sent_info.least_unacked,
          incoming_ack.sent_info.entropy_hash);
    }
    peer_least_packet_awaiting_ack_ = incoming_ack.sent_info.least_unacked;
    // TODO(satyamshekhar): We get this iterator O(logN) in
    // RecalculateReceivedEntropyHash also.
    entropy_manager_.ClearReceivedEntropyBefore(
        peer_least_packet_awaiting_ack_);
  }
  DCHECK(outgoing_ack_.received_info.missing_packets.empty() ||
         *outgoing_ack_.received_info.missing_packets.begin() >=
             peer_least_packet_awaiting_ack_);
  // Possibly close any FecGroups which are now irrelevant
  CloseFecGroupsBefore(incoming_ack.sent_info.least_unacked + 1);
}

void QuicConnection::OnFecData(const QuicFecData& fec) {
  DCHECK_NE(0u, last_header_.fec_group);
  QuicFecGroup* group = GetFecGroup();
  group->UpdateFec(last_header_.packet_sequence_number,
                   last_header_.fec_entropy_flag, fec);
}

bool QuicConnection::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
  DCHECK(connected_);
  if (debug_visitor_) {
    debug_visitor_->OnRstStreamFrame(frame);
  }
  DLOG(INFO) << "Stream reset with error "
             << QuicUtils::StreamErrorToString(frame.error_code);
  visitor_->OnRstStream(frame);
  return connected_;
}

bool QuicConnection::OnConnectionCloseFrame(
    const QuicConnectionCloseFrame& frame) {
  DCHECK(connected_);
  if (debug_visitor_) {
    debug_visitor_->OnConnectionCloseFrame(frame);
  }
  DLOG(INFO) << ENDPOINT << "Connection closed with error "
             << QuicUtils::ErrorToString(frame.error_code);
  CloseConnection(frame.error_code, true);
  return false;
}

bool QuicConnection::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
  DCHECK(connected_);
  DLOG(INFO) << ENDPOINT << "Go away received with error "
             << QuicUtils::ErrorToString(frame.error_code)
             << " and reason:" << frame.reason_phrase;
  visitor_->OnGoAway(frame);
  return connected_;
}

void QuicConnection::OnPacketComplete() {
  // TODO(satyamshekhar): Don't do anything if this packet closed the
  // connection.
  if (!last_packet_revived_) {
    DLOG(INFO) << ENDPOINT << "Got packet "
               << last_header_.packet_sequence_number
               << " with " << last_stream_frames_.size()
               << " stream frames for " << last_header_.public_header.guid;
    congestion_manager_.RecordIncomingPacket(
        last_size_, last_header_.packet_sequence_number,
        time_of_last_received_packet_, last_packet_revived_);
  } else {
    DLOG(INFO) << ENDPOINT << "Got revived packet with "
               << last_stream_frames_.size() << " frames.";
  }

  if ((last_stream_frames_.empty() ||
       visitor_->OnPacket(self_address_, peer_address_,
                          last_header_, last_stream_frames_))) {
    RecordPacketReceived(last_header_);
  }

  MaybeSendAckInResponseToPacket();
  last_stream_frames_.clear();
}

QuicAckFrame* QuicConnection::CreateAckFrame() {
  UpdateOutgoingAck();
  if (time_largest_observed_ == QuicTime::Zero()) {
    // We have not received any new higher sequence numbers since we sent our
    // last ACK.
    outgoing_ack_.received_info.delta_time_largest_observed =
        QuicTime::Delta::Infinite();
  } else {
    outgoing_ack_.received_info.delta_time_largest_observed =
        clock_->ApproximateNow().Subtract(time_largest_observed_);

    time_largest_observed_ = QuicTime::Zero();
  }
  return new QuicAckFrame(outgoing_ack_);
}

QuicCongestionFeedbackFrame* QuicConnection::CreateFeedbackFrame() {
  return new QuicCongestionFeedbackFrame(outgoing_congestion_feedback_);
}

void QuicConnection::MaybeSendAckInResponseToPacket() {
  if (send_ack_in_response_to_packet_) {
    SendAck();
  } else if (!last_stream_frames_.empty()) {
    // TODO(alyssar) this case should really be "if the packet contained any
    // non-ack frame", rather than "if the packet contained a stream frame"
    helper_->SetAckAlarm(congestion_manager_.DefaultRetransmissionTime());
  }
  send_ack_in_response_to_packet_ = !send_ack_in_response_to_packet_;
}

void QuicConnection::SendVersionNegotiationPacket() {
  QuicVersionTagList supported_versions;
  supported_versions.push_back(kQuicVersion1);
  QuicEncryptedPacket* encrypted =
      packet_creator_.SerializeVersionNegotiationPacket(supported_versions);
  // TODO(satyamshekhar): implement zero server state negotiation.
  int error;
  helper_->WritePacketToWire(*encrypted, &error);
  delete encrypted;
}

QuicConsumedData QuicConnection::SendStreamData(QuicStreamId id,
                                                base::StringPiece data,
                                                QuicStreamOffset offset,
                                                bool fin) {
  return packet_generator_.ConsumeData(id, data, offset, fin);
}

void QuicConnection::SendRstStream(QuicStreamId id,
                                   QuicRstStreamErrorCode error) {
  packet_generator_.AddControlFrame(
      QuicFrame(new QuicRstStreamFrame(id, error)));
}

const QuicConnectionStats& QuicConnection::GetStats() {
  // Update rtt and estimated bandwidth.
  stats_.rtt = congestion_manager_.SmoothedRtt().ToMicroseconds();
  stats_.estimated_bandwidth =
      congestion_manager_.BandwidthEstimate().ToBytesPerSecond();
  return stats_;
}

void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address,
                                      const IPEndPoint& peer_address,
                                      const QuicEncryptedPacket& packet) {
  if (!connected_) {
    return;
  }
  if (debug_visitor_) {
    debug_visitor_->OnPacketReceived(self_address, peer_address, packet);
  }
  last_packet_revived_ = false;
  last_size_ = packet.length();
  last_self_address_ = self_address;
  last_peer_address_ = peer_address;

  stats_.bytes_received += packet.length();
  ++stats_.packets_received;

  framer_.ProcessPacket(packet);
  MaybeProcessRevivedPacket();
}

bool QuicConnection::OnCanWrite() {
  write_blocked_ = false;

  WriteQueuedPackets();

  // Sending queued packets may have caused the socket to become write blocked,
  // or the congestion manager to prohibit sending.  If we've sent everything
  // we had queued and we're still not blocked, let the visitor know it can
  // write more.
  if (CanWrite(NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA)) {
    packet_generator_.StartBatchOperations();
    bool all_bytes_written = visitor_->OnCanWrite();
    packet_generator_.FinishBatchOperations();

    // After the visitor writes, it may have caused the socket to become write
    // blocked or the congestion manager to prohibit sending, so check again.
    if (!write_blocked_ && !all_bytes_written &&
        CanWrite(NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA)) {
      // We're not write blocked, but some stream didn't write out all of its
      // bytes.  Register for 'immediate' resumption so we'll keep writing after
      // other quic connections have had a chance to use the socket.
      helper_->SetSendAlarm(clock_->ApproximateNow());
    }
  }

  return !write_blocked_;
}

bool QuicConnection::WriteQueuedPackets() {
  DCHECK(!write_blocked_);

  size_t num_queued_packets = queued_packets_.size() + 1;
  QueuedPacketList::iterator packet_iterator = queued_packets_.begin();
  while (!write_blocked_ && packet_iterator != queued_packets_.end()) {
    // Ensure that from one iteration of this loop to the next we
    // succeeded in sending a packet so we don't infinitely loop.
    // TODO(rch): clean up and close the connection if we really hit this.
    DCHECK_LT(queued_packets_.size(), num_queued_packets);
    num_queued_packets = queued_packets_.size();
    if (WritePacket(packet_iterator->sequence_number,
                    packet_iterator->packet,
                    packet_iterator->retransmittable,
                    NO_FORCE)) {
      packet_iterator = queued_packets_.erase(packet_iterator);
    } else {
      // Continue, because some queued packets may still be writable.
      // This can happen if a retransmit send fail.
      ++packet_iterator;
    }
  }

  return !write_blocked_;
}

void QuicConnection::RecordPacketReceived(const QuicPacketHeader& header) {
  DLOG(INFO) << ENDPOINT << "Recording received packet: "
             << header.packet_sequence_number;
  QuicPacketSequenceNumber sequence_number = header.packet_sequence_number;
  DCHECK(IsAwaitingPacket(outgoing_ack_.received_info, sequence_number));

  InsertMissingPacketsBetween(
      &outgoing_ack_.received_info,
      max(outgoing_ack_.received_info.largest_observed + 1,
          peer_least_packet_awaiting_ack_),
      header.packet_sequence_number);

  if (outgoing_ack_.received_info.largest_observed >
      header.packet_sequence_number) {
    // We've gotten one of the out of order packets - remove it from our
    // "missing packets" list.
    DVLOG(1) << "Removing "  << sequence_number << " from missing list";
    outgoing_ack_.received_info.missing_packets.erase(sequence_number);
  }
  if (header.packet_sequence_number >
      outgoing_ack_.received_info.largest_observed) {
    outgoing_ack_.received_info.largest_observed =
        header.packet_sequence_number;
    time_largest_observed_ = time_of_last_received_packet_;
  }
  entropy_manager_.RecordReceivedPacketEntropyHash(sequence_number,
                                                   header.entropy_hash);
}

bool QuicConnection::MaybeRetransmitPacketForRTO(
    QuicPacketSequenceNumber sequence_number) {
  DCHECK_EQ(ContainsKey(unacked_packets_, sequence_number),
            ContainsKey(retransmission_map_, sequence_number));

  if (!ContainsKey(unacked_packets_, sequence_number)) {
    DVLOG(2) << "alarm fired for " << sequence_number
             << " but it has been acked or already retransmitted with"
             << " different sequence number.";
    // So no extra delay is added for this packet.
    return true;
  }

  // If the packet hasn't been acked and we're getting truncated acks, ignore
  // any RTO for packets larger than the peer's largest observed packet; it may
  // have been received by the peer and just wasn't acked due to the ack frame
  // running out of space.
  if (received_truncated_ack_ &&
      sequence_number > peer_largest_observed_packet_) {
    return false;
  } else {
    ++stats_.rto_count;
    RetransmitPacket(sequence_number);
    return true;
  }
}

void QuicConnection::RetransmitAllUnackedPackets() {
  for (UnackedPacketMap::iterator it = unacked_packets_.begin();
       it != unacked_packets_.end(); ++it) {
    RetransmitPacket(it->first);
  }
}

void QuicConnection::RetransmitPacket(
    QuicPacketSequenceNumber sequence_number) {
  UnackedPacketMap::iterator unacked_it =
      unacked_packets_.find(sequence_number);
  RetransmissionMap::iterator retransmission_it =
      retransmission_map_.find(sequence_number);
  // There should always be an entry corresponding to |sequence_number| in
  // both |retransmission_map_| and |unacked_packets_|. Retransmissions due to
  // RTO for sequence numbers that are already acked or retransmitted are
  // ignored by MaybeRetransmitPacketForRTO.
  DCHECK(unacked_it != unacked_packets_.end());
  DCHECK(retransmission_it != retransmission_map_.end());
  RetransmittableFrames* unacked = unacked_it->second;
  // TODO(pwestin): Need to fix potential issue with FEC and a 1 packet
  // congestion window see b/8331807 for details.
  congestion_manager_.AbandoningPacket(sequence_number);
  // TODO(ianswett): Never change the sequence number of the connect packet.
  // Re-packetize the frames with a new sequence number for retransmission.
  // Retransmitted data packets do not use FEC, even when it's enabled.
  SerializedPacket serialized_packet =
      packet_creator_.SerializeAllFrames(unacked->frames());
  RetransmissionInfo retransmission_info(serialized_packet.sequence_number);
  retransmission_info.number_retransmissions =
      retransmission_it->second.number_retransmissions + 1;
  retransmission_map_.insert(make_pair(serialized_packet.sequence_number,
                                       retransmission_info));
  // Remove info with old sequence number.
  unacked_packets_.erase(unacked_it);
  retransmission_map_.erase(retransmission_it);
  DVLOG(1) << "Retransmitting unacked packet " << sequence_number << " as "
           << serialized_packet.sequence_number;
  DCHECK(unacked_packets_.empty() ||
         unacked_packets_.rbegin()->first < serialized_packet.sequence_number);
  unacked_packets_.insert(make_pair(serialized_packet.sequence_number,
                                    unacked));
  SendOrQueuePacket(serialized_packet.sequence_number,
                    serialized_packet.packet,
                    serialized_packet.entropy_hash,
                    HAS_RETRANSMITTABLE_DATA);
}

bool QuicConnection::CanWrite(Retransmission retransmission,
                              HasRetransmittableData retransmittable) {
  // TODO(ianswett): If the packet is a retransmit, the current send alarm may
  // be too long.
  if (write_blocked_ || helper_->IsSendAlarmSet()) {
    return false;
  }

  QuicTime now = clock_->Now();
  QuicTime::Delta delay = congestion_manager_.TimeUntilSend(
      now, retransmission, retransmittable);
  if (delay.IsInfinite()) {
    return false;
  }

  // If the scheduler requires a delay, then we can not send this packet now.
  if (!delay.IsZero()) {
    helper_->SetSendAlarm(now.Add(delay));
    return false;
  }
  return true;
}

bool QuicConnection::IsRetransmission(
    QuicPacketSequenceNumber sequence_number) {
  RetransmissionMap::iterator it = retransmission_map_.find(sequence_number);
  return it != retransmission_map_.end() &&
      it->second.number_retransmissions > 0;
}

void QuicConnection::MaybeSetupRetransmission(
    QuicPacketSequenceNumber sequence_number) {
  RetransmissionMap::iterator it = retransmission_map_.find(sequence_number);
  if (it == retransmission_map_.end()) {
    DVLOG(1) << "Will not retransmit packet " << sequence_number;
    return;
  }

  RetransmissionInfo retransmission_info = it->second;
  QuicTime::Delta retransmission_delay =
      congestion_manager_.GetRetransmissionDelay(
          unacked_packets_.size(),
          retransmission_info.number_retransmissions);
  retransmission_info.scheduled_time =
      clock_->ApproximateNow().Add(retransmission_delay);
  retransmission_timeouts_.push(retransmission_info);

  // Do not set the retransmisson alarm if we're already handling the
  // retransmission alarm because the retransmission alarm will be reset when
  // OnRetransmissionTimeout completes.
  if (!handling_retransmission_timeout_) {
    helper_->SetRetransmissionAlarm(retransmission_delay);
  }
  // TODO(satyamshekhar): restore packet reordering with Ian's TODO in
  // SendStreamData().
}

bool QuicConnection::WritePacket(QuicPacketSequenceNumber sequence_number,
                                 QuicPacket* packet,
                                 HasRetransmittableData retransmittable,
                                 Force forced) {
  if (!connected_) {
    DLOG(INFO) << ENDPOINT
               << "Not sending packet as connection is disconnected.";
    delete packet;
    // Returning true because we deleted the packet and the caller shouldn't
    // delete it again.
    return true;
  }

  Retransmission retransmission = IsRetransmission(sequence_number) ?
      IS_RETRANSMISSION : NOT_RETRANSMISSION;
  // If we are not forced and we can't write, then simply return false;
  if (forced == NO_FORCE && !CanWrite(retransmission, retransmittable)) {
    return false;
  }

  scoped_ptr<QuicEncryptedPacket> encrypted(
      framer_.EncryptPacket(sequence_number, *packet));
  DLOG(INFO) << ENDPOINT << "Sending packet number " << sequence_number
             << " : " << (packet->is_fec_packet() ? "FEC " :
                 (retransmittable == HAS_RETRANSMITTABLE_DATA
                      ? "data bearing " : " ack only "))
             << " Packet length:" << packet->length();

  DCHECK(encrypted->length() <= kMaxPacketSize)
      << "Packet " << sequence_number << " will not be read; too large: "
      << packet->length() << " " << encrypted->length() << " "
      << outgoing_ack_ << " forced: " << (forced == FORCE ? "yes" : "no");

  int error;
  QuicTime now = clock_->Now();
  int rv = helper_->WritePacketToWire(*encrypted, &error);
  if (rv == -1 && helper_->IsWriteBlocked(error)) {
    // TODO(satyashekhar): It might be more efficient (fewer system calls), if
    // all connections share this variable i.e this becomes a part of
    // PacketWriterInterface.
    write_blocked_ = true;
    // If the socket buffers the the data, then the packet should not
    // be queued and sent again, which would result in an unnecessary duplicate
    // packet being sent.
    return helper_->IsWriteBlockedDataBuffered();
  }
  time_of_last_sent_packet_ = now;
  DVLOG(1) << "time of last sent packet: " << now.ToDebuggingValue();
  // TODO(wtc): Is it correct to continue if the write failed.

  // Set the retransmit alarm only when we have sent the packet to the client
  // and not when it goes to the pending queue, otherwise we will end up adding
  // an entry to retransmission_timeout_ every time we attempt a write.
  MaybeSetupRetransmission(sequence_number);

  congestion_manager_.SentPacket(sequence_number, now, packet->length(),
                                 retransmission);

  stats_.bytes_sent += encrypted->length();
  ++stats_.packets_sent;

  if (retransmission == IS_RETRANSMISSION) {
    stats_.bytes_retransmitted += encrypted->length();
    ++stats_.packets_retransmitted;
  }

  delete packet;
  return true;
}

bool QuicConnection::OnSerializedPacket(
    const SerializedPacket& serialized_packet) {
  if (serialized_packet.retransmittable_frames != NULL) {
    DCHECK(unacked_packets_.empty() ||
           unacked_packets_.rbegin()->first <
               serialized_packet.sequence_number);
    unacked_packets_.insert(
        make_pair(serialized_packet.sequence_number,
                  serialized_packet.retransmittable_frames));
    // All unacked packets might be retransmitted.
    retransmission_map_.insert(
        make_pair(serialized_packet.sequence_number,
                  RetransmissionInfo(serialized_packet.sequence_number)));
  }
  return SendOrQueuePacket(serialized_packet.sequence_number,
                           serialized_packet.packet,
                           serialized_packet.entropy_hash,
                           serialized_packet.retransmittable_frames != NULL ?
                               HAS_RETRANSMITTABLE_DATA :
                               NO_RETRANSMITTABLE_DATA);
}

bool QuicConnection::SendOrQueuePacket(QuicPacketSequenceNumber sequence_number,
                                       QuicPacket* packet,
                                       QuicPacketEntropyHash entropy_hash,
                                       HasRetransmittableData retransmittable) {
  entropy_manager_.RecordSentPacketEntropyHash(sequence_number, entropy_hash);
  if (!WritePacket(sequence_number, packet, retransmittable, NO_FORCE)) {
    queued_packets_.push_back(QueuedPacket(sequence_number, packet,
                                           retransmittable));
    return false;
  }
  return true;
}

bool QuicConnection::ShouldSimulateLostPacket() {
  // TODO(rch): enable this
  return false;
  /*
  return FLAGS_fake_packet_loss_percentage > 0 &&
      random_->Rand32() % 100 < FLAGS_fake_packet_loss_percentage;
  */
}

void QuicConnection::UpdateOutgoingAck() {
  if (!unacked_packets_.empty()) {
    outgoing_ack_.sent_info.least_unacked = unacked_packets_.begin()->first;
  } else {
    // If there are no unacked packets, set the least unacked packet to
    // sequence_number() + 1 since that will be the sequence number of this
    // ack packet whenever it is sent.
    outgoing_ack_.sent_info.least_unacked =
        packet_creator_.sequence_number() + 1;
  }
  outgoing_ack_.sent_info.entropy_hash = entropy_manager_.SentEntropyHash(
      outgoing_ack_.sent_info.least_unacked - 1);
  outgoing_ack_.received_info.entropy_hash =
      entropy_manager_.ReceivedEntropyHash(
          outgoing_ack_.received_info.largest_observed);
}

void QuicConnection::SendAck() {
  helper_->ClearAckAlarm();
  UpdateOutgoingAck();
  DVLOG(1) << "Sending ack: " << outgoing_ack_;

  // TODO(rch): delay this until the CreateFeedbackFrame
  // method is invoked.  This requires changes SetShouldSendAck
  // to be a no-arg method, and re-jiggering its implementation.
  bool send_feedback = false;
  if (congestion_manager_.GenerateCongestionFeedback(
          &outgoing_congestion_feedback_)) {
    DVLOG(1) << "Sending feedback " << outgoing_congestion_feedback_;
    send_feedback = true;
  }

  packet_generator_.SetShouldSendAck(send_feedback);
}

QuicTime QuicConnection::OnRetransmissionTimeout() {
  // This guards against registering the alarm later than we should.
  //
  // If we have packet A and B in the list and we call
  // MaybeRetransmitPacketForRTO on A, that may trigger a call to
  // SetRetransmissionAlarm if A is retransmitted as C.  In that case we
  // don't want to register the alarm under SetRetransmissionAlarm; we
  // want to set it to the RTO of B when we return from this function.
  handling_retransmission_timeout_ = true;

  for (int i = 0; i < kMaxPacketsPerRetransmissionAlarm &&
           !retransmission_timeouts_.empty(); ++i) {
    RetransmissionInfo retransmission_info = retransmission_timeouts_.top();
    DCHECK(retransmission_info.scheduled_time.IsInitialized());
    if (retransmission_info.scheduled_time > clock_->ApproximateNow()) {
      break;
    }
    retransmission_timeouts_.pop();
    if (!MaybeRetransmitPacketForRTO(retransmission_info.sequence_number)) {
      DLOG(INFO) << ENDPOINT << "MaybeRetransmitPacketForRTO failed: "
                 << "adding an extra delay for "
                 << retransmission_info.sequence_number;
      retransmission_info.scheduled_time = clock_->ApproximateNow().Add(
          congestion_manager_.DefaultRetransmissionTime());
      retransmission_timeouts_.push(retransmission_info);
    }
  }

  handling_retransmission_timeout_ = false;

  if (retransmission_timeouts_.empty()) {
    return QuicTime::Zero();
  }

  // We have packets remaining.  Return the absolute RTO of the oldest packet
  // on the list.
  return retransmission_timeouts_.top().scheduled_time;
}

void QuicConnection::ChangeEncrypter(QuicEncrypter* encrypter) {
  framer_.set_encrypter(encrypter);
}

void QuicConnection::PushDecrypter(QuicDecrypter* decrypter) {
  framer_.push_decrypter(decrypter);
}

void QuicConnection::PopDecrypter() {
  framer_.pop_decrypter();
}

void QuicConnection::MaybeProcessRevivedPacket() {
  QuicFecGroup* group = GetFecGroup();
  if (group == NULL || !group->CanRevive()) {
    return;
  }
  QuicPacketHeader revived_header;
  char revived_payload[kMaxPacketSize];
  size_t len = group->Revive(&revived_header, revived_payload, kMaxPacketSize);
  revived_header.public_header.guid = guid_;
  revived_header.public_header.version_flag = false;
  revived_header.public_header.reset_flag = false;
  revived_header.fec_flag = false;
  revived_header.fec_group = kNoFecOffset;
  group_map_.erase(last_header_.fec_group);
  delete group;

  last_packet_revived_ = true;
  if (debug_visitor_) {
    debug_visitor_->OnRevivedPacket(revived_header,
                                    StringPiece(revived_payload, len));
  }

  ++stats_.packets_revived;
  framer_.ProcessRevivedPacket(&revived_header,
                               StringPiece(revived_payload, len));
}

QuicFecGroup* QuicConnection::GetFecGroup() {
  QuicFecGroupNumber fec_group_num = last_header_.fec_group;
  if (fec_group_num == 0) {
    return NULL;
  }
  if (group_map_.count(fec_group_num) == 0) {
    // TODO(rch): limit the number of active FEC groups.
    group_map_[fec_group_num] = new QuicFecGroup();
  }
  return group_map_[fec_group_num];
}

void QuicConnection::SendConnectionClose(QuicErrorCode error) {
  SendConnectionCloseWithDetails(error, string());
}

void QuicConnection::SendConnectionClosePacket(QuicErrorCode error,
                                               const string& details) {
  DLOG(INFO) << ENDPOINT << "Force closing with error "
             << QuicUtils::ErrorToString(error) << " (" << error << ") "
             << details;
  QuicConnectionCloseFrame frame;
  frame.error_code = error;
  frame.error_details = details;
  UpdateOutgoingAck();
  frame.ack_frame = outgoing_ack_;

  SerializedPacket serialized_packet =
      packet_creator_.SerializeConnectionClose(&frame);

  // We need to update the sent entrophy hash for all sent packets.
  entropy_manager_.RecordSentPacketEntropyHash(
      serialized_packet.sequence_number,
      serialized_packet.entropy_hash);

  WritePacket(serialized_packet.sequence_number,
              serialized_packet.packet,
              serialized_packet.retransmittable_frames != NULL ?
                  HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA,
              FORCE);
}

void QuicConnection::SendConnectionCloseWithDetails(QuicErrorCode error,
                                                    const string& details) {
  SendConnectionClosePacket(error, details);
  CloseConnection(error, false);
}

void QuicConnection::CloseConnection(QuicErrorCode error, bool from_peer) {
  connected_ = false;
  visitor_->ConnectionClose(error, from_peer);
}

void QuicConnection::SendGoAway(QuicErrorCode error,
                                QuicStreamId last_good_stream_id,
                                const string& reason) {
  DLOG(INFO) << ENDPOINT << "Going away with error "
             << QuicUtils::ErrorToString(error)
             << " (" << error << ")";
  packet_generator_.AddControlFrame(
      QuicFrame(new QuicGoAwayFrame(error, last_good_stream_id, reason)));
}

void QuicConnection::CloseFecGroupsBefore(
    QuicPacketSequenceNumber sequence_number) {
  FecGroupMap::iterator it = group_map_.begin();
  while (it != group_map_.end()) {
    // If this is the current group or the group doesn't protect this packet
    // we can ignore it.
    if (last_header_.fec_group == it->first ||
        !it->second->ProtectsPacketsBefore(sequence_number)) {
      ++it;
      continue;
    }
    QuicFecGroup* fec_group = it->second;
    DCHECK(!fec_group->CanRevive());
    FecGroupMap::iterator next = it;
    ++next;
    group_map_.erase(it);
    delete fec_group;
    it = next;
  }
}

bool QuicConnection::HasQueuedData() const {
  return !queued_packets_.empty() || packet_generator_.HasQueuedData();
}

bool QuicConnection::CheckForTimeout() {
  QuicTime now = clock_->ApproximateNow();
  QuicTime time_of_last_packet = std::max(time_of_last_received_packet_,
                                          time_of_last_sent_packet_);

  QuicTime::Delta delta = now.Subtract(time_of_last_packet);
  DVLOG(1) << "last packet " << time_of_last_packet.ToDebuggingValue()
           << " now:" << now.ToDebuggingValue()
           << " delta:" << delta.ToMicroseconds();
  if (delta >= timeout_) {
    SendConnectionClose(QUIC_CONNECTION_TIMED_OUT);
    return true;
  }
  helper_->SetTimeoutAlarm(timeout_.Subtract(delta));
  return false;
}

}  // namespace net


Replacement O-Ring for Twist Lock for the Aqua Medic Turboflotor 1000 Protein Skimmer & Kalkwasser Stirrer 1000.
Replacement Foam Cup for the Aqua Medic Turboflotor Blue 500 Protein Skimmer.
Replacement Aqua Medic Turboflotor T1000 Multi SL Protein Skimmer NEW-style Air Inlet w/ Reducing Nozzle.


text:
Visitors' Choice Delta
B.C. Centre for Disease Control's public health survey had nearly 400,000 people participate. (B.C. government)
B.C.'s COVID-19 community infection rate held below 1%
Survey finds widespread worry about pandemic impact
Jul. 20, 2020 3:00 p.m.
B.C.'s efforts to flatten the COVID-19 pandemic curve continue to be successful, but the restrictions are having a significant effect on residents as they drag on into the summer.
Those are among the findings of the health ministry's survey of nearly 400,000 people, and the latest modelling from the B.C. Centre for Disease Control.
Provincial health officer Dr. Bonnie Henry and Health Minister Adrian Dix released the modelling results and survey data July 20, showing that the summer reopening of the economy has led to only a few additional confirmed coronavirus infections in June and early July. They warn that the small number of cases so far makes it difficult to project how the rest of the summer will unfold, as travel picks up around the province and from outside it.
The case numbers show that community COVID-19 infection rates have stayed below one per cent, and antibody testing shows less than one per cent of the population has been exposed. As with other regions, the BCCDC estimates that the actual number of infections is about eight times the reported cases.
Snapshot for week of July 5-9 compared to previous week is encouraging, but latest results are troubling #COVID19BC #bcleg pic.twitter.com/qR33sJijza
— Tom Fletcher (@tomfletcherbc) July 20, 2020
Henry said public health officials expected to see increased cases, but the risk for B.C. now is that clusters of infection are showing up after gatherings in restaurants, bars, house parties and houseboats.
"It might be a small group one night and a different small group the next time, and those are the environments where this virus can be passed on," Henry said, adding B.C. still does have "the possibility of explosive growth unless we're careful."
The most recent case results are a concern, with 102 positive tests recorded from July 17-20, Henry said.
RELATED: B.C. records 102 new cases, no deaths since Friday
RELATED: B.C.'s COVID-19 deficit could go deeper than $12.5B
The survey reflects the employment impacts measured so far, as B.C. families with children report a greater mental health and economic burden than the broader population. B.C. residents aged 18 to 29 also report greater mental health and economic effects, as they face the highest unemployment rate.
The survey finds that four out of five B.C. residents approve of the province's response to the pandemic, with 96 per cent reporting they practice preventive personal hygiene such as hand washing and physical distance.
Delta police investigating alleged assault in Tsawwassen
Choom's application for White Rock pot shop withdrawn
Delta Police dog retires on a high note after decade of service
Nine-year-old German Shepherd now fights over toys instead of chasing down bad guys
Abbotsford aviation company offering two free pilot scholarships
Canwest Aero Inc. giving away pair of scholarships valued at $2,500 each
Explore North Delta Reporter
Delta News
Delta Weather
Delta Classifieds
© 2021, North Delta Reporter and Black Press Group Ltd.

redpajama_set_name: RedPajamaCommonCrawl


Every now and again, as a writer, I pen a paragraph or phrase that I REALLY, REALLY like. The words flow in a way that I find personally poetic. The idea conveyed seems deeply honest. The descriptions work… And, invariably, I wonder if I should delete it. Surely, it comes across as too writerly, I'll think. The prose is probably borderline purple. It betrays my own feelings too explicitly. It's self-indulgent to leave it. I can say whatever it is in a simpler, direct fashion. My journalism training returns: just the facts man, leave your editorializing and flowery language out of it. Many times I listen to myself and delete it. Sometimes, I try to sneak it in, and my editor suggests that I take an ax to it. Once in awhile, though, I'll get to keep it. This paragraph (pictured) in Lies She Told is an example of it. I'm happy that I kept it. It's my favorite in the book. It's my darling. And I'm glad I didn't delete her. Do you kill your darlings or do you try to keep them?


text:
Federal spending transparency website riddled with errors: GAO audit
Inaccuracies cast doubt on Obama adminstration's commitment to USASpending.gov
Sen. Tom Coburn, the Oklahoma Republican who worked on the bipartisan USASpending.gov website to audit government spending, says that the site's accuracy rate is incredibly flawed. (Associated Press) more >
By Stephen Dinan - The Washington Times - Tuesday, August 5, 2014
It's supposed to be the government's transparency website so that the public can see how taxpayer money is spent, but USASpending.gov is so error-prone that it's missing more than $600 billion in awards from 2012 alone, and as much as 98 percent of its records were plagued by inaccuracies, according to a scathing new audit.
The website was a special bipartisan project of then-Sen. Barack Obama and Sen. Tom Coburn during Mr. Obama's brief tenure in Congress, but the Government Accountability Office said in a report last week that the Obama administration has been less than stellar in following through on making the openness initiative work.
Some agencies claimed not to know what to report, while others ignored the instructions. And even those that were reporting data got it wrong, the GAO said.
"The administration set a goal of 100 percent accuracy by the end of 2011," Mr. Coburn, Oklahoma Republican and Congress's top waste watcher, said. "Three years later the federal government cannot even break a 10 percent accuracy rate."
The website, which has become a key tool for citizen watchdogs and journalists, misreported the name of the entity receiving money in about one in 20 cases, botched the dollar amount in as many as 7 percent of awards, obfuscated the purpose of the money in up to 33 percent of cases and botched the location of the recipient in even more instances, the GAO audit said.
A sampling of data found just 4 percent of records were error-free, and that number could be as low as 2 percent when extrapolated governmentwide, the auditors said.
SEE ALSO: STVERAK: Organizing for Action: Obama's broken transparency promises
The administration's commitment to openness took another hit Tuesday when the government's top inspectors general, who are the first line of defense against waste and abuse, sent a letter to Congress Tuesday warning they are getting stonewalled on key investigations by the Obama administration.
"Limiting access in this manner is inconsistent with the IG Act, at odds with the independence of inspectors general and risks leaving the agencies insulated from scrutiny and unacceptably vulnerable to mismanagement and misconduct — the very problems that our offices were established to review and that the American people expect us to be able to address," the 47 IGs said in their letter.
Among the inspectors general that have raised specific complaints just this year have been the top watchdogs for the Peace Corps and the Department of Justice, both of whom say they were blocked from key information in sensitive probes.
Mr. Obama won office promising to run "the most transparent" White House in history, including opening up negotiations on bills to C-SPAN audiences, releasing the names of lobbyists who visited the White House and encouraging agencies to assume information is public unless there's a very strong legal reason to withhold it.
But Iowa Sen. Chuck Grassley, the ranking Republican on the Senate Committee on the Judiciary, said the IGs' joint complaint undercuts that record.
"These nonpartisan, independent agency watchdogs say they are getting stonewalled," Mr. Grassley wrote in a letter of his own Tuesday. "How are the watchdogs supposed to be able to do their jobs without agency cooperation?"
PHOTOS: See Obama's biggest White House fails
The spending website was one of Mr. Obama's earliest achievements while serving as a senator from Illinois, stemming from a bill he sponsored with Mr. Coburn in 2006, which was signed by then-President George W. Bush.
Mr. Obama even touted the measure during the 2008 presidential debates, citing his work on "what we call 'Google for Government,' which says that we are going to list every dollar of federal spending."
In office at the White House, however, his administration's record has been mixed.
The GAO said his budget office took some steps, issuing guidance and clarifications to try to figure out what's to be posted. But the Office of Management and Budget also has ignored repeated warnings from the GAO that reporting standards for executive branch agencies fell short. The OMB said it recognized the errors but never took steps to correct them, investigators said.
OMB spokesman Jamal Brown said officials want to get the transparency policies right, and said many of the GAO's recommendations are now part of the new federal DATA Act, which pushes agencies to clean up data and comply with disclosure.
"OMB is committed to federal spending transparency and working with agencies to improve the completeness and accuracy of data submissions to USASpending.gov," Mr. Brown said.
The DATA Act passed Congress earlier this year and was signed by Mr. Obama in May. It transfers oversight of the spending website from the OMB to the Department of the Treasury.
Treasury Department officials submitted a short response to the GAO saying they "appreciate your comments and will take them into consideration" as they ramp up new oversight controls.
Both Democrats and Republicans on Capitol Hill said the new GAO report gives them a road map to make sure the administration follows through on the DATA Act.
"It is completely unacceptable that the federal government continues to struggle to report even the most basic information on how taxpayer resources are spent," said Sen. Mark R. Warner, Virginia Democrat.
• Stephen Dinan can be reached at sdinan@washingtontimes.com.


Berrys' 2011 Fine Wine Report seeks to identify trends within the global wine market, highlighting potential and existing problems as well as flagging up exciting signs of progress, particularly in the realm of improvements in the quality of wine.
Berry Bros. & Rudd is the UK's oldest wine merchant, founded in 1698, and has, over the course of more than three centuries, developed a reputation not only for the quality of its wines but also for the authority and expertise of its key personnel in both Buying and Sales. The Company boasts five Masters of Wine, a remarkable number out of the global total of 290, four of whom have contributed to this Fine Wine Report.
Bordeaux's markets for its wines are very diverse, but 68% by volume is sold in France, with only 32% going to export. In terms of value, however, the position is very different, with France accounting for only 55% of the total, showing that a sizeable volume of lower-priced wine goes through multiple retailers, while overseas countries are more interested in the higher-quality, more expensive bottles.
Of the major export markets, Germany is the No.1 destination for volume sales, followed by China, but when value is the determining factor then Hong Kong, the UK and China fill the top three places with Germany only 5th.
Whilst the vast majority of Bordeaux wine is made to be drunk and enjoyed relatively young, the very top echelon of super-premium wines have the capacity to mature and to improve with age over an extended period of time, up to 60 years in some cases, and this latter category has recently become the focus of some extremely speculative buying. It is not difficult to see why; the volume of wine produced from the top estates is strictly defined by law, so there is no question of simply turning on the tap and increasing production.
For decades the only markets for these top wines lay in Europe and North America, and prices remained relatively stable with the principal fluctuations caused by the varying qualities of each vintage. Recently, however while production remains unchanged, demand has risen sharply, with new entrants to the markets from Russia, Asia and South America. Under these circumstances prices for the best vintages have unsurprisingly soared, and châteaux proprietors, alive to the burgeoning interest in their wines, have not been slow to capitalise.
The ever-increasing demand for these top wines has created, over the past 30 years, an en-primeur market, in other words the chance to buy these wines as "futures", some 2 years before they are actually bottled. The world's merchants and journalists descend on Bordeaux in April each year to taste the previous year's wine, at this stage just 6 months old.
The châteaux release their opening prices during May and June, often waiting for the pronouncement of the world's most influential wine writer, Robert Parker, before deciding where to pitch their wine. In the past decade we have seen four exceptional vintages, each arguably better than the one before, in 2000, 2005, 2009 and 2010. Release prices have risen to unprecedented levels, but this has failed to put a brake on demand thus far.
Historically the Burgundian market place has been divided between merchants, who bought grapes, grape juice at harvest or wines subsequently, and blended them according to their house style and traditions, and individual domaines responsible for all aspects of production from growing the vines to bottling the wines and taking them to market.


This article was first published in the Northwest Florida Daily News on Sunday, July 16, 2017.
I don't think any of us realize how much we switch our brains off when we're playing tourist.
As I mentioned a couple of weeks ago, I recently took an overseas trip and did some people watching to see how both I and my fellow travelers behaved when we were being tourists. You should try it, it's enlightening. I'd suggest that you also notice how you behave yourself, as I don't think any of us realize how much we switch our brains off when we're playing tourist.
A number of airports have recently released details of the things that people try to take on flights. Would you believe live lobsters? Yes, apparently that's quite common. You know how things are when you see that 20-pound LIVE lobster and you MUST take it home? Yep, stick it in your hand luggage.
According to the British Broadcasting Corporation (BBC), one of the things that's most common to be found in luggage on the Eurostar (the train that goes under the English Channel between France and England) is unexplored World War I ordnance. Apparently people dig them up when visiting the battlefields of Northern Europe and think it's a.) a great souvenir to put on a shelf at home and b.) perfectly acceptable to carry in baggage on a public train in a tunnel underwater.
There's also well-documented tales of people trying to check in palm trees, a 10-pound frozen turkey, and bricks. Pairs of pink fluffy handcuffs are also a common find. The mind boggles!
However, it's the completely innocent items that we tend to forget about. Snow globes? Yes, seems OK as a souvenir, but breaks the rules about the amount of liquid you can take on a flight. How about that fondue set that seemed such a great present for your parents? The little forks that come with it are looked on by the Transportation Security Administration (TSA) as potential weapons.
Closer to home are the frankly strange things that people do to the condos and beach homes they stay in. Most regular are the visitors who completely rearrange the furniture. I've been guilty of a bit of this myself, but always put it back the way I found it. I also heard of one group of guests who moved all the sofas and chairs out onto the beach! You can imagine how that went down with the owners. I've also heard of renters turning up with full tool sets so they can carry out their own maintenance and modifications.
Getting back to the airports, have you ever noticed tourists going through security who have been told to empty their pockets, put their electronics in the bin and put all their liquids in a plastic bag, yet then try to carry their phones and a can of Coke through the body scanner? Happens every time I'm waiting in line behind them.


text:
Clipper agrees new ten year contract with mountain warehouse
Clipper, a leading provider of value-added logistics solutions, e-fulfilment and returns management services, is pleased to announce that it has signed a new ten year open book contract with Mountain Warehouse, the UK's leading outdoor retailer.
The new contract is expected to commence in spring 2021. Investment in automation and robotics will increase capacity to facilitate further growth for the customer, and the new contract will operate from Clipper's existing Peterborough distribution centre.
This will be a fast-moving multi-channel logistics operation, operating seven days per week. Clipper will provide full end-to-end services to support Mountain Warehouse's multi-channel operations, including order fulfilment and returns management.
Marcus Ward, Chief Operating and Financial Office of Mountain Warehouse commented: "We have been impressed with Clipper's innovative thinking and track record. The engagement from Clipper's senior team from an early stage and Clipper's proven ability to meet our high standards, has given us the confidence to enter into a long term partnership. We are really excited to get started."
Steve Parkin, Executive Chairman of Clipper said: "We are delighted to welcome Mountain Warehouse to the ever-growing family of Clipper customers. The contract is a clear indication of the collaboration and use of shared resources that will define the retail logistics supply chain into the future. The contract enhances our command of the end-to-end service proposition in online retail, and demonstrate that Clipper is also well-positioned to continue to support high street retail as it recovers from lockdown. Our strategy to focus on providing innovative solutions in both the online and traditional bricks and mortar retail landscapes continues to drive value for our customers.


Currently, Caplan is working on restoring a 150-year-old farmstead where he and his family tend sheep and chickens, grow most of their own vegetables, and have a small apple orchard.
I write because it's the best drug in the world, a total immersion in a fantasy world that comes alive every time I set to work.
I am a hybrid writer. I started out as a seat of the pants sort, but have evolved in my approach over the years. Now I start out by doing lots of research on my subject area: time period, technology, etc. and at the same time am developing major plot outlines and character sketches. But once I get started I let the process take over and continue to evolve the plot and characters right through the first draft.
I generally make notes to myself on the document as I am writing whenever I think of something that might impact the story development.
My characters come alive as i write. They are alive on the page. In my head they are like puppets, dormant, perhaps with an interior life of their own, but I only hear them once I begin writing.
Keep reading. Keep writing. Refine your niche. Define your markets. Network with other writers. Travel.
By a process of elimination. I always start out looking for a publisher to take on my books as I prefer to write rather than market my books, but fortunately or unfortunately, the publishing world has evolved so that self-publishing is an increasingly viable, though crowded, option.
I believe the future is wide open. We are not going back to the days of a few major publishers having the exclusive filter on what the reading public has access to. The freedom of readers and writers will only increase as technology continues to open up new opportunities.
What genres do you write?: literary, contemporary, science fiction, thriller, dystopian.


Firstly, we use the official property for the task, navigator.cookieEnabled, to help determine whether the browser has cookies enabled. However, we immediately run into a limitation- this property is supported only in IE4+ and NS6+. So, in both cases where the property returns false or does not exist (in other browsers), we set the variable cookieEnabled to false instead for continued investigation.
Moving on, it's now time to probe all other browsers for cookie availability. The age-old "give it a try" technique works nicely. By setting a dummy value to document.cookie and immediately probing it to see if the value is retained, we can tell if cookies is enabled on the client's end.
The variable cookieEnabled now contains a Boolean value indicating the client's cookie support. Nice and crunchy!


Pratt's lawn & Landscape, Inc., has served Georgetown, Lexington and surrounding areas within Kentucky since 1993. We offer year round, comprehensive landscape services for residential homes, commercial buildings, town homes, condos and more.
Leia is a Jack Russel and born in the spring of 2013. She belongs to one of our landscape architects, Thad Ross, and comes to work with him every day. She is considered a member of our team and the mascot for our company.


Are you in Eldoret,Nairobi, Machakos, Kisii and Nakuru looking for a part-time or job replacing income?? If yes whats app 0701860328 with the word "info"
Add an extra 10,000 -20,000 weekly on your salary extra income.. Send INTERESTED on whatsapp via 0708666402 and I'll get back to you immediately.
Enter your email address to receive alerts when we have new listings available for kenya latest jobs online 2017.


text:
OER Glossary | Contact us
NIH Public Access Policy Details
The NIH Public Access Policy implements Division F Section 217 of PL 111-8 (Omnibus Appropriations Act, 2009). The law states:
The Director of the National Institutes of Health ("NIH") shall require in the current fiscal year and thereafter that all investigators funded by the NIH submit or have submitted for them to the National Library of Medicine's PubMed Central an electronic version of their final, peer-reviewed manuscripts upon acceptance for publication, to be made publicly available no later than 12 months after the official date of publication: Provided, that the NIH shall implement the public access policy in a manner consistent with copyright law.
Guide Notices
Testimony and Other Policy Related Communications
The Policy applies to any manuscript1 that:
Is peer-reviewed;
And, is accepted for publication in a journal2 on or after April 7, 20083;
And, arises from:
Any direct funding4 from an NIH grant or cooperative agreement active in Fiscal Year 2008 or beyond, or;
Any direct funding from an NIH contract signed on or after April 7, 2008, or;
Any direct funding from the NIH Intramural Program, or;
An NIH employee.
1 Until further notice, manuscripts written in scripts other than Latin (e.g., Russian, Japanese) cannot be processed by the NIHMS. These manuscripts are not required to be posted on PubMed Central and do not require evidence of compliance on applications, proposals or reports. The NIHMS continues to process manuscripts written in Latin (Roman) script that contain characters and fonts used in standard mathematical notation.
2 See the FAQ for the full definition of a journal.
3 Authors may submit final peer-reviewed manuscripts accepted before April 7, 2008 that arise from NIH funds, if they have the right or permission to do so.
4 "Directly" funded means costs that can be identified specifically with a particular sponsored project, or that can be directly assigned to such activities relatively easily with a high degree of accuracy. When awardees list a publication in the progress report publication list of an RPPR or a renewal application, they are claiming that the publication directly arises from that award and the awardee is responsible for the public access compliance of the listed publications.
For Institutional Training, Career Development, and Related Awards (T15, T32/TL1, T34/TL4, T35, T90, R25/RL5, R90/RL9, K12/KM1/KL2, D43, D71, DP7, U2R, U45): Trainee, scholar, and participant publications fall under the public access policy if the publication resulted from work conducted while the individual was supported by the award (i.e., receiving a stipend or salary from the award). See NOT-OD-15-091 for more information.
For publications arising from shared resources, see NOT-OD-16-079.
NOT-OD-18-011
Statement on Article Publication Resulting from NIH Funded Research
To protect the credibility of published research, authors are encouraged to publish papers arising from NIH-funded research in reputable journals.
Reporting Instructions for Publications Supported by Shared Resources in Research Performance Progress Reports (RPPR) and Renewal Applications
Clarifies public access reporting requirements for publications arising from shared resources.
Clarifying Publication Reporting Instructions for Research Performance Progress Reports (RPPR) and Renewal Applications
Clarifies which publications should be included in progress reports and renewal applications for institutional training, career development, and related awards.
Applies to the following activity codes: T15, T32, TL1, T34, TL4, T35, T90, R25, RL5, R90, RL9, K12, KM1, KL2, D43, D71, DP7, U2R, and U45.
Reporting Publications in the Research Performance Progress Report (RPPR)
Amends instructions for reporting publications in the Research Performance Progress Report (RPPR).
Encourages awardees to electronically report any publications found in Table 1 of the RPPR which were previously reported using the paper 2590 process or as part of a competing renewal application. This transitional, one-time measure to report each publication electronically in the RPPR ensures that NIH systems can store all appropriate award-publication associations.
Changes to Public Access Policy Compliance Efforts Apply to All Awards with Anticipated Start Dates on or after July 1, 2013
NIH will delay processing of an award if publications arising from it are not in compliance with the NIH public access policy.
Investigators will need to use My NCBI to enter papers onto progress reports.
eRA Commons Users Can Now Generate a Publications Report for the PHS 2590 with My NCBI
Announces availability of enhancements to My NCBI to facilitate reporting of publications in paper progress reports (form PHS 2590).
Public Access Compliance Monitor: A New Resource for Institutions to Track Public Access Compliance
Announces the release of the Public Access Compliance Monitor (PACM; http://www.pubmedcentral.nih.gov/utils/pacm/ ), a web-based tool that institutions can use to track compliance of publications that fall under the NIH Public Access Policy.
Provides guidance on accessing PACM.
Upcoming Changes to Public Access Policy Reporting Requirements and Related NIH Efforts to Enhance Compliance
Informs grantees that in Spring, 2013, at the earliest, NIH will delay processing of non-competing continuation grant awards if publications arising from that award are not in compliance with the NIH public access policy.
Announces changes to My NCBI that improve the workflow and communication between PD/PIs and non- PD/PI authors.
All grantees submitting paper PHS 2590 progress reports will be required to provide a My NCBI generated PDF list of publications as part of their progress report.
My NCBI Tool to Replace eRA Commons for Bibliography Management
Announces My NCBI Tool – My Bibliography -- for bibliography management
Details benefits of integration
Until further notice, only papers written in Latin script will be collected via the NIH Manuscript Submission System for the NIH Public Access Policy
Clarification on the Use of an NIHMSID to Indicate Compliance with the NIH Public Access Policy
Clarifies the temporary nature of NIHMSIDs for use in reporting by defining the specific period during which an NIHMSID may be used to indicate compliance.
Defines default publication date used by NIH
Reminds awardee institutions of the actions they can take to ensure compliance with the NIH Public Access Policy.
The Omnibus Appropriations Act of 2009 Makes the NIH Public Access Policy Permanent
In accordance with Division F Section 217 of PL 111-8 (Omnibus Appropriations Act, 2009), the NIH Public Access Policy (NOT-OD-08-033 ) is made permanent.
Reminder Concerning Grantee Compliance with the Public Access Policy and Related NIH Monitoring Activities
Describes NIH Public Access Policy compliance monitoring efforts for Fiscal Year (FY) 2009.
Provides reminders concerning grantee demonstration of compliance and the location of citations for papers in applications, proposals and progress reports.
NIH Guide Notice for Public Access
Notice of revised policy statement, including specifics of applicability.
Letter from Chairman Pitts on the NIH Public Access Policy (November 10, 2011), and Reply from Francis Collins, M.D. (December 16, 2011).
Testimony Before the Subcommittee on Information Policy, Census, and National Archives Committee on Government Oversight and Reform- David J. Lipman, M.D. (July 29, 2010)
Written Testimony Before the Subcommittee on Courts, the Internet, and Intellectual Property Committee on the Judiciary United States House of Representatives - Elias A. Zerhouni, M.D. (September 11, 2008)
Slides presented to the Subcommittee on Courts, the Internet, and Intellectual Property Committee on the Judiciary United States House of Representatives (PowerPoint - 2.31 MB) - Elias A. Zerhouni, M.D. (September 11, 2008)
Offical Transcript of the Hearing on Fair Copyright in Research Works Act from the Subcommittee on Courts, the Internet, and Intellectual Property Committee on the Judiciary United States House of Representatives (PDF - 50 MB) (September 11, 2008)
View comments on the public access policy (March 2008 to May 2008)
Managing Papers
Reporting Papers
NIH Public Access Policy FAQ
My Bibliography FAQ
NIHMS Help and FAQ
RPPR FAQ
MY NCBI Delegates FAQ
Special users
For Sponsored Programs
For NIH Employee Authors
For NIH Extramural Staff
Temporary NIHMS Processing Delays
Guidance for all ICs
Information for ICs not using the Public Access Support Center
Information for ICs enrolled in the Public Access Support Center
Communication and Training Tools
My NCBI
NIHMS
Technical Issues: E-mail OER Webmaster


text:
1956 Carla 2022
Carla Ruth McWha
October 19, 1956 — February 2, 2022
Carla Ruth McWha (Reeves), 65, of Terrell, Tx went to be with her Lord on February 2, 2022. Carla was born on October 19, 1956 to Gilbert and Hazel Reeves in Houston, Tx. She moved to Price, Tx in 1971, and attended Carlisle High School. There she exuded school pride as a Drum Major and an editor of the yearbook, followed by a graduation, with honor, in 1975.
On December 27, 1996, Carla married Gray McWha, and they spent a loving 25 years together. Carla was the Operations Manager for the Residency Program at Baylor Scott & White of Garland. While there, she earned her credentials as a Certified Professional Medical Coder, and spent some time at Trinity Valley Community College. After 17 years of hard work & dedication she retired. After which, Carla enjoyed what made her the happiest, her family and grandbabies. She loved to cook and try out new recipes. Carla was admired for her armadillo eggs, various banana puddings, gumbo, but everyone's favorite was her twice baked potatoes. Carla also had a huge heart for her community. She was a member of the American Legion, Post 165 in Kaufman, Tx, where she was the Treasurer. She was also the President of the Ladies Auxiliary at the VFW. Both her and her husband spent many hours organizing fundraisers, planning veteran and family events, and even rode their Harley as part of the American Legion Riders Club.
Carla was a beloved wife, mother, grandmother and sister. She was preceded in death by her mother and father. Those left to cherish her precious memory, are, husband Gray McWha, son Brad Lowery, daughters Michele Hammack and husband Chris, Shawna Sharp and husband Chase, grandchildren Nicholas Achterberg, Kyler Sharp, Jacie Sharp, brother, Allen Reeves and wife Brenda and numerous family and friends who will miss her dearly.
A memorial will be held at Parker-Ashworth Funeral Home in Kaufman, Tx on Saturday, March 12, at 2:00 in the afternoon. In lieu of flowers, Carla would be honored for donations to be made to any children's or veteran's fundraiser.
To plant Memorial Trees in memory of Carla Ruth McWha, please click here to visit our Sympathy Store.
To order memorial trees or send flowers to the family in memory of Carla Ruth McWha, please visit our flower store.
Parker-Ashworth Funeral Home
2217 S Washington St, Kaufman, TX 75142


text:
England's Cap On College Tuition Rises To Nearly $11,400, Riling Critics
From Cambridge and Oxford to Lancashire and Surrey, the fees at all English universities are capped — and a new rate hike, from £9,000 to £9,250 (roughly $11,070 to $11,378) is angering critics, particularly those who say the increase didn't undergo legislative review.
Opponents of the tuition hike had pledged to fight the move when it was floated this summer; now, the BBC says, they're angry that the change seems to have been made final without being posted on the Department for Education's website.
"This is a shabby little way to announce something, hiding it away in a far-flung corner of a government website," says Liberal Democrat leader Tim Farron, according to the BBC.
Another member of Parliament, the Labour Party's Gordon Marsden, said the government was being sneaky about an "increase that doesn't like to speak its name," the BBC reports.
The rise in fees is already reflected on the University of Oxford's website for students from Britain and the European Union who'll begin studying in 2017; the Cambridge site lists the same rate of 9,250 pounds, with the stipulation that the price "is subject to government approval."
Reacting to news of the tuition hike, the National Union of Students is promising to organize a boycott of the government's National Student Survey that's taken by undergraduates in their final year of college.
England's broad cap on university tuition stands in contrast to the system in the U.S., where costs vary wildly between private and public schools.
In the 2015-15 school year, the average cost of tuition and fees at all four-year universities was nearly $15,000 in the U.S., according to the National Center for Education Statistics.
That figure represents both public colleges, whose average tuition rate was $8,543, and private institutions' average of $26,740.
As with the English university fees we're discussing, those figures include only tuition and related fees — not room and board.
When comparing the affordability of American and English schools, we should also note that many undergraduate programs in England award degrees after three years' study rather than four.
Both in the U.S. and England, college costs have risen sharply since the economic crisis that hit its peak in many places back in 2008. For instance, some American states saw rises of more than 70 percent from 2009 to 2015. And many English students protested back in 2010, when a plan was announced to raise the limit on university fees from 3,225 pounds yearly to 9,000 pounds.


text:
Мартін Чалфі (;  15 січня 1947, Чикаго) — американський учений. Отримав докторський ступінь з нейробіології в Гарварді і є професором біології в Колумбійському університеті. Став лауреатом Нобелівської премії з хімії 2008 року разом з Осамою Сімомура і Роджером Цянь за відкриття і розвиток використання зеленого флуоресцентного білка (GFP).

Наукова робота
Мартін Чалфі народився в сім'ї Елі Чалфі (1910-1996) і Вів'єн Фрідлі (1913-2005), з сімей єврейських емігрантів з Російської імперії (батьки батька були з Бресту). Середню освіту здобув у Чикаго.

Лабораторія Чалфі використовує нематоду C. elegans для дослідження різних аспектів розвитку і функціонування нервових клітин.
Мартін Чалфі опублікував понад 200 робіт, з яких принаймні 16 цитуються понад 100 разів.

Примітки

Хіміки США
Члени і члени-кореспонденти Національної академії наук США

redpajama_set_name: RedPajamaWikipedia


Do you want to maximize your presence at Marintec China 2019?
Connecting with your customers has never been easier. Reach out to your customers and prospects with the following new FREE resources!
Why using the "Visit our stand" banners?
Click & save the image below. Use the banner on your website or emails.
Take this tutorial on how to edit your banners if you do not have an in-house designer or photo editor software.
Note: You may like this tutorial on how to edit your banners if you do not have an in-house designer or photo editor software.


text:
Intel: Never mind Dempsey, here's Woodcrest
Intel overshadows launch of new server chip by disclosing performance numbers of unreleased Woodcrest chip.
Tom Krazit
May 24, 2006 6:53 a.m. PT
The early numbers look good for Intel's server group, but preproduction results do not a comeback make.
Intel released the results of 20 benchmarking tests Tuesday showing how much the performance of its server processors has improved over the last few years. The numbers overshadowed the expected release of Intel's Dempsey processor, which won't have much time to make an impact before systems based on the Woodcrest chip touted in the benchmarks arrive in the third quarter.
Woodcrest, the first server processor that will be released using Intel's new Core architecture, posted better results than Advanced Micro Devices' Opteron 285 processor on several general-purpose server benchmarks developed by industry consortiums such as the SPEC (Standards Performance Evaluation Corporation) and the TPC (Transaction Processing Performance Council), as well as tests measuring performance on applications like Microsoft Exchange or high-performance computing.
The tests were all conducted by Intel on preproduction servers from several different partners, including Dell, IBM, Hewlett-Packard, Fujitsu and others, that used Intel's Woodcrest processor. The results were compared to the most recent results posted by AMD or its partners, an Intel representative said, meaning some of the tests used Opteron processors a little slower than the 285 model. Details about the specific results, configurations and Intel's testing methods can be found on Intel's Web site.
Intel's server group hasn't really wanted to talk about performance over the last year, with AMD's Opteron chip holding an advantage on most benchmarks, as confirmed by many of the benchmark graphs posted Tuesday. As a result, AMD's server market share has grown from virtually zero three years ago to more than 20 percent, according to Mercury Research. But Intel has high hopes for Woodcrest and the rest of the Core architecture processors, which will replace the Netburst architecture used by Intel's current server processors, including Dempsey.
The release of the Woodcrest results puts a bit of a damper on the Dempsey unveiling. Intel plans to market Dempsey as a low-cost alternative to Woodcrest, Intel server chief Pat Gelsinger told CNET News.com in March.
Hewlett-Packard and IBM announced plans Tuesday to ship servers based on Dempsey, now known as the Dual-Core Intel Xeon 5000 series processors. But Dell, up until last week an exclusive customer of Intel's, announced plans only for workstations based on the Xeon 5000 series processors Tuesday. Last week, Dell announced plans to use Opteron in four-processor servers by the end of the year. A Dell representative said the company would ship servers based on Dempsey in the coming weeks.
The benchmark results are similar to ones released under a nondisclosure agreement to analysts at the last Intel Developer Forum, in March, with Intel actually having improved its performance in certain areas, said Nathan Brookwood, an analyst with Insight 64. Earlier this year, an Intel executive claimed the company's Core architecture would deliver a 20 percent improvement overall as compared with AMD's chips. The Woodcrest numbers deliver that much of an advantage in some tests, but less in others.
Woodcrest, which will be known as the Dual-Core Xeon 5100 series processors, will be formally released next month, with servers expected to become available in the third quarter. At that point, independent reviewers and potential customers will be able to conduct their own benchmarks. SPEC and TPC are well-known benchmarking tests, but chip and server companies spend millions making sure their hardware runs well on those tests, which don't always reflect the performance of homegrown applications on the hardware.
Discuss: Intel: Never mind Dempsey, here's Woodcrest