text:
Acidobacteria 0 domande A physiologically diverse phylum of acidophilic, gram-negative bacteria found in a wide variety of habitats, but particularly abundant in soils and sediments.
Agricultural Inoculants 0 domande Beneficial microorganisms (bacteria or fungi) encapsulated in carrier material and applied to the environment for remediation and enhancement of agricultural productivity.
Forme Atipiche Di Batteri 0 domande Microorganisms that have undergone greater changes than normal in morphology, physiology, or cultural characteristics.
Batteri Aerobi 0 domande
Batteri Anaerobi 0 domande
Bacteroidetes 0 domande A phylum of bacteria comprised of three classes: Bacteroides, Flavobacteria, and Sphingobacteria.
Agenti Patogeni Presenti Nel Sangue 0 domande Infectious organisms in the BLOOD, of which the predominant medical interest is their contamination of blood-soiled linens, towels, gowns, BANDAGES, other items from individuals in risk categories, NEEDLES and other sharp objects, MEDICAL WASTE and DENTAL WASTE, all of which health workers are exposed to. This concept is differentiated from the clinical conditions of BACTEREMIA; VIREMIA; and FUNGEMIA where the organism is present in the blood of a patient as the result of a natural infectious process.
Chlorobi 0 domande A phylum of anoxygenic, phototrophic bacteria including the family Chlorobiaceae. They occur in aquatic sediments, sulfur springs, and hot springs and utilize reduced sulfur compounds instead of oxygen.
Cloroflessi 0 domande Phylum of green nonsulfur bacteria including the family Chloroflexaceae, among others.
Cyanobacteria 0 domande A phylum of oxygenic photosynthetic bacteria comprised of unicellular to multicellular bacteria possessing CHLOROPHYLL a and carrying out oxygenic PHOTOSYNTHESIS. Cyanobacteria are the only known organisms capable of fixing both CARBON DIOXIDE (in the presence of light) and NITROGEN. Cell morphology can include nitrogen-fixing heterocysts and/or resting cells called akinetes. Formerly called blue-green algae, cyanobacteria were traditionally treated as ALGAE.
Batteri Che Producono Endospore 2 domande A group of rods or cocci whose taxonomic affinities are uncertain. They form endospores, thick-walled bodies formed within the vegetative cells of certain bacteria, able to withstand adverse environmental conditions for prolonged periods.
Fibrobacteres 0 domande A phylum of gram-negative bacteria closely related to the BACTEROIDETES. Species have been found in the gastrointestinal tracts of animals, especially termites, though indications are that species are more broadly distributed in other environments.
Fusobatteri 0 domande A phylum of anaerobic, gram-negative bacteria with a chemoorganotrophic heterotrophic metabolism. They are resident flora of the OROPHARYNX.
Batteri Gram-Negativi 12 domande Bacteria which lose crystal violet stain but are stained pink when treated by Gram's method.
Anaplasmataceae 0 domande A family of bacteria which inhabit RED BLOOD CELLS and cause several animal diseases.
Arcobacter 0 domande A genus of gram-negative, aerotolerant, spiral-shaped bacteria isolated from water and associated with diarrhea in humans and animals.
Bartonellaceae 0 domande A family of small gram-negative bacteria whose organisms are parasites of erythrocytes in man and other vertebrates and the etiologic agents of several diseases.
Brachyspira 0 domande A genus of spiral bacteria of the family Brachyspiraceae.
Buchnera 0 domande A genus of gram-negative bacteria which are obligately intracellular endosymbionts of APHIDS. The bacteria are found within specialized cells in the aphid body cavity.
Campylobacter 0 domande A genus of bacteria found in the reproductive organs, intestinal tract, and oral cavity of animals and man. Some species are pathogenic.
Chlamydiales 0 domande An order of obligately intracellular, gram-negative bacteria that have the chlamydia-like developmental cycle of replication. This is a two-stage cycle that includes a metabolically inactive infectious form, and a vegetative form that replicates by binary fission. Members of Chlamydiales are disseminated by aerosol or by contact. There are at least six recognized families: CHLAMYDIACEAE, Criblamydiaceae, Parachlamydiaceae, Rhabdochlamydia, Simkaniaceae, and Waddliaceae.
Cloroflesso 0 domande A genus of green nonsulfur bacteria in the family Chloroflexaceae. They are photosynthetic, thermophilic, filamentous gliding bacteria found in hot springs.
Batteri Aerobigram-Negativi 0 domande A large group of aerobic bacteria which show up as pink (negative) when treated by the gram-staining method. This is because the cell walls of gram-negative bacteria are low in peptidoglycan and thus have low affinity for violet stain and high affinity for the pink dye safranine.
Batteri Anaerobi Gram-Negativi 1 quesito A large group of anaerobic bacteria which show up as pink (negative) when treated by the Gram-staining method.
Bastoncelli Anaerobi Gram-Negativi Facoltativi 7 domande A large group of facultatively anaerobic, rod-shaped bacteria that show up as pink (negative) when treated by the gram-staining method.
Batteri Gram-Negativi Fotosintetici Ossidativi 0 domande Widely distributed unicellular or multicellular bacteria. The CYANOBACTERIA use chlorophyll a and phycobilins for oxygenic photosynthesis while genera in the Prochlorales use both chlorophyll a and b but not phycobilins.
Anabaena 0 domande A genus of CYANOBACTERIA consisting of trichomes that are untapered with conspicuous constrictions at cross-walls. A firm individual sheath is absent, but a soft covering is often present. Many species are known worldwide as major components of freshwater PLANKTON and also of many saline lakes. The species ANABAENA FLOS-AQUAE is responsible for acute poisonings of various animals.
Aphanizomenon 0 domande A form-genus of planktonic CYANOBACTERIA in the order Nostocales.
Cyanothece 0 domande A form-genus of unicellular coccoid to rod-shaped CYANOBACTERIA, in the order Chroococcales. Three different clusters of strains from diverse habitats are included.
Cylindrospermopsis 0 domande A form-genus of CYANOBACTERIA in the order Nostocales, characterized by thin trichomes, cylindrical akinetes, and terminal heterocysts.
Microcystis 0 domande A form-genus of CYANOBACTERIA in the order Chroococcales. Many species are planktonic and possess gas vacuoles.
Nodularia 0 domande A form-genus of filamentous CYANOBACTERIA in the order Nostocales. Its members can be planktonic or benthic and the trichomes are composed of disc-shaped vegetative cells.
Nostoc 0 domande A form-genus of CYANOBACTERIA in the order Nostocales. Trichomes composed of spherical or ovoid vegetative cells along with heterocysts and akinetes. The species form symbiotic associations with a wide range of eukaryotes.
Oscillatoria 0 domande A genus of filamentous CYANOBACTERIA in the order Oscillatoriales. It is commonly found in freshwater environments, especially hot springs.
Plectonema 0 domande A form-genus of CYANOBACTERIA in the order Oscillatoriales. They are non-heterocystous but may carry out NITROGEN FIXATION under microaerobic conditions. Some smaller members have undergone transfer to the form-genus Leptolyngbya.
Proclorofiti 0 domande An order of GRAM-NEGATIVE OXYGENIC PHOTOSYNTHETIC BACTERIA containing CHLOROPHYLL, a and b, but lacking PHYCOBILISOMES (light-harvesting antennae). There are three genera: PROCHLORON; PROCHLOROCOCCUS; and PROCHLOROTHRIX. This order was thought to be the missing link between CYANOBACTERIA and plant CHLOROPLASTS, hence the name.
Synechococcus 0 domande A form-genus of spherical to rod-shaped CYANOBACTERIA in the order Chroococcales. They contain THYLAKOIDS and are found in a wide range of habitats.
Synechocystis 0 domande A form-genus of unicellular CYANOBACTERIA in the order Chroococcales. None of the strains fix NITROGEN, there are no gas vacuoles, and sheath layers are never produced.
Helicobacter 1 quesito A genus of gram-negative, spiral-shaped bacteria that has been isolated from the intestinal tract of mammals, including humans. It has been associated with PEPTIC ULCER.
Batteri Lawsonia 0 domande A genus of gram-negative, obligate intracellular bacteria causing a proliferative enteritis in animals, especially pigs, deer, horses, and rabbits.
Methylosinus 0 domande A genus of gram-negative rods which form exospores and are obligate methanotrophs.
Oceanospirillaceae 0 domande A family of gram-negative bacteria in the order Oceanospirillales.
Ornithobacterium 0 domande A genus of gram-negative, chemoorganotrophic bacteria, in the family FLAVOBACTERIACEAE. It is pathogenic in BIRDS.
Piscirickettsiaceae 0 domande A family of gram-negative bacteria, in the order Thiotrichales.
Planctomycetales 0 domande A phylum of gram-negative bacteria whose members are found in a variety of water habitats as well as animal tissues.
Rhodobacter 0 domande A genus of gram-negative bacteria widely distributed in fresh water as well as marine and hypersaline habitats.
Rhodomicrobium 0 domande A genus, in the family HYPHOMICROBIACEAE, comprised of ovoid-shaped bacteria with polar growth and a characteristic vegetative growth cycle. Cells grow preferably photoheterotrophically under anaerobic conditions in the light, but will also grow under microaerobic or aerobic conditions in the dark. (From Bergey's Manual of Determinative Bacteriology, 9th ed)
Rhodovulum 0 domande A genus of facultatively or obligately anaerobic marine phototrophic bacteria, in the family RHODOBACTERACEAE.
Rickettsiaceae 0 domande A family of small, gram-negative organisms, often parasitic in humans and other animals, causing diseases that may be transmitted by invertebrate vectors.
Roseobacter 0 domande A genus of obligately aerobic marine phototrophic and chemoorganotrophic bacteria, in the family RHODOBACTERACEAE.
Spirillaceae 0 domande A family of gram-negative bacteria in the order Nitrosomonadales. It formerly included the genera CAMPYLOBACTER and SPIRILLUM, then was abandoned, and is now reinstated as a family with a single genus SPIRILLUM.
Tenericutes 3 domande A phylum of gram-negative bacteria consisting of cells bounded by a plasma membrane. Its organisms differ from other bacteria in that they are devoid of cell walls. This phylum was formerly the class Mollicutes. Mollicutes is now the sole class in the phylum Tenericutes.
Verrucomicrobia 0 domande A phylum of gram-negative bacteria containing seven class-level groups from a wide variety of environments. Most members are chemoheterotrophs.
Batteri Gram-Positivi 12 domande Bacteria which retain the crystal violet stain when treated by Gram's method.
Proteobacteria 0 domande A phylum of bacteria consisting of the purple bacteria and their relatives which form a branch of the eubacterial tree. This group of predominantly gram-negative bacteria is classified based on homology of equivalent nucleotide sequences of 16S ribosomal RNA or by hybridization of ribosomal RNA or DNA with 16S and 23S ribosomal RNA.
Spirochaetales 0 domande An order of slender, flexuous, helically coiled bacteria, with one or more complete turns in the helix.
Batteri Riduttori Di Zolfo 0 domande A group of gram-negative, anaerobic bacteria that is able to oxidize acetate completely to carbon dioxide using elemental sulfur as the electron acceptor.


text:
Ron Ruggless
Laura Chadwick, program director for the National Restaurant Association Restaurant Innovation Summit; author Darrell West; and John Miller, Cali Group president and CEO
Operations>Technology
Robots rising: The growing role of automation in restaurants
NRA Innovation Summit addresses impact on employees, operations
Ron Ruggless | Nov 16, 2018
With the price of robots going down and the cost of labor going up, the restaurant industry is looking more intensely than ever at automation, panelists at the recent Restaurant Innovation Summit said.
"People are going to be shocked at the acceleration of technology innovation across every sector. Certainly you are seeing it in the restaurant business, the finance area, education, health care, and every aspect of economic life will be affected," said Darrell West, founding director of the Center for Technology Innovation at the Brookings Institution in Washington, D.C., and author of "The Future of Work."
West spoke Nov. 8 at the annual summit, sponsored by the National Restaurant Association in Dallas this year, with NRA summit program director Laura Chadwick and John Miller, CEO of the Pasadena, Calif.-based Cali Group, whose CaliBurger concept introduced the hamburger-cooking robot "Flippy."
"I think that in the next six months, we will deploy robots to customers in ways that will shock people," Miller said.
John Miller, CEO of the Pasadena, Calif.-based Cali Group
In January, the Cali Group announced a pilot program with NEC Corp. of America to create a facial-recognition payment program at CaliBurger. It enables customers to pay with a glance at a camera instead of swiping a credit card.
Last year, Cali Group launched a loyalty program that used facial recognition tools at its kiosks as well.
The pilot face-based payment system requires a two-step authentication process, including having the customer smile at the camera and then enter the three-digit verification number from their credit card. The company plans to eliminate the number and authenticate the transaction with just the patron's smile.
Miller told Innovation Summit attendees that quick-service restaurants eventually will use data to "see" customers the way online companies like Amazon do, suggesting other sales and handling the purchasing transactions.
"In QSR, kiosks, we believe, will become standard," Miller said. "We have a big project leveraging cameras integrated into the kiosk to use facial recognition and machine vision to really see a customer and have a one-on-one experience with that customer."
Managing data in the offline world will become a bigger part of the restaurant and retail space, he added.
"Data science in the retail and restaurant world will be real important," Miller said.
But robots also make workers uneasy. Chadwick cited surveys that indicate 72 percent of Americans are worried about automation and its impact on the workforce.
However, Miller said CaliBurger, which introduced the Flippy robot in 2017, has found employees welcome the technology.
"On the worker side, our experience has been really positive," Miller said. The robot has taken over less attractive jobs like those at hot grills or fryers.
To enhance the other kitchen positions, CaliBurger will call a worker a "chef tech" rather than a "grill cook," he said, noting that the additional skills learned could be a gateway to other jobs.
"There is a psychological value to thinking about your job as higher tech," Miller noted, and CaliBurger views it more as redeploying labor to higher-level positions and creating skills that could give workers other opportunities.
"The public basically has a love-hate relationship with anything technology," West said. "On the one hand, we love new technology because we know it makes our life easier, more convenient. From a business standpoint, it's a way to save money [and] become more efficient in your operations. In the food production, food safety is a big thing."
Darrell West, founding director of the Center for Technology Innovation at the Brookings Institution in Washington, D.C., and author of "The Future of Work"
But while automation has virtues, West said, it does have a darker side.
"When you step back and think about the impact on the workforce, there are going to be workforce consequences," West said. "They are not necessarily consequences that we can't deal with, but it is going to involve policy issues that we have to think about as a society."
Entry-level jobs will be the most at risk, he said, adding that "there certainly will be jobs lost, but there will be new types of jobs created."
Companies will have to consider investing in worker retraining so employees are eventually prepared to take on more sophisticated jobs.
"In the short run," West said, "we are more likely to see augmentation of humans, in the sense that robots will not replace humans but they are going to help us do a better job on the routine tasks, the mundane tasks and even the more dangerous tasks. The key is going to be the worker retraining piece."
Contact Ron Ruggless at [email protected]
Follow him on Twitter: @RonRuggless
TAGS: Operations Workforce Quick Service Fast Casual

redpajama_set_name: RedPajamaCommonCrawl


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

#include "components/ntp_snippets/ntp_snippets_service.h"

#include <memory>
#include <vector>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_reader.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/test/histogram_tester.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/image_fetcher/image_decoder.h"
#include "components/image_fetcher/image_fetcher.h"
#include "components/ntp_snippets/category_factory.h"
#include "components/ntp_snippets/ntp_snippet.h"
#include "components/ntp_snippets/ntp_snippets_database.h"
#include "components/ntp_snippets/ntp_snippets_fetcher.h"
#include "components/ntp_snippets/ntp_snippets_scheduler.h"
#include "components/ntp_snippets/ntp_snippets_test_utils.h"
#include "components/ntp_snippets/switches.h"
#include "components/prefs/testing_pref_service.h"
#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
#include "components/signin/core/browser/fake_signin_manager.h"
#include "google_apis/google_api_keys.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::ElementsAre;
using testing::Eq;
using testing::Invoke;
using testing::IsEmpty;
using testing::Mock;
using testing::Return;
using testing::SizeIs;
using testing::StartsWith;
using testing::_;

namespace ntp_snippets {

namespace {

MATCHER_P(IdEq, value, "") {
  return arg->id() == value;
}

const base::Time::Exploded kDefaultCreationTime = {2015, 11, 4, 25, 13, 46, 45};
const char kTestContentSnippetsServerFormat[] =
    "https://chromereader-pa.googleapis.com/v1/fetch?key=%s";

const char kSnippetUrl[] = "http://localhost/foobar";
const char kSnippetTitle[] = "Title";
const char kSnippetText[] = "Snippet";
const char kSnippetSalientImage[] = "http://localhost/salient_image";
const char kSnippetPublisherName[] = "Foo News";
const char kSnippetAmpUrl[] = "http://localhost/amp";
const float kSnippetScore = 5.0;

base::Time GetDefaultCreationTime() {
  base::Time out_time;
  EXPECT_TRUE(base::Time::FromUTCExploded(kDefaultCreationTime, &out_time));
  return out_time;
}

base::Time GetDefaultExpirationTime() {
  return base::Time::Now() + base::TimeDelta::FromHours(1);
}

std::string GetTestJson(const std::vector<std::string>& snippets) {
  return base::StringPrintf("{\"recos\":[%s]}",
                            base::JoinString(snippets, ", ").c_str());
}

std::string GetSnippetWithUrlAndTimesAndSources(
    const std::string& url,
    const std::string& content_creation_time_str,
    const std::string& expiry_time_str,
    const std::vector<std::string>& source_urls,
    const std::vector<std::string>& publishers,
    const std::vector<std::string>& amp_urls) {
  char json_str_format[] =
      "{ \"contentInfo\": {"
      "\"url\" : \"%s\","
      "\"title\" : \"%s\","
      "\"snippet\" : \"%s\","
      "\"thumbnailUrl\" : \"%s\","
      "\"creationTimestampSec\" : \"%s\","
      "\"expiryTimestampSec\" : \"%s\","
      "\"sourceCorpusInfo\" : [%s]"
      "}, "
      "\"score\" : %f}";

  char source_corpus_info_format[] =
      "{\"corpusId\": \"%s\","
      "\"publisherData\": {"
      "\"sourceName\": \"%s\""
      "},"
      "\"ampUrl\": \"%s\"}";

  std::string source_corpus_info_list_str;
  for (size_t i = 0; i < source_urls.size(); ++i) {
    std::string source_corpus_info_str =
        base::StringPrintf(source_corpus_info_format,
                           source_urls[i].empty() ? "" : source_urls[i].c_str(),
                           publishers[i].empty() ? "" : publishers[i].c_str(),
                           amp_urls[i].empty() ? "" : amp_urls[i].c_str());
    source_corpus_info_list_str.append(source_corpus_info_str);
    source_corpus_info_list_str.append(",");
  }
  // Remove the last comma
  source_corpus_info_list_str.erase(source_corpus_info_list_str.size()-1, 1);
  return base::StringPrintf(json_str_format, url.c_str(), kSnippetTitle,
                            kSnippetText, kSnippetSalientImage,
                            content_creation_time_str.c_str(),
                            expiry_time_str.c_str(),
                            source_corpus_info_list_str.c_str(), kSnippetScore);
}

std::string GetSnippetWithSources(const std::vector<std::string>& source_urls,
                                  const std::vector<std::string>& publishers,
                                  const std::vector<std::string>& amp_urls) {
  return GetSnippetWithUrlAndTimesAndSources(
      kSnippetUrl, NTPSnippet::TimeToJsonString(GetDefaultCreationTime()),
      NTPSnippet::TimeToJsonString(GetDefaultExpirationTime()), source_urls,
      publishers, amp_urls);
}

std::string GetSnippetWithUrlAndTimes(
    const std::string& url,
    const std::string& content_creation_time_str,
    const std::string& expiry_time_str) {
  return GetSnippetWithUrlAndTimesAndSources(
      url, content_creation_time_str, expiry_time_str,
      {std::string(url)}, {std::string(kSnippetPublisherName)},
      {std::string(kSnippetAmpUrl)});
}

std::string GetSnippetWithTimes(const std::string& content_creation_time_str,
                                const std::string& expiry_time_str) {
  return GetSnippetWithUrlAndTimes(kSnippetUrl, content_creation_time_str,
                                   expiry_time_str);
}

std::string GetSnippetWithUrl(const std::string& url) {
  return GetSnippetWithUrlAndTimes(
      url, NTPSnippet::TimeToJsonString(GetDefaultCreationTime()),
      NTPSnippet::TimeToJsonString(GetDefaultExpirationTime()));
}

std::string GetSnippet() {
  return GetSnippetWithUrlAndTimes(
      kSnippetUrl, NTPSnippet::TimeToJsonString(GetDefaultCreationTime()),
      NTPSnippet::TimeToJsonString(GetDefaultExpirationTime()));
}

std::string GetExpiredSnippet() {
  return GetSnippetWithTimes(
      NTPSnippet::TimeToJsonString(GetDefaultCreationTime()),
      NTPSnippet::TimeToJsonString(base::Time::Now()));
}

std::string GetInvalidSnippet() {
  std::string json_str = GetSnippet();
  // Make the json invalid by removing the final closing brace.
  return json_str.substr(0, json_str.size() - 1);
}

std::string GetIncompleteSnippet() {
  std::string json_str = GetSnippet();
  // Rename the "url" entry. The result is syntactically valid json that will
  // fail to parse as snippets.
  size_t pos = json_str.find("\"url\"");
  if (pos == std::string::npos) {
    NOTREACHED();
    return std::string();
  }
  json_str[pos + 1] = 'x';
  return json_str;
}

void ParseJson(
    const std::string& json,
    const ntp_snippets::NTPSnippetsFetcher::SuccessCallback& success_callback,
    const ntp_snippets::NTPSnippetsFetcher::ErrorCallback& error_callback) {
  base::JSONReader json_reader;
  std::unique_ptr<base::Value> value = json_reader.ReadToValue(json);
  if (value) {
    success_callback.Run(std::move(value));
  } else {
    error_callback.Run(json_reader.GetErrorMessage());
  }
}

// Factory for FakeURLFetcher objects that always generate errors.
class FailingFakeURLFetcherFactory : public net::URLFetcherFactory {
 public:
  std::unique_ptr<net::URLFetcher> CreateURLFetcher(
      int id, const GURL& url, net::URLFetcher::RequestType request_type,
      net::URLFetcherDelegate* d) override {
    return base::MakeUnique<net::FakeURLFetcher>(
        url, d, /*response_data=*/std::string(), net::HTTP_NOT_FOUND,
        net::URLRequestStatus::FAILED);
  }
};

class MockScheduler : public NTPSnippetsScheduler {
 public:
  MOCK_METHOD4(Schedule,
               bool(base::TimeDelta period_wifi_charging,
                    base::TimeDelta period_wifi,
                    base::TimeDelta period_fallback,
                    base::Time reschedule_time));
  MOCK_METHOD0(Unschedule, bool());
};

class MockProviderObserver : public ContentSuggestionsProvider::Observer {
 public:
  void OnNewSuggestions(ContentSuggestionsProvider* provider,
                        Category category,
                        std::vector<ContentSuggestion> suggestions) override {}
  MOCK_METHOD3(OnCategoryStatusChanged,
               void(ContentSuggestionsProvider* provider,
                    Category category,
                    CategoryStatus new_status));
};

class WaitForDBLoad {
 public:
  WaitForDBLoad(MockProviderObserver* observer, NTPSnippetsService* service)
      : observer_(observer) {
    EXPECT_CALL(*observer_, OnCategoryStatusChanged(_, _, _))
        .WillOnce(Invoke(this, &WaitForDBLoad::OnCategoryStatusChanged));
    if (!service->ready())
      run_loop_.Run();
  }

  ~WaitForDBLoad() { Mock::VerifyAndClearExpectations(observer_); }

 private:
  void OnCategoryStatusChanged(ContentSuggestionsProvider* provider,
                               Category category,
                               CategoryStatus new_status) {
    EXPECT_EQ(new_status, CategoryStatus::AVAILABLE_LOADING);
    run_loop_.Quit();
  }

  MockProviderObserver* observer_;
  base::RunLoop run_loop_;

  DISALLOW_COPY_AND_ASSIGN(WaitForDBLoad);
};

}  // namespace

class NTPSnippetsServiceTest : public test::NTPSnippetsTestBase {
 public:
  NTPSnippetsServiceTest()
      : fake_url_fetcher_factory_(
            /*default_factory=*/&failing_url_fetcher_factory_),
        test_url_(base::StringPrintf(kTestContentSnippetsServerFormat,
                                     google_apis::GetAPIKey().c_str())) {
    NTPSnippetsService::RegisterProfilePrefs(pref_service()->registry());
    RequestThrottler::RegisterProfilePrefs(pref_service()->registry());

    // Since no SuggestionsService is injected in tests, we need to force the
    // service to fetch from all hosts.
    base::CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kDontRestrict);
    EXPECT_TRUE(database_dir_.CreateUniqueTempDir());
  }

  ~NTPSnippetsServiceTest() override {
    // We need to run the message loop after deleting the database, because
    // ProtoDatabaseImpl deletes the actual LevelDB asynchronously on the task
    // runner. Without this, we'd get reports of memory leaks.
    Mock::VerifyAndClear(&mock_scheduler());
    service_.reset();
    base::RunLoop().RunUntilIdle();
  }

  void SetUp() override {
    test::NTPSnippetsTestBase::SetUp();
    EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1);
    CreateSnippetsService();
  }

  void RecreateSnippetsService() {
    Mock::VerifyAndClear(&mock_scheduler());
    service_.reset();
    base::RunLoop().RunUntilIdle();
    EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1);
    CreateSnippetsService();
  }

  void CreateSnippetsService() {
    DCHECK(!service_);

    scoped_refptr<base::SingleThreadTaskRunner> task_runner(
        base::ThreadTaskRunnerHandle::Get());
    scoped_refptr<net::TestURLRequestContextGetter> request_context_getter =
        new net::TestURLRequestContextGetter(task_runner.get());

    ResetSigninManager();
    std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher =
        base::MakeUnique<NTPSnippetsFetcher>(
            fake_signin_manager(), fake_token_service_.get(),
            std::move(request_context_getter), pref_service(),
            base::Bind(&ParseJson),
            /*is_stable_channel=*/true);

    fake_signin_manager()->SignIn("foo@bar.com");
    snippets_fetcher->SetPersonalizationForTesting(
        NTPSnippetsFetcher::Personalization::kNonPersonal);

    // Add an initial fetch response, as the service tries to fetch when there
    // is nothing in the DB.
    SetUpFetchResponse(GetTestJson({GetSnippet()}));

    service_.reset(new NTPSnippetsService(
        &observer_, &category_factory_, pref_service(), nullptr, "fr",
        &scheduler_, std::move(snippets_fetcher), /*image_fetcher=*/nullptr,
        /*image_fetcher=*/nullptr, base::MakeUnique<NTPSnippetsDatabase>(
                                       database_dir_.path(), task_runner),
        base::MakeUnique<NTPSnippetsStatusService>(fake_signin_manager(),
                                                   pref_service())));

    WaitForDBLoad(&observer_, service_.get());
  }

  std::string MakeUniqueID(const std::string& within_category_id) {
    return service()->MakeUniqueID(articles_category(), within_category_id);
  }

  Category articles_category() {
    return category_factory_.FromKnownCategory(KnownCategories::ARTICLES);
  }

 protected:
  const GURL& test_url() { return test_url_; }
  NTPSnippetsService* service() { return service_.get(); }
  MockProviderObserver& observer() { return observer_; }
  MockScheduler& mock_scheduler() { return scheduler_; }

  // Provide the json to be returned by the fake fetcher.
  void SetUpFetchResponse(const std::string& json) {
    fake_url_fetcher_factory_.SetFakeResponse(test_url_, json, net::HTTP_OK,
                                              net::URLRequestStatus::SUCCESS);
  }

  void LoadFromJSONString(const std::string& json) {
    SetUpFetchResponse(json);
    service()->FetchSnippets(true);
    base::RunLoop().RunUntilIdle();
  }

 private:
  base::MessageLoop message_loop_;
  FailingFakeURLFetcherFactory failing_url_fetcher_factory_;
  // Instantiation of factory automatically sets itself as URLFetcher's factory.
  net::FakeURLFetcherFactory fake_url_fetcher_factory_;
  const GURL test_url_;
  std::unique_ptr<OAuth2TokenService> fake_token_service_;
  MockScheduler scheduler_;
  MockProviderObserver observer_;
  CategoryFactory category_factory_;
  // Last so that the dependencies are deleted after the service.
  std::unique_ptr<NTPSnippetsService> service_;

  base::ScopedTempDir database_dir_;

  DISALLOW_COPY_AND_ASSIGN(NTPSnippetsServiceTest);
};

TEST_F(NTPSnippetsServiceTest, ScheduleOnStart) {
  // SetUp() checks that Schedule is called.

  // When we have no snippets are all, loading the service initiates a fetch.
  base::RunLoop().RunUntilIdle();
  ASSERT_EQ("OK", service()->snippets_fetcher()->last_status());
}

TEST_F(NTPSnippetsServiceTest, Full) {
  std::string json_str(GetTestJson({GetSnippet()}));

  LoadFromJSONString(json_str);
  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
  const NTPSnippet& snippet = *service()->GetSnippetsForTesting().front();

  EXPECT_EQ(snippet.id(), kSnippetUrl);
  EXPECT_EQ(snippet.title(), kSnippetTitle);
  EXPECT_EQ(snippet.snippet(), kSnippetText);
  EXPECT_EQ(snippet.salient_image_url(), GURL(kSnippetSalientImage));
  EXPECT_EQ(GetDefaultCreationTime(), snippet.publish_date());
  EXPECT_EQ(snippet.best_source().publisher_name, kSnippetPublisherName);
  EXPECT_EQ(snippet.best_source().amp_url, GURL(kSnippetAmpUrl));
}

TEST_F(NTPSnippetsServiceTest, Clear) {
  std::string json_str(GetTestJson({GetSnippet()}));

  LoadFromJSONString(json_str);
  EXPECT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));

  service()->ClearCachedSuggestionsForDebugging(articles_category());
  EXPECT_THAT(service()->GetSnippetsForTesting(), IsEmpty());
}

TEST_F(NTPSnippetsServiceTest, InsertAtFront) {
  std::string first("http://first");
  LoadFromJSONString(GetTestJson({GetSnippetWithUrl(first)}));
  EXPECT_THAT(service()->GetSnippetsForTesting(), ElementsAre(IdEq(first)));

  std::string second("http://second");
  LoadFromJSONString(GetTestJson({GetSnippetWithUrl(second)}));
  // The snippet loaded last should be at the first position in the list now.
  EXPECT_THAT(service()->GetSnippetsForTesting(),
              ElementsAre(IdEq(second), IdEq(first)));
}

TEST_F(NTPSnippetsServiceTest, LimitNumSnippets) {
  int max_snippet_count = NTPSnippetsService::GetMaxSnippetCountForTesting();
  int snippets_per_load = max_snippet_count / 2 + 1;
  char url_format[] = "http://localhost/%i";

  std::vector<std::string> snippets1;
  std::vector<std::string> snippets2;
  for (int i = 0; i < snippets_per_load; i++) {
    snippets1.push_back(GetSnippetWithUrl(base::StringPrintf(url_format, i)));
    snippets2.push_back(GetSnippetWithUrl(
        base::StringPrintf(url_format, snippets_per_load + i)));
  }

  LoadFromJSONString(GetTestJson(snippets1));
  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(snippets1.size()));

  LoadFromJSONString(GetTestJson(snippets2));
  EXPECT_THAT(service()->GetSnippetsForTesting(), SizeIs(max_snippet_count));
}

TEST_F(NTPSnippetsServiceTest, LoadInvalidJson) {
  LoadFromJSONString(GetTestJson({GetInvalidSnippet()}));
  EXPECT_THAT(service()->snippets_fetcher()->last_status(),
              StartsWith("Received invalid JSON"));
  EXPECT_THAT(service()->GetSnippetsForTesting(), IsEmpty());
}

TEST_F(NTPSnippetsServiceTest, LoadInvalidJsonWithExistingSnippets) {
  LoadFromJSONString(GetTestJson({GetSnippet()}));
  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
  ASSERT_EQ("OK", service()->snippets_fetcher()->last_status());

  LoadFromJSONString(GetTestJson({GetInvalidSnippet()}));
  EXPECT_THAT(service()->snippets_fetcher()->last_status(),
              StartsWith("Received invalid JSON"));
  // This should not have changed the existing snippets.
  EXPECT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
}

TEST_F(NTPSnippetsServiceTest, LoadIncompleteJson) {
  LoadFromJSONString(GetTestJson({GetIncompleteSnippet()}));
  EXPECT_EQ("Invalid / empty list.",
            service()->snippets_fetcher()->last_status());
  EXPECT_THAT(service()->GetSnippetsForTesting(), IsEmpty());
}

TEST_F(NTPSnippetsServiceTest, LoadIncompleteJsonWithExistingSnippets) {
  LoadFromJSONString(GetTestJson({GetSnippet()}));
  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));

  LoadFromJSONString(GetTestJson({GetIncompleteSnippet()}));
  EXPECT_EQ("Invalid / empty list.",
            service()->snippets_fetcher()->last_status());
  // This should not have changed the existing snippets.
  EXPECT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
}

TEST_F(NTPSnippetsServiceTest, Dismiss) {
  std::vector<std::string> source_urls, publishers, amp_urls;
  source_urls.push_back(std::string("http://site.com"));
  publishers.push_back(std::string("Source 1"));
  amp_urls.push_back(std::string());
  std::string json_str(
      GetTestJson({GetSnippetWithSources(source_urls, publishers, amp_urls)}));

  LoadFromJSONString(json_str);

  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));

  // Dismissing a non-existent snippet shouldn't do anything.
  service()->DismissSuggestion(MakeUniqueID("http://othersite.com"));
  EXPECT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));

  // Dismiss the snippet.
  service()->DismissSuggestion(MakeUniqueID(kSnippetUrl));
  EXPECT_THAT(service()->GetSnippetsForTesting(), IsEmpty());

  // Make sure that fetching the same snippet again does not re-add it.
  LoadFromJSONString(json_str);
  EXPECT_THAT(service()->GetSnippetsForTesting(), IsEmpty());

  // The snippet should stay dismissed even after re-creating the service.
  RecreateSnippetsService();
  LoadFromJSONString(json_str);
  EXPECT_THAT(service()->GetSnippetsForTesting(), IsEmpty());

  // The snippet can be added again after clearing dismissed snippets.
  service()->ClearDismissedSuggestionsForDebugging(articles_category());
  EXPECT_THAT(service()->GetSnippetsForTesting(), IsEmpty());
  LoadFromJSONString(json_str);
  EXPECT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
}

TEST_F(NTPSnippetsServiceTest, GetDismissed) {
  LoadFromJSONString(GetTestJson({GetSnippet()}));

  service()->DismissSuggestion(MakeUniqueID(kSnippetUrl));
  std::vector<ContentSuggestion> suggestions =
      service()->GetDismissedSuggestionsForDebugging(articles_category());
  EXPECT_EQ(1u, suggestions.size());
  for (auto& suggestion : suggestions) {
    EXPECT_EQ(MakeUniqueID(kSnippetUrl), suggestion.id());
  }

  // There should be no dismissed snippet after clearing the list.
  service()->ClearDismissedSuggestionsForDebugging(articles_category());
  EXPECT_EQ(0u, service()
                    ->GetDismissedSuggestionsForDebugging(articles_category())
                    .size());
}

TEST_F(NTPSnippetsServiceTest, CreationTimestampParseFail) {
  std::string json_str(GetTestJson({GetSnippetWithTimes(
      "aaa1448459205",
      NTPSnippet::TimeToJsonString(GetDefaultExpirationTime()))}));

  LoadFromJSONString(json_str);
  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
  const NTPSnippet& snippet = *service()->GetSnippetsForTesting().front();
  EXPECT_EQ(snippet.id(), kSnippetUrl);
  EXPECT_EQ(snippet.title(), kSnippetTitle);
  EXPECT_EQ(snippet.snippet(), kSnippetText);
  EXPECT_EQ(base::Time::UnixEpoch(), snippet.publish_date());
}

TEST_F(NTPSnippetsServiceTest, RemoveExpiredContent) {
  std::string json_str(GetTestJson({GetExpiredSnippet()}));

  LoadFromJSONString(json_str);
  EXPECT_THAT(service()->GetSnippetsForTesting(), IsEmpty());
}

TEST_F(NTPSnippetsServiceTest, TestSingleSource) {
  std::vector<std::string> source_urls, publishers, amp_urls;
  source_urls.push_back(std::string("http://source1.com"));
  publishers.push_back(std::string("Source 1"));
  amp_urls.push_back(std::string("http://source1.amp.com"));
  std::string json_str(
      GetTestJson({GetSnippetWithSources(source_urls, publishers, amp_urls)}));

  LoadFromJSONString(json_str);
  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
  const NTPSnippet& snippet = *service()->GetSnippetsForTesting().front();
  EXPECT_EQ(snippet.sources().size(), 1u);
  EXPECT_EQ(snippet.id(), kSnippetUrl);
  EXPECT_EQ(snippet.best_source().url, GURL("http://source1.com"));
  EXPECT_EQ(snippet.best_source().publisher_name, std::string("Source 1"));
  EXPECT_EQ(snippet.best_source().amp_url, GURL("http://source1.amp.com"));
}

TEST_F(NTPSnippetsServiceTest, TestSingleSourceWithMalformedUrl) {
  std::vector<std::string> source_urls, publishers, amp_urls;
  source_urls.push_back(std::string("aaaa"));
  publishers.push_back(std::string("Source 1"));
  amp_urls.push_back(std::string("http://source1.amp.com"));
  std::string json_str(
      GetTestJson({GetSnippetWithSources(source_urls, publishers, amp_urls)}));

  LoadFromJSONString(json_str);
  EXPECT_THAT(service()->GetSnippetsForTesting(), IsEmpty());
}

TEST_F(NTPSnippetsServiceTest, TestSingleSourceWithMissingData) {
  std::vector<std::string> source_urls, publishers, amp_urls;
  source_urls.push_back(std::string("http://source1.com"));
  publishers.push_back(std::string());
  amp_urls.push_back(std::string());
  std::string json_str(
      GetTestJson({GetSnippetWithSources(source_urls, publishers, amp_urls)}));

  LoadFromJSONString(json_str);
  EXPECT_THAT(service()->GetSnippetsForTesting(), IsEmpty());
}

TEST_F(NTPSnippetsServiceTest, TestMultipleSources) {
  std::vector<std::string> source_urls, publishers, amp_urls;
  source_urls.push_back(std::string("http://source1.com"));
  source_urls.push_back(std::string("http://source2.com"));
  publishers.push_back(std::string("Source 1"));
  publishers.push_back(std::string("Source 2"));
  amp_urls.push_back(std::string("http://source1.amp.com"));
  amp_urls.push_back(std::string("http://source2.amp.com"));
  std::string json_str(
      GetTestJson({GetSnippetWithSources(source_urls, publishers, amp_urls)}));

  LoadFromJSONString(json_str);
  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
  const NTPSnippet& snippet = *service()->GetSnippetsForTesting().front();
  // Expect the first source to be chosen
  EXPECT_EQ(snippet.sources().size(), 2u);
  EXPECT_EQ(snippet.id(), kSnippetUrl);
  EXPECT_EQ(snippet.best_source().url, GURL("http://source1.com"));
  EXPECT_EQ(snippet.best_source().publisher_name, std::string("Source 1"));
  EXPECT_EQ(snippet.best_source().amp_url, GURL("http://source1.amp.com"));
}

TEST_F(NTPSnippetsServiceTest, TestMultipleIncompleteSources) {
  // Set Source 2 to have no AMP url, and Source 1 to have no publisher name
  // Source 2 should win since we favor publisher name over amp url
  std::vector<std::string> source_urls, publishers, amp_urls;
  source_urls.push_back(std::string("http://source1.com"));
  source_urls.push_back(std::string("http://source2.com"));
  publishers.push_back(std::string());
  publishers.push_back(std::string("Source 2"));
  amp_urls.push_back(std::string("http://source1.amp.com"));
  amp_urls.push_back(std::string());
  std::string json_str(
      GetTestJson({GetSnippetWithSources(source_urls, publishers, amp_urls)}));

  LoadFromJSONString(json_str);
  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
  {
    const NTPSnippet& snippet = *service()->GetSnippetsForTesting().front();
    EXPECT_EQ(snippet.sources().size(), 2u);
    EXPECT_EQ(snippet.id(), kSnippetUrl);
    EXPECT_EQ(snippet.best_source().url, GURL("http://source2.com"));
    EXPECT_EQ(snippet.best_source().publisher_name, std::string("Source 2"));
    EXPECT_EQ(snippet.best_source().amp_url, GURL());
  }

  service()->ClearCachedSuggestionsForDebugging(articles_category());
  // Set Source 1 to have no AMP url, and Source 2 to have no publisher name
  // Source 1 should win in this case since we prefer publisher name to AMP url
  source_urls.clear();
  source_urls.push_back(std::string("http://source1.com"));
  source_urls.push_back(std::string("http://source2.com"));
  publishers.clear();
  publishers.push_back(std::string("Source 1"));
  publishers.push_back(std::string());
  amp_urls.clear();
  amp_urls.push_back(std::string());
  amp_urls.push_back(std::string("http://source2.amp.com"));
  json_str =
      GetTestJson({GetSnippetWithSources(source_urls, publishers, amp_urls)});

  LoadFromJSONString(json_str);
  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
  {
    const NTPSnippet& snippet = *service()->GetSnippetsForTesting().front();
    EXPECT_EQ(snippet.sources().size(), 2u);
    EXPECT_EQ(snippet.id(), kSnippetUrl);
    EXPECT_EQ(snippet.best_source().url, GURL("http://source1.com"));
    EXPECT_EQ(snippet.best_source().publisher_name, std::string("Source 1"));
    EXPECT_EQ(snippet.best_source().amp_url, GURL());
  }

  service()->ClearCachedSuggestionsForDebugging(articles_category());
  // Set source 1 to have no AMP url and no source, and source 2 to only have
  // amp url. There should be no snippets since we only add sources we consider
  // complete
  source_urls.clear();
  source_urls.push_back(std::string("http://source1.com"));
  source_urls.push_back(std::string("http://source2.com"));
  publishers.clear();
  publishers.push_back(std::string());
  publishers.push_back(std::string());
  amp_urls.clear();
  amp_urls.push_back(std::string());
  amp_urls.push_back(std::string("http://source2.amp.com"));
  json_str =
      GetTestJson({GetSnippetWithSources(source_urls, publishers, amp_urls)});

  LoadFromJSONString(json_str);
  EXPECT_THAT(service()->GetSnippetsForTesting(), IsEmpty());
}

TEST_F(NTPSnippetsServiceTest, TestMultipleCompleteSources) {
  // Test 2 complete sources, we should choose the first complete source
  std::vector<std::string> source_urls, publishers, amp_urls;
  source_urls.push_back(std::string("http://source1.com"));
  source_urls.push_back(std::string("http://source2.com"));
  source_urls.push_back(std::string("http://source3.com"));
  publishers.push_back(std::string("Source 1"));
  publishers.push_back(std::string());
  publishers.push_back(std::string("Source 3"));
  amp_urls.push_back(std::string("http://source1.amp.com"));
  amp_urls.push_back(std::string("http://source2.amp.com"));
  amp_urls.push_back(std::string("http://source3.amp.com"));
  std::string json_str(
      GetTestJson({GetSnippetWithSources(source_urls, publishers, amp_urls)}));

  LoadFromJSONString(json_str);
  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
  {
    const NTPSnippet& snippet = *service()->GetSnippetsForTesting().front();
    EXPECT_EQ(snippet.sources().size(), 3u);
    EXPECT_EQ(snippet.id(), kSnippetUrl);
    EXPECT_EQ(snippet.best_source().url, GURL("http://source1.com"));
    EXPECT_EQ(snippet.best_source().publisher_name, std::string("Source 1"));
    EXPECT_EQ(snippet.best_source().amp_url, GURL("http://source1.amp.com"));
  }

  // Test 2 complete sources, we should choose the first complete source
  service()->ClearCachedSuggestionsForDebugging(articles_category());
  source_urls.clear();
  source_urls.push_back(std::string("http://source1.com"));
  source_urls.push_back(std::string("http://source2.com"));
  source_urls.push_back(std::string("http://source3.com"));
  publishers.clear();
  publishers.push_back(std::string());
  publishers.push_back(std::string("Source 2"));
  publishers.push_back(std::string("Source 3"));
  amp_urls.clear();
  amp_urls.push_back(std::string("http://source1.amp.com"));
  amp_urls.push_back(std::string("http://source2.amp.com"));
  amp_urls.push_back(std::string("http://source3.amp.com"));
  json_str =
      GetTestJson({GetSnippetWithSources(source_urls, publishers, amp_urls)});

  LoadFromJSONString(json_str);
  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
  {
    const NTPSnippet& snippet = *service()->GetSnippetsForTesting().front();
    EXPECT_EQ(snippet.sources().size(), 3u);
    EXPECT_EQ(snippet.id(), kSnippetUrl);
    EXPECT_EQ(snippet.best_source().url, GURL("http://source2.com"));
    EXPECT_EQ(snippet.best_source().publisher_name, std::string("Source 2"));
    EXPECT_EQ(snippet.best_source().amp_url, GURL("http://source2.amp.com"));
  }

  // Test 3 complete sources, we should choose the first complete source
  service()->ClearCachedSuggestionsForDebugging(articles_category());
  source_urls.clear();
  source_urls.push_back(std::string("http://source1.com"));
  source_urls.push_back(std::string("http://source2.com"));
  source_urls.push_back(std::string("http://source3.com"));
  publishers.clear();
  publishers.push_back(std::string("Source 1"));
  publishers.push_back(std::string("Source 2"));
  publishers.push_back(std::string("Source 3"));
  amp_urls.clear();
  amp_urls.push_back(std::string());
  amp_urls.push_back(std::string("http://source2.amp.com"));
  amp_urls.push_back(std::string("http://source3.amp.com"));
  json_str =
      GetTestJson({GetSnippetWithSources(source_urls, publishers, amp_urls)});

  LoadFromJSONString(json_str);
  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
  {
    const NTPSnippet& snippet = *service()->GetSnippetsForTesting().front();
    EXPECT_EQ(snippet.sources().size(), 3u);
    EXPECT_EQ(snippet.id(), kSnippetUrl);
    EXPECT_EQ(snippet.best_source().url, GURL("http://source2.com"));
    EXPECT_EQ(snippet.best_source().publisher_name, std::string("Source 2"));
    EXPECT_EQ(snippet.best_source().amp_url, GURL("http://source2.amp.com"));
  }
}

TEST_F(NTPSnippetsServiceTest, LogNumArticlesHistogram) {
  base::HistogramTester tester;
  LoadFromJSONString(GetTestJson({GetInvalidSnippet()}));

  EXPECT_THAT(tester.GetAllSamples("NewTabPage.Snippets.NumArticles"),
              ElementsAre(base::Bucket(/*min=*/0, /*count=*/1)));
  // Invalid JSON shouldn't contribute to NumArticlesFetched.
  EXPECT_THAT(tester.GetAllSamples("NewTabPage.Snippets.NumArticlesFetched"),
              IsEmpty());
  // Valid JSON with empty list.
  LoadFromJSONString(GetTestJson(std::vector<std::string>()));
  EXPECT_THAT(tester.GetAllSamples("NewTabPage.Snippets.NumArticles"),
              ElementsAre(base::Bucket(/*min=*/0, /*count=*/2)));
  EXPECT_THAT(tester.GetAllSamples("NewTabPage.Snippets.NumArticlesFetched"),
              ElementsAre(base::Bucket(/*min=*/0, /*count=*/1)));
  // Snippet list should be populated with size 1.
  LoadFromJSONString(GetTestJson({GetSnippet()}));
  EXPECT_THAT(tester.GetAllSamples("NewTabPage.Snippets.NumArticles"),
              ElementsAre(base::Bucket(/*min=*/0, /*count=*/2),
                          base::Bucket(/*min=*/1, /*count=*/1)));
  EXPECT_THAT(tester.GetAllSamples("NewTabPage.Snippets.NumArticlesFetched"),
              ElementsAre(base::Bucket(/*min=*/0, /*count=*/1),
                          base::Bucket(/*min=*/1, /*count=*/1)));
  // Duplicate snippet shouldn't increase the list size.
  LoadFromJSONString(GetTestJson({GetSnippet()}));
  EXPECT_THAT(tester.GetAllSamples("NewTabPage.Snippets.NumArticles"),
              ElementsAre(base::Bucket(/*min=*/0, /*count=*/2),
                          base::Bucket(/*min=*/1, /*count=*/2)));
  EXPECT_THAT(tester.GetAllSamples("NewTabPage.Snippets.NumArticlesFetched"),
              ElementsAre(base::Bucket(/*min=*/0, /*count=*/1),
                          base::Bucket(/*min=*/1, /*count=*/2)));
  EXPECT_THAT(
      tester.GetAllSamples("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded"),
      IsEmpty());
  // Dismissing a snippet should decrease the list size. This will only be
  // logged after the next fetch.
  service()->DismissSuggestion(MakeUniqueID(kSnippetUrl));
  LoadFromJSONString(GetTestJson({GetSnippet()}));
  EXPECT_THAT(tester.GetAllSamples("NewTabPage.Snippets.NumArticles"),
              ElementsAre(base::Bucket(/*min=*/0, /*count=*/3),
                          base::Bucket(/*min=*/1, /*count=*/2)));
  // Dismissed snippets shouldn't influence NumArticlesFetched.
  EXPECT_THAT(tester.GetAllSamples("NewTabPage.Snippets.NumArticlesFetched"),
              ElementsAre(base::Bucket(/*min=*/0, /*count=*/1),
                          base::Bucket(/*min=*/1, /*count=*/3)));
  EXPECT_THAT(
      tester.GetAllSamples("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded"),
      ElementsAre(base::Bucket(/*min=*/1, /*count=*/1)));
  // Recreating the service and loading from prefs shouldn't count as fetched
  // articles.
  RecreateSnippetsService();
  tester.ExpectTotalCount("NewTabPage.Snippets.NumArticlesFetched", 4);
}

TEST_F(NTPSnippetsServiceTest, DismissShouldRespectAllKnownUrls) {
  const std::string creation =
      NTPSnippet::TimeToJsonString(GetDefaultCreationTime());
  const std::string expiry =
      NTPSnippet::TimeToJsonString(GetDefaultExpirationTime());
  const std::vector<std::string> source_urls = {
      "http://mashable.com/2016/05/11/stolen",
      "http://www.aol.com/article/2016/05/stolen-doggie",
      "http://mashable.com/2016/05/11/stolen?utm_cid=1"};
  const std::vector<std::string> publishers = {"Mashable", "AOL", "Mashable"};
  const std::vector<std::string> amp_urls = {
      "http://mashable-amphtml.googleusercontent.com/1",
      "http://t2.gstatic.com/images?q=tbn:3",
      "http://t2.gstatic.com/images?q=tbn:3"};

  // Add the snippet from the mashable domain.
  LoadFromJSONString(GetTestJson({GetSnippetWithUrlAndTimesAndSources(
      source_urls[0], creation, expiry, source_urls, publishers, amp_urls)}));
  ASSERT_THAT(service()->GetSnippetsForTesting(), SizeIs(1));
  // Dismiss the snippet via the mashable source corpus ID.
  service()->DismissSuggestion(MakeUniqueID(source_urls[0]));
  EXPECT_THAT(service()->GetSnippetsForTesting(), IsEmpty());

  // The same article from the AOL domain should now be detected as dismissed.
  LoadFromJSONString(GetTestJson({GetSnippetWithUrlAndTimesAndSources(
      source_urls[1], creation, expiry, source_urls, publishers, amp_urls)}));
  ASSERT_THAT(service()->GetSnippetsForTesting(), IsEmpty());
}

TEST_F(NTPSnippetsServiceTest, StatusChanges) {
  // Simulate user signed out
  SetUpFetchResponse(GetTestJson({GetSnippet()}));
  EXPECT_CALL(observer(),
              OnCategoryStatusChanged(_, _, CategoryStatus::SIGNED_OUT));
  service()->OnDisabledReasonChanged(DisabledReason::SIGNED_OUT);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(NTPSnippetsService::State::DISABLED, service()->state_);
  EXPECT_THAT(service()->GetSnippetsForTesting(),
              IsEmpty());  // No fetch should be made.

  // Simulate user sign in. The service should be ready again and load snippets.
  SetUpFetchResponse(GetTestJson({GetSnippet()}));
  EXPECT_CALL(observer(),
              OnCategoryStatusChanged(_, _, CategoryStatus::AVAILABLE_LOADING));
  EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1);
  service()->OnDisabledReasonChanged(DisabledReason::NONE);
  EXPECT_CALL(observer(),
              OnCategoryStatusChanged(_, _, CategoryStatus::AVAILABLE));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(NTPSnippetsService::State::READY, service()->state_);
  EXPECT_FALSE(service()->GetSnippetsForTesting().empty());
}

}  // namespace ntp_snippets

redpajama_set_name: RedPajamaGithub


text:
Q: Load HTML From another File I want to know that is there a way in codeigniter to write some data in ahtml file from the controller and then get that html from that file in the controller.
$data["messages"] = $this->message_view->getParticularMessage($this->input->post('id'))
$data["users"] = $this->user_view->getAllUsers()
write_file('/messages/panel.tpl', $data)
$string = read_file('/messages/panel.tpl');
error_log(print_r($string , true));
echo json_encode(array('value'=> $string));

A: To Write  file in codeigniter:
$this->load->helper('file');

$data = 'Some file data';
    if ( ! write_file('/messages/panel.tpl', $data))
    {
            echo 'Unable to write the file';
    }
    else
    {
            echo 'File written!';
    }

And to load html file use this:
$this->load->view('/messages/panel.tpl');

redpajama_set_name: RedPajamaStackExchange


Renowned Author, Motivational Speaker Dr. Kevin Elko to Headline Alabama AGC, Mobile Section 2018 Annual Luncheon - Threaded Fasteners, Inc.
MOBILE, Ala. (December 19, 2017) – The Mobile and Northwest Florida section of Associated General Contractors (AGC) Alabama is delighted to announce renowned motivational speaker and author Dr. Kevin Elko will deliver the keynote address during its 2018 Annual Luncheon. Local businesses and their leadership teams are encouraged to attend this timely event.
Elko, a celebrated leadership and performance consultant, focuses a substantial portion of his time helping organizations in the areas of leadership, goal setting and myriad other motivational topics. During the two-hour lunch event beginning at 11 a.m. Wednesday, January 17, 2018 at the Country Club of Mobile, he will present "Inspiring Individuals, Corporations and Teams to Greater Success!" The cost is $50 per person, and reservations can be made by calling (251) 610-6715.
Elko earned his bachelor's degree in biology education and coaching from California University of Pennsylvania as well as two master's degrees and his doctorate from West Virginia University. He was later inducted into West Virginia University Hall of Fame. He went on to intern at the United States Olympic Committee in Colorado Springs before consulting with various successful National Football League (NFL) teams, including The Pittsburgh Steelers, The Dallas Cowboys, The Philadelphia Eagles, The Miami Dolphins and The New Orleans Saints. He has also worked with seven Bowl Championship Series (BCS) National Championship football teams, including The University of Miami, Louisiana State University (LSU), The University of Alabama and Florida State University.
Since 1920, Alabama AGC has brought together qualified construction contractors and industry-related companies dedicated to skill, integrity and responsibility. The Association improves the quality of construction and protects the public interest by providing broad influence and a full range of services satisfying the needs and concerns of its members, partners and the industry. To learn more, visit the section's official website at http://theconstructioncenter.org.


text:
The Champions League match was halted after the official was accused of racist abuse
Posted By: Marsh Tyler
The UEFA Champions League soccer match between Paris Saint-Germain and Istanbul in Basaksehir was halted on Tuesday, after the two teams accused the match official of having racially insulted a black assistant coach.
The match in Paris – a crucial match in the European Championship – was halted after just 14 minutes when Sebastian Kultesco, fourth Romanian referee, called referee Ovidio Hattigan to the touchline. It was not immediately clear the reason for the request.
When Hatigan approached the team's bench, it appeared that Koltisco was requesting that Pierre Wibo, the former Cameroonian international now working as the assistant coach of the Turkish team, be fired from the match.
Reports in Romania, and The sound of the accident, Suggested that Koltisco informed Hategan that a member of the Basaksehir training team – Weibo – should be fired, and referred to him as "that black person".
While Hategan was preparing to take a red card out of his pocket, Webó approached the referee and charged Coltescu Using the elemental title to distinguish it.
"Why did the negro say?" Webó He shouted repeatedly Towards Koltisco, where he was taken off the field. "Why did you say the nigger?"
Basaksehir players immediately protested against Hatigan. Then Demba Ba, the veteran Senegalese striker, approached Koltisco and asked him, "Why when you mention a black man, you have to say, 'This black man'?"
"You wouldn't say 'these white men', '" said Ba, pointing his finger. "You could say these men."
Koltisco's role as fourth referee includes overseeing training areas and seats and handling player substitutions. As Ba protested inches away from his face, it seemed that he – or any other member of the all-Roman referee unit – was defending the choice of words as a matter of language rather than intent.
READ Man United thinks Jadon Sancho will "be ready for the Crystal Palace match" before moving on Football sport
After several minutes of discussion, the Başakşehir players decided to leave the stadium, and their PSG counterparts followed quickly, and as soon as he left the stadium, two hats could be heard on the TV broadcast microphones insisting that the protocol for dealing with the problem – whether to restart the game – "It wasn't up to me."
UEFA, the governing body for European football and the organizer of the competition, has tentatively planned to resume the game at 10 pm local time, after a 45-minute delay, with Koltisco replacing the referee serving as an on-site video assistant.
It was reported that the PSG players are ready to continue playing – until returning to the tunnel to make their way to the stadium – but Basaksehir confirmed in Twitter His players refused to do so "because of the racism of the fourth referee, Sebastian Koltisco, against our assistant coach, Pierre Webo."
Paris Saint-Germain too Publicly confirmed The "racist remarks from the fourth referee" prompted him to stop playing.
Two hours after the players left, UEFA said in a statement that the teams had agreed to play the last 76 minutes of the match on Wednesday after agreeing on the unusual condition of replacing the match officials completely. It also said it would review the incident that halted the match.
"A comprehensive investigation into the incident will be opened immediately," UEFA said in a statement.
Paris Saint-Germain will go through it knowing their place in the tournament knockout rounds is secure, after Manchester United's defeat by RB Leipzig on Tuesday evening. Elimination stamp From the Premier League club. Basaksehir has already been excluded from the competition.
READ Lightning starred in the scenes after winning the third match in a row
Marsh Tyler
Communicator. Reader. Hipster-friendly introvert. General zombie specialist. Tv trailblazer
Australian Open 2021: The Australian scandal: Three people tested positive on flights from Los Angeles and Abu Dhabi and about 50 players isolated
What the West lost by winning the Gulf War
Anthony Mackie honors Captain America in new Netflix movie
Train Like Father Michael: Mick Schumacher's complex F1 starts
How to download applications to Sony Smart TV
Copyright © Prudent Press Agency
<# print( 'Prudent Press Agency' ) #>


text:
Home > Maths > How Many Surfaces? Making a Möbius Strip
How Many Surfaces? Making a Möbius Strip
By: Suzanne Elvidge BSc (hons), MSc - Updated: 24 Aug 2012 |
A Möbius strip is a loop of paper with a twist in it, that behaves in a very odd way.
How to Make a Möbius Strip
Take a strip of paper, curve it round into a loop and glue the ends together. Draw a line all the way around the strip without taking the pencil off the paper. How many sides has it got? Run the pencil along the edge of the strip – how many edges has it got?
The simple loop has two surfaces and two edges.
Take a second strip of paper and curve it round into a loop, but before gluing the ends together, twist one end of the paper, to make a loop with a single twist in it. This is a Möbius strip. Draw a line all the way around the strip without taking the pencil off the paper. How many sides has it got? Run the pencil along the edge of the strip – how many edges has it got? Try making one with two twists in it – does that make any difference?
Because the Möbius strip has one twist in it, this connects the top surface of one end of the piece of paper to the bottom surface of the other end of the piece of paper. This creates a loop of paper with only one surface and one edge. When a strip has an even number of twists in it, this connects the top surface of one end with the top surface of the other, and so creates a loop with two surfaces.
Cut a Möbius strip in half, down the pencil line and describe what kind of strip is created. Is this a Möbius strip? Test by drawing a line down the centre. What happens when it's cut in half again?
This creates a one larger loop with two twists. Cutting it in half again makes two interlocking loops. Cutting each of these loops again will make four interlocking loops. Try it with three or more twists.
Try cutting a Möbius strip into a third instead of a half – is the result any different?
This creates two interlocking loops, one half the size of the other.
Who was Möbius?
The loop of paper with a twist was first described by a German mathematician called Johann Benedict Listing. August Ferdinand Möbius, who the strip is named after, was the son of a dancing teacher, and was born in November 1790. He was a German mathematician and astronomer, and he was interested in a type of geometry (the maths of points, lines, angles, surfaces, and solids) called 'topology'.
Uses for a Möbius Strip
Because a Möbius strip has only one side, it has a lot of possible uses in industry. A conveyor belt, sanding belt or drive belt made from a Möbius strip would wear evenly on both sides. A computer printer ribbon made from a Möbius strip would last twice as long, and a recording audio tape would record for twice as long.
A Möbius strip scarf will lie flat under a jacket or coat. The Möbius strip is used as the 'reduce – reuse – recycle' recycling symbol.
Measuring Slopes: Make a Clinometer
Shapes: Looking at Tessellation
Proving 1=2 and 2=3
A Fractal Pattern
Get Knotted: Learn About Topology
Encouraging Children...
Biology...
Chemistry...
Physics...
Environment & Meteorology...
Maths...
Facts, Figures & Trivia...
Psychology...


Писатель vs критик: полемика об уральцах в русской печати середины XIX в.
Sukhikh, O. E. (2005). Imperiya napokaz, ili Imperskij opyt vospitaniya vernopoddannicheskih chuvstv u kazahskoj znati v XVIII–XIX vv. [Empire for Show, or Imperial Experience of Educating Loyalty in the Kazakh Aristocracy in the 18th–19th Centuries]. In Aziatskaya Rossiia: lyudi i struktury imperii. K 50-letiyu so dnya rozhd. prof. A. V. Remneva: sb. nauch. st. [Asian Russia: People and Structures of the Empire. For Professor A. V. Remnev's 50th Birthday. A Collection of Scholarly Articles] (pp. 149–162). Omsk: Omsk State University Press.
Zykova, G. V. (2005). Poėtika russkogo zhurnala 1830–1870-kh gg. [The Poetics of a Russian Magazine of the 1830s–1870s]. Moscow: MAKS Press.


text:
import { JsExpression } from './js-expression';
import { JsonPointer } from 'jsonpointerx';

function newTestExpression(expression: string, context?: any, thisArg?: any): JsExpression {
  let res = JsExpression.compile(expression);
  res.context = context;
  res.thisArg = thisArg;
  return res;
}

function testExpression(expression: string, result: any, context?: any, thisArg?: any): void {
  let compiled = newTestExpression(expression, context, thisArg);
  expect(compiled.run()).toEqual(result, `result of ${expression} is not ${result}`);
}

describe('js-expression test suite', () => {
  let expr: string;
  let context: any;
  let thisArg: any;
  let compiled: JsExpression;

  it('context members', () => {
    context = { a: 42, b: { c: { d: 9 } } };
    thisArg = undefined;

    expr = 'a';
    compiled = newTestExpression(expr, context, thisArg);
    expect(compiled.run()).toEqual(
      context.a,
      `expr ${expr} failed for context ${compiled.context}`,
    );
    context.a = 13;
    expect(compiled.run()).toEqual(
      context.a,
      `expr ${expr} failed for context ${compiled.context}`,
    );

    expr = "b.c['d']";
    compiled = newTestExpression(expr, context, thisArg);
    expect(compiled.run()).toEqual(
      context.b.c.d,
      `expr ${expr} failed for context ${compiled.context}`,
    );
    context.b.c.d += 1;
    expect(compiled.run()).toEqual(
      context.b.c.d,
      `expr ${expr} failed for context ${compiled.context}`,
    );

    expr = "b['c'].d";
    compiled = newTestExpression(expr, context, thisArg);
    context.b.c.d += 1;
    expect(compiled.run()).toEqual(
      context.b.c.d,
      `expr ${expr} failed for context ${compiled.context}`,
    );
    context.b.c.d += 1;
    expect(compiled.run()).toEqual(
      context.b.c.d,
      `expr ${expr} failed for context ${compiled.context}`,
    );

    expr = 'r';
    compiled = newTestExpression(expr, context, thisArg);
    expect(compiled.run()).toBeUndefined(`expr ${expr} failed for undefined variable`);

    expr = 'r.s';
    compiled = newTestExpression(expr, context, thisArg);
    expect(compiled.run()).toBeUndefined(`expr ${expr} failed for member of undefined variable`);

    expr = 'a.b.c && a.b.d';
    compiled = newTestExpression(expr, context, thisArg);
    expect(compiled.getContextMembersRoot()).toEqual(['a', 'b']);

    expr = 'a.b.c && b.c.d && c.d.e';
    compiled = newTestExpression(expr, context, thisArg);
    expect(compiled.getContextMembersRoot()).toEqual([]);
  });

  it('this members', () => {
    context = undefined;
    thisArg = { a: 42, b: { c: { d: 9 } } };

    expr = 'this.a';
    compiled = newTestExpression(expr, context, thisArg);
    expect(compiled.run()).toEqual(thisArg.a, `expr ${expr} failed for this ${compiled.thisArg}`);
    thisArg.a = 13;
    expect(compiled.run()).toEqual(thisArg.a, `expr ${expr} failed for this ${compiled.thisArg}`);

    expr = "this.b.c['d']";
    compiled = newTestExpression(expr, context, thisArg);
    expect(compiled.run()).toEqual(
      thisArg.b.c.d,
      `expr ${expr} failed for this ${compiled.thisArg}`,
    );
    thisArg.b.c.d += 1;
    expect(compiled.run()).toEqual(
      thisArg.b.c.d,
      `expr ${expr} failed for this ${compiled.thisArg}`,
    );

    expr = "this.b['c'].d";
    compiled = newTestExpression(expr, context, thisArg);
    thisArg.b.c.d += 1;
    expect(compiled.run()).toEqual(
      thisArg.b.c.d,
      `expr ${expr} failed for this ${compiled.thisArg}`,
    );
    thisArg.b.c.d += 1;
    expect(compiled.run()).toEqual(
      thisArg.b.c.d,
      `expr ${expr} failed for this ${compiled.thisArg}`,
    );

    expr = 'this.r';
    compiled = newTestExpression(expr, context, thisArg);
    expect(compiled.run()).toBeUndefined(`expr ${expr} failed for undefined member`);

    expr = 'this.r.s';
    compiled = newTestExpression(expr, context, thisArg);
    expect(compiled.run()).toBeUndefined(`expr ${expr} failed for member of undefined member`);

    expr = 'this.a.b.c && this.a.x.y';
    compiled = newTestExpression(expr, context, thisArg);
    expect(compiled.getThisMembersRoot()).toEqual(['a']);
  });

  it('expressions', () => {
    context = { a: 4, b: 0 };
    testExpression('a < 5', true, context);
    testExpression('a >= 4', true, context);
    testExpression('a > 4', false, context);

    testExpression('!a', false, context);
    testExpression('!b', true, context);

    testExpression('!!a', true, context);
    testExpression('!!b', false, context);

    testExpression('a < 5 && b <= 0', true, context);

    testExpression('!(a < 5) && !(b <= 0)', false, context);
    testExpression('a > 5 && b >= 0', false, context);

    testExpression('b == 0', true, context);
    testExpression('b === 0', true, context);

    context.c = 7;
    testExpression('c ? a : b', 4, context);
    context.c = 0;
    testExpression('c ? a : b', 0, context);

    testExpression('[1,2]', [1, 2], undefined);
  });

  it('expect run to return undefined if no expression has been compiled', () => {
    let jse = new JsExpression();
    expect(jse.run()).toBeUndefined();
  });

  it('expect unknown variable to be undefined', () => {
    context = {};
    testExpression('a', undefined, context);
  });

  it('expect unsupported binary operation to throw', () => {
    compiled = newTestExpression('5 % 3', undefined, undefined);
    expect(compiled.run()).toEqual(2, `result of 5 % 3 is not 2`);
    let modOp = JsExpression.binaryOps['%'];
    delete JsExpression.binaryOps['%'];
    expect(() => {
      JsExpression.compile('5 % 3');
    }).toThrow();
    JsExpression.binaryOps['%'] = modOp;
  });

  it('expect unsupported unary operation to throw', () => {
    context = { a: 4, b: 0 };
    compiled = newTestExpression('-a', context, undefined);
    expect(compiled.run()).toEqual(-context.a, `result of '-a' is not -${context.a}`);
    let negateOp = JsExpression.unaryOps['-'];
    delete JsExpression.unaryOps['-'];
    expect(() => {
      JsExpression.compile('-a');
    }).toThrow();
    JsExpression.unaryOps['-'] = negateOp;
  });

  it('add and remove binary operation should work', () => {
    JsExpression.addBinaryOp('^', 10, (a, b) => Math.pow(a, b));
    compiled = newTestExpression('5 ^ 3', undefined, undefined);
    expect(compiled.run()).toEqual(125, `result of 5 ^ 3 is not 125`);
    JsExpression.removeBinaryOp('^');
    expect(() => {
      JsExpression.compile('5 ^ 3');
    }).toThrow();
  });

  it('add and remove unary operation should work', () => {
    // tslint:disable-next-line no-bitwise
    JsExpression.addUnaryOp('~', (a) => ~a);
    compiled = newTestExpression('~3', undefined, undefined);
    expect(compiled.run()).toEqual(-4, `result of ~3 is not -4`);
    JsExpression.removeUnaryOp('~');
    expect(() => {
      JsExpression.compile('~3');
    }).toThrow();
  });

  it('expect compiledFn to work', () => {
    let compiledFnd = JsExpression.compiledFn('(a % b) + this.c');
    expect(compiledFnd({ c: 7 }, { a: 5, b: 3 })).toEqual(9);
  });

  it('expect compiledFn to work', () => {
    let compiledFnd = JsExpression.compiledFn('(a % b) + this.c');
    class TestClass {
      c = 7;
      testFunc: (context: any) => any;
      constructor() {
        this.testFunc = compiledFnd.bind(this, this);
      }
    }
    let testObj = new TestClass();
    expect(testObj.testFunc({ a: 5, b: 3 })).toEqual(9);
  });
});


text:
BAKER REPORT: SITUATION "GRAVE AND DETERIORATING"
by Jim Lobe
Neo-Cons Move to Preempt Baker Report
(IPS) WASHINGTON -- Calling the situation in Iraq "grave and deteriorating," the bipartisan Iraq Study Group (ISG) Wednesday urged a major overhaul of U.S. policies both in Iraq and the larger Middle East.
As anticipated, the 10-member group, which was co-chaired by former Secretary of State James Baker and former Rep. Lee Hamilton, called for a phase-out of the U.S. combat role in Iraq between now and the first quarter of 2008 and an intensification of efforts to train and deploy Iraqi forces.
Among 79 recommendations included in its report, the ISG also called for urgently convening all of Iraq's neighbors, including Syria and Iran, as part of a comprehensive "New Diplomatic Offensive" designed to both stabilise Iraq and to address "key regional issues," including the Arab-Israeli conflict.
"There must be a renewed and sustained commitment by the United States to a comprehensive Arab-Israeli peace on all fronts: Lebanon, Syria, and President George W. Bush's June 2002 commitment to a two-state solution for Israel and Palestine," the 142-page asserted in an implicit rebuke to Bush's neglect of these conflicts.
Calling on Washington to "act boldly," the report, which was adopted unanimously by the group's members, declared that "The United States does its ally Israel no favors in avoiding direct involvement to solve the Arab-Israeli conflict."
"You cannot look at this area of the world and pick and choose among the countries that you're going to deal with," Hamilton, the director of the Woodrow Wilson International Center here, told a press briefing where the report was officially released. "Everything in the Middle East is connected to everything else, and this diplomatic initiative that we have put forward recognizes that."
The report, which also called for increased U.S. military and other assistance for Afghanistan's government, was delivered to the White House at a breakfast meeting between the ISG and Bush early Wednesday. Bush thanked its members for their work and pledged to take its ideas "very seriously."
How seriously he will take them, however, is the subject of much speculation here. Just last week, for example, Bush appeared to rule out direct talks with either Damascus or Tehran, although the White House Wednesday stressed that it was prepared to engage the two countries as part of the "Iraq Compact Group" which last met, however, in 2004.
Most political analysts here insist that Bush's response could well depend on the degree to which Democrats rally behind the report and the reaction of key Republican lawmakers, who, shaken by their loss of Congress in last month's elections, have become increasingly impatient with the White House's insistence that its current strategy in Iraq and the region is working or needs only a few tactical adjustments.
The Congressionally-mandated ISG began work last March and included former Defense Secretary William Perry; former Attorney-General Edward Meese, and President Bill Clinton's chief of staff, Leon Panetta, and former Supreme Court Justice Sandra Day O'Connor, among others.
In addition to offering policy recommendations, its main purpose was to de-politicize the increasingly rancorous debate over Iraq by forming a consensus designed to appeal to centrists in both parties. "This country cannot be at war and be as divided as we are today," Panetta said.
The report thus explicitly ruled out policy options supported by the two parties' core constituencies. It warned, for example, that a "precipitate withdrawal of troops" from Iraq, as favoured by some Democrats, would result in "a significant power vacuum, greater human suffering, regional destabilization, and a threat to the global economy."
It also predicted that dividing Iraq into three autonomous regions, as proposed by the incoming Senate Foreign Relations Committee chairman, Joseph Biden, would "likely result in a humanitarian disaster or a broad-based civil war."
Conversely, it ruled out a "stay-the-course" solution as "no longer viable." "The United States must not make an open-ended commitment to keep large numbers of American troops deployed in America," Hamilton said.
Indeed, the tone of both the report and Wednesday's briefing was both urgent and grim, as both co-chairs stressed repeatedly that the time for reversing the situation in Iraq was fast running out and may in fact already have done so.
"We believe that the situation in Iraq is very, very serious," noted Hamilton. "We do not know if it can be turned around, but we think we have an obligation to try, and if the recommendations that we have made are effectively implemented, there is at least a chance that you can see established a stable government in Iraq and stability in the region."
On Iraq itself, the report stressed that the U.S. should draw down virtually all of its combat troops over the next 15 months at the same time that it increases the number of U.S. trainers and troops "embedded" with Iraqi army units from the current 4,000 to as many as 20,000.
It did not rule out a substantial increase in the 140,000 troops currently deployed to Iraq, as a number of Republican hawks Ð and some retired generals -- have recently urged to curb violence in Baghdad, but warned that any major increase will not be sustainable in the medium or long term.
Stressing that no military solution in Iraq was possible, the report called for the U.S. to "engage all parties in Iraq, with the exception of al Qaeda" and for Bush to state that Washington does not seek either permanent military bases there or control of its oil.
It also urged Washington to set a series of specific objectives -- or "milestones" -- for furthering national reconciliation, security, and governance. If, however, the Iraqi government fails to make "substantial progress" toward their achievement, "the United States should reduce its political, military, or economic support," the report said.
As for the New Diplomatic Offensive, which is likely to prove the most controversial part of the report, the ISG stressed that it should go "beyond the primarily economic Compact for Iraq" by addressing political, diplomatic, and security issues throughout the region.
It called for the U.S. to "immediately seek the creation of the Iraq International Support Group" to include all of the country's neighbors, as well as key countries in the region and the world. All of Iraq's neighbors, including Syria and Iran, according to the ISG, "favor a unified Iraq that is strong enough to maintain its territorial integrity, but not so powerful as to threaten its neighbors."
"Under the aegis of the New Diplomatic Offensive and the Support Group, the United States should engage directly with Iran and Syria in order to try to obtain their commitment to constructive policies toward Iraq and other regional issues," the report stated, noting that Washington should "consider incentives to engage them constructively, much as it did successfully with Libya."
According to Baker, who met earlier in the fall with senior representatives from both countries, "we didn't get the feeling that Iran is chomping at the bit to come to the table with us to talk about Iraq, and, in fact, we say (in the report) we think they very well might not." On the other hand, he said, "there's some strong indications that (Syria) would be in a position to help us and might want to help us."
As to the wider regional context, including the Arab-Israelis conflict, the ISG called for "the unconditional calling and holding of meetings, under the auspices of the United States or the Quartet between Israel and Lebanon and Syria on the one hand, and Israel and Palestinians (who acknowledge Israel's right to exist) on the other... as soon as possible."
The aim would be "to negotiate peace as was done at the Madrid conference in 1991, and on two separate tracks -- one Syrian/Lebanese, and the other Palestinian."
Albion Monitor December 7, 2006 (http://www.albionmonitor.com)


A beautifully created weathervane depicting a Falcon.Ea..
A beautifully created DIY weathervane kit depicting a B..
A beautifully created DIY weathervane kit depicting a t..
The Pheasant - a most beautiful bird. Shown here in the..
The sweet sound of Jenny Wren's call - a highlight of S..
"Henrietta" a nice alternative to the traditional Roost..
Nothing is more traditional than the Old Rooster. This ..
"The Predator - nature's most feared bird of prey. Show..
A stunning scene of two Magpies chattering on a branch ..
Two wild geese search for a nesting site in the undergr..


text:
Hello Neighbor is a horror game for cowards
2017-02-01 15:00:00by Mike Cosimano
No jump scares!
When I arrived at TinyBuild's PAX South booth for my Hello Neighbor appointment, hoping to either get a hold of somebody or hop on a station myself, I noticed something that both piqued my interest and got me a little worried: a lot of kids were playing the game. And I'm only 21 years old, so you know that when I say "kids," I mean "actual children."
To me, that meant that either Hello Neighbor was a kid-friendly game or a popular YouTuber had gotten their hands on it. Or both! (See also: Minecraft.) Turns out I was right -- the "stealth horror" title is fairly popular on YouTube, as you'd expect from a video game that feels like it owes more than a little to the Slender craze. According to TinyBuild CEO Alex Nichiporchik, that is absolutely intentional. "Our target demographic is the 'Minecraft Generation'," Nichiporchik said to me at PAX South.
If my reconnaissance told me anything, the team was absolutely successful in targeting young players. The kids I saw playing Hello Neighbor seemed like they were having a blast. It's not hard to see why -- the game has all the mechanical trappings of a YouTube-friendly survival horror game, but it's been designed to avoid potentially frightening jump scares and has been endowed with a cartoony aesthetic that feels more Toontown than Resident Evil 7.
Oh, what's that he said? No jump scares in a horror game?! Yes, Hello Neighbor is a game that wants you to float on the surface tension of its atmosphere, rather than drown in it. In a game like Resident Evil 7, the unkillable monstrosities stalking you look like they've been taking late-night ugly classes down at the community college. When they inevitably catch you, these horrid fiends relocate your guts from the warzone that is your tum-tum. Good stuff! But in Hello Neighbor, your adversary looks like one of the snobs from an '80s skiing movie grew up and inflated his skull with a basketball pump. He's a silly cartoon man, and that's absolutely the intended tone. "The original alpha builds were more violent and curse-y. We toned it down so kids would be able to play it," Nichiporchik said.
Here's the pitch: you're breaking into your neighbor's house in the hopes of getting into his mysterious basement. Along the way, you'll solve minor environmental puzzles, all while avoiding the titular Neighbor. You have no method of defending yourself, which feels odd when you're at eye level with this character and you've got a wrench ready to go in your right hand. So, if you've ever played a horror game where you're being stalked by a monster you can only run from, you know the score. Open a door you shouldn't, there he is, run away, find a closet, hope he leaves. Supposedly, the AI will learn from your behavior and set traps, but I never saw anything quite that sophisticated.
When the Neighbor catches you, you just respawn across the street, all set for another run. There's no horrifying death, no screams, no awful in-your-face moment. He just runs up to you and that's it. Since the game allows you to keep some items after you die, at points it almost feels like you're speedrunning, rather than being stealthy. "We give you all the information to avoid jump scares," Nichiporchik told us. "We want tension and anxiety, not jumps." He wasn't kidding; the game makes it painfully clear when the neighbor is onto you, with both excessive sound and visual cues. I found myself laughing when I was caught, rather than shrieking in terror or (in the case of my Until Dawn PAX demo, all those years ago) instinctively raising my arms to defend myself, slapping myself in the face, and knocking my headphones off. Hello Neighbor is, uh, an improvement.
My only concern is longevity. The game will probably be a tremendous hit with kids looking to follow in their favorite personalities' steps, but for the rest of us, it still costs $30 USD. I caught a glimpse of a menu option in the build I was shown that appeared to show different break-in scenarios (the one I played involved some bad sounds coming from the Neighbor's basement), which could do a lot to make the game feel replayable. Maybe there could be a scenario where you have to break into a house occupied by a whole family, and only the parents will make you respawn but the kids will just go run and alert the parents?
The full game will ostensibly be much larger than the one-story house I was shown, containing about "ten hours of gameplay" in total, but I assume that's if you're trying to sneak around the way the designers intended. Since there was no apparent penalty for failure, I can see myself constantly bum-rushing the house and grabbing the items I need, potentially shaving hours off my playtime. The four Alpha builds released to the public cannot be "combined into one thing," according to Nichiporchik, so the full game is still an unknown quantity to the public. "Nobody knows what the full game is, but we have an idea," Nichiporchik said.
Hello Neighbor is a bright, approachable horror game, and I know that sounds ludicrous. It's a Slender-like the whole family can enjoy! People who like horror from a clinical perspective but can't handle the jump scares in practice are an unserved niche. That kind of genre fan deserves a game made just for them -- bonus points if it ends up being good. Hello Neighbor may not be at the top of my "most anticipated list," but it looks sturdy in the Alpha stage, even if it doesn't yet boast a $30 hook.
Mike CosimanoSenior Reporter gamer profile
It takes a lot to make a stew. more + disclosures
Also on Destructoid: Hello Neighbor (1) From our database:
Hello Neighbor is a horror game for cowards - Mike Cosimano
Filed under... #Alpha #Horror #notable #PAX #Previews #TinyBuild


text:
The Queensland Eco Village developed over 30 years ago, founded on Permaculture principles.
Welcome to CW
Eco Park – Village Camping Area
Eco Park information
Make an ecopark booking
Crystal Waters Permaculture
CW Permaculture Course 2021
Permaculture Steve Cran
PDC booking form
Village Markets
The Documentary
Permaculture 2021
Crystal Waters PDC Course
REGISTRATION for this course is now open!
Scroll Down for information and Register your position in a 2021 Permaculture Course at Crystal Waters
The Centre of Advanced Permaculture (CAP) led by Steve Cran, provide a range of essential skills for energetic people of all ages who see the need to stand up and be active in these challenging times.
In this 2-week Residential Course set in Crystal Waters Permaculture Village, you Learn to design and build resilient systems using locally available materials in all-terrains and climate. Steve has extensive experience in practical trainings in Permaculture, so this PDC is comprehensive with lots of hands-on practical. As a participant, you get to experience Permaculture and do organic gardening best practices with like-minded people. This Training is also designed to teach you how to adapt to social and climate change events.
* Covers all essential PDC curriculum Topics
* 50% hands-on real-time skills
* Sustainable livelihoods
* Alternative Building & structures
* Organic Vegetable production
* Soils, Seeds and sustainability
* Design for your own property or for others
* Earth repair and environment regeneration
* Best-practices for climate adaptation & resilience
* We cover humanitarian & disaster response
This Permaculture "PDC" is also offered as an initial Permaculture Training experience for people wishing to advance their knowledge and abilities as a Permaculture teacher and field Trainer, into a 10-week Residential Programme. If you choose, you can integrate this PDC into the Full Program which is run here at CAP in Crystal Waters Permaculture Village. Discuss details with Steve.
The Centre of Advanced Permaculture has a mission to train new effective Permaculture teachers and project managers to a high standard. These trainers and project managers will seed further permaculture field schools and other CAP's around the world and link them with the central CAP. Currently, there are very few dedicated permaculture schools offering this level of training for permaculture trainers as a career path.
"The only future for the human race is a sustainable one, so let's make it so!"
Founder of CAP (Centre of Advanced Permaculture):
Steve Cran
Permaculture aid specialist, permaculture consultant, teacher, and climate adaptation specialist
Steve Cran is a Permaculture Aid veteran, teacher, social activist, climate change resilience specialist and a very handy guy to have around after a natural disaster. With a 30+-year career in Permaculture, Steve has developed effective, sustainable, recovery solutions for communities affected by natural disasters, war, or long-term poverty.
He was an early resident of Crystal Waters in the 90's then has travelled and taught Permaculture extensively Internationally. In 2019 Steve returned to Crystal Waters to develop a Permaculture School and Gardens to exhibit what's possible and to help stimulate the expansion of Permaculture in the Crystal Waters EcoVillage over the next several years.
Steve takes on the challenge of assisting people from all backgrounds and all types of lifestyles, to rebuild their resilience and sustainability knowledge so that those students can take their experience back into their own communities. Steve has developed projects in war zones, post disaster zones, poverty zones and in many difficult areas on this troubled planet where most people would not dare go. Here in Australia with both Locals and travellers – Steve now aims to show people how to use Permaculture strategies to develop places and Centres all around Australia as examples of what people can do in their own lives when given the knowledge and experiences such as what is taught in the Permaculture Design Course (PDC).
The 2-week Residential Course is now Open for a limited number of participants in the 2021 New Year
Early-bird price: $1850 paid by January 29 (Couples: $3,000). $2,000 after February 1st, 2021.
All Meals/Food is provided during the Course, with Camping & Accommodation nearby.
The location of the Course will mainly be on the Crystal Waters CAP Campus at upper Lot 1 above the roundabout near the Village Green at Crystal Waters EcoVillage in SE Queensland.
View Location and other details about Crystal Waters at www.crystalwaters.org.au
About Crystal Waters Permaculture Village
GATHERING OF CRYSTAL WATERS FOLK
Crystal Waters Permaculture Village was established at the headwaters of the Mary River in the Sunshine Coast Hinterland in 1988. Around 250 people live on 84 residential lots within the 650 acre property.
All Enquiries & Bookings can be directed to Bruce Gibson:
Visit our Facebook Page for updates and announcements.
Add yourself to our News Updates for PDC Courses at Crystal Waters EcoVillage.
65 Kilcoy Lane
Conondale, Qld, 4552
CW History and background
Eco Park - Village Camping Area
Services / Business
Permaculture Course 2021
© 2019 Crystal Waters. Website Designed and maintained by Bruce Gibson - Digital Organics.