text:
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/ash/holding_space/holding_space_file_system_delegate.h"

#include <set>
#include <string>

#include "ash/components/arc/session/arc_bridge_service.h"
#include "ash/components/arc/session/arc_service_manager.h"
#include "ash/constants/ash_features.h"
#include "ash/public/cpp/holding_space/holding_space_constants.h"
#include "ash/public/cpp/holding_space/holding_space_item.h"
#include "ash/public/cpp/holding_space/holding_space_model.h"
#include "base/containers/contains.h"
#include "base/files/file_path.h"
#include "base/files/file_path_watcher.h"
#include "base/files/file_util.h"
#include "base/ranges/algorithm.h"
#include "base/sequence_checker.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h"
#include "chrome/browser/ash/arc/arc_util.h"
#include "chrome/browser/ash/drive/drive_integration_service.h"
#include "chrome/browser/ash/file_manager/path_util.h"
#include "chrome/browser/ash/file_manager/volume_manager.h"
#include "chrome/browser/chromeos/fileapi/file_change_service_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"

namespace ash {

namespace {

// Returns the absolute file path for the specified `drive_path`.
// NOTE: This method requires that the `DriveIntegrationService` be mounted.
base::FilePath ConvertDrivePathToAbsoluteFilePath(
    Profile* profile,
    const base::FilePath& drive_path) {
  const auto* drive_integration_service =
      drive::DriveIntegrationServiceFactory::FindForProfile(profile);
  if (drive_integration_service) {
    base::FilePath absolute_file_path =
        drive_integration_service->GetMountPointPath();
    if (base::FilePath("/").AppendRelativePath(drive_path, &absolute_file_path))
      return absolute_file_path;
  }
  NOTREACHED();
  return base::FilePath();
}

// Returns a mojo connection to the ARC file system.
arc::ConnectionHolder<arc::mojom::FileSystemInstance,
                      arc::mojom::FileSystemHost>*
GetArcFileSystem() {
  if (!arc::ArcServiceManager::Get())
    return nullptr;
  return arc::ArcServiceManager::Get()->arc_bridge_service()->file_system();
}

// Returns whether:
// *   the ARC is enabled for `profile`, and
// *   connection to ARC file system service is *not* established at the time.
bool IsArcFileSystemDisconnected(Profile* profile) {
  return arc::IsArcPlayStoreEnabledForProfile(profile) && GetArcFileSystem() &&
         !GetArcFileSystem()->IsConnected();
}

// Returns whether the item is backed by an Android file. Can be used with
// non-initialized items.
bool ItemBackedByAndroidFile(const HoldingSpaceItem* item) {
  return file_manager::util::GetAndroidFilesPath().IsParent(item->file_path());
}

}  // namespace

// HoldingSpaceFileSystemDelegate::FileSystemWatcher ---------------------------

class HoldingSpaceFileSystemDelegate::FileSystemWatcher {
 public:
  explicit FileSystemWatcher(base::FilePathWatcher::Callback callback)
      : callback_(callback) {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
    DETACH_FROM_SEQUENCE(sequence_checker_);
  }

  FileSystemWatcher(const FileSystemWatcher&) = delete;
  FileSystemWatcher& operator=(const FileSystemWatcher&) = delete;
  ~FileSystemWatcher() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); }

  void AddWatchForParent(const base::FilePath& file_path) {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

    // Observe the file path parent directory for changes - this reduces the
    // number of inotify requests, and works well enough for detecting file
    // deletion.
    const base::FilePath path_to_watch = file_path.DirName();

    auto it = watchers_.lower_bound(path_to_watch);
    if (it == watchers_.end() || it->first != path_to_watch) {
      it = watchers_.emplace_hint(it, std::piecewise_construct,
                                  std::forward_as_tuple(path_to_watch),
                                  std::forward_as_tuple());
      it->second.Watch(
          path_to_watch, base::FilePathWatcher::Type::kNonRecursive,
          base::BindRepeating(&FileSystemWatcher::OnFilePathChanged,
                              weak_factory_.GetWeakPtr()));
    }

    // If the target path got deleted while request to add a watcher was in
    // flight, notify observers of path change immediately.
    if (!base::PathExists(file_path))
      OnFilePathChanged(path_to_watch, /*error=*/false);
  }

  void RemoveWatch(const base::FilePath& file_path) {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    watchers_.erase(file_path);
  }

  base::WeakPtr<FileSystemWatcher> GetWeakPtr() {
    return weak_factory_.GetWeakPtr();
  }

 private:
  void OnFilePathChanged(const base::FilePath& file_path, bool error) {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    // In tests `OnFilePathChanged()` events are sometimes propagated before
    // `OnFileMoved()` events. Delay propagation of `OnFilePathChanged()`
    // events to give `OnFileMoved()` events time to propagate.
    content::GetUIThreadTaskRunner({})->PostDelayedTask(
        FROM_HERE, base::BindOnce(callback_, file_path, error),
        base::Milliseconds(1));
  }

  SEQUENCE_CHECKER(sequence_checker_);
  base::FilePathWatcher::Callback callback_;
  std::map<base::FilePath, base::FilePathWatcher> watchers_;
  base::WeakPtrFactory<FileSystemWatcher> weak_factory_{this};
};

// HoldingSpaceFileSystemDelegate ----------------------------------------------

HoldingSpaceFileSystemDelegate::HoldingSpaceFileSystemDelegate(
    HoldingSpaceKeyedService* service,
    HoldingSpaceModel* model)
    : HoldingSpaceKeyedServiceDelegate(service, model),
      file_system_watcher_runner_(base::ThreadPool::CreateSequencedTaskRunner(
          {base::MayBlock(), base::TaskPriority::BEST_EFFORT})) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
}

HoldingSpaceFileSystemDelegate::~HoldingSpaceFileSystemDelegate() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  weak_factory_.InvalidateWeakPtrs();
  file_system_watcher_runner_->DeleteSoon(FROM_HERE,
                                          file_system_watcher_.release());
}

void HoldingSpaceFileSystemDelegate::OnConnectionReady() {
  // Schedule validity checks for android items.
  for (auto& item : model()->items()) {
    if (!ItemBackedByAndroidFile(item.get()))
      continue;

    holding_space_util::ValidityRequirement requirements;
    if (!features::IsHoldingSpacePredictabilityEnabled()) {
      if (item->type() != HoldingSpaceItem::Type::kPinnedFile)
        requirements.must_be_newer_than = kMaxFileAge;
    }
    ScheduleFilePathValidityCheck({item->file_path(), requirements});
  }
}

void HoldingSpaceFileSystemDelegate::OnFilesChanged(
    const std::vector<drivefs::mojom::FileChange>& changes) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // When a file is moved, a `kDelete` change will be followed by a `kCreate`
  // change with the same `stable_id` in the same set of `changes`. In some
  // versions of the `DriveFsHost`, `stable_id` is not supported and will always
  // be `0` for backwards compatibility.
  std::map<int64_t, base::FilePath> deleted_paths_by_stable_id;
  std::set<base::FilePath> deleted_paths;

  for (const auto& change : changes) {
    // Holding space requires absolute file paths.
    const base::FilePath absolute_file_path =
        ConvertDrivePathToAbsoluteFilePath(profile(), change.path);
    if (absolute_file_path.empty())
      continue;

    switch (change.type) {
      case drivefs::mojom::FileChange::Type::kCreate: {
        if (change.stable_id) {
          // If the `kCreate` change has an associated `stable_id`, it can
          // potentially be paired with a preceding `kDelete` change. In such
          // cases, the change sequence actually constitutes a move rather than
          // a delete of the underlying file.
          auto it = deleted_paths_by_stable_id.find(change.stable_id);
          if (it != deleted_paths_by_stable_id.end()) {
            OnFilePathMoved(/*src=*/it->second, /*dst=*/absolute_file_path);
            deleted_paths_by_stable_id.erase(it);
          }
        }
        break;
      }
      case drivefs::mojom::FileChange::Type::kDelete: {
        // If the change has a `stable_id` it can potentially constitute part of
        // a move rather than a delete of the underlying file. Whether the
        // change is move or a delete will not be known until a `kCreate` change
        // follows (or is confirmed *not* to follow). When `stable_id` is absent
        // it is not possible to detect a move.
        if (change.stable_id)
          deleted_paths_by_stable_id[change.stable_id] = absolute_file_path;
        else
          deleted_paths.insert(absolute_file_path);
        break;
      }
      case drivefs::mojom::FileChange::Type::kModify: {
        OnFilePathModified(absolute_file_path);
        break;
      }
    }
  }

  // At this point, all `kDelete` changes in `deleted_paths_by_stable_id` are
  // confirmed to be deletions, having already stripped out all changes that
  // were actually constituting moves.
  for (const auto& deleted_path_by_stable_id : deleted_paths_by_stable_id)
    deleted_paths.insert(deleted_path_by_stable_id.second);

  // Remove any holding space items backed by deleted file paths.
  model()->RemoveIf(base::BindRepeating(
      [](const std::set<base::FilePath>& deleted_paths,
         const HoldingSpaceItem* item) {
        return base::ranges::any_of(
            deleted_paths, [&](const base::FilePath& deleted_path) {
              return item->file_path() == deleted_path ||
                     deleted_path.IsParent(item->file_path());
            });
      },
      std::cref(deleted_paths)));
}

void HoldingSpaceFileSystemDelegate::Init() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  file_system_watcher_ = std::make_unique<FileSystemWatcher>(
      base::BindRepeating(&HoldingSpaceFileSystemDelegate::OnFilePathChanged,
                          weak_factory_.GetWeakPtr()));

  // Arc file system.
  auto* const arc_file_system = GetArcFileSystem();
  if (arc_file_system)
    arc_file_system_observer_.Observe(arc_file_system);

  // Drive file system.
  auto* const drive_integration_service =
      drive::DriveIntegrationServiceFactory::FindForProfile(profile());
  if (drive_integration_service)
    drivefs_host_observer_.Observe(drive_integration_service->GetDriveFsHost());

  // Local file system.
  file_change_service_observer_.Observe(
      chromeos::FileChangeServiceFactory::GetInstance()->GetService(profile()));

  // Volume manager.
  auto* const volume_manager = file_manager::VolumeManager::Get(profile());
  if (volume_manager)
    volume_manager_observer_.Observe(volume_manager);

  // Schedule a task to clean up items that belong to volumes that haven't been
  // mounted in a reasonable amount of time. The primary goal of handling the
  // delayed volume mount is to support volumes that are mounted asynchronously
  // during the startup.
  clear_non_initialized_items_timer_.Start(
      FROM_HERE, base::Minutes(1),
      base::BindOnce(&HoldingSpaceFileSystemDelegate::ClearNonInitializedItems,
                     base::Unretained(this)));
}

void HoldingSpaceFileSystemDelegate::OnHoldingSpaceItemsAdded(
    const std::vector<const HoldingSpaceItem*>& items) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  const bool arc_file_system_disconnected =
      IsArcFileSystemDisconnected(profile());
  for (const HoldingSpaceItem* item : items) {
    if (item->IsInitialized() && item->progress().IsComplete()) {
      // Watch the directory containing `item`'s backing file. If the directory
      // is already being watched, this will no-op. Note that it is not
      // necessary to register a watch if the `item` is in-progress since
      // in-progress items are not subject to validity checks.
      AddWatchForParent(item->file_path());
      continue;
    }

    // In-progress items are not subject to validity checks.
    if (!item->progress().IsComplete())
      continue;

    // If the item has not yet been initialized, check whether it's path can be
    // resolved to a file system URL - failure to do so may indicate that the
    // volume to which it path belongs is not mounted there. If the file system
    // URL cannot be resolved, leave the item in partially initialized state.
    // Validity will be checked when the associated mount point is mounted.
    // NOTE: Items will not be kept in partially initialized state indefinitely
    // - see `clear_non_initialized_items_timer_`.
    // NOTE: This does not work well for removable devices, as all removable
    // devices have the same top level "external" mount point (media/removable),
    // so a removable device path will be successfully resolved even if the
    // device is not currently mounted. The logic will have to be updated if
    // support for restoring items across removable device mounts becomes a
    // requirement.
    const GURL file_system_url =
        holding_space_util::ResolveFileSystemUrl(profile(), item->file_path());
    if (file_system_url.is_empty())
      continue;

    // Defer validity checks (and initialization) for android files if the ARC
    // file system connection is not yet ready.
    if (arc_file_system_disconnected && ItemBackedByAndroidFile(item))
      continue;

    holding_space_util::ValidityRequirement requirements;
    if (!features::IsHoldingSpacePredictabilityEnabled()) {
      if (item->type() != HoldingSpaceItem::Type::kPinnedFile)
        requirements.must_be_newer_than = kMaxFileAge;
    }
    ScheduleFilePathValidityCheck({item->file_path(), requirements});
  }
}

void HoldingSpaceFileSystemDelegate::OnHoldingSpaceItemsRemoved(
    const std::vector<const HoldingSpaceItem*>& items) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  for (const HoldingSpaceItem* item : items)
    MaybeRemoveWatch(item->file_path().DirName());
}

void HoldingSpaceFileSystemDelegate::OnHoldingSpaceItemUpdated(
    const HoldingSpaceItem* item,
    uint32_t updated_fields) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // In-progress items are not subject to validity checks.
  if (item->progress().IsComplete())
    AddWatchForParent(item->file_path());
}

void HoldingSpaceFileSystemDelegate::OnHoldingSpaceItemInitialized(
    const HoldingSpaceItem* item) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  AddWatchForParent(item->file_path());
}

void HoldingSpaceFileSystemDelegate::OnVolumeMounted(
    MountError error_code,
    const file_manager::Volume& volume) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  holding_space_util::FilePathsWithValidityRequirements
      file_paths_with_requirements;
  // Check validity of partially initialized items under the volume's mount
  // path.
  for (auto& item : model()->items()) {
    if (item->IsInitialized())
      continue;
    if (!volume.mount_path().IsParent(item->file_path()))
      continue;

    holding_space_util::ValidityRequirement requirements;
    if (!features::IsHoldingSpacePredictabilityEnabled()) {
      if (item->type() != HoldingSpaceItem::Type::kPinnedFile)
        requirements.must_be_newer_than = kMaxFileAge;
    }
    ScheduleFilePathValidityCheck({item->file_path(), requirements});
  }
}

void HoldingSpaceFileSystemDelegate::OnVolumeUnmounted(
    MountError error_code,
    const file_manager::Volume& volume) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // Drive FS may restart from time to time, so only remove items if drive is
  // disabled.
  if (volume.type() == file_manager::VOLUME_TYPE_GOOGLE_DRIVE) {
    const auto* drive_integration_service =
        drive::DriveIntegrationServiceFactory::FindForProfile(profile());
    if (drive_integration_service && drive_integration_service->is_enabled()) {
      return;
    }
  }
  // Schedule task to remove items under the unmounted file path from the model.
  // During suspend, some volumes get unmounted - for example, drive FS. The
  // file system delegate gets shutdown to avoid removing items from unmounted
  // volumes, but depending on the order in which observers are added to power
  // manager dbus client, the file system delegate may get shutdown after
  // unmounting a volume. To avoid observer ordering issues, schedule
  // asynchronous task to remove unmounted items from the model.
  base::SequencedTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::BindOnce(&HoldingSpaceFileSystemDelegate::RemoveItemsParentedByPath,
                     weak_factory_.GetWeakPtr(), volume.mount_path()));
}

void HoldingSpaceFileSystemDelegate::OnFileModified(
    const storage::FileSystemURL& url) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  OnFilePathModified(url.path());
}

void HoldingSpaceFileSystemDelegate::OnFileMoved(
    const storage::FileSystemURL& src,
    const storage::FileSystemURL& dst) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  OnFilePathMoved(src.path(), dst.path());
}

void HoldingSpaceFileSystemDelegate::OnFilePathChanged(
    const base::FilePath& file_path,
    bool error) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(!error);

  // The `file_path` that changed is a directory containing backing files for
  // one or more holding space items. Changes to this directory may indicate
  // that some, all, or none of these backing files have been removed. Verify
  // the existence of these backing files to trigger removal of any holding
  // space items that no longer exist.
  for (const auto& item : model()->items()) {
    if (file_path.IsParent(item->file_path()))
      ScheduleFilePathValidityCheck({item->file_path(), /*requirements=*/{}});
  }
}

void HoldingSpaceFileSystemDelegate::OnFilePathModified(
    const base::FilePath& file_path) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  model()->InvalidateItemImageIf(base::BindRepeating(
      [](const base::FilePath& file_path, const HoldingSpaceItem* item) {
        return item->file_path() == file_path;
      },
      file_path));
}

void HoldingSpaceFileSystemDelegate::OnFilePathMoved(
    const base::FilePath& src,
    const base::FilePath& dst) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // Collect items that should be moved to a new path. This includes:
  // *   Items whose path matches the source path.
  // *   Items parented by the source path.
  // Maps item ID to the item's new file path.
  std::vector<std::pair<std::string, base::FilePath>> items_to_move;
  for (auto& item : model()->items()) {
    if (src == item->file_path()) {
      items_to_move.push_back(std::make_pair(item->id(), dst));
      continue;
    }

    if (src.IsParent(item->file_path())) {
      base::FilePath target_path(dst);
      if (!src.AppendRelativePath(item->file_path(), &target_path)) {
        NOTREACHED();
        continue;
      }
      items_to_move.push_back(std::make_pair(item->id(), target_path));
    }
  }

  // Handle existing holding space items under the target file path.
  // Moving an existing item to a new path may create conflict within the
  // holding space if an item with the target path already exists within the
  // holding space. If this is the case, assume that the original item was
  // overwritten, and remove it from the holding space.

  // NOTE: Don't remove items at destination if no holding space items have to
  // be updated due to the file move. The reason for this is to:
  // *   Support use case where apps change files by moving temp file with
  //     modifications to the file path.
  // *   Handle duplicate file path move notifications.
  // Instead, update the items as if the target path was modified.
  if (items_to_move.empty()) {
    OnFilePathModified(dst);
    return;
  }

  // Resolve conflicts with existing items that arise from the move.
  std::set<std::string> item_ids_to_remove;
  for (auto& item : model()->items()) {
    if (dst == item->file_path() || dst.IsParent(item->file_path())) {
      item_ids_to_remove.insert(item->id());
    }
  }
  model()->RemoveItems(item_ids_to_remove);

  // Finally, update the files that have been moved.
  for (const auto& to_move : items_to_move) {
    if (item_ids_to_remove.count(to_move.first))
      continue;

    model()
        ->UpdateItem(/*id=*/to_move.first)
        ->SetBackingFile(/*file_path=*/to_move.second,
                         holding_space_util::ResolveFileSystemUrl(
                             profile(), /*file_path=*/to_move.second));
  }

  // If a backing file update occurred, it's possible that there are no longer
  // any holding space items associated with `src`. When that is the case, `src`
  // no longer needs to be watched.
  MaybeRemoveWatch(src);
}

void HoldingSpaceFileSystemDelegate::ScheduleFilePathValidityCheck(
    holding_space_util::FilePathWithValidityRequirement requirement) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  pending_file_path_validity_checks_.push_back(std::move(requirement));
  if (file_path_validity_checks_scheduled_)
    return;

  file_path_validity_checks_scheduled_ = true;

  // Schedule file validity check for pending items. The check is scheduled
  // asynchronously so path checks added in quick succession are handled in a
  // single batch.
  base::SequencedTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::BindOnce(
          &HoldingSpaceFileSystemDelegate::RunPendingFilePathValidityChecks,
          weak_factory_.GetWeakPtr()));
}

void HoldingSpaceFileSystemDelegate::RunPendingFilePathValidityChecks() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  holding_space_util::FilePathsWithValidityRequirements requirements;
  requirements.swap(pending_file_path_validity_checks_);

  file_path_validity_checks_scheduled_ = false;
  holding_space_util::PartitionFilePathsByValidity(
      profile(), std::move(requirements),
      base::BindOnce(
          &HoldingSpaceFileSystemDelegate::OnFilePathValidityChecksComplete,
          weak_factory_.GetWeakPtr()));
}

void HoldingSpaceFileSystemDelegate::OnFilePathValidityChecksComplete(
    std::vector<base::FilePath> valid_paths,
    std::vector<base::FilePath> invalid_paths) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  const bool arc_file_system_disconnected =
      IsArcFileSystemDisconnected(profile());

  // Remove items with invalid paths.
  model()->RemoveIf(base::BindRepeating(
      [](bool arc_file_system_disconnected,
         const std::vector<base::FilePath>* invalid_paths,
         const HoldingSpaceItem* item) {
        // In-progress items are not subject to validity checks.
        if (!item->progress().IsComplete())
          return false;

        // Avoid removing Android files if connection to ARC file system has
        // been lost (e.g. Android container might have crashed). Validity
        // checks will be re-run once the file system gets connected.
        if (arc_file_system_disconnected && ItemBackedByAndroidFile(item))
          return false;

        return base::Contains(*invalid_paths, item->file_path());
      },
      arc_file_system_disconnected, &invalid_paths));

  std::vector<const HoldingSpaceItem*> items_to_initialize;
  for (auto& item : model()->items()) {
    // Defer initialization of items backed by android files if the connection
    // to ARC file system service has been lost.
    if (arc_file_system_disconnected && ItemBackedByAndroidFile(item.get()))
      continue;

    if (!item->IsInitialized() &&
        base::Contains(valid_paths, item->file_path())) {
      items_to_initialize.push_back(item.get());
    }
  }

  for (auto* item : items_to_initialize) {
    model()->InitializeOrRemoveItem(
        item->id(),
        holding_space_util::ResolveFileSystemUrl(profile(), item->file_path()));
  }
}

void HoldingSpaceFileSystemDelegate::AddWatchForParent(
    const base::FilePath& file_path) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  file_system_watcher_runner_->PostTask(
      FROM_HERE, base::BindOnce(&FileSystemWatcher::AddWatchForParent,
                                file_system_watcher_->GetWeakPtr(), file_path));
}

void HoldingSpaceFileSystemDelegate::MaybeRemoveWatch(
    const base::FilePath& file_path) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  // The watch for `file_path` should only be removed if no holding space items
  // exist in the model which are backed by files it directly parents.
  const bool remove_watch =
      base::ranges::none_of(model()->items(), [&file_path](const auto& item) {
        return item->IsInitialized() &&
               item->file_path().DirName() == file_path;
      });

  if (!remove_watch)
    return;

  file_system_watcher_runner_->PostTask(
      FROM_HERE, base::BindOnce(&FileSystemWatcher::RemoveWatch,
                                file_system_watcher_->GetWeakPtr(), file_path));
}

void HoldingSpaceFileSystemDelegate::RemoveItemsParentedByPath(
    const base::FilePath& parent_path) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  model()->RemoveIf(base::BindRepeating(
      [](const base::FilePath& parent_path, const HoldingSpaceItem* item) {
        return parent_path.IsParent(item->file_path());
      },
      parent_path));
}

void HoldingSpaceFileSystemDelegate::ClearNonInitializedItems() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  model()->RemoveIf(base::BindRepeating(
      [](Profile* profile, const HoldingSpaceItem* item) {
        if (item->IsInitialized())
          return false;

        // Do not remove items whose path can be resolved to a file system URL.
        // In this case, the associated mount point has been mounted, but the
        // initialization may have been delayed - for example due to
        // issues/delays with initializing ARC.
        const GURL url = holding_space_util::ResolveFileSystemUrl(
            profile, item->file_path());
        return url.is_empty();
      },
      profile()));
}

}  // namespace ash


Many watch fanatics consider Vacheron Constantin a grail watchmaker. But across 250 years of impressive watchmaking design, finishing and in-house movements, the brand has only ever made one casual sports watch — the Overseas. Born as the 222 in 1976, the watch has always been overshadowed by contemporaries like the Patek Philippe Nautilus and Audemars Piguet Royal Oak. But in 2016, Vacheron completely overhauled the Overseas with the addition of several new iterations, including a world timer, ultra-thin and perpetual calendar.
But as far as a true, everyday "sports watch" goes, the new chronograph version is the clear winner. It features a new in-house column wheel chronograph movement with a vertical coupling clutch (a rarity that makes for a smoother engagement and disengagement of the chronograph function) that took Vacheron five years to develop. The funky '70s case shape incorporates screw-down pushers and a soft-iron ring, allowing for 150 meters of water resistance and 25,000 A/m of magnetic resistance.
That all seems like an exercise in pure function until you realize this is Vacheron we're talking about. That in-house movement has a gorgeous 22k gold rotor and a Geneva seal, meaning it means a rigorous set of requirements of high-end finishing. The upshot? The Overseas is an extraordinary combination of high-end watchmaking and rugged utility.


text:
Robots from across the globe advance on Disaster City
Robots have become vital tools that first responders can use worldwide to assist victims of disaster. They help take civilian emergency responders out of harm's way and augment their capabilities. On Nov. 14-18, robotics experts and emergency responders from across the globe are gathering at TEEX's Disaster City in College Station to evaluate and test the latest generation of robots.
The emergency response robotic performance standards being evaluated include sensing, mobility, navigation, planning, integration, and operator control in order to ensure that the robots meet operational requirements under the extremely challenging conditions that rescuers frequently are faced with, including long endurance missions. Where appropriate, the standards will also address issues of robotic component interoperability.
Responders will help to validate emerging standard robot test methods, become familiar with available robot capabilities, and advise robot developers regarding operational requirements. Search and rescue response personnel participating include FEMA Urban Search and Rescue (US&R) teams; federal, state and local bomb squads; and police/SWAT teams.
The robotic standards effort focuses on fostering collaboration between first responders, robot manufacturers, other government agencies, and technology developers to advance consensus standards for task specific robot capabilities and interoperability of components. These standards will allow DHS to provide guidance to local, state, and federal homeland security entities regarding the purchase, deployment and use of robots for rescue applications.
The Department of Homeland Security Science and Technology Directorate has funded an effort with the National Institute of Standards and Technology (NIST) to develop comprehensive standards related to the development, testing, and certification of effective technologies for search and rescue robotics.
Media Opportunity:
What: A variety of robots covering land, air and water are participating in the evaluation including large and small ground robots, small unmanned underwater vehicles (sUUV), and small unmanned aerial systems (sUAS). Robots will capture performance data within emerging standard test methods and then be deployed with responders to perform operational tasks in practice scenarios.
Where: Disaster City, College Station, Texas Disaster City is 52 acres of simulated catastrophe, including rubble piles, collapsed buildings, train derailments and much more. It's the largest and most comprehensive urban search and rescue training facility in the world and is part of TEEX's Emergency Preparedness Campus.
This event is the seventh in a series of DHS/NIST response robot evaluation exercises and the fifth with Texas A&M Engineering and the Texas Engineering Extension Service (TEEX) Disaster Preparedness and Response at the TEEX Disaster City? facility.
Media note: Media attending the event must wear long pants and closed-toe shoes. A long-sleeve shirt is recommended. Other personal protective equipment will be provided for you.

redpajama_set_name: RedPajamaCommonCrawl


Don't get too excited lol. They are hideous. I mean like wake up the next morning and chew your arm off to get away so you don't wake them up hideous.
...but apparently they work because from what I understand they have a LOOOOONG back order list. Don't take my word for it though. Here's their video advertisement.


Standard length from back nape to hem is 23" or you can choose your length up to 27".
"So easy to wear and very flattering. I love mine, good to know no one will be wearing the same."
"Your clothes are the ones people compliment without fail, I always get comments when I wear one"
"The top has arrived and it's just super, I will really enjoy it"


Visiting New Orleans for the big game at The Mercedes Benz Superdome? Hotels-Rates offers tons of info you need to select the best-fitting hotel, for the lowest price, close to The Mercedes Benz Superdome. We constantly collect information on hotels, attractions and points of interest in New Orleans, LA and throughout the U.S., so that you can choose the best-fitting hotel for you. Our extensive database shows there are 131 hotels in New Orleans within 5 miles of The Mercedes Benz Superdome, with the lowest rate for those hotels being $47.1. We also found 78 hotels in New Orleans within 1 mile of The Mercedes Benz Superdome, with the lowest rate for those hotels being $80. Hotels-Rates welcomes all NFL fans to check out the wide variety of hotels and attractions in and around New Orleans and The Mercedes Benz Superdome. If you're looking for other things to do in New Orleans, we think you might like the Audubon Zoo, The National WWII Museum, Harrah's Casino and Audubon Aquarium of the Americas, most of which are relatively close to the venue.


text:
Home » Tips for Better Dry Fly Fishing for Trout – Rick Kustich
Tips for Better Dry Fly Fishing for Trout – Rick Kustich
By Rick Kustich:
Dry fly fishing for trout is where my fly fishing obsession started over forty years ago. Regardless of which direction the sport pulls me in, I always return to my fly fishing roots with the same enthusiasm and wonderment. Going one on one with a wily stream-bred trout can be both challenging and captivating and I am always amazed at how the hours just melt away during a hatch on a favorite trout river. And while it is tough to admit that fooling a fish with a brain a mere fraction of the size of mine can be so difficult, a wild trout that is in tune with its surroundings can be a worthy adversary for any angler's fly fishing skills.
Dry fly fishing can be complex or quite simple. But I have long been drawn to rivers with large wild trout that do not make mistakes easily. This has caused me to refine my craft while learning many lessons along the way. And some key steps have emerged that are essential for success.
Knowledge of your water
The starting point for successful dry fly fishing always seems to center on gaining an understanding of the water to be fished. This seems simple enough as a predator should always have an understanding of its quarry's vulnerabilities. But having a true working knowledge of the insect hatches that a particular river or stream produces can go a long way towards a properly prepared fly box. Hatches can vary by stream, even within the same region. Books, the Internet, local fly shops and fly-fishing acquaintances can all provide useful detailed information. But there is no substitute for personal observation.
Timing your outings
Try to learn something each time you're on the water and maintain notes of your experiences in a logbook. I consistently discover that my notes are much more accurate than memory and have used this written account to identify certain trends in insect and feeding activity. This information has been the basis for attempting to time my outings to meet peak hatch or spinner fall activity. While seasonal emergences of a particular insect can occur within a predictable range, variations in factors like air temperature, water temperature, sunlight, clouds, and water level can all impact daily timing of insect activity. Use these factors to select the best days to fish or the optimum time within the day when only fishing for a short period.
Careful observation
When on the water it is important to keep your senses on high alert – both sight and sound can assist in locating feeding trout. At times fish feeding on the surface can be quite obvious, especially when positioned in the middle of a pool or in obvious lanes that collect food. But shrewd trout will attempt to stay hidden even when feeding on the surface. Be sure to look closely around logjams, overhanging brush, and close to the bank. Fish in these positions combined with a subtle rise form can stay hidden in plain sight. So often anglers walk or float right by a feeding trout by simply not being observant.
Your ears can be as important as your eyes for locating feeding trout. Splashy rises are easy to hear, but also be tuned in for the sounds of subtle feeding. When it is quiet you can actually hear a trout's lips smacking on the surface of the water as it grabs a fly. Sound can help locate a fish tucked away in the cover or when low light makes it more difficult to see.
Important information can be gained by studying a trout's rise form. How a trout is feeding is generally dictated by the type and life cycle phase of its food source. Splashy sporadic rises are typically associated with emerging insects such as caddis or fast swimming mayflies. Sporadic activity can also be experienced during some stonefly hatches and certain large mayflies. More consistent slurping rises are usually a sign of feeding on adult insects or struggling emergers in the surface film. Look for bubbles on the surface after a trout eats to determine if it is actually feeding on the surface. A lack of bubbles could indicate a trout feeding just below the surface on emerging insects.
In slick water the head of the fish may be visible while feeding and can be accompanied by a head and tail rise to eat the fly. Sipping rises can indicate that trout are feeding on spent or egg laying insects and occurs most commonly in the evenings and mornings. The manner in which a trout is feeding can help you determine the trout's menu and assist in selecting the right fly for the situation.
Stealthy wading
Once a feeding target has been identified it is time to get into casting position. On most streams and rivers a stealthy approach will allow for a trout to remain unaware of your presence and maintain a feeding rhythm. Drab clothing that blends in with your surroundings is a must, as is removing all shiny gadgets that can reflect light. Avoid quick movements and wade careful and slow so as not to push water and create shock waves. Avoid entering the water if possible, though it is typically necessary. When in the water move carefully making sure you have a firm foot hold before making the next step. Do your best to not kick or grind the rocks since this creates vibrations that can easily be felt by the sensitive lateral lines of a trout. I normally wade without studs in my boots to eliminate the grinding sound that can be caused by the metal scratching across rock.
Careless wading is the most likely way to alert a trout of your presence. Once a trout feels uncomfortable it will alter its feeding pattern or quit feeding altogether. When dry fly fishing from a boat I am always amazed at how close you can get to a feeding trout, even when creating a much higher profile. But the lack of noise and vibrations experienced when wading allows a quiet boat to have a more stealthy approach.
Get the right angle
From a dry fly fishing perspective a significant effort is made in attaining a natural drag free drift. Drag is caused by the varying surface currents pushing and pulling a tight line or leader in a way that forces the fly to move faster or slower than the current. While many insects swim and flutter when on or near the surface, a dead drift will provide the best presentation in most situations. A dry fly that moves only with the current provides the illusion of being real and is the key trigger point to fool a wily trout into eating.
Positioning yourself at the proper angle will have a direct impact on your ability to attain a dead drift and ultimately the proper presentation. On larger rivers and streams where there is plenty of room for a back cast, the preferred position is slightly upstream and well off to the side from the feeding trout. With an across-stream cast the fly will show itself to the fish before the leader and line. However, using a slightly downstream position when making an across-stream cast tends to be problematic with the pull of the current on the line and leader easily creating drag on the fly.
On smaller water choked with trees and other shoreline vegetation, an upstream angle will be the best and oftentimes only approach. An upstream cast can be made more effective by maintaining a slight angle with only the fly and a small portion of the tippet floating over the trout's feeding position. An advantage of the upstream cast is that you are positioned in the trout's blind spot making your movement much more difficult to detect. However, as you move into position for a cast to a feeding trout it is possible to spook other fish located in the pool alerting your feeding target. It is best to maintain a safe distance to the feeding trout making as long a cast as possible.
Long leaders
Proper presentation of a dry fly begins with leader construction. On big water when wind isn't a factor, I prefer a long leader with an extra long tippet section. I commonly use a leader with a full length of fifteen to eighteen feet including a tippet of three to five feet in length. The long leader and tippet section make it difficult to straighten out the leader on a cast to a feeding trout. The slack that this creates helps to facilitate a natural drift. In windy conditions it will be impossible to control accuracy with such a long leader and the overall length and tippet can be reduced proportionately to a total of approximately twelve feet. On smaller streams where it is common to use light, short rods, use a leader with a length not exceeding ten feet.
Slack line casts
Additional slack can be added to the leader and tippet through the casting stroke. Both the stop cast and pile or dump cast result in delivering the fly in a manner where the leader and tippet form curls and coils on the water. This allows the fly to float freely until the leader straightens out by the varying pulls of the current. Pulling or flicking the tip of the rod back toward you after the forward stroke has been completed and the line has straightened out performs the stop cast. The pile or dump cast requires a soft or weak forward stroke to deliver the fly. Not forming a complete or abrupt stop on the forward cast but rather allowing the rod to continue to a point of being parallel to the water completes the cast. The result is a leader with slack and coils that helps eliminate drag. Slack line casts take some practice to be able to use proficiently but are a key element of successful dry fly fishing.
A slack line cast can be used at any casting angle to the fish. When making a cast at a down and across angle on bigger water, I combine a slack line cast with a reach cast. A reach entails extending the casting arm upstream so that the line and leader lands upstream of the fly further reducing the impact of drag. Using a stop cast combined with a reach by first completing the stop and then reaching up effectively creates an upstream, mid air mend. When performed correctly this is a very effective approach to fool difficult and challenging surface feeding trout.
Accuracy matters
When dry fly fishing for trout, accuracy matters. A feeding fish will usually not move far to take a fly if there is an abundance of naturals on the surface. Placing the fly so that it drifts along the same drift line as the feeding trout will be critical. However, a fish may move a bit further for a fly when the abundance of naturals is sparse. An effective cast should land slightly upstream of the fish's position so that the fly drifts into the trout's cone of vision with enough slack in the leader to float drag free.
Make a good first cast as it may be the best chance at fooling a wily fish. If possible, line up the distance of the cast well off to the side. It will always be safe to err on the side of making the cast too short. Too long of a cast may place the fly line over the fish and cause it to stop feeding.
Accuracy becomes more challenging when using slack line casts. Since the cast will be completed without the full turnover of the leader, you will need to account for a distance adjustment because of the slack in the leader. This normally means that the line beyond the tip of the rod required to reach a feeding trout will be a few feet longer than it would with a tight line cast. Getting the right distance with a slack line cast requires practice and becomes more problematic in windy conditions as the fly will be blown around as it settles on the water. Reducing leader length, keeping the cast low, and making short drifts with the presentation increases your odds in the wind. If there is an advantage to the wind it is in the fact that the naturals may be blown around on the surface and move at a speed that is slightly different from the current. Under these conditions you can sometimes have a slight amount of drag and still be successful. Having slack in the leader doesn't just facilitate proper presentation, but also allows a fish to easily suck in your offering. A tight leader can prevent this from occurring.
When there is more than one fish feeding in a small area it is typically best to select one to target. This way casts are made with a specific purpose. In situations where more than one fish is feeding I attempt to pick out the largest fish, unless in doing so my line will travel over the other feeding fish. Casting over other trout can alert all the fish feeding in that area of your presence.
Get the rhythm
It is common for a trout feeding on the top to develop some type of rhythm. The feeding fish may not grab each bug floating on or near the surface, but when a sufficient supply of insects is present feeding can occur at fairly regular intervals. I have also witnessed trout that rise to the surface, eat two or three bugs in rapid succession, take a break and then repeat the rapid feeding approach. In situations where the bugs are abundant and the current is fairly soft a trout may stay at the surface and eat nearly every bug that comes its way. But no matter what the rhythm, it is important in most situations to recognize the sequence and present the fly at a time when it is most likely for the fish to feed.
It is important to constantly observe the trout you are targeting. Its rhythm can change at any time, so be ready to make adjustments. And while it is common for a trout to stay positioned in one spot as it feeds, it is just as common for a fish to move around. A trout can move from side to side and up and down in the pool while feeding. In these situations you need to mentally chart the trout's movements and attempt to anticipate the next place that it will show. After each unsuccessful cast be sure to lift the fly off the water carefully so as not to alert the trout to your presence.
See the fly
There is one rather basic factor in dry fly fishing for trout that greatly impacts success – being able to see the fly. With large patterns, good lighting, and placid waters it will be quite easy to view your fly on the surface. But add in the typical factors of smaller flies, varying light conditions, and riffles or swirls in the current and it is a whole different story. Being able to watch your fly not only indicates when it has been eaten by a trout but provides critical signs regarding the accuracy of your cast or how well the fly is drifting. Getting a drag free float is often critical and monitoring how well your presentation is drifting will allow you to make the necessary adjustments to your cast or angle to improve the presentation.
Almost all my dry flies have some type of sight assistance built into the wing or on the topside of the body. I use a white post on many of my dun and spinner phase mayfly patterns. Other mayfly patterns incorporate a synthetic material in the wing that has a shimmering appearance such as Aero dry. Even a strand or two of Krystal Flash can add just enough sight aid for small patterns. Light deer hair shows up well on dark water and is a good choice for emerger patterns. Light elk creates a visible wing on most caddis imitations. White or orange hair or foam on the top of a terrestrial pattern allows it to show quite well on the surface. And a black post can work surprising well on flat water with the right amount of glare on the surface. But too much of a good thing can work against you. Flies that are overdone with sighting material, especially when the wing is too large, will not be as effective. It is also important to have a few styles of fly representing the same insect to show a fish some variety as it is common for a fish to prefer one style over another.
Be ready for low light
While many significant hatches occur during the light of day on prolific trout waters, insect and feeding activity often reach a crescendo in the low light near and after sundown. Late evening hatches and spinner falls can bring on a period of intense feeding and some of the largest fish. Preparation is the key to taking advantage of this opportunity. A good light, preferably a headlamp, is a given. Make sure your tippet is at a desired length as evening approaches and make any adjustments while it is still light. Make sure flies and tippet are organized in your vest or pack for a quick change. Pick out the flies you'll most likely use in advance to approaching nightfall.
There is an art to fishing in low light. It is best to fish water that is familiar as it gets dark. Flies with a white post will show up for a while after sundown but eventually you will have to rely on watching rise forms. Get the right angle so that any available light can be used to see a rising fish. You can get surprisingly close to surface feeding trout in this low light period. It can take some practice and feel but the key is to know the length of your cast. The drift will not necessarily need to be perfectly drag free and late evening feeders often seem to let their guard down. Slowly lift the rod when it appears that a trout has fed on your fly. As you begin your next cast, watch the fly as it is removed from the surface as this will help determine if the cast is too short or too long. Sometimes you can use your ears as well as your eyes to determine when a trout has possibly eaten your fly.
Light, small diameter tippets contribute directly to the effort of attaining a natural drift. Small diameter material has less surface area and is less impacted by the pull of the current but also increases the challenge level in bringing a trout to the net. I really dislike breaking off a fish that has taken my fly so I always use a tippet with sufficient strength. I typically use 5x in most situations. 6x or even 7x can be used with small flies in difficult fishing conditions and I'll go up to 4x or even 3x in low light or when using large flies for aggressive fish.
When using light tippets the hook-set should consist of a slow rise of the rod to bring the line tight and provide just enough force to place the hook point in the fish's mouth. A sharp rise reduces the ability of the rod and line to help absorb the shock of the hook-set. Softer rods have a greater ability to cushion the hook-set than faster action rods. A light drag setting allows the fish to take line when needed. In small, confined areas or when a fish is running out of control, tension can be added by letting the line run through the index and middle finger of the rod hand. It takes some practice to get used to the proper amount of tension. Use a net to assist in landing and a successful release.
Dry fly fishing remains one of the most captivating forms of fly fishing. Following some of these rather simple tips is sure to increase your success and enjoyment of the sport.


text:
Q: inequality with binomial coefficients I'd like to show that if $s \le n/4$, then we have
$$ {n \choose s-1} + {n \choose s-2}+ \dots {n \choose 0} \le {n \choose s}.$$
I'm happy with any short proof of this, but a "combinatorial proof" would be especially nice.
Comment: this is a special case of something listed as an "easy exercise" in Chapter 5 of Babai and Frankl's book. (See Proposition 5.13): http://people.cs.uchicago.edu/~laci/CLASS/HANDOUTS-COMB/BaFrNew.pdf

A: Here's a short direct proof of your inequality for $ s \leq n/3$.
Lemma: For $ s \leq n/3$, $ {n \choose s } = \frac{n-s+1}{s} { n \choose s-1}  > 2 { n \choose s-1} $.
Then, it follows that
$$\begin{array} {r l l } { n \choose s } & > 2 { n \choose s-1} &  = { n \choose s-1} + { n \choose s-1} \\
& > { n \choose s-1 } + 2 {n \choose s-2}  & = { n \choose s-1} + { n \choose s-2} + { n \choose s-2}\\
& > {n\choose s-1 } + {n \choose s-2} + 2 { n \choose s-3} \\
& > \ldots \\
& > \sum { n \choose s-i}. \end{array} $$

One way to motivate the idea is via the induction part of proposition 5.13.

A: Prove Proposition 5.13 in the book by induction.

For $ n\geq 2s$, we have
$$ { n \choose s } + {n \choose s-1 } + \ldots + { n \choose 0 } < { n \choose s } \times ( 1 + \frac{s}{n-2s+1} ). $$

It is indeed an easy exercise (when you know this is what you have to prove).
Then, follow the book for the next 2 lines:

If $ s \leq n/ l $ then the right hand side is less than $ { n \choose s} \cdot  ( 1 + \frac{1}{ l - 2 } )$. For example, with $s \leq n/4$, we obtain the inequality
$$ { n \choose s } + {n \choose s-1 } + \ldots + { n \choose 0 } < 2 \cdot { n \choose s } . $$

I'm not quite sure why he didn't pick $l = 3$ though. That is almost certainly a typo.

redpajama_set_name: RedPajamaStackExchange


text:
/*
 * @summary Verify that ObjectInputStream can skip over unresolvable serialized
 *          proxy instances.
 */

import java.io.*;
import java.lang.reflect.*;

class A implements Serializable {
    private static final long serialVersionUID = 0L;
    String a;
    String z;
}

class B implements Serializable {
    private static final long serialVersionUID = 0L;
    String s;

    private void readObject(ObjectInputStream in)
        throws IOException, ClassNotFoundException
    {
        in.defaultReadObject();
        // leave proxy object unconsumed
    }
}

public class Read {
    public static void main(String[] args) throws Exception {
        FileInputStream in = new FileInputStream("tmp.ser");
        try {
            ObjectInputStream oin = new ObjectInputStream(in);
            A a = (A) oin.readObject();
            if (! (a.a.equals("a") && a.z.equals("z"))) {
                throw new Error("A fields corrupted");
            }
            B b = (B) oin.readObject();
            if (! b.s.equals("s")) {
                throw new Error("B fields corrupted");
            }
            try {
                oin.readObject();
                throw new Error("proxy read should not succeed");
            } catch (ClassNotFoundException ex) {
            }
        } finally {
            in.close();
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
Film	Home	WWE	TV	Gaming	Comics	Music	Offbeat	Quizzes	Write For Us	Careers	Comps	Sport	UFC
Film	WWE	TV	Gaming	Comics	Music	Offbeat	Quizzes	Write For Us	Careers
10 Most Underrated Movies Of The New Millennium
by David Braga
Apr 3, 2013 April 3rd, 2013
There€™s hardly ever a single, lone reason for why a given film goes unnoticed or gets overlooked. Usually, it€™s a combination of forces; poor scheduling, ineffective marketing, an out of vogue star, misunderstood criticism at the time of its release, or any one of a multitude of other causes. The point is, movies get overlooked all the time, and sometimes, some truly great ones fly under the radar. Over time, many of these films prove their worth by developing advocates or cult followings, while others struggle even to gain that much of a foothold. Since 2000 alone, there have been far too many great films that have gone unnoticed and become underrated. It would be impossible to make a list containing all of them, but hopefully by compiling ten of them here, they can get some of the attention that they deserve, or at least encourage those that may have seen and dismissed them to revisit and rewatch. Here are the 10 most underrated films of the new millennium (so far):
10. Primer (2004)
$7000 can go a long way when it's in the hands of an intelligent craftsman. Shane Carruth, the writer, director and star of Primer, is one such man. His film, a sorely underseen Sundance darling, takes on time travel from both a practical and scientific perspective to become one of the most original and creative science fiction films of the new century. The science of the film isn€™t cleaned up or simplified for the audience, so oftentimes we can only grasp vague concepts of what the characters are discussing (which is maybe better, since time travel movies usually beg to have holes poked in them by over explaining things). But it€™s fascinating the way Carruth shows how stumbling onto such technology could affect a group of every day men, not only in the way that they use the ability to travel through time, but also in how it slowly consumes them in their personal lives. This isn€™t a mad scientist story, it€™s a human story, one of small, potent power. At only 77 minutes it€™s short and sweet, although seen by far too few people.
Posted On: 3rd Apr 2013
David Braga
David Braga lives in Boston, MA, where he watches movies, football, and enjoys a healthy amount of beer. It's a tough life, but someone has to live it.
See more from David
10 Movies That Made No Sense If You Watched Them In Other Countries
13 Awesome Performances In Otherwise Disappointing 2021 Movies
5 More Directors Who Were Lumbered With Actors They Didn't Even Want
10 Best Scenes When Movie Characters Turned Evil
10 Movie Scenes Everyone Always Gets Wrong
10 Huge Marvel Characters That Could Make Their MCU Debut In 2022
20 Actors You Never Knew Were In Star Wars
20 Best Performances In MCU History (So Far)
10 Upcoming Movies That Are Doomed To Fail
10 Movie Actors Who Refused To Talk To Directors On Set
10 Best Horror Movies Where Nobody Dies


Welcome to HaitiXchange Digital Media. Based in Haiti and registered with the Ministry of Economy and Finance, we provide top-of-the-line video and multimedia services both locally, and abroad. Our extensive portfolio includes video, photos, and voice-overs, seen and heard by many.
Our prices are affordable without sacrificing quality. Call or email us for additional information on how we can help you with your next digital media project.
Pascal Antoine is the founder of the original HaitiXchange.com, a multi-media website that featured Haitian news and culture, actually moved to Haiti from Brooklyn, New York to found and run HaitiXchange Digital Media. He is a media entrepreneur, video editor, producer and voice-over actor.
A graduate of the Massachusetts Institute of Technology, he was born in Paris, France and raised in Brooklyn New York by Haitian parents. Making Port-au-Prince, Haiti his home has allowed him to follow a lifelong desire to contribute to the country's advancement from the source itself.
Watch all of our stuff on YouTube!
HaitiXchange offers affordable, high quality media services. Take a look at our portfolio, and let us know what we can do for you.


Since its establishment 20 years ago, the food company Fria Bröd AB has taken its gluten-free bread from the little industrial area in Västra Frölunda to 15 countries in Europe. Jeanine Öhrstedt Holmgren was recruited as CEO almost five years ago to help the company obtain greater market share in the gluten-free market.
The clock has barely hit seven in the morning when verksamt.se's reporter Anders Nyberg visits Jeanine at the Gothenburg factory to hear more about the company's export journey.
Yea, isn't that amazing. A lot has happened since the founders Lena and Gunnar Adås 20 years ago saw the need to give gluten intolerants the opportunity to eat good bread.
What was the first country outside Sweden that you started selling in?
The first country was our neighbour Finland, then Norway and Denmark came along quite quickly. After that, everything has been running smoothly. We not only sell to stores and wholesalers in Europe, we also cooperate with celiac associations in Europe, i.e. the association for gluten intolerance.
It's a great way to start with cultures reminiscent of your own. There are also short shipping routes. We freeze all our bread and it is quite expensive logistics, so starting to sell in neighbouring countries felt like a natural thing to do.
What do you think a company looking for a new market should consider?
Go to the countries, walk around and look at the stores, visit potential customers, especially when it comes to food. In this way, you will get to know the country, the culture and the customers better. I usually also say it's can be of great use to Google and gather information.
Also, contact Business Sweden, they can be a great sounding board and have offices across Europe. It has been worthwhile for us to consult with them. Then there are verksamt.se and a number of other government agencies where you can get a lot of assistance. Dare to ask. When you go out as an entrepreneur, it's easy to start selling to those who want to purchase. But I think you should be careful about which customers and partners you choose.
Don't sell to everyone who wants to buy?
No. Make some kind of background investigation. Make a risk analysis: review the company, check the creditworthiness of the company in a commercial credit reporting agency's database. Ask questions such as: What does the company stand for, what is its history, how financially stable is the company, does its ability to pay look good? Take such an example as the payment terms, i.e. the time you have to wait to get paid. Your suppliers give you perhaps 30 or 45 days to pay; what happens if the company you sell to doesn't pay until 60 or 90 days, or even sometimes 120 days? Include this in your calculations.
That sounds hard and risky?
Not really. But it's not always the easiest thing. It is really difficult to know which customers and collaborative partners are right. But it is also the fun of a running company – being challenged all the time. We ourselves encountered the situation where a collaborative partner contacted us and wanted to sell our products. Everything looked great with them. They showed good sales figures and were already selling products from other Swedish companies. We tried things out with them for half a year, but in the end, they ended up not selling anything. We didn't actually incur any financial costs, but we had counted on seeing an inward cash flow. Nothing ever came of it.
Think twice, and start within the EU. It is easier because it is the same regulatory framework throughout the EU. For us in particular, someone who works with gluten-free bread, it may be the case that the definition of gluten-free is not the same in all countries, however within the EU it is the same regulatory framework. Actually, in fact both the United States and Canada have finally applied the EU's gluten-free rules and regulation, so now a market is starting to open for us in the US too.
Thank you, Jeanine. Should we eat some gluten-free lussekatter now?
Yes, let's! I love saffron buns. Thank you for coming by and chatting with us.


text:
Chris Lopez, Kailyn Lowry's Baby Daddy: 5 Fast Facts You Need to Know
By Daniel S. Levine
Kailyn Lowry. (Getty)
Kailyn Lowry, one of the stars of Teen Mom 2 and 16 And Pregnant, has finally confirmed that Chris Lopez is the father of her third child.
The 25-year-old Lowry, who wrote the bestsellers Love Is Bubblegum and Pride Over Pity, is already the mother of Lincoln Marshall Marroquin, 3, and Isaac Elliot Rivera, 7. Both of her sons are from previous relationships. Isaac's father is Jo Rivera, an ex-boyfriend. Lincoln's father is Javi Marroquin, to whom she was married to from 2012 to 2016.
Lopez was actually seen in an episode of Teen Mom 2, but we didn't see his face. A source told E! News that his face was blurred out when we saw him at Lowry and Marroquin's house when Marroquin returned from his U.S. Air Force deployment.
Here's what we know about Lopez and Lowry's relationships.
1. Lowry Finally Confirmed Lopez Is the Father on Twitter
This is the photo Chris Lopez uses as a profile picture on Twitter. (Twitter/Chris Lopez)
On May 2, Lowry finally confirmed long-standing rumors that Lopez is the father of her third child by responding to an OK Magazine report. "Ancestry DNA & yeah he is… stop with the headlines already," she tweeted.
Ancestry DNA & yeah he is… stop with the headlines already. https://t.co/tAB1ef6RHu
— Kail Lowry (@KailLowry) May 2, 2017
As Radar Online notes, Lowry previously teased connections to Lopez. For example, she nicknamed her baby bump "Baby Lo" (although that could just as easily be a reference to her own name). In an Instagram live video, she mentioned, "Chris would say, 'I'm Holden the baby.'"
Lowry also showed herself using an Ancestry DNA package to find out where her ancestors are from.
Read More From Heavy
DaddyOFive: 5 Fast Facts You Need to Know
2. Lopez Once Tweeted & Deleted an Apology to a 'Miracle Child'
Mom x3 + a degree ??? new blog post up on kaillowry.com of my grad pix shoot we did yesterday with the boys ?
A post shared by Kailyn Lowry (@kaillowry) on Apr 30, 2017 at 7:10pm PDT
One hint that Lopez is the father came from Lopez himself. On January 5, he tweeted "To my miracle child… I'm sorry." The tweet was then deleted, In Touch notes, but not before Lowry liked it.
Lopez now uses the Twitter handle @HUMLHSTLR, where he appears to be reacting to the news. He first tweeted a .GIF of a scene from Supernatural.
?? pic.twitter.com/fzXZTR488Y
— BAM? (@HUMBLHSTLR) May 2, 2017
Then, Lopez wrote, "Did I miss something?" and "I'm so lost."
He's also sent other hints in the past. On January 15, he wrote "I won the bet… well technically we both called it." Lowry later replied to the second tweet, writing "Are you [for real]."
@Chris3zero2 are you fr
— Kail Lowry (@KailLowry) January 16, 2017
It's believed that a tweet Lowry sent on April 23 was also directed towards Lopez. "Cut out those toxic to you & you'll see what you've been missing out on," she wrote.
Cut out those toxic to you & you'll see what you've been missing out on
— Kail Lowry (@KailLowry) April 23, 2017
Billy Kimmel, Jimmy's Son: 5 Fast Facts You Need to Know
3. Lowry Wrote That This is the Baby She 'Wasn't Sure If I Could Have'
https://www.instagram.com/p/BTWzzsQhBEn/?taken-by=kaillowry&hl=en
Lowry announced that she is expecting her third child with a blog post in February. She didn't reveal the father's identity in the lengthy blog post, and said that she was four months pregnant at the time. She wants to wait until the baby is born this summer to find out. Lowry and Marroquin's divorce wasn't finalized until December 2016.
Lowry wrote that she's very excited about having another child, especially since she wasn't sure if she could have another one. She wrote:
This is the baby I thought I wasn't sure if I could have. I know this isn't an ideal situation but I know everything will be okay. And like I say in my book — with a little bit of hustle and heart, I can and I will survive anything. Having another child is something I am so happy about and I just can't wait. My boys are so excited, those who love me are so excited, and I hope that everyone can just be happy for me during this time.
'Taken' Renewed or Cancelled: Will NBC's Bryan Mills Series Be Back for Season 2?
4. Tyler Hill & J.C. Cueva Were Considered Potential Baby Daddies
Happy bump day from Baby Lo & me ?????
A post shared by Kailyn Lowry (@kaillowry) on Apr 26, 2017 at 6:14am PDT
Lopez's name has been floating around as a potential father for Lowry's third child for several months now. But before this was confirmed, Tyler Hill and J.C. Cueva were considered candidates.
The Hollywood Gossip notes that Lowry allegedly slept with Hill while Marroquin was deployed overseas with the U.S. Air Force. She was seen FaceTiming with Hill and it was rumored that their relationship went further than just talking over the phone. Cueva is a producer on Teen Mom 2.
In February, Hill confirmed that he's not the father of Lowry's baby. When a fan texted Hill, asking if him if he was Lowry's "secret bae," Hill wrote, "Na. She['s] not my type apparently."
"The father is a friend Kail was briefly dating," Lowry's publicist told Radar Online.
What Movies & TV Shows Are Coming to Netflix in May 2017?
5. Lopez Is Lowry's Third Different Baby Daddy
https://www.instagram.com/p/BTHKpmjlqfq/?taken-by=kaillowry&hl=en
Lowry has three children, all from different fathers. Isaac's father is ex-boyfriend Joe Rivera. While pregnant with Isaac, Lowry was featured on MTV's 16 And Pregnant. Isaac is now 7 years old.
Lincoln's father is Lowry's ex-husband, Javi Marroquin, and he's now 3 years old. Marroquin and Lowry were married from 2012 to 2016. During the previous season of Teen Mom 2, Lowry revealed that she suffered a miscarriage in 2015.
"MTV and the producers were very sensitive to the situation and just understood that I wasn't necessarily ready to talk about it as soon as it happened," Lowry told People Magazine. "They kind of just gave me my time to grieve, and when I was ready and felt like I was comfortable talking about it, I did."
After breaking up with Marroquin, Lowry surprisingly became friends with Rivera again, she told MTV News.
"Jo and I hated each others' guts…we were not good friends [and] we barely co-parented," Lowry told MTV News. "All of a sudden, it was a complete 180. Now we're best friends — I can tell him anything. I can call him, and we can switch weekends easily or if I need him to grab Isaac from school. We are so good now."
'Roseanne' Revival: 5 Fast Facts You Need to Know
5 Fast Facts, Teen Mom, Teen Mom 2
Teen Mom 2 star Kailyn Lowry finally confirmed that Chris Lopez, a friend, is the father of her third child.


We love to entertain! When the air gets a little cooler, we just take the party outside and get the fire pit going. There is nothing more cozy than an outdoor dinner party with all of the lights and ambiance!
We have plenty of chairs to gather around the fire pit after dinner and enjoy some warm beverages.
When it comes to entertaining, we always try to include a seasonal salad. This pear and apple salad is perfect for fall entertaining, and fancy enough for the holidays. It's equal sweet and savory and the dressing is also easy to whip up!
Sahale's Naturally Pomegranate Flavored Pistachios Glazed Mix is one of my favorite snacks. With whole roasted pistachios and almonds, cherries and pomegranate flavored apples, lemon and black pepper…. it's like a trip for your taste buds. I'll let you in on a secret… don't just pick up one bag for the recipe… grab several. Trust me. You are welcome!
They are perfect for hiking, after school snacks, road trips, and all of those times you need to nosh between Point A and Point B. They are also great to mix up in some savory recipes.
Pomegranates, apples, and pears all come into season in the fall, you can also pick them up any time of year!
Sahale snacks are available at the following retailers. Click on the store near you to get a coupon for $1.50 off one 4oz bag. Coupon is valid from October 29, 2017 through December 29, 2017.
Love, hugs, and eating salad for dinner.
What a lovely salada perfect for fall gatherings at home. Love the idea of using seasonal fruit and nuts.


text:
Strolling In The Sunshine
Published on 2021-04-16 / By kd@trefeddianhotel
With the sun shining and the weathermen predicting more good weather, we are looking forward to taking advantage of the warmer days and heading out for a spectacular coastal walk.
Wales is the first country in the world to have a footpath that follows the whole length of its coastline. Aberdovey and the hotel are perfectly located, right in the middle of its route, and here are just three sections of the Wales Coast Path that our team really enjoy.
Morfa Mawddach to Barmouth
Either take the train along the stunning Cambrian Coast route or park your car at Morfa Mawddach station and walk across the Barmouth Bridge. Spanning half a mile, the bridge is the longest timber viaduct in Wales and one of the oldest in Britain offering amazing views towards Cadair Idris, the second highest mountain in Snowdonia and out to Cardigan Bay across the Mawddach estuary.
The bridge opened in 1867 and included a lifting drawbridge section to permit the passage of tall ships at the northern end. The section was rebuilt in 1901 as a swing bridge with two steel spans.
The pretty seaside town of Barmouth is the perfect place to get a spot of lunch and to meander the independent shops before heading back to relax in one of the lounges at the hotel.
Llwyngwril to Tywyn
Starting in the beautiful village of Llwyngwril, with a long and rich history, this section of the Wales Coast Path takes you away from the sea to follow the country lanes where the trail takes a downhill route across some farmland.
The coast is a distant memory as the track contours the hill of Foel Llanfendigaid to the landward side before following a quiet road past the former army base at Tonfannau with its abandoned airplane hangars and soldier billet huts.
The lane reaches the mouth of the Dysynni River and runs past a large salt lagoon, known as the Broadwater, then heads into the seaside town of Tywyn. Home to the Talyllyn Railway, this Victorian seaside town has a fabulous promenade along the seafront where you can sit and watch the dolphins swimming in the bay.
Tywyn to Aberdovey
Taking the Wales Coast Path from Tywyn to Aberdovey brings you right back to the sea.
Starting at the Neptune Caravan Park, the route takes you to the beach and you can stroll along the four miles of golden sandy beach. Head past the peat beds left by the petrified forest and enjoy panoramic views that stretch down the Pembrokeshire coast as far as Fishguard and looking north to the Llyn Peninsula.
You will walk past the hotel in its enviable position on the hill, overlooking the golf course and Cardigan Bay beyond. Here you can cut across the sand dunes and golf course back to the hotel to put your feet up or carry on into the pretty harbourside village of Aberdovey to enjoy a homemade ice cream from The Sweet Shop Aberdyfi.


It's been a hot summer. A really hot summer. Here in Minnesota the aforementioned hot summer followed a shockingly mild winter, which I would never complain about. That being said, I am kind of excited for things to cool off a bit. Reason number one? I miss wearing my scarves!


text:
Article MUST SEE: Little Boy's adventures in his adorable "truck"
Alaina Carr, documents the many adventures of her two year old son Miles and his "truck".
Alaina told POPSUGAR that this beloved 30-day photo series first began one day when Miles was playing with his truck in the house. "He would lean out his window and yell 'Fries! Nuggets! Uh Fries! And toys! Thank you,'" Alaina recalled. "I wanted to make his little dreams come true, so I took him through an actual drive-through the next day."
When Alaina posted the photos on Facebook, she was shocked by the response and decided to continue with "The Adventures of Miles." Considering how much Miles adores his truck, it wasn't difficult to get him excited about the project. "Anywhere we go, the truck goes. To get his big sister off the bus, he drives his truck. To get the mail, he drives his truck. To take the dog on a walk, he drives his truck," Alaina said. "I can't wait to be able to re-create some of these when he's a teenager, and I can't wait for the day when he has his own children and he can show them 'The Adventures of Miles.'"
From daily tasks like stopping through the drive-through and ordering takeaway, a fishing adventure, pumping gas to even picking up a first date and getting married, Miles and his Little Tikes Cozy Truck have been through it all.
Check them out below.
Image via Facebook
Share MUST SEE: Little Boy's adventures in his adorable "truck" on Facebook
Share MUST SEE: Little Boy's adventures in his adorable "truck" on Twitter
Share MUST SEE: Little Boy's adventures in his adorable "truck" on Pinterest
Share MUST SEE: Little Boy's adventures in his adorable "truck" on Tumblr
Share MUST SEE: Little Boy's adventures in his adorable "truck" via email
Share MUST SEE: Little Boy's adventures in his adorable "truck" via browser
Oh these photos are just so very awesome.
That is just gorgeous, thank you for sharing.
I love this, fantastic. If only I had such ideas and the greater use of technology 15 years ago. It's amazing what you can capture now and share.
Terrific. Thanks for sharing. So cute.
How cute is that ?!
so cute. A different concept, but one way to remember his love of the car and his childhood.
what a cutie.
I love the one where the policeman is writing him a ticket!! Awesome
I'm loving those photos – how cute is that little man and his "truck".
mom#1 said
That's so cute. What a wonderful way to document his favorite activity.
Splendid pictures! What a lovely child!!
Tinarh said
Hahaha…love them! How awesome to have these to look back on later in life!
this is just the cutest thing!
Such great photos and they look like they had fun doing it
Very cute – I like the less staged ones best.
Aaawww … how sweet is this little boy and his car? Love it!
On review now


 High School - Spin Doctor Productions. Professional DJs / Disc Jockeys serving Guelph, Fergus, Cambridge, Kitchener, Waterloo, Hamilton, Brantford, Woodstock, Milton, London, Orangeville, Brampton, Mississauga, Oakville, Toronto, Vaughn, Ontario, Canada!
All at a budget price.
Rad vibes and cool sounds you and your friends will rock out to. The music of course!
More Totally WICKED Sound & More KILLER lights.
More of everything. You know you want it!
Make the school year with a PARTY you won't forget! Semi-formals, Formals and Proms.
Tell us what you need and we'll create an awesome event.
Add "Tweet the Dance" to Your Event!
The Spin Doctor DJ was professional and accommodating. The students enjoyed the music. Thank you.


A high-ranking official of the Maryland Health Department is seeking the nomination of the Libertarian Party to challenge U.S. Rep. John Sarbanes (D).
J. David Lashar, the agency's former chief of staff who is currently working as its senior transformation executive in the Office of Enterprise Transformation, is competing for the nomination at the Libertarians' March 10 state convention. He is the only candidate in the race so far.
In an email to Maryland Matters, Lashar confirmed that he is seeking the Libertarian nod but said he was hesitant to discuss his candidacy until he wins the nomination. He said he has told higher-ups in the Hogan administration about his plans to run.
Lashar served as the health department's chief of staff for a year under Acting Secretary Dennis R. Schrader. When Schrader became the agency's chief operating officer earlier this year, under the newly nominated secretary, Robert R. Neall, Lashar moved with him.
Sarbanes is heavily favored to win a seventh term representing the 3rd Congressional District – a controversially shaped, serpentine district that runs from north of Baltimore City, east to Annapolis and west to portions of eastern Montgomery County.
Lashar rails against gerrymandering frequently on his campaign website.
Republicans are not expected to heavily contest the district this year. A political unknown, Charles Anthony of Silver Spring, who doesn't even have a campaign website, is the only candidate seeking the GOP nomination so far.


text:
Gopalaswami Parthasarathi fue un diplomático indio.

Gopalaswami Parthasarathi fue hijo de N. Gopalaswami Ayyangar.
En 1936 fue miembro del :en:Lincoln's Inn y llamado al Bar en Londres como Barrister.
De 1936 a 1949 fue Asistente Editor de The Hindu.
De 1951 a 1953 fue Editor del :en:Press Trust of India.
De 1954 a enero de 1957 y de 1961 a 1962 fue presidente de la :en:International Control Commission en Camboya.
De enero de 1957 a junio de 1958 fue embajador en Yakarta.
De  a  fue embajador en Beijing.
A partir de 1960 fue presidente de la Comité de Planificación de Políticas en el Ministerio de Asuntos Exteriores (India).
De 1962 a enero de 1965 fue Alto Comisionado en Karachi.
De enero de 1965 a  fue Representante Permanente de la India ante la Sede de la Organización de las Naciones Unidas.
De  a 1974 fue el primer Vice-Canciller de la :en:Jawaharlal Nehru University.

Referencias

Embajadores de la India en Indonesia
Embajadores de India en China
Altos Comisionados de India en Pakistán
Nacidos en Chennai

redpajama_set_name: RedPajamaWikipedia


We sat down with Brad Davey, Executive Director from ConnexOntario to learn more about what they do and what they are all about. This is what we found out!
How is ConnexOntario relevant for those on campus?
Connex Ontario has a vision where everyone can access information about the healthcare and social support services they need, at the right time, and at the right place.
And how do they do this you may ask.
They provide free and confidential health services information for people experiencing problems with alcohol and drugs, mental illness and/or gambling.
They do this by maintaining a centralized, up-to-date, and accurate database of detailed drug, alcohol, problem gambling, and mental health treatment service information.
Their information and referral service is live-answer 24/7, confidential, and free.
Through the use of leading-edge technology, ConnexOntario provides hope, early help and a human voice 24-hours per day to all individuals seeking information on, for example, mental health, drug, alcohol, and gambling problems. ConnexOntario also provides data to service planners seeking access to quality health and human services information.
They are currently working on an app to make it more accessible in the near future.
Side Note: ConnexOntario also hosts the www.workinginmentalhealth.ca website as well. This is a website if you are looking for a career that makes a difference in other people's lives and in the community we can help.


text:
Q: AWS Aplication Load Balancer HTTP to HTTPS with EC2 instance I have a EC2 instance running a Node.Js server on Ubuntu.
My goals are:

*

*Connect my hosted zone to the EC2 instance

*Route all incoming traffic from port 80 to port 3000 (because my server runs on port 3000)

*and most importantly Use an Application Load Balancer to forward all requests to HTTPS (I already created a SSL Certificate in the Certificate Manager).

Currently, I am only able to open the website with the EC2 intances' Public Ip on port 3000 (http://prntscr.com/livali). Https requests or Http to port 80 don't work (http://prntscr.com/livau2). Altought a made an A record on my hosted zone with the instances' Public Ip, it's not possible to open the instance via the hosted zone (http://prntscr.com/liv9no).
I am really confused, as I am somehow not able to get this up and running. I would really appreciate a step by step guide on how to set this whole thing up.

A: If you already have a SSL certificate it is secure to use only port 443 instead of port 80.

*

*Create an internet facing Application Load Balancer that listens on port 443 and routes traffic to your EC2 instance on port 3000.

*Redirect users to HTTPS when accessing your domain on HTTP
See Docs > Load Balancer Listeners > Redirect Actions

*Add an A record to point your domain name to the Load Balancer's public DNS.

A: These are web server concerns rather than DNS concerns. You'll need to set up something like NGINX or Apache to proxy port 80 to port 3000. See Apache redirect to another port for information.
You can also force HTTPS with a rewrite rule in Apache: https://wiki.apache.org/httpd/RewriteHTTPToHTTPS
Another option for forcing HTTPS is to create a CloudFront distribution and use that. https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-https.html


Elizabethtown, Ky. December 5, 2016—The Elizabethtown Tourism and Convention Bureau gave their free smartphone app a facelift on December 5.
The upgraded app, titled Tour Etown, is now manned by Bar-Z Adventures, the same mobile app company that provides the Kentucky Department of Travel and Tourism's (K.D.T.T.) mobile application.
Previously, Elizabethtown Tourism provided two free smartphone apps to residents and tourists. One supplied information about the Elizabethtown area, while the other gave self-guided tours of historic downtown. The upgraded app will encompass both area information and tours of downtown Elizabethtown.
"I think users will have a better experience with the upgraded version of our mobile app. It's easier to navigate and provides more information that we were not able to include in our previous app," said Jessica Gowen, communications director of Elizabethtown Tourism and Convention Bureau.
Users who currently have the app downloaded to their mobile devices will not have to re-download the app. Once Tour Etown is opened, a notification will pop up asking them to upgrade. Users who have downloaded Elizabethtown Historical Tours will no longer be able to access this app. They will need to download Tour Etown.
The Tour Etown app features attractions, lodging, restaurants, events, and more. New features include The Bourbon Trail, the Lincoln connection, and self-guided tours. Mobile users can also choose to receive important alerts involving Elizabethtown.
The free app can be downloaded by searching "Elizabethtown" in Android's Google Play store and Apple's iTunes store.


text:
// -----------------------------------------------------------------------
//  <copyright file="FrameworkInitializer.cs" company="">
//      Copyright (c) 2014-2015 OSky. All rights reserved.
//  </copyright>
//  <site>http://www.OSky.org</site>
//  <last-editor>Lmf</last-editor>
//  <last-date>2015-10-10 15:35</last-date>
// -----------------------------------------------------------------------

using System;

using OSky.Core.Configs;
using OSky.Core.Dependency;
using OSky.Core.Initialize;
using OSky.Core.Properties;
using OSky.Core.Security;
using OSky.Utility;

namespace OSky.Core
{
    /// <summary>
    /// 框架初始化
    /// </summary>
    public class FrameworkInitializer : IFrameworkInitializer
    {
        //基础模块,只初始化一次
        private static bool _basicLoggingInitialized;
        private static bool _databaseInitialized;
        private static bool _entityInfoInitialized;

        /// <summary>
        /// 开始执行框架初始化
        /// </summary>
        /// <param name="services">服务映射集合</param>
        /// <param name="iocBuilder">依赖注入构建器</param>
        public void Initialize(IServiceCollection services, IIocBuilder iocBuilder)
        {
            services.CheckNotNull("services");
            iocBuilder.CheckNotNull("iocBuilder");

            OSkyConfig config = OSkyConfig.Instance;

            //使用副本进行初始化,防止不同平台间的相互污染
            IServiceCollection newServices = services.Clone();
            IServiceProvider provider = iocBuilder.Build(newServices);

            IBasicLoggingInitializer loggingInitializer = provider.GetService<IBasicLoggingInitializer>();
            if (!_basicLoggingInitialized && loggingInitializer != null)
            {
                loggingInitializer.Initialize(config.LoggingConfig);
                _basicLoggingInitialized = true;
            }

            IDatabaseInitializer databaseInitializer = provider.GetService<IDatabaseInitializer>();
            if (!_databaseInitialized)
            {
                if (databaseInitializer == null)
                {
                    throw new InvalidOperationException(Resources.FrameworkInitializerBase_DatabaseInitializeIsNull);
                }
                databaseInitializer.Initialize(config.DataConfig);
                _databaseInitialized = true;
            }

            if (!_entityInfoInitialized)
            {
                IEntityInfoHandler entityInfoHandler = provider.GetService<IEntityInfoHandler>();
                if (entityInfoHandler == null)
                {
                    throw new InvalidOperationException(Resources.FrameworkInitializerBase_EntityInfoHandlerIsNull);
                }
                entityInfoHandler.Initialize();
                _entityInfoInitialized = true;
            }

            IFunctionHandler functionHandler = provider.GetService<IFunctionHandler>();
            if (functionHandler == null)
            {
                throw new InvalidOperationException(Resources.FrameworkInitializerBase_FunctionHandlerIsNull);
            }
            functionHandler.Initialize();
        }
    }
}


Tan is a Foundation Professor in the Department of Electrical and Computer Engineering at Michigan State University and director of the Smart Microsystems Laboratory there. At Maryland, Tan was advised by Professor John Baras (ECE/ISR) and Professor P. S. Krishnaprasad (ECE/ISR).
An expert in automatic control systems, he has made significant contributions to modeling and control of smart materials, and is internationally recognized for his seminal work in developing fish-like robots for underwater sensing. He has successfully blended deep theoretical concepts into his research with practical approaches to provide innovative solutions to complex problems. His research is interdisciplinary, spanning controls, dynamics, materials, fabrication, and robotics. He has established extensive collaborations at MSU and beyond with electrical and mechanical engineers, computer scientists, environmental scientists, and ecologists.


text:
Girl Scouts Fight for Their Right to Pee Outdoors
If you're in Ohio and can't live without Thin Mints, you'd better give the Ohio Girl Scout Council a call and demand they leave their existing camping sites open to the troops. Otherwise, you may very well be subject to a shortage of Samoas.
That's because a number of troops in the state are planning to boycott Girl Scout Cookie sales this year. It's a last-ditch effort to get the organization to leave open campsites that do not have indoor plumbing. The organization is instead planning to close these sites in favor of their new Premier Leadership Centers, all of which feature bathrooms inside.
"The council management has forced the cookie boycott by turning a deaf ear," said Lynn Richardson of Trefoil Integrity, a group that wants to keep the camps open. But she adds that it's up to each individual Girl Scout to decide what to do. "The girls boycotting are the ones who still have hopes that the board will change."
[Image courtesy of The U.S. Army's Flickr stream.]


I posted this on another forum. This is how I make pizza while we are camping.
I see you are using the Camp Chef Pizza Oven. I have that on my Wish List (the girlfriend works in the Cabela's Camping Department) as I have the Camp Chef 14" 2 burner stove with a single BBQ and a single griddle as the mainstays.
How do you like it? You mention in the video you perhaps didn't let the oven warm up enough.
I've been using Camp Chef for about 5-6 years now and I love it. I've had the pizza oven for almost as long. It works pretty darn good. I also have the pro style griddle and grill box. In fact, i have a 14" set for the trailer and a 16" set for home.
Plus my dough was getting over proofed so I had to get going on the pizza making.
Oh man, Tom, thanks to you....we just made our first Campground pizza here at Enchanted Rock. About to dig in.
The DW is savoring the aroma, sayin' OH MAN! as she pulled it out of the oven.
Update: straight out of the 377s oven, this is AWESOME!!! Thanks Tom for all your cheer!
Another additive here: the DW bestS friend from IN dropped in yesterday for a surprise visit and they both work on this homemade pizza this morning, sautéing the onions, green peppers...and laudy laudy forgot the black olives. Best pizza I've ever had!
I'm lookin forward to dough ball #2.


text:
Home COLUMNS Notes from the Larkspur Supper Club If you have livestock, you will have dead stock
Keeping watch for the Black Swan
The cost of living high on the hog
If you have livestock, you will have dead stock
by Dan Needles
It's been a tough week here at the farm. Bobcat Ransier made several trips out with his backhoe to plant three members of the sheep flock. One expired as a result of misadventure and two others succumbed to the effects of a mysterious parasite.
Bob shut the machine off after the final excavation and paused to do some bereavement counselling. "Do you want to check around the place before I fill this in?" he asked.
When my father-in-law presented me with my first six sheep as a wedding present 31 years ago he warned me that they had an alarming instinct for self-destruction. But they still catch me off guard.
I assured Bob there was no plague going on. You can't do anything about an old sheep who is determined to jam herself halfway under a gate and it's a tricky thing to spot certain parasite problems in time to take action. I've already dosed the flock twice this summer for roundworms, corkscrew worms and liver fluke on top of the usual 9-way booster vaccination and a drench for coccidiosis.
"It could have something to do with the age of these animals," said Bob. Coming here is like going to the Legion. Maybe you should invest in some younger stock."
He may have a point. In a well-run sheep flock the older ewes are supposed to be culled, usually by the age of ten. But I find it difficult to fire an old sheep off to the works after she has cranked out eight or nine lambs for me. It just doesn't seem right or fair. This is a fatal weakness in a shepherd and I think one of the reasons that people prefer to run a thousand sheep at a time, rather than twelve, as I do. You don't get attached.
When I was a kid you didn't have to do much with a sheep besides dock the tail and maybe soak it with a tick spray once a year. Now a sheep gets dosed and drenched and vaccinated for a host of different ailments. Even then they still think up creative ways to die that I have never heard of.
Some years ago I came into the barn and found Cinder, the black ewe, lying down and staring straight up at the ceiling, apparently fascinated by the light bulb above her. I realized she was in some kind of a spasm so I loaded her onto the back of the truck and drove her into town to see Dr. Jim, who wasn't doing farm calls any more. I stopped at a red light and noticed people looking at the sheep and then looking up in the air to see what she was interested in. Dr. Jim diagnosed sheep polio.
"Sheep polio?" I said, alarmed. "I've never heard of polio in a sheep."
"That's the thing," said Jim. "You've only had the sheep for twenty years and you only keep twelve. So you're always going to see something new. There's more than 250 things that can go wrong with a sheep. You're not even halfway there yet."
Sheep polio is caused by a thiamine deficiency, not a virus. Jim was very surprised when I got a handful of off-label thiamine needles from a friend at the hospital (they use it for treating severe alcoholics) and succeeded in bringing Cinder back to health. He actually dropped by to look at this miracle sheep that had defied the odds.
"She's okay but she'll probably have some brain damage," he warned. I forgot to ask him how you would tell if a sheep has brain damage. But sure enough she seemed to suffer a serious short term memory loss. Hay was always a complete surprise for her after that and she often came up from the pasture and stared at the barn as if to say, "Who put that there?"
Cinder lasted another couple of years and produced two more lambs but I made the mistake of allowing a portrait artist to set up in the barnyard and fashion an oil painting of her. I find this is almost always fatal for an animal. Within a month Cinder figured out a way to hang herself in a gate she had lived beside for a decade. She now hangs in the hallway outside my office, a testimonial to long service and a tribute to imaginative and inventive ways to exit this world.
— Dan Needles


It wasn't long after Marisol's fourteenth birthday when Eileen called and invited Gina and Colman to a family conference in Sudbury. Eileen didn't tell her the reason for it, and Gina had trepidations about it, imagining various scenarios that ranged from Ugo and Eileen getting a divorce to one of their children having leukemia. For some reason she never imagined what it was about, and when Eileen told her as they were sitting in the formal living room that was only used for guests, she realized that she should have seen it coming.
"We've decided to put Meredith in a foster home," Eileen said with her eyes fixed on the coffee table, which displayed a book about Florence.
"There's no need to use language like that," Eileen said primly.
"I was a model child," Ugo said with a smirk.
"Leonora always takes your side," Ugo said, playing the victim.
"Technically, she's not our child," Eileen said.
"We're only trying to do what's best for her," Eileen said.
"You never had them," Ugo said with a scornful look at Gina.
Ugo made a face, with his lower lip curled over, but he didn't say a word of protest.
"Now, when are we going to tell the girl what's happening?" Colman asked.
"The sooner, the better," Ugo muttered.
"You mean we should talk with her together?" Eileen asked as if she didn't think it was a good idea.
"You mean Meredith," Ugo said.